Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/imx set the multicast filter properly.
details: https://anonhg.NetBSD.org/src/rev/0f27278d50c2
branches: trunk
changeset: 1005107:0f27278d50c2
user: ryo <ryo%NetBSD.org@localhost>
date: Fri Nov 29 17:20:30 2019 +0000
description:
set the multicast filter properly.
don't always IFF_ALLMULTI if multicast is configured.
fix the handling of GAUR and GALR.
diffstat:
sys/arch/arm/imx/if_enet.c | 52 ++++++++++++++++++++++++++++-----------------
1 files changed, 32 insertions(+), 20 deletions(-)
diffs (90 lines):
diff -r 22457fe3615d -r 0f27278d50c2 sys/arch/arm/imx/if_enet.c
--- a/sys/arch/arm/imx/if_enet.c Fri Nov 29 16:33:44 2019 +0000
+++ b/sys/arch/arm/imx/if_enet.c Fri Nov 29 17:20:30 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_enet.c,v 1.28 2019/11/12 05:09:29 hkenken Exp $ */
+/* $NetBSD: if_enet.c,v 1.29 2019/11/29 17:20:30 ryo Exp $ */
/*
* Copyright (c) 2014 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_enet.c,v 1.28 2019/11/12 05:09:29 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_enet.c,v 1.29 2019/11/29 17:20:30 ryo Exp $");
#include "vlan.h"
@@ -714,15 +714,14 @@
struct ifnet *ifp = &ec->ec_if;
struct ether_multi *enm;
struct ether_multistep step;
- int promisc;
- uint32_t crc;
+ uint32_t crc, hashidx;
uint32_t gaddr[2];
- promisc = 0;
- if ((ifp->if_flags & IFF_PROMISC) || ec->ec_multicnt > 0) {
- ifp->if_flags |= IFF_ALLMULTI;
- if (ifp->if_flags & IFF_PROMISC)
- promisc = 1;
+ if (ifp->if_flags & IFF_PROMISC) {
+ /* receive all unicast packet */
+ ENET_REG_WRITE(sc, ENET_IAUR, 0xffffffff);
+ ENET_REG_WRITE(sc, ENET_IALR, 0xffffffff);
+ /* receive all multicast packet */
gaddr[0] = gaddr[1] = 0xffffffff;
} else {
gaddr[0] = gaddr[1] = 0;
@@ -730,25 +729,38 @@
ETHER_LOCK(ec);
ETHER_FIRST_MULTI(step, ec, enm);
while (enm != NULL) {
+ if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
+ ETHER_ADDR_LEN)) {
+ /*
+ * if specified by range, give up setting hash,
+ * and fallback to allmulti.
+ */
+ gaddr[0] = gaddr[1] = 0xffffffff;
+ break;
+ }
+
crc = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN);
- gaddr[crc >> 31] |= 1 << ((crc >> 26) & 0x1f);
+ hashidx = __SHIFTOUT(crc, __BITS(30,26));
+ gaddr[__SHIFTOUT(crc, __BIT(31))] |= __BIT(hashidx);
+
ETHER_NEXT_MULTI(step, enm);
}
ETHER_UNLOCK(ec);
- }
- ENET_REG_WRITE(sc, ENET_GAUR, gaddr[0]);
- ENET_REG_WRITE(sc, ENET_GALR, gaddr[1]);
-
- if (promisc) {
- /* match all packet */
- ENET_REG_WRITE(sc, ENET_IAUR, 0xffffffff);
- ENET_REG_WRITE(sc, ENET_IALR, 0xffffffff);
- } else {
- /* don't match any packet */
+ /* dont't receive any unicast packet (except own address) */
ENET_REG_WRITE(sc, ENET_IAUR, 0);
ENET_REG_WRITE(sc, ENET_IALR, 0);
}
+
+ if (gaddr[0] == 0xffffffff && gaddr[1] == 0xffffffff)
+ ifp->if_flags |= IFF_ALLMULTI;
+ else
+ ifp->if_flags &= ~IFF_ALLMULTI;
+
+ /* receive multicast packets according to multicast filter */
+ ENET_REG_WRITE(sc, ENET_GAUR, gaddr[1]);
+ ENET_REG_WRITE(sc, ENET_GALR, gaddr[0]);
+
}
static void
Home |
Main Index |
Thread Index |
Old Index