Here is a diff for the mtd(4) Myson MTD800/MTD803/MTD891 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: mtd8xx.c =================================================================== RCS file: /home/cvs/src/sys/dev/ic/mtd8xx.c,v retrieving revision 1.21 diff -u -p -r1.21 mtd8xx.c --- mtd8xx.c 26 Nov 2013 09:50:33 -0000 1.21 +++ mtd8xx.c 2 Dec 2013 01:34:24 -0000 @@ -68,7 +68,7 @@ static u_int32_t mtd_mii_command(struct static int mtd_miibus_readreg(struct device *, int, int); static void mtd_miibus_writereg(struct device *, int, int, int); static void mtd_miibus_statchg(struct device *); -static void mtd_setmulti(struct mtd_softc *); +void mtd_iff(struct mtd_softc *); static int mtd_encap(struct mtd_softc *, struct mbuf *, u_int32_t *); static int mtd_list_rx_init(struct mtd_softc *); @@ -313,42 +313,45 @@ mtd_miibus_statchg(struct device *self) void -mtd_setmulti(struct mtd_softc *sc) +mtd_iff(struct mtd_softc *sc) { struct arpcom *ac = &sc->sc_arpcom; struct ifnet *ifp = &sc->sc_arpcom.ac_if; - u_int32_t rxfilt, crc, hash[2] = { 0, 0 }; struct ether_multistep step; struct ether_multi *enm; - int mcnt = 0; + u_int32_t rxfilt, crc, hash[2]; - if (ac->ac_multirangecnt > 0) - ifp->if_flags |= IFF_ALLMULTI; + rxfilt = CSR_READ_4(MTD_TCRRCR); + rxfilt &= ~(RCR_AB | RCR_AM | RCR_PROM); + ifp->if_flags &= ~IFF_ALLMULTI; + + /* + * Always accept broadcast frames. + */ + rxfilt |= RCR_AB; - rxfilt = CSR_READ_4(MTD_TCRRCR) & ~RCR_AM; - if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) { + if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) { + ifp->if_flags |= IFF_ALLMULTI; rxfilt |= RCR_AM; - CSR_WRITE_4(MTD_TCRRCR, rxfilt); - CSR_WRITE_4(MTD_MAR0, 0xffffffff); - CSR_WRITE_4(MTD_MAR4, 0xffffffff); - return; - } + if (ifp->if_flags & IFF_PROMISC) + rxfilt |= RCR_PROM; + hash[0] = hash[1] = 0xffffffff; + } else { + rxfilt |= RCR_AM; + /* Program new filter. */ + bzero(hash, sizeof(hash)); + + ETHER_FIRST_MULTI(step, &sc->sc_arpcom, enm); + while (enm != NULL) { + crc = ether_crc32_be(enm->enm_addrlo, + ETHER_ADDR_LEN) >> 26; + + hash[crc >> 5] |= 1 << (crc & 0xf); - /* First, zot all the existing hash bits. */ - CSR_WRITE_4(MTD_MAR0, 0); - CSR_WRITE_4(MTD_MAR4, 0); - - /* Now program new ones. */ - ETHER_FIRST_MULTI(step, ac, enm); - while (enm != NULL) { - crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) >> 26; - hash[crc >> 5] |= 1 << (crc & 0xf); - ++mcnt; - ETHER_NEXT_MULTI(step, enm); + ETHER_NEXT_MULTI(step, enm); + } } - if (mcnt) - rxfilt |= RCR_AM; CSR_WRITE_4(MTD_MAR0, hash[0]); CSR_WRITE_4(MTD_MAR4, hash[1]); CSR_WRITE_4(MTD_TCRRCR, rxfilt); @@ -584,37 +587,39 @@ mtd_ioctl(struct ifnet *ifp, u_long comm switch (command) { case SIOCSIFADDR: ifp->if_flags |= IFF_UP; - mtd_init(ifp); - switch (ifa->ifa_addr->sa_family) { + if (!(ifp->if_flags & IFF_RUNNING)) + mtd_init(ifp); + #ifdef INET - case AF_INET: + if (ifa->ifa_addr->sa_family == AF_INET) arp_ifinit(&sc->sc_arpcom, ifa); - break; -#endif /* INET */ - } +#endif break; case SIOCSIFFLAGS: - if (ifp->if_flags & IFF_UP) - mtd_init(ifp); - else { + if (ifp->if_flags & IFF_UP) { + if (ifp->if_flags & IFF_RUNNING) + error = ENETRESET; + else + mtd_init(ifp); + } else { if (ifp->if_flags & IFF_RUNNING) mtd_stop(ifp); } - error = 0; break; case SIOCGIFMEDIA: case SIOCSIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, command); break; + default: error = ether_ioctl(ifp, &sc->sc_arpcom, command, data); } if (error == ENETRESET) { if (ifp->if_flags & IFF_RUNNING) - mtd_setmulti(sc); + mtd_iff(sc); error = 0; } @@ -646,17 +651,8 @@ mtd_init(struct ifnet *ifp) CSR_SETBIT(MTD_TCRRCR, TCR_ENHANCED); } - if (ifp->if_flags & IFF_PROMISC) - CSR_SETBIT(MTD_TCRRCR, RCR_PROM); - else - CSR_CLRBIT(MTD_TCRRCR, RCR_PROM); - - if (ifp->if_flags & IFF_BROADCAST) - CSR_SETBIT(MTD_TCRRCR, RCR_AB); - else - CSR_CLRBIT(MTD_TCRRCR, RCR_AB); - - mtd_setmulti(sc); + /* Program promiscuous mode and multicast filters. */ + mtd_iff(sc); if (mtd_list_rx_init(sc)) { printf("%s: can't allocate memeory for rx buffers\n", -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.