OpenBSD'ify the receive filter handling and cleanup some of the ioctl bits.     
                                                                       
                                                                                
                                                                       
Tested with..
url0 at uhub2 port 2 "USBKR100 USB 10/100 LAN" rev 1.10/1.00 addr 2
url0: address 00:10:60:e0:b5:89
urlphy0 at url0 phy 0: RTL internal phy

OK?


Index: if_url.c
===================================================================
RCS file: /home/cvs/src/sys/dev/usb/if_url.c,v
retrieving revision 1.63
diff -u -p -r1.63 if_url.c
--- if_url.c    3 Jul 2011 15:47:17 -0000       1.63
+++ if_url.c    5 Mar 2012 06:05:19 -0000
@@ -123,7 +123,7 @@ int url_int_miibus_readreg(struct device
 void url_int_miibus_writereg(struct device *, int, int, int);
 void url_miibus_statchg(struct device *);
 int url_init(struct ifnet *);
-void url_setmulti(struct url_softc *);
+void url_iff(struct url_softc *);
 void url_reset(struct url_softc *);
 
 int url_csr_read_1(struct url_softc *, int);
@@ -506,17 +506,6 @@ url_init(struct ifnet *ifp)
 
        /* Init receive control register */
        URL_SETBIT2(sc, URL_RCR, URL_RCR_TAIL | URL_RCR_AD);
-       if (ifp->if_flags & IFF_BROADCAST)
-               URL_SETBIT2(sc, URL_RCR, URL_RCR_AB);
-       else
-               URL_CLRBIT2(sc, URL_RCR, URL_RCR_AB);
-
-       /* If we want promiscuous mode, accept all physical frames. */
-       if (ifp->if_flags & IFF_PROMISC)
-               URL_SETBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP);
-       else
-               URL_CLRBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP);
-
 
        /* Initialize transmit ring */
        if (url_tx_list_init(sc) == ENOBUFS) {
@@ -532,8 +521,8 @@ url_init(struct ifnet *ifp)
                return (EIO);
        }
 
-       /* Load the multicast filter */
-       url_setmulti(sc);
+       /* Program promiscuous mode and multicast filters */
+       url_iff(sc);
 
        /* Enable RX and TX */
        URL_SETBIT(sc, URL_CR, URL_CR_TE | URL_CR_RE);
@@ -595,68 +584,56 @@ url_activate(struct device *self, int ac
        return (0);
 }
 
-#define url_calchash(addr) (ether_crc32_be((addr), ETHER_ADDR_LEN) >> 26)
-
-
 void
-url_setmulti(struct url_softc *sc)
+url_iff(struct url_softc *sc)
 {
-       struct ifnet *ifp;
+       struct ifnet *ifp = GET_IFP(sc);
+       struct arpcom *ac = &sc->sc_ac;
        struct ether_multi *enm;
        struct ether_multistep step;
-       u_int32_t hashes[2] = { 0, 0 };
+       u_int32_t hashes[2];
+       u_int16_t rcr;
        int h = 0;
-       int mcnt = 0;
 
        DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
 
        if (usbd_is_dying(sc->sc_udev))
                return;
 
-       ifp = GET_IFP(sc);
-
-       if (ifp->if_flags & IFF_PROMISC) {
-               URL_SETBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP);
-               return;
-       } else if (ifp->if_flags & IFF_ALLMULTI) {
-       allmulti:
-               ifp->if_flags |= IFF_ALLMULTI;
-               URL_SETBIT2(sc, URL_RCR, URL_RCR_AAM);
-               URL_CLRBIT2(sc, URL_RCR, URL_RCR_AAP);
-               return;
-       }
-
-       /* first, zot all the existing hash bits */
-       url_csr_write_4(sc, URL_MAR0, 0);
-       url_csr_write_4(sc, URL_MAR4, 0);
-
-       /* now program new ones */
-       ETHER_FIRST_MULTI(step, &sc->sc_ac, enm);
-       while (enm != NULL) {
-               if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
-                          ETHER_ADDR_LEN) != 0)
-                       goto allmulti;
-
-               h = url_calchash(enm->enm_addrlo);
-               if (h < 32)
-                       hashes[0] |= (1 << h);
-               else
-                       hashes[1] |= (1 << (h -32));
-               mcnt++;
-               ETHER_NEXT_MULTI(step, enm);
-       }
-
+       URL_CLRBIT2(sc, URL_RCR, URL_RCR_AAM | URL_RCR_AAP | URL_RCR_AM);
+       bzero(hashes, sizeof(hashes));
        ifp->if_flags &= ~IFF_ALLMULTI;
 
-       URL_CLRBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP);
+       /*
+        * Always accept broadcast frames.
+        */
+       rcr |= URL_RCR_AB;
 
-       if (mcnt){
-               URL_SETBIT2(sc, URL_RCR, URL_RCR_AM);
+       if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
+               ifp->if_flags |= IFF_ALLMULTI;
+               rcr |= URL_RCR_AAM;
+               if (ifp->if_flags & IFF_PROMISC)
+                       rcr |= URL_RCR_AAP;
        } else {
-               URL_CLRBIT2(sc, URL_RCR, URL_RCR_AM);
+               rcr |= URL_RCR_AM;
+
+               /* now program new ones */
+               ETHER_FIRST_MULTI(step, &sc->sc_ac, enm);
+               while (enm != NULL) {
+                       h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) >> 
26;
+
+                       if (h < 32)
+                               hashes[0] |= (1 << h);
+                       else
+                               hashes[1] |= (1 << (h - 32));
+
+                       ETHER_NEXT_MULTI(step, enm);
+               }
        }
+
        url_csr_write_4(sc, URL_MAR0, hashes[0]);
        url_csr_write_4(sc, URL_MAR4, hashes[1]);
+       URL_SETBIT2(sc, URL_RCR, rcr);
 }
 
 int
@@ -1059,7 +1036,6 @@ url_ioctl(struct ifnet *ifp, u_long cmd,
        struct url_softc *sc = ifp->if_softc;
        struct ifaddr *ifa = (struct ifaddr *)data;
        struct ifreq *ifr = (struct ifreq *)data;
-       struct mii_data *mii;
        int s, error = 0;
 
        DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
@@ -1072,40 +1048,29 @@ url_ioctl(struct ifnet *ifp, u_long cmd,
        switch (cmd) {
        case SIOCSIFADDR:
                ifp->if_flags |= IFF_UP;
-               url_init(ifp);
-
-               switch (ifa->ifa_addr->sa_family) {
+               if (!(ifp->if_flags & IFF_RUNNING))
+                       url_init(ifp);
 #ifdef INET
-               case AF_INET:
+               if (ifa->ifa_addr->sa_family == AF_INET)
                        arp_ifinit(&sc->sc_ac, ifa);
-                       break;
-#endif /* INET */
-               }
+#endif
                break;
 
        case SIOCSIFFLAGS:
                if (ifp->if_flags & IFF_UP) {
-                       if (ifp->if_flags & IFF_RUNNING &&
-                           ifp->if_flags & IFF_PROMISC) {
-                               URL_SETBIT2(sc, URL_RCR,
-                                           URL_RCR_AAM|URL_RCR_AAP);
-                       } else if (ifp->if_flags & IFF_RUNNING &&
-                                  !(ifp->if_flags & IFF_PROMISC)) {
-                               URL_CLRBIT2(sc, URL_RCR,
-                                           URL_RCR_AAM|URL_RCR_AAP);
-                       } else if (!(ifp->if_flags & IFF_RUNNING))
+                       if (ifp->if_flags & IFF_RUNNING)
+                               error = ENETRESET;
+                       else
                                url_init(ifp);
                } else {
                        if (ifp->if_flags & IFF_RUNNING)
                                url_stop(ifp, 1);
                }
-               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->sc_mii.mii_media, cmd);
                break;
 
        default:
@@ -1114,7 +1079,7 @@ url_ioctl(struct ifnet *ifp, u_long cmd,
 
        if (error == ENETRESET) {
                if (ifp->if_flags & IFF_RUNNING)
-                       url_setmulti(sc);
+                       url_iff(sc);
                error = 0;
        }
 

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

Reply via email to