Here is a diff for the cue(4) CATC USB-EL1201A 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_cue.c =================================================================== RCS file: /home/cvs/src/sys/dev/usb/if_cue.c,v retrieving revision 1.64 diff -u -p -r1.64 if_cue.c --- if_cue.c 15 Nov 2013 10:17:39 -0000 1.64 +++ if_cue.c 17 Nov 2013 20:26:19 -0000 @@ -139,7 +139,7 @@ void cue_init(void *); void cue_stop(struct cue_softc *); void cue_watchdog(struct ifnet *); -void cue_setmulti(struct cue_softc *); +void cue_iff(struct cue_softc *); void cue_reset(struct cue_softc *); int cue_csr_read_1(struct cue_softc *, int); @@ -340,52 +340,50 @@ cue_getmac(struct cue_softc *sc, void *b #define CUE_BITS 9 void -cue_setmulti(struct cue_softc *sc) +cue_iff(struct cue_softc *sc) { + struct ifnet *ifp = GET_IFP(sc); struct arpcom *ac = &sc->arpcom; - struct ifnet *ifp; struct ether_multi *enm; struct ether_multistep step; u_int32_t h, i; - ifp = GET_IFP(sc); - - DPRINTFN(2,("%s: cue_setmulti if_flags=0x%x\n", + DPRINTFN(2,("%s: cue_iff if_flags=0x%x\n", sc->cue_dev.dv_xname, ifp->if_flags)); + CUE_CLRBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC); + ifp->if_flags &= ~IFF_ALLMULTI; + if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) { ifp->if_flags |= IFF_ALLMULTI; + if (ifp->if_flags & IFF_PROMISC) + CUE_SETBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC); for (i = 0; i < CUE_MCAST_TABLE_LEN; i++) sc->cue_mctab[i] = 0xFF; - cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR, - &sc->cue_mctab, CUE_MCAST_TABLE_LEN); - return; - } + } else { + /* first, zot all the existing hash bits */ + for (i = 0; i < CUE_MCAST_TABLE_LEN; i++) + sc->cue_mctab[i] = 0; - /* first, zot all the existing hash bits */ - for (i = 0; i < CUE_MCAST_TABLE_LEN; i++) - sc->cue_mctab[i] = 0; - - /* now program new ones */ - ETHER_FIRST_MULTI(step, ac, enm); - while (enm != NULL) { - h = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN) & - ((1 << CUE_BITS) - 1); - sc->cue_mctab[h >> 3] |= 1 << (h & 0x7); - ETHER_NEXT_MULTI(step, enm); - } + /* now program new ones */ + ETHER_FIRST_MULTI(step, ac, enm); + while (enm != NULL) { + h = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN) & + ((1 << CUE_BITS) - 1); - ifp->if_flags &= ~IFF_ALLMULTI; + sc->cue_mctab[h >> 3] |= 1 << (h & 0x7); + + ETHER_NEXT_MULTI(step, enm); + } + } /* * Also include the broadcast address in the filter * so we can receive broadcast frames. */ - if (ifp->if_flags & IFF_BROADCAST) { - h = ether_crc32_le(etherbroadcastaddr, ETHER_ADDR_LEN) & - ((1 << CUE_BITS) - 1); - sc->cue_mctab[h >> 3] |= 1 << (h & 0x7); - } + h = ether_crc32_le(etherbroadcastaddr, ETHER_ADDR_LEN) & + ((1 << CUE_BITS) - 1); + sc->cue_mctab[h >> 3] |= 1 << (h & 0x7); cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR, &sc->cue_mctab, CUE_MCAST_TABLE_LEN); @@ -970,17 +968,12 @@ cue_init(void *xsc) DPRINTFN(10,("%s: %s: enter\n", sc->cue_dev.dv_xname,__func__)); - if (ifp->if_flags & IFF_RUNNING) - return; - s = splnet(); /* * Cancel pending I/O and free all RX/TX buffers. */ -#if 1 cue_reset(sc); -#endif /* Set advanced operation modes. */ cue_csr_write_1(sc, CUE_ADVANCED_OPMODES, @@ -1011,8 +1004,8 @@ cue_init(void *xsc) return; } - /* Load the multicast filter. */ - cue_setmulti(sc); + /* Program promiscuous mode and multicast filters. */ + cue_iff(sc); /* * Set the number of RX and TX buffers that we want @@ -1094,37 +1087,24 @@ cue_ioctl(struct ifnet *ifp, u_long comm switch(command) { case SIOCSIFADDR: ifp->if_flags |= IFF_UP; - cue_init(sc); - - switch (ifa->ifa_addr->sa_family) { + if (!(ifp->if_flags & IFF_RUNNING)) + cue_init(sc); #ifdef INET - case AF_INET: + if (ifa->ifa_addr->sa_family == AF_INET) arp_ifinit(&sc->arpcom, 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 && - !(sc->cue_if_flags & IFF_PROMISC)) { - CUE_SETBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC); - cue_setmulti(sc); - } else if (ifp->if_flags & IFF_RUNNING && - !(ifp->if_flags & IFF_PROMISC) && - sc->cue_if_flags & IFF_PROMISC) { - CUE_CLRBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC); - cue_setmulti(sc); - } else if (!(ifp->if_flags & IFF_RUNNING)) + if (ifp->if_flags & IFF_RUNNING) + error = ENETRESET; + else cue_init(sc); } else { if (ifp->if_flags & IFF_RUNNING) cue_stop(sc); } - sc->cue_if_flags = ifp->if_flags; - error = 0; break; default: @@ -1133,7 +1113,7 @@ cue_ioctl(struct ifnet *ifp, u_long comm if (error == ENETRESET) { if (ifp->if_flags & IFF_RUNNING) - cue_setmulti(sc); + cue_iff(sc); error = 0; } Index: if_cuereg.h =================================================================== RCS file: /home/cvs/src/sys/dev/usb/if_cuereg.h,v retrieving revision 1.12 diff -u -p -r1.12 if_cuereg.h --- if_cuereg.h 15 Apr 2013 09:23:01 -0000 1.12 +++ if_cuereg.h 2 Jun 2013 21:05:20 -0000 @@ -179,8 +179,6 @@ struct cue_softc { int cue_ed[CUE_ENDPT_MAX]; struct usbd_pipe *cue_ep[CUE_ENDPT_MAX]; u_int8_t cue_mctab[CUE_MCAST_TABLE_LEN]; - int cue_if_flags; - u_int16_t cue_rxfilt; struct cue_cdata cue_cdata; u_int cue_rx_errs; -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.