Module Name: src Committed By: nisimura Date: Tue Dec 3 11:26:13 UTC 2019
Modified Files: src/sys/dev/pci: if_kse.c Log Message: streamline receive filter logic, work-in-progress. To generate a diff of this commit: cvs rdiff -u -r1.43 -r1.44 src/sys/dev/pci/if_kse.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/if_kse.c diff -u src/sys/dev/pci/if_kse.c:1.43 src/sys/dev/pci/if_kse.c:1.44 --- src/sys/dev/pci/if_kse.c:1.43 Fri Nov 29 05:47:26 2019 +++ src/sys/dev/pci/if_kse.c Tue Dec 3 11:26:12 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_kse.c,v 1.43 2019/11/29 05:47:26 nisimura Exp $ */ +/* $NetBSD: if_kse.c,v 1.44 2019/12/03 11:26:12 nisimura Exp $ */ /*- * Copyright (c) 2006 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_kse.c,v 1.43 2019/11/29 05:47:26 nisimura Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_kse.c,v 1.44 2019/12/03 11:26:12 nisimura Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -63,7 +63,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_kse.c,v 1 #include <dev/pci/pcireg.h> #include <dev/pci/pcidevs.h> -#define KSE_LINKDEBUG 0 +#define KSE_LINKDEBUG 1 #define CSR_READ_4(sc, off) \ bus_space_read_4(sc->sc_st, sc->sc_sh, off) @@ -132,8 +132,8 @@ __KERNEL_RCSID(0, "$NetBSD: if_kse.c,v 1 #define RXC_ICC (1U<<16) /* run IP checksum */ #define RXC_FCE (1U<<9) /* accept PAUSE to throttle Tx */ #define RXC_RB (1U<<6) /* receive broadcast frame */ -#define RXC_RM (1U<<5) /* receive multicast frame */ -#define RXC_RU (1U<<4) /* receive unicast frame */ +#define RXC_RM (1U<<5) /* receive all multicast (inc. RB) */ +#define RXC_RU (1U<<4) /* receive 16 additional unicasts */ #define RXC_RE (1U<<3) /* accept error frame */ #define RXC_RA (1U<<2) /* receive all frame */ #define RXC_MHTE (1U<<1) /* use multicast hash table */ @@ -791,11 +791,7 @@ kse_init(struct ifnet *ifp) CSR_WRITE_4(sc, RDLB, KSE_CDRXADDR(sc, 0)); sc->sc_txc = TXC_TEN | TXC_EP | TXC_AC; - sc->sc_rxc = RXC_REN | RXC_RU; - if (ifp->if_flags & IFF_PROMISC) - sc->sc_rxc |= RXC_RA; - if (ifp->if_flags & IFF_BROADCAST) - sc->sc_rxc |= RXC_RB; + sc->sc_rxc = RXC_REN | RXC_RU | RXC_RB; sc->sc_t1csum = sc->sc_mcsum = 0; if (ifp->if_capenable & IFCAP_CSUM_IPv4_Rx) { sc->sc_rxc |= RXC_ICC; @@ -1090,21 +1086,25 @@ kse_set_filter(struct kse_softc *sc) struct ether_multi *enm; struct ethercom *ec = &sc->sc_ethercom; struct ifnet *ifp = &ec->ec_if; - uint32_t h, hashes[2]; + uint32_t crc, mchash[2]; - sc->sc_rxc &= ~(RXC_MHTE | RXC_RM); + sc->sc_rxc &= ~(RXC_MHTE | RXC_RM | RXC_RA); ifp->if_flags &= ~IFF_ALLMULTI; - if (ifp->if_flags & IFF_PROMISC) - return; + if ((ifp->if_flags & IFF_PROMISC) || ec->ec_multicnt > 0) { + ifp->if_flags |= IFF_ALLMULTI; + goto update; + } + + mchash[0] = mchash[1] = crc = 0; ETHER_LOCK(ec); ETHER_FIRST_MULTI(step, ec, enm); - if (enm == NULL) { - ETHER_UNLOCK(ec); - return; - } - hashes[0] = hashes[1] = 0; - do { + while (enm != NULL) { +#if KSE_MCASTDEBUG == 1 + printf("%s: addrs %s %s\n", __func__, + ether_sprintf(enm->enm_addrlo), + ether_sprintf(enm->enm_addrhi)); +#endif if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { /* * We must listen to a range of multicast addresses. @@ -1115,20 +1115,29 @@ kse_set_filter(struct kse_softc *sc) * range is big enough to require all bits set.) */ ETHER_UNLOCK(ec); - goto allmulti; + ifp->if_flags |= IFF_ALLMULTI; + goto update; } - h = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN) >> 26; - hashes[h >> 5] |= 1 << (h & 0x1f); + crc = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN); + mchash[crc >> 31] |= 1 << ((crc >> 26) & 0x1f); ETHER_NEXT_MULTI(step, enm); - } while (enm != NULL); + } ETHER_UNLOCK(ec); - sc->sc_rxc |= RXC_MHTE; - CSR_WRITE_4(sc, MTR0, hashes[0]); - CSR_WRITE_4(sc, MTR1, hashes[1]); + + if (crc) { + CSR_WRITE_4(sc, MTR0, mchash[0]); + CSR_WRITE_4(sc, MTR1, mchash[1]); + sc->sc_rxc |= RXC_MHTE; + } + return; + + update: + /* With RA or RM, MHTE/MTR0/MTR1 are never consulted. */ + if (ifp->if_flags & IFF_PROMISC) + sc->sc_rxc |= RXC_RA; + else + sc->sc_rxc |= RXC_RM; return; - allmulti: - sc->sc_rxc |= RXC_RM; - ifp->if_flags |= IFF_ALLMULTI; } static int