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.