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