The following diff rewrites parts of the code for promiscuous mode
and multicast handling for the nfe(4) driver. Please test promisc
mode and multicast mode of operation with any nfe(4) adapters.
Please provide a dmesg.
Index: if_nfe.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_nfe.c,v
retrieving revision 1.89
diff -u -p -r1.89 if_nfe.c
--- if_nfe.c 18 Jun 2009 08:19:03 -0000 1.89
+++ if_nfe.c 20 Jun 2009 02:52:31 -0000
@@ -100,7 +100,7 @@ void nfe_reset_tx_ring(struct nfe_softc
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 *);
@@ -543,24 +543,14 @@ nfe_ioctl(struct ifnet *ifp, u_long cmd,
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:
@@ -574,7 +564,7 @@ nfe_ioctl(struct ifnet *ifp, u_long cmd,
if (error == ENETRESET) {
if (ifp->if_flags & IFF_RUNNING)
- nfe_setmulti(sc);
+ nfe_iff(sc);
error = 0;
}
@@ -1156,7 +1146,7 @@ nfe_init(struct ifnet *ifp)
NFE_WRITE(sc, NFE_RXTX_CTL, NFE_RXTX_BIT1 | sc->rxtxctl);
/* set Rx filter */
- nfe_setmulti(sc);
+ nfe_iff(sc);
nfe_ifmedia_upd(ifp);
@@ -1698,39 +1688,45 @@ nfe_ifmedia_sts(struct ifnet *ifp, struc
}
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;
}
+ filter |= NFE_U2M;
+
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_NEXT_MULTI(step, enm);
}
+
for (i = 0; i < ETHER_ADDR_LEN; i++)
mask[i] |= addr[i];
@@ -1746,7 +1742,6 @@ done:
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);
}
Index: if_nfevar.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_nfevar.h,v
retrieving revision 1.13
diff -u -p -r1.13 if_nfevar.h
--- if_nfevar.h 5 Dec 2007 08:30:33 -0000 1.13
+++ if_nfevar.h 20 Jun 2009 02:39:01 -0000
@@ -75,7 +75,6 @@ struct nfe_softc {
struct timeout sc_tick_ch;
void *sc_powerhook;
- int sc_if_flags;
u_int sc_flags;
#define NFE_JUMBO_SUP 0x01
#define NFE_40BIT_ADDR 0x02
--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.