summaryrefslogtreecommitdiff
path: root/sys/dev/usb/if_axe.c
diff options
context:
space:
mode:
authorRyan Thomas McBride <mcbride@cvs.openbsd.org>2004-06-06 17:56:38 +0000
committerRyan Thomas McBride <mcbride@cvs.openbsd.org>2004-06-06 17:56:38 +0000
commitb66d62c67d0c6e9c9e272002eb94f76bae347204 (patch)
treeb1065a5eafec1ecf572afc4d953b647595905f87 /sys/dev/usb/if_axe.c
parentc2d42bcab482d8ff7df96f4a747d47aacb855904 (diff)
Multicast cleanups
- make multicast ranges work - replace handrolled crc code with ether_crc32_{be,le}() - add missing calls to ether_{add,del}multi() ok deraadt@
Diffstat (limited to 'sys/dev/usb/if_axe.c')
-rw-r--r--sys/dev/usb/if_axe.c39
1 files changed, 12 insertions, 27 deletions
diff --git a/sys/dev/usb/if_axe.c b/sys/dev/usb/if_axe.c
index 9249aabaf3a..07e84ba11a4 100644
--- a/sys/dev/usb/if_axe.c
+++ b/sys/dev/usb/if_axe.c
@@ -189,7 +189,6 @@ Static void axe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
Static void axe_reset(struct axe_softc *sc);
Static void axe_setmulti(struct axe_softc *);
-Static u_int32_t axe_mchash(caddr_t);
Static void axe_lock_mii(struct axe_softc *sc);
Static void axe_unlock_mii(struct axe_softc *sc);
@@ -346,29 +345,6 @@ axe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
ifmr->ifm_status = mii->mii_media_status;
}
-Static u_int32_t
-axe_mchash(caddr_t addr)
-{
- u_int32_t crc, carry;
- int idx, bit;
- u_int8_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);
-}
-
Static void
axe_setmulti(struct axe_softc *sc)
{
@@ -401,7 +377,7 @@ axe_setmulti(struct axe_softc *sc)
ETHER_ADDR_LEN) != 0)
goto allmulti;
- h = axe_mchash(enm->enm_addrlo);
+ h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) >> 26;
hashtbl[h / 8] |= 1 << (h % 8);
ETHER_NEXT_MULTI(step, enm);
}
@@ -1256,8 +1232,17 @@ axe_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
- axe_setmulti(sc);
- error = 0;
+ error = (cmd == SIOCADDMULTI) ?
+ ether_addmulti(ifr, &sc->arpcom) :
+ ether_delmulti(ifr, &sc->arpcom);
+ if (error == ENETRESET) {
+ /*
+ * Multicast list has changed; set the hardware
+ * filter accordingly.
+ */
+ axe_setmulti(sc);
+ error = 0;
+ }
break;
case SIOCGIFMEDIA:
case SIOCSIFMEDIA: