rebuild the filter flags from scratch instead of pulling the state from the card and setting/unsetting the necessary bits.
--- dev/usb/if_axen.c | 23 ++++++++++++----------- dev/usb/if_axenreg.h | 4 ++-- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/dev/usb/if_axen.c b/dev/usb/if_axen.c index dfdcecf..088f40f 100644 --- a/dev/usb/if_axen.c +++ b/dev/usb/if_axen.c @@ -392,27 +392,27 @@ axen_iff(struct axen_softc *sc) /* Enable receiver, set RX mode */ axen_lock_mii(sc); - axen_cmd(sc, AXEN_CMD_MAC_READ2, 2, AXEN_MAC_RXCTL, &wval); - rxmode = UGETW(wval); - rxmode &= ~(AXEN_RXCTL_ACPT_ALL_MCAST | AXEN_RXCTL_ACPT_PHY_MCAST | - AXEN_RXCTL_PROMISC); + rxmode = AXEN_RXCTL_DROPCRCERR | AXEN_RXCTL_START; ifp->if_flags &= ~IFF_ALLMULTI; /* - * Always accept broadcast frames. * Always accept frames destined to our station address. */ - rxmode |= AXEN_RXCTL_ACPT_BCAST; + rxmode |= AXEN_RXCTL_ACPT_PHY_MCAST; + /* + * Accept broadcast frames iff interface has IFF_BROADCAST set. + */ + if (ifp->if_flags & IFF_BROADCAST) + rxmode |= AXEN_RXCTL_ACPT_BCAST; if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) { ifp->if_flags |= IFF_ALLMULTI; - rxmode |= AXEN_RXCTL_ACPT_ALL_MCAST | AXEN_RXCTL_ACPT_PHY_MCAST; + rxmode |= AXEN_RXCTL_ACPT_ALL_MCAST; if (ifp->if_flags & IFF_PROMISC) rxmode |= AXEN_RXCTL_PROMISC; } else { - rxmode |= AXEN_RXCTL_ACPT_ALL_MCAST | AXEN_RXCTL_ACPT_PHY_MCAST; - - /* now program new ones */ + rxmode |= AXEN_RXCTL_ACPT_MCAST; + /* compute multicast filter array */ ETHER_FIRST_MULTI(step, ac, enm); while (enm != NULL) { h = ether_crc32_be(enm->enm_addrlo, @@ -424,6 +424,7 @@ axen_iff(struct axen_softc *sc) axen_cmd(sc, AXEN_CMD_MAC_WRITE_FILTER, 8, AXEN_FILTER_MULTI, (void *)&hashtbl); + USETW(wval, rxmode); axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval); axen_unlock_mii(sc); @@ -543,7 +544,7 @@ axen_ax88179_init(struct axen_softc *sc) axen_cmd(sc, AXEN_CMD_MAC_WRITE, 1, AXEN_TX_COE, &val); /* Set RX control register */ - ctl = AXEN_RXCTL_DROPCRCERR | AXEN_RXCTL_AUTOB; + ctl = AXEN_RXCTL_DROPCRCERR; ctl |= AXEN_RXCTL_ACPT_PHY_MCAST | AXEN_RXCTL_ACPT_ALL_MCAST; ctl |= AXEN_RXCTL_START; USETW(wval, ctl); diff --git a/dev/usb/if_axenreg.h b/dev/usb/if_axenreg.h index 336727f..766c89e 100644 --- a/dev/usb/if_axenreg.h +++ b/dev/usb/if_axenreg.h @@ -157,8 +157,8 @@ #define AXEN_RXCTL_PROMISC 0x0001 #define AXEN_RXCTL_ACPT_ALL_MCAST 0x0002 #define AXEN_RXCTL_HA8B 0x0004 -#define AXEN_RXCTL_AUTOB 0x0008 -#define AXEN_RXCTL_ACPT_BCAST 0x0010 +#define AXEN_RXCTL_ACPT_BCAST 0x0008 +#define AXEN_RXCTL_ACPT_MCAST 0x0010 #define AXEN_RXCTL_ACPT_PHY_MCAST 0x0020 #define AXEN_RXCTL_START 0x0080 #define AXEN_RXCTL_DROPCRCERR 0x0100 -- 2.20.1