Here is a diff for the epic(4) SMC 83C170 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: smc83c170.c
===================================================================
RCS file: /home/cvs/src/sys/dev/ic/smc83c170.c,v
retrieving revision 1.16
diff -u -p -r1.16 smc83c170.c
--- smc83c170.c 26 Nov 2013 09:50:33 -0000      1.16
+++ smc83c170.c 1 Dec 2013 01:12:31 -0000
@@ -84,7 +84,7 @@ void  epic_reset(struct epic_softc *);
 void   epic_rxdrain(struct epic_softc *);
 int    epic_add_rxbuf(struct epic_softc *, int);
 void   epic_read_eeprom(struct epic_softc *, int, int, u_int16_t *);
-void   epic_set_mchash(struct epic_softc *);
+void   epic_iff(struct epic_softc *);
 void   epic_fixup_clock_source(struct epic_softc *);
 int    epic_mii_read(struct device *, int, int);
 void   epic_mii_write(struct device *, int, int, int);
@@ -536,31 +536,24 @@ epic_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))
                        epic_init(ifp);
+#ifdef INET
+               if (ifa->ifa_addr->sa_family == AF_INET)
                        arp_ifinit(&sc->sc_arpcom, ifa);
-                       break;
 #endif
-               default:
-                       epic_init(ifp);
-                       break;
-               }
                break;
 
        case SIOCSIFFLAGS:
-               /*
-                * If interface is marked up and not running, then start it.
-                * If it is marked down and running, stop it.
-                * XXX If it's up then re-initialize it. This is so flags
-                * such as IFF_PROMISC are handled.
-                */
-               if (ifp->if_flags & IFF_UP)
-                       epic_init(ifp);
-               else if (ifp->if_flags & IFF_RUNNING)
-                       epic_stop(ifp, 1);
+               if (ifp->if_flags & IFF_UP) {
+                       if (ifp->if_flags & IFF_RUNNING)
+                               error = ENETRESET;
+                       else
+                               epic_init(ifp);
+               } else {
+                       if (ifp->if_flags & IFF_RUNNING)
+                               epic_stop(ifp, 1);
+               }
                break;
 
        case SIOCSIFMEDIA:
@@ -575,7 +568,7 @@ epic_ioctl(struct ifnet *ifp, u_long cmd
        if (error == ENETRESET) {
                if (ifp->if_flags & IFF_RUNNING) {
                        mii_pollstat(&sc->sc_mii);
-                       epic_set_mchash(sc);
+                       epic_iff(sc);
                }
                error = 0;
        }
@@ -974,8 +967,8 @@ epic_init(struct ifnet *ifp)
        /* Set the current media. */
        epic_mediachange(ifp);
 
-       /* Set up the multicast hash table. */
-       epic_set_mchash(sc);
+       /* Program promiscuous mode and multicast filters. */
+       epic_iff(sc);
 
        /*
         * Initialize the transmit descriptor ring.  txlast is initialized
@@ -1260,7 +1253,7 @@ epic_add_rxbuf(struct epic_softc *sc, in
  * NOTE: We rely on a recently-updated mii_media_active here!
  */
 void
-epic_set_mchash(struct epic_softc *sc)
+epic_iff(struct epic_softc *sc)
 {
        struct arpcom *ac = &sc->sc_arpcom;
        struct ifnet *ifp = &sc->sc_arpcom.ac_if;
@@ -1268,47 +1261,38 @@ epic_set_mchash(struct epic_softc *sc)
        struct ether_multistep step;
        u_int32_t hash, mchash[4];
 
-       /*
-        * Set up the multicast address filter by passing all multicast
-        * addresses through a CRC generator, and then using the low-order
-        * 6 bits as an index into the 64 bit multicast hash table (only
-        * the lower 16 bits of each 32 bit multicast hash register are
-        * valid).  The high order bits select the register, while the
-        * rest of the bits select the bit within the register.
-        */
-
-       if (ifp->if_flags & IFF_PROMISC)
-               goto allmulti;
-
-       if (IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_10_T) {
-               /* XXX hardware bug in 10Mbps mode. */
-               goto allmulti;
-       }
+       ifp->if_flags &= ~IFF_ALLMULTI;
 
-       if (ac->ac_multirangecnt > 0)
-               goto allmulti;
+       if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0 ||
+           IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_10_T) {
+               ifp->if_flags |= IFF_ALLMULTI;
+               mchash[0] = mchash[1] = mchash[2] = mchash[3] = 0xffff;
+       } else {
+               mchash[0] = mchash[1] = mchash[2] = mchash[3] = 0;
 
-       mchash[0] = mchash[1] = mchash[2] = mchash[3] = 0;
+               /*
+                * Set up the multicast address filter by passing all
+                * multicast addresses through a CRC generator, and then
+                * using the low-order 6 bits as an index into the 64 bit
+                * multicast hash table (only the lower 16 bits of each 32
+                * bit multicast hash register are valid).  The high order
+                * bits select the register, while the rest of the bits
+                * select the bit within the register.
+                */
+               ETHER_FIRST_MULTI(step, ac, enm);
+               while (enm != NULL) {
+                       hash = ether_crc32_be(enm->enm_addrlo,
+                           ETHER_ADDR_LEN);
 
-       ETHER_FIRST_MULTI(step, ac, enm);
-       while (enm != NULL) {
-               hash = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
-               hash >>= 26;
+                       hash >>= 26;
 
-               /* Set the corresponding bit in the hash table. */
-               mchash[hash >> 4] |= 1 << (hash & 0xf);
+                       /* Set the corresponding bit in the hash table. */
+                       mchash[hash >> 4] |= 1 << (hash & 0xf);
 
-               ETHER_NEXT_MULTI(step, enm);
+                       ETHER_NEXT_MULTI(step, enm);
+               }
        }
 
-       ifp->if_flags &= ~IFF_ALLMULTI;
-       goto sethash;
-
- allmulti:
-       ifp->if_flags |= IFF_ALLMULTI;
-       mchash[0] = mchash[1] = mchash[2] = mchash[3] = 0xffff;
-
- sethash:
        bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_MC0, mchash[0]);
        bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_MC1, mchash[1]);
        bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_MC2, mchash[2]);
@@ -1407,7 +1391,7 @@ epic_statchg(struct device *self)
         * There is a multicast filter bug in 10Mbps mode.  Kick the
         * multicast filter in case the speed changed.
         */
-       epic_set_mchash(sc);
+       epic_iff(sc);
 }
 
 /*

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

Reply via email to