git: bb8d0944b5d5 - main - e1000: Verify i210 and i211 multicast table writes
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 11 Aug 2026 20:59:56 UTC
The branch main has been updated by kbowling:
URL: https://cgit.FreeBSD.org/src/commit/?id=bb8d0944b5d53863f00492b69b7bf13d2618fc95
commit bb8d0944b5d53863f00492b69b7bf13d2618fc95
Author: Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-08-11 17:35:43 +0000
Commit: Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-08-11 20:59:32 +0000
e1000: Verify i210 and i211 multicast table writes
The i210 and i211 can occasionally fail to accept multicast table
writes, particularly while addresses are added and removed rapidly.
Read the table back and rewrite mismatches for up to three passes.
This prevents multicast reception from retaining stale filter state
while keeping the workaround limited to the affected controllers.
MFC after: 2 weeks
---
sys/dev/e1000/e1000_mac.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/sys/dev/e1000/e1000_mac.c b/sys/dev/e1000/e1000_mac.c
index 46e91773c126..f311df658d78 100644
--- a/sys/dev/e1000/e1000_mac.c
+++ b/sys/dev/e1000/e1000_mac.c
@@ -584,6 +584,37 @@ u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr)
return hash_value;
}
+/**
+ * e1000_i21x_check_mta - Verify MTA writes on i210 and i211
+ * @hw: pointer to the HW structure
+ *
+ * The i210 and i211 can occasionally fail to accept MTA writes. Read the
+ * table back and rewrite mismatched entries, with a bounded retry count.
+ **/
+static void
+e1000_i21x_check_mta(struct e1000_hw *hw)
+{
+ bool failed;
+ int i, retries = 3;
+
+ do {
+ 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])
+ continue;
+ failed = true;
+ E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i,
+ hw->mac.mta_shadow[i]);
+ E1000_WRITE_FLUSH(hw);
+ }
+ if (failed && --retries == 0) {
+ DEBUGOUT("Failed to update MTA after retries\n");
+ break;
+ }
+ } while (failed);
+}
+
/**
* e1000_update_mc_addr_list_generic - Update Multicast addresses
* @hw: pointer to the HW structure
@@ -619,6 +650,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_check_mta(hw);
}
/**