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.