summaryrefslogtreecommitdiffstats
path: root/sys/dev/re
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2007-01-11 20:31:35 +0000
committerwpaul <wpaul@FreeBSD.org>2007-01-11 20:31:35 +0000
commite11910c3d4e61048b0c0c4d5938f9a0593cfa8ac (patch)
tree1bbf536ba52e5a4b4adaa4397fba319d2aee3875 /sys/dev/re
parentb069330b5dbcbbaa7e679c4afe7bfef6aea0f8a2 (diff)
downloadFreeBSD-src-e11910c3d4e61048b0c0c4d5938f9a0593cfa8ac.zip
FreeBSD-src-e11910c3d4e61048b0c0c4d5938f9a0593cfa8ac.tar.gz
Fix re_setmulti() so that it works correctly for PCIe chips where
the multicast hash table are in reverse order compared to older devices.
Diffstat (limited to 'sys/dev/re')
-rw-r--r--sys/dev/re/if_re.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c
index 2ea024d..6eae2ac 100644
--- a/sys/dev/re/if_re.c
+++ b/sys/dev/re/if_re.c
@@ -620,6 +620,7 @@ re_setmulti(sc)
struct ifmultiaddr *ifma;
u_int32_t rxfilt;
int mcnt = 0;
+ u_int32_t hwrev;
RL_LOCK_ASSERT(sc);
@@ -660,8 +661,24 @@ re_setmulti(sc)
rxfilt &= ~RL_RXCFG_RX_MULTI;
CSR_WRITE_4(sc, RL_RXCFG, rxfilt);
- CSR_WRITE_4(sc, RL_MAR0, hashes[0]);
- CSR_WRITE_4(sc, RL_MAR4, hashes[1]);
+
+ /*
+ * For some unfathomable reason, RealTek decided to reverse
+ * the order of the multicast hash registers in the PCI Express
+ * parts. This means we have to write the hash pattern in reverse
+ * order for those devices.
+ */
+
+ hwrev = CSR_READ_4(sc, RL_TXCFG) & RL_TXCFG_HWREV;
+
+ if (hwrev == RL_HWREV_8100E || hwrev == RL_HWREV_8101E ||
+ hwrev == RL_HWREV_8168_SPIN1 || hwrev == RL_HWREV_8168_SPIN2) {
+ CSR_WRITE_4(sc, RL_MAR0, bswap32(hashes[1]));
+ CSR_WRITE_4(sc, RL_MAR4, bswap32(hashes[0]));
+ } else {
+ CSR_WRITE_4(sc, RL_MAR0, hashes[0]);
+ CSR_WRITE_4(sc, RL_MAR4, hashes[1]);
+ }
}
static void
OpenPOWER on IntegriCloud