summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2013-04-01 06:40:41 +0000
committerBrad Smith <brad@cvs.openbsd.org>2013-04-01 06:40:41 +0000
commit41f2d99ba6c08df29089e3d02b8515640652eba6 (patch)
tree8723ef218a889d33b66511fba4c84888da7d49b7 /sys/dev/pci
parent00651a7ec096a1f3120d173f5e237172874b269e (diff)
Rewrite receive filter and ioctl handling code.
ok jsg@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/if_nfe.c80
-rw-r--r--sys/dev/pci/if_nfevar.h3
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