Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci streamline receive filter logic, work-in-progress.



details:   https://anonhg.NetBSD.org/src/rev/bf1e877ed947
branches:  trunk
changeset: 846876:bf1e877ed947
user:      nisimura <nisimura%NetBSD.org@localhost>
date:      Tue Dec 03 11:26:12 2019 +0000

description:
streamline receive filter logic, work-in-progress.

diffstat:

 sys/dev/pci/if_kse.c |  69 +++++++++++++++++++++++++++++----------------------
 1 files changed, 39 insertions(+), 30 deletions(-)

diffs (127 lines):

diff -r d823c32781ff -r bf1e877ed947 sys/dev/pci/if_kse.c
--- a/sys/dev/pci/if_kse.c      Tue Dec 03 11:25:43 2019 +0000
+++ b/sys/dev/pci/if_kse.c      Tue Dec 03 11:26:12 2019 +0000
@@ -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 @@
 #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 @@
 #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 @@
        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 @@
        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 @@
                         * 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;
- allmulti:
-       sc->sc_rxc |= RXC_RM;
-       ifp->if_flags |= IFF_ALLMULTI;
+
+ 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;
 }
 
 static int



Home | Main Index | Thread Index | Old Index