Here is a diff for the sf(4) Starfire 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: aic6915.c
===================================================================
RCS file: /home/cvs/src/sys/dev/ic/aic6915.c,v
retrieving revision 1.11
diff -u -p -r1.11 aic6915.c
--- aic6915.c   26 Nov 2013 09:50:32 -0000      1.11
+++ aic6915.c   1 Dec 2013 00:48:16 -0000
@@ -89,7 +89,7 @@ void  sf_macreset(struct sf_softc *);
 void   sf_rxdrain(struct sf_softc *);
 int    sf_add_rxbuf(struct sf_softc *, int);
 uint8_t        sf_read_eeprom(struct sf_softc *, int);
-void   sf_set_filter(struct sf_softc *);
+void   sf_iff(struct sf_softc *);
 
 int    sf_mii_read(struct device *, int, int);
 void   sf_mii_write(struct device *, int, int, int);
@@ -532,19 +532,14 @@ sf_ioctl(struct ifnet *ifp, u_long cmd, 
 
        case SIOCSIFFLAGS:
                if (ifp->if_flags & IFF_UP) {
-                       if (ifp->if_flags & IFF_RUNNING &&
-                           ((ifp->if_flags ^ sc->sc_flags) &
-                            IFF_PROMISC)) {
-                               sf_set_filter(sc);
-                       } else {
-                               if (!(ifp->if_flags & IFF_RUNNING))
-                                       sf_init(ifp);
-                       }
+                       if (ifp->if_flags & IFF_RUNNING)
+                               error = ENETRESET;
+                       else
+                               sf_init(ifp);
                } else {
                        if (ifp->if_flags & IFF_RUNNING)
                                sf_stop(ifp, 1);
                }
-               sc->sc_flags = ifp->if_flags;
                break;
 
        case SIOCGIFMEDIA:
@@ -558,7 +553,7 @@ sf_ioctl(struct ifnet *ifp, u_long cmd, 
 
        if (error == ENETRESET) {
                if (ifp->if_flags & IFF_RUNNING)
-                       sf_set_filter(sc);
+                       sf_iff(sc);
                error = 0;
        }
 
@@ -1087,10 +1082,9 @@ sf_init(struct ifnet *ifp)
            RDC_RxBurstSize(4));                /* default */
 
        /*
-        * Set the receive filter.
+        * Program promiscuous mode and multicast filters.
         */
-       sc->sc_RxAddressFilteringCtl = 0;
-       sf_set_filter(sc);
+       sf_iff(sc);
 
        /*
         * Set MacConfig1.  When we set the media, MacConfig1 will
@@ -1293,85 +1287,65 @@ sf_set_filter_hash(struct sf_softc *sc, 
 }
 
 /*
- * sf_set_filter:
+ * sf_iff:
  *
  *     Set the Starfire receive filter.
  */
 void
-sf_set_filter(struct sf_softc *sc)
+sf_iff(struct sf_softc *sc)
 {
        struct arpcom *ac = &sc->sc_arpcom;
        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
        struct ether_multi *enm;
        struct ether_multistep step;
+       uint32_t filterctl;
        int i;
 
-       /* Start by clearing the perfect and hash tables. */
+       filterctl = sf_funcreg_read(sc, SF_RxAddressFilteringCtl);
+       filterctl &= ~(RAFC_PassBroadcast | RAFC_PromiscuousMode |
+           RAFC_PerfectFilteringMode(3) | RAFC_HashFilteringMode(3));
+       ifp->if_flags &= ~IFF_ALLMULTI;
+
+       /* Clear the perfect and hash tables. */
        for (i = 0; i < SF_PERFECT_SIZE; i += sizeof(uint32_t))
                sf_genreg_write(sc, SF_PERFECT_BASE + i, 0);
-
        for (i = 0; i < SF_HASH_SIZE; i += sizeof(uint32_t))
                sf_genreg_write(sc, SF_HASH_BASE + i, 0);
 
        /*
-        * Clear the perfect and hash mode bits.
-        */
-       sc->sc_RxAddressFilteringCtl &=
-           ~(RAFC_PerfectFilteringMode(3) | RAFC_HashFilteringMode(3));
-
-       if (ifp->if_flags & IFF_BROADCAST)
-               sc->sc_RxAddressFilteringCtl |= RAFC_PassBroadcast;
-       else
-               sc->sc_RxAddressFilteringCtl &= ~RAFC_PassBroadcast;
-
-       if (ifp->if_flags & IFF_PROMISC) {
-               sc->sc_RxAddressFilteringCtl |= RAFC_PromiscuousMode;
-               goto allmulti;
-       } else
-               sc->sc_RxAddressFilteringCtl &= ~RAFC_PromiscuousMode;
-
-       /*
-        * Set normal perfect filtering mode.
+        * Always accept broadcast frames.
         */
-       sc->sc_RxAddressFilteringCtl |= RAFC_PerfectFilteringMode(1);
+       filterctl |= RAFC_PassBroadcast;
 
-       /*
-        * First, write the station address to the perfect filter
-        * table.
-        */
-       sf_set_filter_perfect(sc, 0, LLADDR(ifp->if_sadl));
+       if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
+               ifp->if_flags |= IFF_ALLMULTI;
+               filterctl |= RAFC_PassMulticast;
+               if (ifp->if_flags & IFF_PROMISC)
+                       filterctl |= RAFC_PromiscuousMode;
+       } else {
+               /*
+                * Set "hash only multicast dest, match regardless of VLAN ID".
+                */
+               filterctl |= RAFC_HashFilteringMode(2);
 
-       if (ac->ac_multirangecnt > 0)
-               goto allmulti;
+               ETHER_FIRST_MULTI(step, ac, enm);
+               while (enm != NULL) {
+                       sf_set_filter_hash(sc, enm->enm_addrlo);
 
-       /*
-        * Now set the hash bits for each multicast address in our
-        * list.
-        */
-       ETHER_FIRST_MULTI(step, ac, enm);
-       if (enm == NULL)
-               goto done;
-       while (enm != NULL) {
-               sf_set_filter_hash(sc, enm->enm_addrlo);
-               ETHER_NEXT_MULTI(step, enm);
+                       ETHER_NEXT_MULTI(step, enm);
+               }
        }
 
-       /*
-        * Set "hash only multicast dest, match regardless of VLAN ID".
-        */
-       sc->sc_RxAddressFilteringCtl |= RAFC_HashFilteringMode(2);
-       goto done;
+       if ((ifp->if_flags & IFF_PROMISC) == 0) {
+               /*
+                * Write the station address to the perfect filter table.
+                */
+               sf_set_filter_perfect(sc, 0, LLADDR(ifp->if_sadl));
 
- allmulti:
-       /*
-        * XXX RAFC_PassMulticast is sub-optimal if using VLAN mode.
-        */
-       sc->sc_RxAddressFilteringCtl |= RAFC_PassMulticast;
-       ifp->if_flags |= IFF_ALLMULTI;
+               filterctl |= RAFC_PerfectFilteringMode(1);
+       }
 
- done:
-       sf_funcreg_write(sc, SF_RxAddressFilteringCtl,
-           sc->sc_RxAddressFilteringCtl);
+       sf_funcreg_write(sc, SF_RxAddressFilteringCtl, filterctl);
 }
 
 /*
Index: aic6915.h
===================================================================
RCS file: /home/cvs/src/sys/dev/ic/aic6915.h,v
retrieving revision 1.4
diff -u -p -r1.4 aic6915.h
--- aic6915.h   10 Aug 2009 20:29:54 -0000      1.4
+++ aic6915.h   9 Mar 2013 05:00:45 -0000
@@ -764,7 +764,6 @@ struct sf_softc {
        bus_dma_tag_t sc_dmat;          /* bus DMA tag */
        struct arpcom sc_arpcom;        /* ethernet common data */
        int sc_iomapped;                /* are we I/O mapped? */
-       int sc_flags;                   /* misc. flags */
 
        struct mii_data sc_mii;         /* MII/media information */
        struct timeout sc_mii_timeout;  /* MII callout */
@@ -796,8 +795,6 @@ struct sf_softc {
        int     sc_txthresh;            /* current Tx threshold */
 
        uint32_t sc_MacConfig1;         /* prototype MacConfig1 register */
-
-       uint32_t sc_RxAddressFilteringCtl;
 };
 
 #define        SF_CDTXDADDR(sc, x)     ((sc)->sc_cddma + SF_CDTXDOFF((x)))

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

Reply via email to