summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authornaddy <naddy@FreeBSD.org>2004-06-09 00:25:44 +0000
committernaddy <naddy@FreeBSD.org>2004-06-09 00:25:44 +0000
commit63528fda2c419d469b34b2b3dfebaf0fb1dd40fc (patch)
tree314b29de7f16f06ef11e67cc4e6135082906d615 /sys
parent10c0032386a6a1aef02048598a920c5ab2a27e0e (diff)
downloadFreeBSD-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.c38
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);
OpenPOWER on IntegriCloud