[PATCH v1 2/3] net/e1000/base: retry failed MTA writes on i210/i211
Anatoly Burakov
anatoly.burakov at intel.com
Fri Oct 16 12:23:00 CEST 2026
From: Dima Ruinskiy <dima.ruinskiy at intel.com>
On i210 and i211, writes to the multicast table array (MTA) sometimes
fail silently, leaving the hardware MTA out of sync with the driver's
`mta_shadow` copy.
After updating the MTA in `e1000_update_mc_addr_list_generic()`, read
the registers back on these devices and compare them with `mta_shadow`.
Rewrite any register that does not match, up to three attempts.
Signed-off-by: Grzegorz Siwik <grzegorz.siwik at intel.com>
Signed-off-by: Dima Ruinskiy <dima.ruinskiy at intel.com>
Signed-off-by: Yashaswini Raghuram Prathivadi Bhayankaram <yashaswini.raghuram.prathivadi.bhayankaram at intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov at intel.com>
---
.mailmap | 1 +
drivers/net/intel/e1000/base/e1000_mac.c | 34 ++++++++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/.mailmap b/.mailmap
index 6d9e262cfb..f2e35dd968 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1927,6 +1927,7 @@ Yaron Illouz <yaroni at radcom.com>
Yaroslav Brustinov <ybrustin at cisco.com>
Yash Sharma <ysharma at marvell.com>
Yashaswini Kanaujia <ykanaujia at marvell.com>
+Yashaswini Raghuram Prathivadi Bhayankaram <yashaswini.raghuram.prathivadi.bhayankaram at intel.com>
Yasufumi Ogawa <ogawa.yasufumi at lab.ntt.co.jp> <yasufum.o at gmail.com>
Ye Chen <yex.chen at intel.com>
Yehor Malikov <yehor.malikov at solidigm.com>
diff --git a/drivers/net/intel/e1000/base/e1000_mac.c b/drivers/net/intel/e1000/base/e1000_mac.c
index 408e8e46e8..f794e24b75 100644
--- a/drivers/net/intel/e1000/base/e1000_mac.c
+++ b/drivers/net/intel/e1000/base/e1000_mac.c
@@ -549,6 +549,38 @@ u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr)
return hash_value;
}
+/**
+ * e1000_i21x_mta_workaround - workaround for MTA write failures
+ * @hw: pointer to the HW structure
+ *
+ * On I210/I211 sometimes multicast table array writes silently fail.
+ * Compare to MTA shadow to see if any registers are incorrectly written.
+ * If a mismatch is found, try to write again up to three times.
+ **/
+static void e1000_i21x_mta_workaround(struct e1000_hw *hw)
+{
+ int failed_cnt = 3;
+ bool is_failed;
+ int i;
+
+ do {
+ is_failed = false;
+ for (i = hw->mac.mta_reg_count - 1; i >= 0; i--) {
+ if (E1000_READ_REG_ARRAY(hw, E1000_MTA, i) !=
+ hw->mac.mta_shadow[i]) {
+ is_failed = true;
+ E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i,
+ hw->mac.mta_shadow[i]);
+ E1000_WRITE_FLUSH(hw);
+ }
+ }
+ if (is_failed && --failed_cnt <= 0) {
+ DEBUGOUT("Failed to update MTA register, too many retries\n");
+ break;
+ }
+ } while (is_failed);
+}
+
/**
* e1000_update_mc_addr_list_generic - Update Multicast addresses
* @hw: pointer to the HW structure
@@ -584,6 +616,8 @@ void e1000_update_mc_addr_list_generic(struct e1000_hw *hw,
for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]);
E1000_WRITE_FLUSH(hw);
+ if (hw->mac.type == e1000_i210 || hw->mac.type == e1000_i211)
+ e1000_i21x_mta_workaround(hw);
}
/**
--
2.52.0
More information about the dev
mailing list