Module Name: src Committed By: martin Date: Sun Dec 8 14:29:37 UTC 2019
Modified Files: src/sys/arch/arm/imx [netbsd-9]: if_enet.c Log Message: Pull up following revision(s) (requested by ryo in ticket #509): sys/arch/arm/imx/if_enet.c: revision 1.29 set the multicast filter properly. don't always IFF_ALLMULTI if multicast is configured. fix the handling of GAUR and GALR. To generate a diff of this commit: cvs rdiff -u -r1.25 -r1.25.2.1 src/sys/arch/arm/imx/if_enet.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/imx/if_enet.c diff -u src/sys/arch/arm/imx/if_enet.c:1.25 src/sys/arch/arm/imx/if_enet.c:1.25.2.1 --- src/sys/arch/arm/imx/if_enet.c:1.25 Tue Jul 30 06:26:31 2019 +++ src/sys/arch/arm/imx/if_enet.c Sun Dec 8 14:29:36 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_enet.c,v 1.25 2019/07/30 06:26:31 hkenken Exp $ */ +/* $NetBSD: if_enet.c,v 1.25.2.1 2019/12/08 14:29:36 martin Exp $ */ /* * Copyright (c) 2014 Ryo Shimizu <r...@nerv.org> @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_enet.c,v 1.25 2019/07/30 06:26:31 hkenken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_enet.c,v 1.25.2.1 2019/12/08 14:29:36 martin Exp $"); #include "vlan.h" @@ -714,15 +714,14 @@ enet_setmulti(struct enet_softc *sc) 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 @@ enet_setmulti(struct enet_softc *sc) 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