OpenBSD'ify the receive filter handling and cleanup some of the ioctl bits.

Tested by stsp@

OK?


Index: if_mos.c
===================================================================
RCS file: /home/cvs/src/sys/dev/usb/if_mos.c,v
retrieving revision 1.16
diff -u -p -r1.16 if_mos.c
--- if_mos.c    28 Feb 2012 08:58:30 -0000      1.16
+++ if_mos.c    5 Mar 2012 04:37:35 -0000
@@ -180,7 +180,7 @@ int mos_readmac(struct mos_softc *, u_ch
 int mos_writemac(struct mos_softc *, u_char *);
 int mos_write_mcast(struct mos_softc *, u_char *);
 
-void mos_setmulti(struct mos_softc *);
+void mos_iff(struct mos_softc *);
 void mos_lock_mii(struct mos_softc *);
 void mos_unlock_mii(struct mos_softc *);
 
@@ -531,46 +531,41 @@ mos_ifmedia_sts(struct ifnet *ifp, struc
 }
 
 void
-mos_setmulti(struct mos_softc *sc)
+mos_iff(struct mos_softc *sc)
 {
-       struct ifnet            *ifp;
+       struct ifnet            *ifp = GET_IFP(sc);
+       struct arpcom           *ac = &sc->arpcom;
        struct ether_multi      *enm;
        struct ether_multistep  step;
        u_int32_t               h = 0;
-       u_int8_t                rxmode;
-       u_int8_t                hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+       u_int8_t                rxmode, hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
 
        if (usbd_is_dying(sc->mos_udev))
                return;
 
-       ifp = GET_IFP(sc);
-
        rxmode = mos_reg_read_1(sc, MOS_CTL);
+       rxmode &= ~(MOS_CTL_ALLMULTI | MOS_CTL_RX_PROMISC);
+       ifp->if_flags &= ~IFF_ALLMULTI;
 
-       if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
-allmulti:
+       if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
+               ifp->if_flags |= IFF_ALLMULTI;
                rxmode |= MOS_CTL_ALLMULTI;
-               mos_reg_write_1(sc, MOS_CTL, rxmode);
-               return;
-       } else
-               rxmode &= ~MOS_CTL_ALLMULTI;
+               if (ifp->if_flags & IFF_PROMISC)
+                       rxmode |= MOS_CTL_RX_PROMISC;
+       } else {
+               /* now program new ones */
+               ETHER_FIRST_MULTI(step, ac, enm);
+               while (enm != NULL) {
+                       h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) >> 
26;
+
+                       hashtbl[h / 8] |= 1 << (h % 8);
 
-       /* now program new ones */
-       ETHER_FIRST_MULTI(step, &sc->arpcom, enm);
-       while (enm != NULL) {
-               if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
-                  ETHER_ADDR_LEN) != 0)
-                       goto allmulti;
-
-               h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) >> 26;
-               hashtbl[h / 8] |= 1 << (h % 8);
-               ETHER_NEXT_MULTI(step, enm);
+                       ETHER_NEXT_MULTI(step, enm);
+               }
        }
 
-       ifp->if_flags &= ~IFF_ALLMULTI;
        mos_write_mcast(sc, (void *)&hashtbl);
        mos_reg_write_1(sc, MOS_CTL, rxmode);
-       return;
 }
 
 void
@@ -1241,22 +1236,15 @@ mos_init(void *xsc)
        mos_reg_write_1(sc, MOS_IPG0, sc->mos_ipgs[0]);
        mos_reg_write_1(sc, MOS_IPG1, sc->mos_ipgs[1]);
 
+       /* Program promiscuous mode and multicast filters. */
+       mos_iff(sc);
+
        /* Enable receiver and transmitter, bridge controls speed/duplex mode */
        rxmode = mos_reg_read_1(sc, MOS_CTL);
        rxmode |= MOS_CTL_RX_ENB | MOS_CTL_TX_ENB | MOS_CTL_BS_ENB;
        rxmode &= ~(MOS_CTL_SLEEP);
-
-       /* If we want promiscuous mode, set the allframes bit. */
-       if (ifp->if_flags & IFF_PROMISC)
-               rxmode |= MOS_CTL_RX_PROMISC;
-
-       /* XXX: broadcast mode? */
-
        mos_reg_write_1(sc, MOS_CTL, rxmode);
 
-       /* Load the multicast filter. */
-       mos_setmulti(sc);
-
        mii_mediachg(GET_MII(sc));
 
        /* Open RX and TX pipes. */
@@ -1303,8 +1291,6 @@ mos_ioctl(struct ifnet *ifp, u_long cmd,
        struct mos_softc        *sc = ifp->if_softc;
        struct ifreq            *ifr = (struct ifreq *)data;
        struct ifaddr           *ifa = (struct ifaddr *)data;
-       struct mii_data         *mii;
-       u_int8_t                rxmode;
        int                     s, error = 0;
 
        s = splnet();
@@ -1320,61 +1306,31 @@ mos_ioctl(struct ifnet *ifp, u_long cmd,
 #endif
                break;
 
-       case SIOCSIFMTU:
-               if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu)
-                       error = EINVAL;
-               else if (ifp->if_mtu != ifr->ifr_mtu)
-                       ifp->if_mtu = ifr->ifr_mtu;
-               break;
-
        case SIOCSIFFLAGS:
                if (ifp->if_flags & IFF_UP) {
-                       if (ifp->if_flags & IFF_RUNNING &&
-                           ifp->if_flags & IFF_PROMISC &&
-                           !(sc->mos_if_flags & IFF_PROMISC)) {
-                               rxmode = mos_reg_read_1(sc, MOS_CTL);
-                               rxmode |= MOS_CTL_RX_PROMISC;
-                               mos_reg_write_1(sc, MOS_CTL, rxmode);
-                               mos_setmulti(sc);
-                       } else if (ifp->if_flags & IFF_RUNNING &&
-                           !(ifp->if_flags & IFF_PROMISC) &&
-                           !(sc->mos_if_flags & IFF_PROMISC)) {
-                               rxmode = mos_reg_read_1(sc, MOS_CTL);
-                               rxmode |= MOS_CTL_RX_PROMISC;
-                               mos_reg_write_1(sc, MOS_CTL, rxmode);
-                               mos_setmulti(sc);
-                       } else if (!(ifp->if_flags & IFF_RUNNING))
+                       if (ifp->if_flags & IFF_RUNNING)
+                               error = ENETRESET;
+                       else
                                mos_init(sc);
                } else {
                        if (ifp->if_flags & IFF_RUNNING)
                                mos_stop(sc);
                }
-               sc->mos_if_flags = ifp->if_flags;
-               break;
-       case SIOCADDMULTI:
-       case SIOCDELMULTI:
-               error = (cmd == SIOCADDMULTI) ?
-                   ether_addmulti(ifr, &sc->arpcom) :
-                   ether_delmulti(ifr, &sc->arpcom);
-
-               if (error == ENETRESET) {
-                       /*
-                        * Multicast list has changed; set the hardware
-                        * filter accordingly.
-                        */
-                       if (ifp->if_flags & IFF_RUNNING)
-                               mos_setmulti(sc);
-                       error = 0;
-               }
                break;
+
        case SIOCGIFMEDIA:
        case SIOCSIFMEDIA:
-               mii = GET_MII(sc);
-               error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
+               error = ifmedia_ioctl(ifp, ifr, &sc->mos_mii.mii_media, cmd);
                break;
 
        default:
                error = ether_ioctl(ifp, &sc->arpcom, cmd, data);
+       }
+
+       if (error == ENETRESET) {
+               if (ifp->if_flags & IFF_RUNNING)
+                       mos_iff(sc);
+               error = 0;
        }
 
        splx(s);
Index: if_mosreg.h
===================================================================
RCS file: /home/cvs/src/sys/dev/usb/if_mosreg.h,v
retrieving revision 1.5
diff -u -p -r1.5 if_mosreg.h
--- if_mosreg.h 28 Feb 2012 08:58:30 -0000      1.5
+++ if_mosreg.h 1 Mar 2012 11:42:04 -0000
@@ -179,7 +179,6 @@ struct mos_softc {
        int                     mos_ed[MOS_ENDPT_MAX];
        usbd_pipe_handle        mos_ep[MOS_ENDPT_MAX];
        int                     mos_unit;
-       int                     mos_if_flags;
        struct mos_cdata        mos_cdata;
        struct timeout          mos_stat_ch;
 

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

Reply via email to