aboutsummaryrefslogtreecommitdiff
path: root/hw/net/e1000e_core.c
diff options
context:
space:
mode:
authorAkihiko Odaki <akihiko.odaki@daynix.com>2023-02-23 19:19:57 +0900
committerJason Wang <jasowang@redhat.com>2023-03-10 15:35:38 +0800
commit86343066ba8ad5253db86a300da287c30d58231e (patch)
tree64efbc64c58e8cb19a9cf48766e60044441d8148 /hw/net/e1000e_core.c
parent31e3f318c8b53597a18f6475dce402d68518e91e (diff)
e1000e: Improve software reset
This change makes e1000e reset more things when software reset was triggered. Some registers are exempted from software reset in the datasheet and this change also implements the behavior accordingly. Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> Signed-off-by: Jason Wang <jasowang@redhat.com>
Diffstat (limited to 'hw/net/e1000e_core.c')
-rw-r--r--hw/net/e1000e_core.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
index 37aec6a970..b8670662c8 100644
--- a/hw/net/e1000e_core.c
+++ b/hw/net/e1000e_core.c
@@ -58,6 +58,8 @@
static inline void
e1000e_set_interrupt_cause(E1000ECore *core, uint32_t val);
+static void e1000e_reset(E1000ECore *core, bool sw);
+
static inline void
e1000e_process_ts_option(E1000ECore *core, struct e1000_tx_desc *dp)
{
@@ -1882,7 +1884,7 @@ e1000e_set_ctrl(E1000ECore *core, int index, uint32_t val)
if (val & E1000_CTRL_RST) {
trace_e1000e_core_ctrl_sw_reset();
- e1000x_reset_mac_addr(core->owner_nic, core->mac, core->permanent_mac);
+ e1000e_reset(core, true);
}
if (val & E1000_CTRL_PHY_RST) {
@@ -3488,8 +3490,7 @@ static const uint32_t e1000e_mac_reg_init[] = {
[EITR...EITR + E1000E_MSIX_VEC_NUM - 1] = E1000E_MIN_XITR,
};
-void
-e1000e_core_reset(E1000ECore *core)
+static void e1000e_reset(E1000ECore *core, bool sw)
{
int i;
@@ -3499,8 +3500,15 @@ e1000e_core_reset(E1000ECore *core)
memset(core->phy, 0, sizeof core->phy);
memcpy(core->phy, e1000e_phy_reg_init, sizeof e1000e_phy_reg_init);
- memset(core->mac, 0, sizeof core->mac);
- memcpy(core->mac, e1000e_mac_reg_init, sizeof e1000e_mac_reg_init);
+
+ for (i = 0; i < E1000E_MAC_SIZE; i++) {
+ if (sw && (i == PBA || i == PBS || i == FLA)) {
+ continue;
+ }
+
+ core->mac[i] = i < ARRAY_SIZE(e1000e_mac_reg_init) ?
+ e1000e_mac_reg_init[i] : 0;
+ }
core->rxbuf_min_shift = 1 + E1000_RING_DESC_LEN_SHIFT;
@@ -3517,6 +3525,12 @@ e1000e_core_reset(E1000ECore *core)
}
}
+void
+e1000e_core_reset(E1000ECore *core)
+{
+ e1000e_reset(core, false);
+}
+
void e1000e_core_pre_save(E1000ECore *core)
{
int i;