diff options
author | Stuart Henderson <sthen@cvs.openbsd.org> | 2009-05-12 13:30:57 +0000 |
---|---|---|
committer | Stuart Henderson <sthen@cvs.openbsd.org> | 2009-05-12 13:30:57 +0000 |
commit | e3fb628632aab0433350126f43ff30e3c4377c05 (patch) | |
tree | 102dc2300e6564ca8095a5f720aec13351fadaee /sys/dev | |
parent | 3b4f54403a1529985fca481d9252747f9877d542 (diff) |
cleanup and simplify promiscuous/multicast setup (setmulti -> iff).
from Brad; ok dlg.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/if_vr.c | 121 | ||||
-rw-r--r-- | sys/dev/pci/if_vrreg.h | 3 |
2 files changed, 44 insertions, 80 deletions
diff --git a/sys/dev/pci/if_vr.c b/sys/dev/pci/if_vr.c index 0706a594c0f..8361a884081 100644 --- a/sys/dev/pci/if_vr.c +++ b/sys/dev/pci/if_vr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vr.c,v 1.91 2009/05/12 08:38:56 sthen Exp $ */ +/* $OpenBSD: if_vr.c,v 1.92 2009/05/12 13:30:56 sthen Exp $ */ /* * Copyright (c) 1997, 1998 @@ -133,7 +133,7 @@ void vr_miibus_writereg(struct device *, int, int, int); void vr_miibus_statchg(struct device *); void vr_setcfg(struct vr_softc *, int); -void vr_setmulti(struct vr_softc *); +void vr_iff(struct vr_softc *); void vr_reset(struct vr_softc *); int vr_list_rx_init(struct vr_softc *); int vr_list_tx_init(struct vr_softc *); @@ -319,60 +319,53 @@ vr_miibus_statchg(struct device *dev) vr_setcfg(sc, sc->sc_mii.mii_media_active); } -/* - * Program the 64-bit multicast hash filter. - */ void -vr_setmulti(struct vr_softc *sc) +vr_iff(struct vr_softc *sc) { - struct ifnet *ifp; + struct arpcom *ac = &sc->arpcom; + struct ifnet *ifp = &sc->arpcom.ac_if; int h = 0; - u_int32_t hashes[2] = { 0, 0 }; - struct arpcom *ac = &sc->arpcom; - struct ether_multi *enm; - struct ether_multistep step; + u_int32_t hashes[2]; + struct ether_multi *enm; + struct ether_multistep step; u_int8_t rxfilt; - int mcnt = 0; - - ifp = &sc->arpcom.ac_if; rxfilt = CSR_READ_1(sc, VR_RXCFG); + rxfilt &= ~(VR_RXCFG_RX_BROAD | VR_RXCFG_RX_MULTI | + VR_RXCFG_RX_PROMISC); + ifp->if_flags &= ~IFF_ALLMULTI; - if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { -allmulti: + /* + * Always accept broadcast frames. + */ + rxfilt |= VR_RXCFG_RX_BROAD; + + if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) { + ifp->if_flags |= IFF_ALLMULTI; + if (ifp->if_flags & IFF_PROMISC) + rxfilt |= VR_RXCFG_RX_PROMISC; + else + rxfilt |= VR_RXCFG_RX_MULTI; + hashes[0] = hashes[1] = 0xFFFFFFFF; + } else { + /* Program new filter. */ rxfilt |= VR_RXCFG_RX_MULTI; - CSR_WRITE_1(sc, VR_RXCFG, rxfilt); - CSR_WRITE_4(sc, VR_MAR0, 0xFFFFFFFF); - CSR_WRITE_4(sc, VR_MAR1, 0xFFFFFFFF); - return; - } + bzero(hashes, sizeof(hashes)); - /* first, zot all the existing hash bits */ - CSR_WRITE_4(sc, VR_MAR0, 0); - CSR_WRITE_4(sc, VR_MAR1, 0); + ETHER_FIRST_MULTI(step, ac, enm); + while (enm != NULL) { + h = ether_crc32_be(enm->enm_addrlo, + ETHER_ADDR_LEN) >> 26; - /* now program new ones */ - 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; - goto allmulti; - } - h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) >> 26; - if (h < 32) - hashes[0] |= (1 << h); - else - hashes[1] |= (1 << (h - 32)); - mcnt++; + if (h < 32) + hashes[0] |= (1 << h); + else + hashes[1] |= (1 << (h - 32)); - ETHER_NEXT_MULTI(step, enm); + ETHER_NEXT_MULTI(step, enm); + } } - if (mcnt) - rxfilt |= VR_RXCFG_RX_MULTI; - else - rxfilt &= ~VR_RXCFG_RX_MULTI; - CSR_WRITE_4(sc, VR_MAR0, hashes[0]); CSR_WRITE_4(sc, VR_MAR1, hashes[1]); CSR_WRITE_1(sc, VR_RXCFG, rxfilt); @@ -1343,22 +1336,10 @@ vr_init(void *xsc) return; } - /* If we want promiscuous mode, set the allframes bit. */ - if (ifp->if_flags & IFF_PROMISC) - VR_SETBIT(sc, VR_RXCFG, VR_RXCFG_RX_PROMISC); - else - VR_CLRBIT(sc, VR_RXCFG, VR_RXCFG_RX_PROMISC); - - /* Set capture broadcast bit to capture broadcast frames. */ - if (ifp->if_flags & IFF_BROADCAST) - VR_SETBIT(sc, VR_RXCFG, VR_RXCFG_RX_BROAD); - else - VR_CLRBIT(sc, VR_RXCFG, VR_RXCFG_RX_BROAD); - /* - * Program the multicast filter, if necessary. + * Program promiscuous mode and multicast filters. */ - vr_setmulti(sc); + vr_iff(sc); /* * Load the address of the RX list. @@ -1443,30 +1424,14 @@ vr_ioctl(struct ifnet *ifp, u_long command, caddr_t data) case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { - if (ifp->if_flags & IFF_RUNNING && - ifp->if_flags & IFF_PROMISC && - !(sc->sc_if_flags & IFF_PROMISC)) { - VR_SETBIT(sc, VR_RXCFG, - VR_RXCFG_RX_PROMISC); - vr_setmulti(sc); - } else if (ifp->if_flags & IFF_RUNNING && - !(ifp->if_flags & IFF_PROMISC) && - sc->sc_if_flags & IFF_PROMISC) { - VR_CLRBIT(sc, VR_RXCFG, - VR_RXCFG_RX_PROMISC); - vr_setmulti(sc); - } else if (ifp->if_flags & IFF_RUNNING && - (ifp->if_flags ^ sc->sc_if_flags) & IFF_ALLMULTI) { - vr_setmulti(sc); - } else { - if (!(ifp->if_flags & IFF_RUNNING)) - vr_init(sc); - } + if (ifp->if_flags & IFF_RUNNING) + error = ENETRESET; + else + vr_init(sc); } else { if (ifp->if_flags & IFF_RUNNING) vr_stop(sc); } - sc->sc_if_flags = ifp->if_flags; break; case SIOCGIFMEDIA: @@ -1480,7 +1445,7 @@ vr_ioctl(struct ifnet *ifp, u_long command, caddr_t data) if (error == ENETRESET) { if (ifp->if_flags & IFF_RUNNING) - vr_setmulti(sc); + vr_iff(sc); error = 0; } diff --git a/sys/dev/pci/if_vrreg.h b/sys/dev/pci/if_vrreg.h index 2c89b3e771c..3b94eb6e8bb 100644 --- a/sys/dev/pci/if_vrreg.h +++ b/sys/dev/pci/if_vrreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vrreg.h,v 1.25 2009/05/11 07:41:52 sthen Exp $ */ +/* $OpenBSD: if_vrreg.h,v 1.26 2009/05/12 13:30:56 sthen Exp $ */ /* * Copyright (c) 1997, 1998 @@ -478,7 +478,6 @@ struct vr_softc { struct timeout sc_to; bus_dmamap_t sc_listmap; /* descriptor list map */ bus_dma_segment_t sc_listseg; - int sc_if_flags; int sc_rxbufs; int vr_link; int vr_quirks; |