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.