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.

Reply via email to