diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2013-04-01 06:40:41 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2013-04-01 06:40:41 +0000 |
commit | 41f2d99ba6c08df29089e3d02b8515640652eba6 (patch) | |
tree | 8723ef218a889d33b66511fba4c84888da7d49b7 /sys/dev/pci | |
parent | 00651a7ec096a1f3120d173f5e237172874b269e (diff) |
Rewrite receive filter and ioctl handling code.
ok jsg@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/if_nfe.c | 80 | ||||
-rw-r--r-- | sys/dev/pci/if_nfevar.h | 3 |
2 files changed, 37 insertions, 46 deletions
diff --git a/sys/dev/pci/if_nfe.c b/sys/dev/pci/if_nfe.c index b7e08f4d1e6..fba45d862e2 100644 --- a/sys/dev/pci/if_nfe.c +++ b/sys/dev/pci/if_nfe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_nfe.c,v 1.100 2012/11/29 21:10:32 brad Exp $ */ +/* $OpenBSD: if_nfe.c,v 1.101 2013/04/01 06:40:40 brad Exp $ */ /*- * Copyright (c) 2006, 2007 Damien Bergamini <damien.bergamini@free.fr> @@ -100,7 +100,7 @@ void nfe_reset_tx_ring(struct nfe_softc *, struct nfe_tx_ring *); void nfe_free_tx_ring(struct nfe_softc *, struct nfe_tx_ring *); int nfe_ifmedia_upd(struct ifnet *); void nfe_ifmedia_sts(struct ifnet *, struct ifmediareq *); -void nfe_setmulti(struct nfe_softc *); +void nfe_iff(struct nfe_softc *); void nfe_get_macaddr(struct nfe_softc *, uint8_t *); void nfe_set_macaddr(struct nfe_softc *, const uint8_t *); void nfe_tick(void *); @@ -558,24 +558,14 @@ nfe_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { - /* - * If only the PROMISC or ALLMULTI flag changes, then - * don't do a full re-init of the chip, just update - * the Rx filter. - */ - if ((ifp->if_flags & IFF_RUNNING) && - ((ifp->if_flags ^ sc->sc_if_flags) & - (IFF_ALLMULTI | IFF_PROMISC)) != 0) { - nfe_setmulti(sc); - } else { - if (!(ifp->if_flags & IFF_RUNNING)) - nfe_init(ifp); - } + if (ifp->if_flags & IFF_RUNNING) + error = ENETRESET; + else + nfe_init(ifp); } else { if (ifp->if_flags & IFF_RUNNING) nfe_stop(ifp, 1); } - sc->sc_if_flags = ifp->if_flags; break; case SIOCSIFMEDIA: @@ -589,7 +579,7 @@ nfe_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) if (error == ENETRESET) { if (ifp->if_flags & IFF_RUNNING) - nfe_setmulti(sc); + nfe_iff(sc); error = 0; } @@ -1169,8 +1159,8 @@ nfe_init(struct ifnet *ifp) DELAY(10); NFE_WRITE(sc, NFE_RXTX_CTL, NFE_RXTX_BIT1 | sc->rxtxctl); - /* set Rx filter */ - nfe_setmulti(sc); + /* program promiscuous mode and multicast filters */ + nfe_iff(sc); nfe_ifmedia_upd(ifp); @@ -1710,43 +1700,47 @@ nfe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) } void -nfe_setmulti(struct nfe_softc *sc) +nfe_iff(struct nfe_softc *sc) { + struct ifnet *ifp = &sc->sc_arpcom.ac_if; struct arpcom *ac = &sc->sc_arpcom; - struct ifnet *ifp = &ac->ac_if; struct ether_multi *enm; struct ether_multistep step; uint8_t addr[ETHER_ADDR_LEN], mask[ETHER_ADDR_LEN]; - uint32_t filter = NFE_RXFILTER_MAGIC; + uint32_t filter; int i; - if ((ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) != 0) { + filter = NFE_RXFILTER_MAGIC; + ifp->if_flags &= ~IFF_ALLMULTI; + + if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) { + ifp->if_flags |= IFF_ALLMULTI; + if (ifp->if_flags & IFF_PROMISC) + filter |= NFE_PROMISC; + else + filter |= NFE_U2M; bzero(addr, ETHER_ADDR_LEN); bzero(mask, ETHER_ADDR_LEN); - goto done; - } + } else { + filter |= NFE_U2M; - bcopy(etherbroadcastaddr, addr, ETHER_ADDR_LEN); - bcopy(etherbroadcastaddr, mask, ETHER_ADDR_LEN); + bcopy(etherbroadcastaddr, addr, ETHER_ADDR_LEN); + bcopy(etherbroadcastaddr, mask, ETHER_ADDR_LEN); - ETHER_FIRST_MULTI(step, ac, enm); - while (enm != NULL) { - if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { - ifp->if_flags |= IFF_ALLMULTI; - bzero(addr, ETHER_ADDR_LEN); - bzero(mask, ETHER_ADDR_LEN); - goto done; - } - for (i = 0; i < ETHER_ADDR_LEN; i++) { - addr[i] &= enm->enm_addrlo[i]; - mask[i] &= ~enm->enm_addrlo[i]; + ETHER_FIRST_MULTI(step, ac, enm); + while (enm != NULL) { + for (i = 0; i < ETHER_ADDR_LEN; i++) { + addr[i] &= enm->enm_addrlo[i]; + mask[i] &= ~enm->enm_addrlo[i]; + } + + ETHER_NEXT_MULTI(step, enm); } - ETHER_NEXT_MULTI(step, enm); + + for (i = 0; i < ETHER_ADDR_LEN; i++) + mask[i] |= addr[i]; } - for (i = 0; i < ETHER_ADDR_LEN; i++) - mask[i] |= addr[i]; -done: addr[0] |= 0x01; /* make sure multicast bit is set */ NFE_WRITE(sc, NFE_MULTIADDR_HI, @@ -1757,8 +1751,6 @@ done: mask[3] << 24 | mask[2] << 16 | mask[1] << 8 | mask[0]); NFE_WRITE(sc, NFE_MULTIMASK_LO, mask[5] << 8 | mask[4]); - - filter |= (ifp->if_flags & IFF_PROMISC) ? NFE_PROMISC : NFE_U2M; NFE_WRITE(sc, NFE_RXFILTER, filter); } diff --git a/sys/dev/pci/if_nfevar.h b/sys/dev/pci/if_nfevar.h index 5c76e54d7a8..f47ac70dace 100644 --- a/sys/dev/pci/if_nfevar.h +++ b/sys/dev/pci/if_nfevar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_nfevar.h,v 1.15 2012/08/31 12:41:17 stsp Exp $ */ +/* $OpenBSD: if_nfevar.h,v 1.16 2013/04/01 06:40:40 brad Exp $ */ /*- * Copyright (c) 2005 Jonathan Gray <jsg@openbsd.org> @@ -74,7 +74,6 @@ struct nfe_softc { struct mii_data sc_mii; struct timeout sc_tick_ch; - int sc_if_flags; u_int sc_flags; #define NFE_JUMBO_SUP 0x01 #define NFE_40BIT_ADDR 0x02 |