diff options
author | Masao Uebayashi <uebayasi@cvs.openbsd.org> | 2013-06-12 00:18:01 +0000 |
---|---|---|
committer | Masao Uebayashi <uebayasi@cvs.openbsd.org> | 2013-06-12 00:18:01 +0000 |
commit | a4f33995f6e09e5db80f38b7bc379c8b17746d57 (patch) | |
tree | ddb93eed464b0a79231aa200d92b3f8421426769 /sys/dev/pci | |
parent | cd87a702480f32ec4a472de5f0a77858ae410181 (diff) |
Almost identical diffs from brad@ and dlg@:
o OpenBSD'ify the vmx(4) receive filter handling code
o IFF_ALLMULTI is like hte OACTIVE flag in that its only ever set and
cleared by an interface driver. with that in mind, this reorders
the config to do that and take advantage of it to conditionally
configure the multicast filtering.
o It also makes the code check if any multicast ranges have been
configured, which every other driver interprets as "set ALLMULTI",
so we do too now.
o Add the usual ifdef INET guard to the ioctl code.
OK yasuoka@ dlg@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/if_vmx.c | 76 |
1 files changed, 33 insertions, 43 deletions
diff --git a/sys/dev/pci/if_vmx.c b/sys/dev/pci/if_vmx.c index 7e25d22fc70..091355c6a7d 100644 --- a/sys/dev/pci/if_vmx.c +++ b/sys/dev/pci/if_vmx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vmx.c,v 1.6 2013/06/10 00:49:26 brad Exp $ */ +/* $OpenBSD: if_vmx.c,v 1.7 2013/06/12 00:18:00 uebayasi Exp $ */ /* * Copyright (c) 2013 Tsubai Masanari @@ -112,7 +112,7 @@ struct vmxnet3_softc { struct vmxnet3_txqueue sc_txq[NTXQUEUE]; struct vmxnet3_rxqueue sc_rxq[NRXQUEUE]; struct vmxnet3_driver_shared *sc_ds; - void *sc_mcast; + u_int8_t *sc_mcast; }; #define VMXNET3_STAT @@ -761,54 +761,42 @@ skip_buffer: } static void -vmxnet3_set_rx_filter(struct vmxnet3_softc *sc) +vmxnet3_iff(struct vmxnet3_softc *sc) { struct ifnet *ifp = &sc->sc_arpcom.ac_if; - struct vmxnet3_driver_shared *ds = sc->sc_ds; - u_int mode = VMXNET3_RXMODE_UCAST; struct arpcom *ac = &sc->sc_arpcom; + struct vmxnet3_driver_shared *ds = sc->sc_ds; struct ether_multi *enm; struct ether_multistep step; - int n; - char *p; - - if (ifp->if_flags & IFF_MULTICAST) - mode |= VMXNET3_RXMODE_MCAST; - if (ifp->if_flags & IFF_ALLMULTI) - mode |= VMXNET3_RXMODE_ALLMULTI; - if (ifp->if_flags & IFF_BROADCAST) - mode |= VMXNET3_RXMODE_BCAST; - if (ifp->if_flags & IFF_PROMISC) - mode |= VMXNET3_RXMODE_PROMISC | VMXNET3_RXMODE_ALLMULTI; - - if ((mode & (VMXNET3_RXMODE_ALLMULTI | VMXNET3_RXMODE_MCAST)) - != VMXNET3_RXMODE_MCAST) { - ds->mcast_tablelen = 0; - goto setit; - } - - n = sc->sc_arpcom.ac_multicnt; - if (n == 0) { - mode &= ~VMXNET3_RXMODE_MCAST; + u_int mode; + u_int8_t *p; + + mode = VMXNET3_RXMODE_UCAST; + if (ISSET(ifp->if_flags, IFF_BROADCAST)) + SET(mode, VMXNET3_RXMODE_BCAST); + if (ISSET(ifp->if_flags, IFF_PROMISC)) + SET(mode, VMXNET3_RXMODE_PROMISC); + + CLR(ifp->if_flags, IFF_ALLMULTI); + if (ISSET(ifp->if_flags, IFF_PROMISC) || ac->ac_multirangecnt > 0 || + ac->ac_multicnt > 682) { + SET(ifp->if_flags, IFF_ALLMULTI); + SET(mode, VMXNET3_RXMODE_MCAST | VMXNET3_RXMODE_ALLMULTI); ds->mcast_tablelen = 0; - goto setit; - } - if (n > 682) { - mode |= VMXNET3_RXMODE_ALLMULTI; - ds->mcast_tablelen = 0; - goto setit; - } + } else if (ISSET(ifp->if_flags, IFF_MULTICAST) && + ac->ac_multicnt > 0) { + p = sc->sc_mcast; + ETHER_FIRST_MULTI(step, ac, enm); + while (enm != NULL) { + bcopy(enm->enm_addrlo, p, ETHER_ADDR_LEN); + p += ETHER_ADDR_LEN; + ETHER_NEXT_MULTI(step, enm); + } + ds->mcast_tablelen = p - sc->sc_mcast; - p = sc->sc_mcast; - ETHER_FIRST_MULTI(step, ac, enm); - while (enm) { - bcopy(enm->enm_addrlo, p, ETHER_ADDR_LEN); - p += ETHER_ADDR_LEN; - ETHER_NEXT_MULTI(step, enm); + SET(mode, VMXNET3_RXMODE_MCAST); } - ds->mcast_tablelen = n * ETHER_ADDR_LEN; -setit: WRITE_CMD(sc, VMXNET3_CMD_SET_FILTER); ds->rxmode = mode; WRITE_CMD(sc, VMXNET3_CMD_SET_RXMODE); @@ -950,7 +938,7 @@ vmxnet3_init(struct vmxnet3_softc *sc) WRITE_BAR0(sc, VMXNET3_BAR0_RXH2(queue), 0); } - vmxnet3_set_rx_filter(sc); + vmxnet3_iff(sc); vmxnet3_enable_all_intrs(sc); vmxnet3_link_state(sc); return 0; @@ -986,8 +974,10 @@ vmxnet3_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) ifp->if_flags |= IFF_UP; if ((ifp->if_flags & IFF_RUNNING) == 0) error = vmxnet3_init(sc); +#ifdef INET if (ifa->ifa_addr->sa_family == AF_INET) arp_ifinit(&sc->sc_arpcom, ifa); +#endif break; case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { @@ -1013,7 +1003,7 @@ vmxnet3_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) if (error == ENETRESET) { if (ifp->if_flags & IFF_RUNNING) - vmxnet3_set_rx_filter(sc); + vmxnet3_iff(sc); error = 0; } |