diff options
author | wpaul <wpaul@FreeBSD.org> | 2007-01-11 20:31:35 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2007-01-11 20:31:35 +0000 |
commit | e11910c3d4e61048b0c0c4d5938f9a0593cfa8ac (patch) | |
tree | 1bbf536ba52e5a4b4adaa4397fba319d2aee3875 /sys | |
parent | b069330b5dbcbbaa7e679c4afe7bfef6aea0f8a2 (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/dev/re/if_re.c | 21 |
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 |