diff options
author | naddy <naddy@FreeBSD.org> | 2004-06-09 00:25:44 +0000 |
---|---|---|
committer | naddy <naddy@FreeBSD.org> | 2004-06-09 00:25:44 +0000 |
commit | 63528fda2c419d469b34b2b3dfebaf0fb1dd40fc (patch) | |
tree | 314b29de7f16f06ef11e67cc4e6135082906d615 /sys | |
parent | 10c0032386a6a1aef02048598a920c5ab2a27e0e (diff) | |
download | FreeBSD-src-63528fda2c419d469b34b2b3dfebaf0fb1dd40fc.zip FreeBSD-src-63528fda2c419d469b34b2b3dfebaf0fb1dd40fc.tar.gz |
* Fix multicast reception.
* Replace handrolled crc calculation with ether_crc32_le().
Based on:
PR: 67544
Submitted by: HASHI Hiroaki <hashiz@tomba.cskk-sv.co.jp>
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/usb/if_udav.c | 38 |
1 files changed, 10 insertions, 28 deletions
diff --git a/sys/dev/usb/if_udav.c b/sys/dev/usb/if_udav.c index cb661bd..99dce8d 100644 --- a/sys/dev/usb/if_udav.c +++ b/sys/dev/usb/if_udav.c @@ -981,35 +981,9 @@ udav_activate(device_ptr_t self, enum devact act) #define UDAV_BITS 6 -#if defined(__NetBSD__) #define UDAV_CALCHASH(addr) \ (ether_crc32_le((addr), ETHER_ADDR_LEN) & ((1 << UDAV_BITS) - 1)) -#elif defined(__FreeBSD__) -Static uint32_t -udav_mchash(const uint8_t *addr) -{ - uint32_t crc, carry; - int idx, bit; - uint8_t data; - - /* Compute CRC for the address value. */ - crc = 0xFFFFFFFF; /* initial value */ - - for (idx = 0; idx < 6; idx++) { - for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1) { - carry = ((crc & 0x80000000) ? 1 : 0) ^ (data & 0x01); - crc <<= 1; - if (carry) - crc = (crc ^ 0x04c11db6) | carry; - } - } - - /* return the filter bit position */ - return((crc >> 26) & 0x0000003F); -} -#endif - Static void udav_setmulti(struct udav_softc *sc) { @@ -1069,8 +1043,9 @@ udav_setmulti(struct udav_softc *sc) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; - h = udav_mchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); - hashes[h / 8] |= 1 << (h % 8); + h = UDAV_CALCHASH(LLADDR((struct sockaddr_dl *) + ifma->ifma_addr)); + hashes[h>>3] |= 1 << (h & 0x7); } #endif @@ -1562,6 +1537,13 @@ udav_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) #endif switch (cmd) { +#if defined(__FreeBSD__) + case SIOCADDMULTI: + case SIOCDELMULTI: + udav_setmulti(sc); + error = 0; + break; +#endif case SIOCGIFMEDIA: case SIOCSIFMEDIA: mii = GET_MII(sc); |