diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2012-10-22 03:23:20 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2012-10-22 03:23:20 +0000 |
commit | 1838174698015be18ab381c6a3c08fe751b47886 (patch) | |
tree | cc366f63e48c419e2ccb5d03e2c41ba5e59c4221 | |
parent | 135858d9d657af51e59554a2194a240f86589d40 (diff) |
Rewrite the receive filter handling code and cleanup the ioctl bits.
Tested by and ok stsp@
-rw-r--r-- | sys/dev/usb/if_mos.c | 116 | ||||
-rw-r--r-- | sys/dev/usb/if_mosreg.h | 3 |
2 files changed, 37 insertions, 82 deletions
diff --git a/sys/dev/usb/if_mos.c b/sys/dev/usb/if_mos.c index c96146f60e6..cecf66beca2 100644 --- a/sys/dev/usb/if_mos.c +++ b/sys/dev/usb/if_mos.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_mos.c,v 1.16 2012/02/28 08:58:30 jsg Exp $ */ +/* $OpenBSD: if_mos.c,v 1.17 2012/10/22 03:23:19 brad Exp $ */ /* * Copyright (c) 2008 Johann Christian Rode <jcrode@gmx.net> @@ -180,7 +180,7 @@ int mos_readmac(struct mos_softc *, u_char *); int mos_writemac(struct mos_softc *, u_char *); int mos_write_mcast(struct mos_softc *, u_char *); -void mos_setmulti(struct mos_softc *); +void mos_iff(struct mos_softc *); void mos_lock_mii(struct mos_softc *); void mos_unlock_mii(struct mos_softc *); @@ -531,46 +531,41 @@ mos_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) } void -mos_setmulti(struct mos_softc *sc) +mos_iff(struct mos_softc *sc) { - struct ifnet *ifp; + struct ifnet *ifp = GET_IFP(sc); + struct arpcom *ac = &sc->arpcom; struct ether_multi *enm; struct ether_multistep step; u_int32_t h = 0; - u_int8_t rxmode; - u_int8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + u_int8_t rxmode, hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; if (usbd_is_dying(sc->mos_udev)) return; - ifp = GET_IFP(sc); - rxmode = mos_reg_read_1(sc, MOS_CTL); + rxmode &= ~(MOS_CTL_ALLMULTI | MOS_CTL_RX_PROMISC); + ifp->if_flags &= ~IFF_ALLMULTI; - if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { -allmulti: + if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) { + ifp->if_flags |= IFF_ALLMULTI; rxmode |= MOS_CTL_ALLMULTI; - mos_reg_write_1(sc, MOS_CTL, rxmode); - return; - } else - rxmode &= ~MOS_CTL_ALLMULTI; - - /* now program new ones */ - ETHER_FIRST_MULTI(step, &sc->arpcom, enm); - while (enm != NULL) { - if (memcmp(enm->enm_addrlo, enm->enm_addrhi, - ETHER_ADDR_LEN) != 0) - goto allmulti; - - h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) >> 26; - hashtbl[h / 8] |= 1 << (h % 8); - ETHER_NEXT_MULTI(step, enm); + if (ifp->if_flags & IFF_PROMISC) + rxmode |= MOS_CTL_RX_PROMISC; + } else { + /* now program new ones */ + ETHER_FIRST_MULTI(step, ac, enm); + while (enm != NULL) { + h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) >> 26; + + hashtbl[h / 8] |= 1 << (h % 8); + + ETHER_NEXT_MULTI(step, enm); + } } - ifp->if_flags &= ~IFF_ALLMULTI; mos_write_mcast(sc, (void *)&hashtbl); mos_reg_write_1(sc, MOS_CTL, rxmode); - return; } void @@ -1241,22 +1236,15 @@ mos_init(void *xsc) mos_reg_write_1(sc, MOS_IPG0, sc->mos_ipgs[0]); mos_reg_write_1(sc, MOS_IPG1, sc->mos_ipgs[1]); + /* Program promiscuous mode and multicast filters. */ + mos_iff(sc); + /* Enable receiver and transmitter, bridge controls speed/duplex mode */ rxmode = mos_reg_read_1(sc, MOS_CTL); rxmode |= MOS_CTL_RX_ENB | MOS_CTL_TX_ENB | MOS_CTL_BS_ENB; rxmode &= ~(MOS_CTL_SLEEP); - - /* If we want promiscuous mode, set the allframes bit. */ - if (ifp->if_flags & IFF_PROMISC) - rxmode |= MOS_CTL_RX_PROMISC; - - /* XXX: broadcast mode? */ - mos_reg_write_1(sc, MOS_CTL, rxmode); - /* Load the multicast filter. */ - mos_setmulti(sc); - mii_mediachg(GET_MII(sc)); /* Open RX and TX pipes. */ @@ -1303,8 +1291,6 @@ mos_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) struct mos_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *)data; struct ifaddr *ifa = (struct ifaddr *)data; - struct mii_data *mii; - u_int8_t rxmode; int s, error = 0; s = splnet(); @@ -1320,63 +1306,33 @@ mos_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) #endif break; - case SIOCSIFMTU: - if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu) - error = EINVAL; - else if (ifp->if_mtu != ifr->ifr_mtu) - ifp->if_mtu = ifr->ifr_mtu; - break; - case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { - if (ifp->if_flags & IFF_RUNNING && - ifp->if_flags & IFF_PROMISC && - !(sc->mos_if_flags & IFF_PROMISC)) { - rxmode = mos_reg_read_1(sc, MOS_CTL); - rxmode |= MOS_CTL_RX_PROMISC; - mos_reg_write_1(sc, MOS_CTL, rxmode); - mos_setmulti(sc); - } else if (ifp->if_flags & IFF_RUNNING && - !(ifp->if_flags & IFF_PROMISC) && - !(sc->mos_if_flags & IFF_PROMISC)) { - rxmode = mos_reg_read_1(sc, MOS_CTL); - rxmode |= MOS_CTL_RX_PROMISC; - mos_reg_write_1(sc, MOS_CTL, rxmode); - mos_setmulti(sc); - } else if (!(ifp->if_flags & IFF_RUNNING)) + if (ifp->if_flags & IFF_RUNNING) + error = ENETRESET; + else mos_init(sc); } else { if (ifp->if_flags & IFF_RUNNING) mos_stop(sc); } - sc->mos_if_flags = ifp->if_flags; - break; - case SIOCADDMULTI: - case SIOCDELMULTI: - 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. - */ - if (ifp->if_flags & IFF_RUNNING) - mos_setmulti(sc); - error = 0; - } break; + case SIOCGIFMEDIA: case SIOCSIFMEDIA: - mii = GET_MII(sc); - error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd); + error = ifmedia_ioctl(ifp, ifr, &sc->mos_mii.mii_media, cmd); break; default: error = ether_ioctl(ifp, &sc->arpcom, cmd, data); } + if (error == ENETRESET) { + if (ifp->if_flags & IFF_RUNNING) + mos_iff(sc); + error = 0; + } + splx(s); return(error); } diff --git a/sys/dev/usb/if_mosreg.h b/sys/dev/usb/if_mosreg.h index c1732ece7bc..19f7205a3d3 100644 --- a/sys/dev/usb/if_mosreg.h +++ b/sys/dev/usb/if_mosreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_mosreg.h,v 1.5 2012/02/28 08:58:30 jsg Exp $ */ +/* $OpenBSD: if_mosreg.h,v 1.6 2012/10/22 03:23:19 brad Exp $ */ /* * Copyright (c) 2008 Johann Christian Rode <jcrode@gmx.net> @@ -179,7 +179,6 @@ struct mos_softc { int mos_ed[MOS_ENDPT_MAX]; usbd_pipe_handle mos_ep[MOS_ENDPT_MAX]; int mos_unit; - int mos_if_flags; struct mos_cdata mos_cdata; struct timeout mos_stat_ch; |