Here is a diff for the bce(4) Broadcom BCM4401 driver to clean up and update
the receive filter / ioctl handling code to be in line with the other drivers.
Anyone with hw and able to test? OK?
Index: if_bce.c
===================================================================
RCS file: /home/cvs/src/sys/dev/pci/if_bce.c,v
retrieving revision 1.37
diff -u -p -r1.37 if_bce.c
--- if_bce.c 21 Aug 2013 05:21:43 -0000 1.37
+++ if_bce.c 9 Sep 2013 18:31:22 -0000
@@ -146,7 +146,7 @@ void bce_add_mac(struct bce_softc *, u_i
void bce_add_rxbuf(struct bce_softc *, int);
void bce_stop(struct ifnet *);
void bce_reset(struct bce_softc *);
-void bce_set_filter(struct ifnet *);
+void bce_iff(struct ifnet *);
int bce_mii_read(struct device *, int, int);
void bce_mii_write(struct device *, int, int, int);
void bce_statchg(struct device *);
@@ -473,28 +473,24 @@ bce_ioctl(struct ifnet *ifp, u_long cmd,
switch (cmd) {
case SIOCSIFADDR:
ifp->if_flags |= IFF_UP;
-
- switch (ifa->ifa_addr->sa_family) {
-#ifdef INET
- case AF_INET:
+ if (!(ifp->if_flags & IFF_RUNNING))
bce_init(ifp);
+#ifdef INET
+ if (ifa->ifa_addr->sa_family == AF_INET)
arp_ifinit(&sc->bce_ac, ifa);
- break;
-#endif /* INET */
- default:
- bce_init(ifp);
- break;
- }
+#endif
break;
case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP)
+ if (ifp->if_flags & IFF_UP) {
if (ifp->if_flags & IFF_RUNNING)
- bce_set_filter(ifp);
+ error = ENETRESET;
else
bce_init(ifp);
- else if (ifp->if_flags & IFF_RUNNING)
- bce_stop(ifp);
+ } else {
+ if (ifp->if_flags & IFF_RUNNING)
+ bce_stop(ifp);
+ }
break;
case SIOCSIFMEDIA:
@@ -508,7 +504,7 @@ bce_ioctl(struct ifnet *ifp, u_long cmd,
if (error == ENETRESET) {
if (ifp->if_flags & IFF_RUNNING)
- bce_set_filter(ifp);
+ bce_iff(ifp);
error = 0;
}
@@ -871,8 +867,8 @@ bce_init(struct ifnet *ifp)
/* setup DMA interrupt control */
bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_DMAI_CTL, 1 <<
24); /* MAGIC */
- /* setup packet filter */
- bce_set_filter(ifp);
+ /* program promiscuous mode and multicast filters */
+ bce_iff(ifp);
/* set max frame length, account for possible VLAN tag */
bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_RX_MAX,
@@ -1198,51 +1194,35 @@ bce_reset(struct bce_softc *sc)
/* Set up the receive filter. */
void
-bce_set_filter(struct ifnet *ifp)
+bce_iff(struct ifnet *ifp)
{
struct bce_softc *sc = ifp->if_softc;
+ struct arpcom *ac = &sc->bce_ac;
+ u_int32_t rxctl;
- if (ifp->if_flags & IFF_PROMISC) {
- ifp->if_flags |= IFF_ALLMULTI;
- bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_RX_CTL,
- bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_RX_CTL)
- | ERC_PE);
- } else {
- ifp->if_flags &= ~IFF_ALLMULTI;
-
- /* turn off promiscuous */
- bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_RX_CTL,
- bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
- BCE_RX_CTL) & ~ERC_PE);
+ rxctl = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_RX_CTL);
+ rxctl &= ~(ERC_AM | ERC_DB | ERC_PE);
+ ifp->if_flags |= IFF_ALLMULTI;
- /* enable/disable broadcast */
- if (ifp->if_flags & IFF_BROADCAST)
- bus_space_write_4(sc->bce_btag, sc->bce_bhandle,
- BCE_RX_CTL, bus_space_read_4(sc->bce_btag,
- sc->bce_bhandle, BCE_RX_CTL) & ~ERC_DB);
- else
- bus_space_write_4(sc->bce_btag, sc->bce_bhandle,
- BCE_RX_CTL, bus_space_read_4(sc->bce_btag,
- sc->bce_bhandle, BCE_RX_CTL) | ERC_DB);
-
- /* disable the filter */
- bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_FILT_CTL,
- 0);
+ /* disable the filter */
+ bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_FILT_CTL, 0);
- /* add our own address */
- bce_add_mac(sc, sc->bce_ac.ac_enaddr, 0);
+ /* add our own address */
+ bce_add_mac(sc, ac->ac_enaddr, 0);
- /* for now accept all multicast */
- bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_RX_CTL,
- bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_RX_CTL) |
- ERC_AM);
+ if (ifp->if_flags & IFF_PROMISC || ac->ac_multicnt > 0) {
ifp->if_flags |= IFF_ALLMULTI;
-
- /* enable the filter */
- bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_FILT_CTL,
- bus_space_read_4(sc->bce_btag, sc->bce_bhandle,
- BCE_FILT_CTL) | 1);
+ if (ifp->if_flags & IFF_PROMISC)
+ rxctl |= ERC_PE;
+ else
+ rxctl |= ERC_AM;
}
+
+ /* enable the filter */
+ bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_FILT_CTL,
+ bus_space_read_4(sc->bce_btag, sc->bce_bhandle, BCE_FILT_CTL) | 1);
+
+ bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_RX_CTL, rxctl);
}
/* Read a PHY register on the MII. */
--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.