diff options
author | Pyun YongHyeon <yongari@FreeBSD.org> | 2010-04-29 17:28:07 +0000 |
---|---|---|
committer | Pyun YongHyeon <yongari@FreeBSD.org> | 2010-04-29 17:28:07 +0000 |
commit | 9c2851d29a3b7ad24d63e3c84ed6c54df04afb30 (patch) | |
tree | ce30258b1b237040fbc31ec1aa9d108631a896c7 /sys/dev/sge | |
parent | 82bfb965d1df947e0f3e0ce4605ac9fc1f18b1ed (diff) | |
download | src-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.c | 31 |
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]); |