[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