From 7a7588432a915a1ec7745a48a63adfede1b24548 Mon Sep 17 00:00:00 2001 From: dyoung Date: Thu, 15 Jul 2004 07:11:23 +0000 Subject: [PATCH] Simplify the Rx filter setup, following the AL981 code in tlp(4). --- sys/dev/ic/atw.c | 62 +++++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 38 deletions(-) diff --git a/sys/dev/ic/atw.c b/sys/dev/ic/atw.c index 02188171380d..8c988456163f 100644 --- a/sys/dev/ic/atw.c +++ b/sys/dev/ic/atw.c @@ -1,4 +1,4 @@ -/* $NetBSD: atw.c,v 1.56 2004/07/15 07:10:25 dyoung Exp $ */ +/* $NetBSD: atw.c,v 1.57 2004/07/15 07:11:23 dyoung Exp $ */ /*- * Copyright (c) 1998, 1999, 2000, 2002, 2003, 2004 The NetBSD Foundation, Inc. @@ -41,7 +41,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: atw.c,v 1.56 2004/07/15 07:10:25 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: atw.c,v 1.57 2004/07/15 07:11:23 dyoung Exp $"); #include "bpfilter.h" @@ -1815,38 +1815,36 @@ atw_filter_setup(struct atw_softc *sc) struct ethercom *ec = &ic->ic_ec; struct ifnet *ifp = &sc->sc_ic.ic_if; int hash; - u_int32_t hashes[2] = { 0, 0 }; + u_int32_t hashes[2]; struct ether_multi *enm; struct ether_multistep step; - DPRINTF(sc, ("%s: atw_filter_setup: sc_flags 0x%08x\n", - sc->sc_dev.dv_xname, sc->sc_flags)); - - /* - * If we're running, idle the receive engine. If we're NOT running, - * we're being called from atw_init(), and our writing ATW_NAR will - * start the transmit and receive processes in motion. + /* According to comments in tlp_al981_filter_setup + * (dev/ic/tulip.c) the ADMtek AL981 does not like for its + * multicast filter to be set while it is running. Hopefully + * the ADM8211 is not the same! */ - if (ifp->if_flags & IFF_RUNNING) + if ((ifp->if_flags & IFF_RUNNING) != 0) atw_idle(sc, ATW_NAR_SR); sc->sc_opmode &= ~(ATW_NAR_PR|ATW_NAR_MM); - ifp->if_flags &= ~IFF_ALLMULTI; - - if (ifp->if_flags & IFF_PROMISC) { + /* XXX in scan mode, do not filter packets. Maybe this is + * unnecessary. + */ + if (ic->ic_state == IEEE80211_S_SCAN || + (ifp->if_flags & IFF_PROMISC) != 0) { sc->sc_opmode |= ATW_NAR_PR; -allmulti: - ifp->if_flags |= IFF_ALLMULTI; - goto setit; + goto allmulti; } + hashes[0] = hashes[1] = 0x0; + /* * Program the 64-bit multicast hash filter. */ ETHER_FIRST_MULTI(step, ec, enm); while (enm != NULL) { - /* XXX */ if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN) != 0) goto allmulti; @@ -1855,33 +1853,21 @@ allmulti: hashes[hash >> 5] |= 1 << (hash & 0x1f); ETHER_NEXT_MULTI(step, enm); } + ifp->if_flags &= ~IFF_ALLMULTI; + goto setit; - if (ifp->if_flags & IFF_BROADCAST) { - hash = atw_calchash(etherbroadcastaddr); - hashes[hash >> 5] |= 1 << (hash & 0x1f); - } - - /* all bits set => hash is useless */ - if (~(hashes[0] & hashes[1]) == 0) - goto allmulti; - - setit: - if (ifp->if_flags & IFF_ALLMULTI) - sc->sc_opmode |= ATW_NAR_MM; - - /* XXX in scan mode, do not filter packets. maybe this is - * unnecessary. - */ - if (ic->ic_state == IEEE80211_S_SCAN) - sc->sc_opmode |= ATW_NAR_PR; +allmulti: + ifp->if_flags |= IFF_ALLMULTI; + hashes[0] = hashes[1] = 0xffffffff; +setit: ATW_WRITE(sc, ATW_MAR0, hashes[0]); ATW_WRITE(sc, ATW_MAR1, hashes[1]); ATW_WRITE(sc, ATW_NAR, sc->sc_opmode); + DELAY(20 * 1000); + DPRINTF(sc, ("%s: ATW_NAR %08x opmode %08x\n", sc->sc_dev.dv_xname, ATW_READ(sc, ATW_NAR), sc->sc_opmode)); - - DPRINTF(sc, ("%s: atw_filter_setup: returning\n", sc->sc_dev.dv_xname)); } /* Tell the ADM8211 our preferred BSSID. The ADM8211 must match