diff options
| author | pk <pk@NetBSD.org> | 1999-03-23 00:27:09 +0000 |
|---|---|---|
| committer | pk <pk@NetBSD.org> | 1999-03-23 00:27:09 +0000 |
| commit | d86e93c62a924095e7df7621661335485aeddbcc (patch) | |
| tree | 7243797bb1a0925f180252b4d75711a4cc1e3e0f /sys/dev/sbus | |
| parent | 5808123a9e04b2e76e6d94d293bcd793edd555d3 (diff) | |
Fix promiscuous modes - patches from Jason Wright.
Diffstat (limited to 'sys/dev/sbus')
| -rw-r--r-- | sys/dev/sbus/be.c | 27 | ||||
| -rw-r--r-- | sys/dev/sbus/qe.c | 121 |
2 files changed, 80 insertions, 68 deletions
diff --git a/sys/dev/sbus/be.c b/sys/dev/sbus/be.c index c6a324bc61c..6b0427ae691 100644 --- a/sys/dev/sbus/be.c +++ b/sys/dev/sbus/be.c @@ -1,4 +1,4 @@ -/* $NetBSD: be.c,v 1.4 1999/02/19 14:57:00 pk Exp $ */ +/* $NetBSD: be.c,v 1.5 1999/03/23 00:27:09 pk Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -142,7 +142,6 @@ struct be_softc { u_int sc_rev; int sc_channel; /* channel number */ - int sc_promisc; int sc_burst; int sc_conf; #define BE_CONF_MII 1 @@ -951,7 +950,6 @@ beioctl(ifp, cmd, data) break; case SIOCSIFFLAGS: - sc->sc_promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI); if ((ifp->if_flags & IFF_UP) == 0 && (ifp->if_flags & IFF_RUNNING) != 0) { /* @@ -1043,7 +1041,7 @@ beinit(sc) bus_space_write_4(t, br, BE_BRI_HASHTAB2, 0); bus_space_write_4(t, br, BE_BRI_HASHTAB3, 0); - DELAY(20); + be_mcreset(sc); bus_space_write_4(t, br, BE_BRI_RANDSEED, 0xbd); @@ -1113,10 +1111,22 @@ be_mcreset(sc) u_int32_t crc; u_int16_t hash[4]; u_int8_t octet; + u_int32_t v; int i, j; struct ether_multi *enm; struct ether_multistep step; + if (ifp->if_flags & IFF_PROMISC) { + v = bus_space_read_4(t, br, BE_BRI_RXCFG); + v |= BE_BR_RXCFG_PMISC; + bus_space_write_4(t, br, BE_BRI_RXCFG, v); + return; + } + + v = bus_space_read_4(t, br, BE_BRI_RXCFG); + v &= ~BE_BR_RXCFG_PMISC; + bus_space_write_4(t, br, BE_BRI_RXCFG, v); + if (ifp->if_flags & IFF_ALLMULTI) { bus_space_write_4(t, br, BE_BRI_HASHTAB0, 0xffff); bus_space_write_4(t, br, BE_BRI_HASHTAB1, 0xffff); @@ -1125,15 +1135,6 @@ be_mcreset(sc) return; } - if (ifp->if_flags & IFF_PROMISC) { - u_int32_t v; - - v = bus_space_read_4(t, br, BE_BRI_RXCFG); - v |= BE_BR_RXCFG_PMISC; - bus_space_write_4(t, br, BE_BRI_RXCFG, v); - return; - } - hash[3] = hash[2] = hash[1] = hash[0] = 0; ETHER_FIRST_MULTI(step, ec, enm); diff --git a/sys/dev/sbus/qe.c b/sys/dev/sbus/qe.c index f2954dd3a26..6a74b29d07a 100644 --- a/sys/dev/sbus/qe.c +++ b/sys/dev/sbus/qe.c @@ -1,4 +1,4 @@ -/* $NetBSD: qe.c,v 1.4 1999/03/09 00:42:20 mrg Exp $ */ +/* $NetBSD: qe.c,v 1.5 1999/03/23 00:27:09 pk Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -145,7 +145,6 @@ struct qe_softc { int sc_channel; /* channel number */ u_int sc_rev; /* board revision */ - int sc_promisc; int sc_burst; struct qec_ring sc_rb; /* Packet Ring Buffer */ @@ -902,7 +901,6 @@ qeioctl(ifp, cmd, data) break; case SIOCSIFFLAGS: - sc->sc_promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI); if ((ifp->if_flags & IFF_UP) == 0 && (ifp->if_flags & IFF_RUNNING) != 0) { /* @@ -911,13 +909,15 @@ qeioctl(ifp, cmd, data) */ qestop(sc); ifp->if_flags &= ~IFF_RUNNING; + } else if ((ifp->if_flags & IFF_UP) != 0 && - (ifp->if_flags & IFF_RUNNING) == 0) { + (ifp->if_flags & IFF_RUNNING) == 0) { /* * If interface is marked up and it is stopped, then * start it. */ qeinit(sc); + } else { /* * Reset the interface to pick up changes in any other @@ -1054,6 +1054,9 @@ qeinit(sc) QE_MR_MACCC_ENXMT | QE_MR_MACCC_ENRCV | ((ifp->if_flags&IFF_PROMISC) ? QE_MR_MACCC_PROM : 0)); + /* Reset multicast filter */ + qe_mcreset(sc); + ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; splx(s); @@ -1074,77 +1077,85 @@ qe_mcreset(sc) struct ether_multistep step; u_int32_t crc; u_int16_t hash[4]; - u_int8_t octet, maccc = 0, *ladrp = (u_int8_t *)&hash[0]; + u_int8_t octet, maccc, *ladrp = (u_int8_t *)&hash[0]; int i, j; #if defined(SUN4U) || defined(__GNUC__) (void)&t; #endif + + maccc = QE_MR_MACCC_ENXMT | QE_MR_MACCC_ENRCV; + + if (ifp->if_flags & IFF_PROMISC) { + maccc |= QE_MR_MACCC_PROM; + bus_space_write_1(t, mr, QE_MRI_MACCC, maccc); + return; + } + if (ifp->if_flags & IFF_ALLMULTI) { bus_space_write_1(t, mr, QE_MRI_IAC, QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR); for (i = 0; i < 8; i++) bus_space_write_1(t, mr, QE_MRI_LADRF, 0xff); bus_space_write_1(t, mr, QE_MRI_IAC, 0); - } else if (ifp->if_flags & IFF_PROMISC) { - maccc |= QE_MR_MACCC_PROM; - } else { - hash[3] = hash[2] = hash[1] = hash[0] = 0; - - ETHER_FIRST_MULTI(step, ec, enm); - while (enm != NULL) { - if (bcmp(enm->enm_addrlo, enm->enm_addrhi, - ETHER_ADDR_LEN) != 0) { - /* - * We must listen to a range of multicast - * addresses. For now, just accept all - * multicasts, rather than trying to set only - * those filter bits needed to match the range. - * (At this time, the only use of address - * ranges is for IP multicast routing, for - * which the range is big enough to require - * all bits set.) - */ - bus_space_write_1(t, mr, QE_MRI_IAC, - QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR); - for (i = 0; i < 8; i++) - bus_space_write_1(t, mr, QE_MRI_LADRF, - 0xff); - bus_space_write_1(t, mr, QE_MRI_IAC, 0); - ifp->if_flags |= IFF_ALLMULTI; - break; - } + bus_space_write_1(t, mr, QE_MRI_MACCC, maccc); + return; + } + + hash[3] = hash[2] = hash[1] = hash[0] = 0; + + ETHER_FIRST_MULTI(step, ec, enm); + while (enm != NULL) { + if (bcmp(enm->enm_addrlo, enm->enm_addrhi, + ETHER_ADDR_LEN) != 0) { + /* + * We must listen to a range of multicast + * addresses. For now, just accept all + * multicasts, rather than trying to set only + * those filter bits needed to match the range. + * (At this time, the only use of address + * ranges is for IP multicast routing, for + * which the range is big enough to require + * all bits set.) + */ + bus_space_write_1(t, mr, QE_MRI_IAC, + QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR); + for (i = 0; i < 8; i++) + bus_space_write_1(t, mr, QE_MRI_LADRF, + 0xff); + bus_space_write_1(t, mr, QE_MRI_IAC, 0); + ifp->if_flags |= IFF_ALLMULTI; + break; + } - crc = 0xffffffff; + crc = 0xffffffff; - for (i = 0; i < ETHER_ADDR_LEN; i++) { - octet = enm->enm_addrlo[i]; + for (i = 0; i < ETHER_ADDR_LEN; i++) { + octet = enm->enm_addrlo[i]; - for (j = 0; j < 8; j++) { - if ((crc & 1) ^ (octet & 1)) { - crc >>= 1; - crc ^= MC_POLY_LE; - } - else - crc >>= 1; - octet >>= 1; + for (j = 0; j < 8; j++) { + if ((crc & 1) ^ (octet & 1)) { + crc >>= 1; + crc ^= MC_POLY_LE; } + else + crc >>= 1; + octet >>= 1; } - - crc >>= 26; - hash[crc >> 4] |= 1 << (crc & 0xf); - ETHER_NEXT_MULTI(step, enm); } - bus_space_write_1(t, mr, QE_MRI_IAC, - QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR); - for (i = 0; i < 8; i++) - bus_space_write_1(t, mr, QE_MRI_LADRF, ladrp[i]); - bus_space_write_1(t, mr, QE_MRI_IAC, 0); + crc >>= 26; + hash[crc >> 4] |= 1 << (crc & 0xf); + ETHER_NEXT_MULTI(step, enm); } - bus_space_write_1(t, mr, QE_MRI_MACCC, - maccc | QE_MR_MACCC_ENXMT | QE_MR_MACCC_ENRCV); + bus_space_write_1(t, mr, QE_MRI_IAC, + QE_MR_IAC_ADDRCHG | QE_MR_IAC_LOGADDR); + for (i = 0; i < 8; i++) + bus_space_write_1(t, mr, QE_MRI_LADRF, ladrp[i]); + bus_space_write_1(t, mr, QE_MRI_IAC, 0); + + bus_space_write_1(t, mr, QE_MRI_MACCC, maccc); } /* |
