aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/sge
diff options
context:
space:
mode:
authorPyun YongHyeon <yongari@FreeBSD.org>2010-04-29 17:28:07 +0000
committerPyun YongHyeon <yongari@FreeBSD.org>2010-04-29 17:28:07 +0000
commit9c2851d29a3b7ad24d63e3c84ed6c54df04afb30 (patch)
treece30258b1b237040fbc31ec1aa9d108631a896c7 /sys/dev/sge
parent82bfb965d1df947e0f3e0ce4605ac9fc1f18b1ed (diff)
downloadsrc-9c2851d29a3b7ad24d63e3c84ed6c54df04afb30.tar.gz
src-9c2851d29a3b7ad24d63e3c84ed6c54df04afb30.zip
Preserve unknown bits of RX MAC control register when driver
programs RX filter configuration. It seems RX MAC control register is one of key registers to get various offloading features as well as performance. Blindly clearing unrelated bits can result in unexpected results. Tested by: xclin <xclin <> cs dot nctu dot edu dot tw >
Notes
Notes: svn path=/head/; revision=207375
Diffstat (limited to 'sys/dev/sge')
-rw-r--r--sys/dev/sge/if_sge.c31
1 files changed, 16 insertions, 15 deletions
diff --git a/sys/dev/sge/if_sge.c b/sys/dev/sge/if_sge.c
index 6c737bd3f42e..49f6c0e673f0 100644
--- a/sys/dev/sge/if_sge.c
+++ b/sys/dev/sge/if_sge.c
@@ -453,8 +453,9 @@ sge_rxfilter(struct sge_softc *sc)
SGE_LOCK_ASSERT(sc);
ifp = sc->sge_ifp;
- hashes[0] = hashes[1] = 0;
- rxfilt = AcceptMyPhys;
+ rxfilt = CSR_READ_2(sc, RxMacControl);
+ rxfilt &= ~(AcceptBroadcast | AcceptAllPhys | AcceptMulticast);
+ rxfilt |= AcceptMyPhys;
if ((ifp->if_flags & IFF_BROADCAST) != 0)
rxfilt |= AcceptBroadcast;
if ((ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0) {
@@ -463,20 +464,20 @@ sge_rxfilter(struct sge_softc *sc)
rxfilt |= AcceptMulticast;
hashes[0] = 0xFFFFFFFF;
hashes[1] = 0xFFFFFFFF;
- goto done;
- }
- rxfilt |= AcceptMulticast;
- /* Now program new ones. */
- if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- crc = ether_crc32_be(LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr), ETHER_ADDR_LEN);
- hashes[crc >> 31] |= 1 << ((crc >> 26) & 0x1f);
+ } else {
+ rxfilt |= AcceptMulticast;
+ hashes[0] = hashes[1] = 0;
+ /* Now program new ones. */
+ if_maddr_rlock(ifp);
+ TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ if (ifma->ifma_addr->sa_family != AF_LINK)
+ continue;
+ crc = ether_crc32_be(LLADDR((struct sockaddr_dl *)
+ ifma->ifma_addr), ETHER_ADDR_LEN);
+ hashes[crc >> 31] |= 1 << ((crc >> 26) & 0x1f);
+ }
+ if_maddr_runlock(ifp);
}
- if_maddr_runlock(ifp);
-done:
CSR_WRITE_2(sc, RxMacControl, rxfilt | 0x02);
CSR_WRITE_4(sc, RxHashTable, hashes[0]);
CSR_WRITE_4(sc, RxHashTable2, hashes[1]);