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