OpenBSD'ify the receive filter handling and cleanup some of the ioctl bits.
Tested by jcs@ with..
axe0 at uhub3 port 2 configuration 1 interface 0 "Apple Computer Ethernet
A1277" rev 2.00/0.01 addr 3
axe0: AX88772, address 58:55:ca:23:8e:d0
ukphy0 at axe0 phy 16: Generic IEEE 802.3u media interface, rev. 1: OUI
0x000ec6, model 0x0006
OK?
Index: if_axe.c
===================================================================
RCS file: /home/cvs/src/sys/dev/usb/if_axe.c,v
retrieving revision 1.108
diff -u -p -r1.108 if_axe.c
--- if_axe.c 1 Mar 2012 04:33:15 -0000 1.108
+++ if_axe.c 5 Mar 2012 04:35:44 -0000
@@ -216,7 +216,7 @@ int axe_ifmedia_upd(struct ifnet *);
void axe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
void axe_reset(struct axe_softc *sc);
-void axe_setmulti(struct axe_softc *);
+void axe_iff(struct axe_softc *);
void axe_lock_mii(struct axe_softc *sc);
void axe_unlock_mii(struct axe_softc *sc);
@@ -456,9 +456,10 @@ axe_ifmedia_sts(struct ifnet *ifp, struc
}
void
-axe_setmulti(struct axe_softc *sc)
+axe_iff(struct axe_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;
@@ -469,35 +470,40 @@ axe_setmulti(struct axe_softc *sc)
if (usbd_is_dying(sc->axe_udev))
return;
- ifp = GET_IFP(sc);
-
axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, urxmode);
rxmode = UGETW(urxmode);
+ rxmode &= ~(AXE_RXCMD_ALLMULTI | AXE_RXCMD_MULTICAST |
AXE_RXCMD_PROMISC);
+ ifp->if_flags &= ~IFF_ALLMULTI;
+
+ /*
+ * Always accept broadcast frames.
+ * Always accept frames destined to our station address.
+ */
+ rxmode |= AXE_RXCMD_BROADCAST;
+ if (!sc->axe_flags & AX178 && !sc->axe_flags & AX772)
+ rxmode |= AXE_172_RXCMD_UNICAST;
- 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 |= AXE_RXCMD_ALLMULTI;
- axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
- return;
- } else
- rxmode &= ~AXE_RXCMD_ALLMULTI;
+ if (ifp->if_flags & IFF_PROMISC)
+ rxmode |= AXE_RXCMD_PROMISC;
+ } else {
+ rxmode |= AXE_RXCMD_MULTICAST;
- /* 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);
+ /* 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);
+
+ ETHER_NEXT_MULTI(step, enm);
+ }
}
- ifp->if_flags &= ~IFF_ALLMULTI;
axe_cmd(sc, AXE_CMD_WRITE_MCAST, 0, 0, (void *)&hashtbl);
axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
- return;
}
void
@@ -1296,6 +1302,7 @@ axe_init(void *xsc)
struct ifnet *ifp = &sc->arpcom.ac_if;
struct axe_chain *c;
usbd_status err;
+ uWord urxmode;
int rxmode;
int i, s;
@@ -1337,8 +1344,13 @@ axe_init(void *xsc)
axe_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->axe_ipgs[2], NULL);
}
+ /* Program promiscuous mode and multicast filters. */
+ axe_iff(sc);
+
/* Enable receiver, set RX mode */
- rxmode = AXE_RXCMD_MULTICAST|AXE_RXCMD_ENABLE;
+ axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, urxmode);
+ rxmode = UGETW(urxmode);
+ rxmode |= AXE_RXCMD_ENABLE;
if (sc->axe_flags & AX772B)
rxmode |= AXE_772B_RXCMD_RH1M;
else if (sc->axe_flags & AX178 || sc->axe_flags & AX772) {
@@ -1346,21 +1358,9 @@ axe_init(void *xsc)
/* largest possible USB buffer size for AX88178 */
rxmode |= AXE_178_RXCMD_MFB;
}
- } else
- rxmode |= AXE_172_RXCMD_UNICAST;
-
- /* If we want promiscuous mode, set the allframes bit. */
- if (ifp->if_flags & IFF_PROMISC)
- rxmode |= AXE_RXCMD_PROMISC;
-
- if (ifp->if_flags & IFF_BROADCAST)
- rxmode |= AXE_RXCMD_BROADCAST;
-
+ }
axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
- /* Load the multicast filter. */
- axe_setmulti(sc);
-
/* Open RX and TX pipes. */
err = usbd_open_pipe(sc->axe_iface, sc->axe_ed[AXE_ENDPT_RX],
USBD_EXCLUSIVE_USE, &sc->axe_ep[AXE_ENDPT_RX]);
@@ -1406,8 +1406,6 @@ axe_ioctl(struct ifnet *ifp, u_long cmd,
struct axe_softc *sc = ifp->if_softc;
struct ifreq *ifr = (struct ifreq *)data;
struct ifaddr *ifa = (struct ifaddr *)data;
- struct mii_data *mii;
- uWord rxmode;
int s, error = 0;
s = splnet();
@@ -1425,35 +1423,19 @@ axe_ioctl(struct ifnet *ifp, u_long cmd,
case SIOCSIFFLAGS:
if (ifp->if_flags & IFF_UP) {
- if (ifp->if_flags & IFF_RUNNING &&
- ifp->if_flags & IFF_PROMISC &&
- !(sc->axe_if_flags & IFF_PROMISC)) {
-
- axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, rxmode);
- axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0,
- UGETW(rxmode) | AXE_RXCMD_PROMISC, NULL);
-
- axe_setmulti(sc);
- } else if (ifp->if_flags & IFF_RUNNING &&
- !(ifp->if_flags & IFF_PROMISC) &&
- sc->axe_if_flags & IFF_PROMISC) {
- axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, rxmode);
- axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0,
- UGETW(rxmode) & ~AXE_RXCMD_PROMISC, NULL);
- axe_setmulti(sc);
- } else if (!(ifp->if_flags & IFF_RUNNING))
+ if (ifp->if_flags & IFF_RUNNING)
+ error = ENETRESET;
+ else
axe_init(sc);
} else {
if (ifp->if_flags & IFF_RUNNING)
axe_stop(sc);
}
- sc->axe_if_flags = ifp->if_flags;
break;
case SIOCGIFMEDIA:
case SIOCSIFMEDIA:
- mii = GET_MII(sc);
- error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
+ error = ifmedia_ioctl(ifp, ifr, &sc->axe_mii.mii_media, cmd);
break;
default:
@@ -1462,7 +1444,7 @@ axe_ioctl(struct ifnet *ifp, u_long cmd,
if (error == ENETRESET) {
if (ifp->if_flags & IFF_RUNNING)
- axe_setmulti(sc);
+ axe_iff(sc);
error = 0;
}
Index: if_axereg.h
===================================================================
RCS file: /home/cvs/src/sys/dev/usb/if_axereg.h,v
retrieving revision 1.21
diff -u -p -r1.21 if_axereg.h
--- if_axereg.h 1 Mar 2012 04:33:15 -0000 1.21
+++ if_axereg.h 2 Mar 2012 23:29:13 -0000
@@ -228,7 +228,6 @@ struct axe_softc {
int axe_ed[AXE_ENDPT_MAX];
usbd_pipe_handle axe_ep[AXE_ENDPT_MAX];
int axe_unit;
- int axe_if_flags;
struct axe_cdata axe_cdata;
struct timeout axe_stat_ch;
--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.