Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/usb iron out multicast filter logic and pick better ...



details:   https://anonhg.NetBSD.org/src/rev/9e6fdf77605a
branches:  trunk
changeset: 1008699:9e6fdf77605a
user:      nisimura <nisimura%NetBSD.org@localhost>
date:      Tue Mar 31 23:26:32 2020 +0000

description:
iron out multicast filter logic and pick better name for its work

diffstat:

 sys/dev/usb/if_mos.c |  63 +++++++++++++++++++++++++--------------------------
 1 files changed, 31 insertions(+), 32 deletions(-)

diffs (119 lines):

diff -r a5dae051fb06 -r 9e6fdf77605a sys/dev/usb/if_mos.c
--- a/sys/dev/usb/if_mos.c      Tue Mar 31 19:08:19 2020 +0000
+++ b/sys/dev/usb/if_mos.c      Tue Mar 31 23:26:32 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_mos.c,v 1.5 2020/03/15 23:04:50 thorpej Exp $       */
+/*     $NetBSD: if_mos.c,v 1.6 2020/03/31 23:26:32 nisimura Exp $      */
 /*     $OpenBSD: if_mos.c,v 1.40 2019/07/07 06:40:10 kevlo Exp $       */
 
 /*
@@ -72,7 +72,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_mos.c,v 1.5 2020/03/15 23:04:50 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_mos.c,v 1.6 2020/03/31 23:26:32 nisimura Exp $");
 
 #include <sys/param.h>
 
@@ -454,14 +454,14 @@
 }
 
 static void
-mos_setiff_locked(struct usbnet *un)
+mos_rcvfilt_locked(struct usbnet *un)
 {
        struct ifnet            *ifp = usbnet_ifp(un);
        struct ethercom         *ec = usbnet_ec(un);
        struct ether_multi      *enm;
        struct ether_multistep  step;
-       u_int32_t               h = 0;
-       u_int8_t                rxmode, hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+       u_int32_t h = 0;
+       u_int8_t rxmode, mchash[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
 
        if (usbnet_isdying(un))
                return;
@@ -471,40 +471,39 @@
 
        ETHER_LOCK(ec);
        if (ifp->if_flags & IFF_PROMISC) {
-allmulti:
                ec->ec_flags |= ETHER_F_ALLMULTI;
-               rxmode |= MOS_CTL_ALLMULTI;
-               if (ifp->if_flags & IFF_PROMISC)
-                       rxmode |= MOS_CTL_RX_PROMISC;
-       } else {
-               /* now program new ones */
-               ec->ec_flags &= ~ETHER_F_ALLMULTI;
-
-               ETHER_FIRST_MULTI(step, ec, enm);
-               while (enm != NULL) {
-                       if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
-                           ETHER_ADDR_LEN)) {
-                               memset(hashtbl, 0, sizeof(hashtbl));
-                               goto allmulti;
-                       }
-                       h = ether_crc32_be(enm->enm_addrlo,
-                           ETHER_ADDR_LEN) >> 26;
-                       hashtbl[h / 8] |= 1 << (h % 8);
-
-                       ETHER_NEXT_MULTI(step, enm);
+               ETHER_UNLOCK(ec);
+               /* run promisc. mode */
+               rxmode |= MOS_CTL_ALLMULTI; /* ??? */
+               rxmode |= MOS_CTL_RX_PROMISC;
+               goto update;
+       }
+       ec->ec_flags &= ~ETHER_F_ALLMULTI;
+       ETHER_FIRST_MULTI(step, ec, enm);
+       while (enm != NULL) {
+               if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
+                       ec->ec_flags |= ETHER_F_ALLMULTI;
+                       ETHER_UNLOCK(ec);
+                       memset(mchash, 0, sizeof(mchash)); /* correct ??? */
+                       /* accept all mulicast frame */
+                       rxmode |= MOS_CTL_ALLMULTI;
+                       goto update;
                }
+               h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
+               /* 3(31:29) and 3(28:26) sampling to have uint8_t[8] */
+               mchash[h >> 29] |= 1 << ((h >> 26) % 8);
+               ETHER_NEXT_MULTI(step, enm);
        }
        ETHER_UNLOCK(ec);
-
+       /* MOS receive filter is always on */
+ update:
        /* 
         * The datasheet claims broadcast frames were always accepted
         * regardless of filter settings. But the hardware seems to
         * filter broadcast frames, so pass them explicitly.
         */
-       h = ether_crc32_be(etherbroadcastaddr, ETHER_ADDR_LEN) >> 26;
-       hashtbl[h / 8] |= 1 << (h % 8);
-
-       mos_write_mcast(un, hashtbl);
+       mchash[7] |= 0x80;
+       mos_write_mcast(un, mchash);
        mos_reg_write_1(un, MOS_CTL, rxmode);
 }
 
@@ -745,7 +744,7 @@
        mos_reg_write_1(un, MOS_IPG1, ipgs[1]);
 
        /* Program promiscuous mode and multicast filters. */
-       mos_setiff_locked(un);
+       mos_rcvfilt_locked(un);
 
        /* Enable receiver and transmitter, bridge controls speed/duplex mode */
        rxmode = mos_reg_read_1(un, MOS_CTL);
@@ -781,7 +780,7 @@
        switch (cmd) {
        case SIOCADDMULTI:
        case SIOCDELMULTI:
-               mos_setiff_locked(un);
+               mos_rcvfilt_locked(un);
                break;
        default:
                break;



Home | Main Index | Thread Index | Old Index