NetBSD Problem Report #23893
Received: (qmail 12974 invoked by uid 605); 26 Dec 2003 18:06:32 -0000
Message-Id: <20031226180630.2CBA111158@narn.netbsd.org>
Date: Fri, 26 Dec 2003 18:06:30 +0000 (UTC)
From: kiyohara@kk.iij4u.or.jp
Sender: gnats-bugs-owner@NetBSD.org
Reply-To: kiyohara@kk.iij4u.or.jp
To: gnats-bugs@gnats.NetBSD.org
Subject: Correspond promisc & multicast
X-Send-Pr-Version: www-1.0
>Number: 23893
>Category: port-powerpc
>Synopsis: Correspond promisc & multicast
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: port-powerpc-maintainer
>State: closed
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Fri Dec 26 18:07:01 +0000 2003
>Closed-Date: Sat Dec 27 00:56:01 +0000 2003
>Last-Modified: Sat Dec 27 00:56:01 +0000 2003
>Originator: KIYOHARA Takashi
>Release: 1.6ZG
>Organization:
>Environment:
NetBSD evbppc.fool 1.6ZG NetBSD 1.6ZG (OPENBLOCKS266) #0: Sun Dec 21 12:58:20 JST 2003 lance@highpriestess.fool:/sys/arch/evbppc/compile/OPENBLOCKS266 evbppc
>Description:
Don't work promisc & multicast on ibm4xx emac. Correspond promisc & multicast mode. ibm4xx bridgeing OK.
>How-To-Repeat:
>Fix:
Index: arch/powerpc/ibm4xx/dev/if_emac.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/ibm4xx/dev/if_emac.c,v
retrieving revision 1.17
diff -c -r1.17 if_emac.c
*** arch/powerpc/ibm4xx/dev/if_emac.c 2003/10/27 03:58:17 1.17
--- arch/powerpc/ibm4xx/dev/if_emac.c 2003/12/19 17:39:44
***************
*** 242,247 ****
--- 242,250 ----
#define EMAC_READ(sc, reg) \
bus_space_read_stream_4((sc)->sc_st, (sc)->sc_sh, (reg))
+ #define EMAC_SET_FILTER(aht, category) \
+ (aht)[3 - ((category) >> 4)] |= 1 << ((category) & 0xf);
+
static int emac_match(struct device *, struct cfdata *, void *);
static void emac_attach(struct device *, struct device *, void *);
***************
*** 255,260 ****
--- 258,264 ----
static void emac_start(struct ifnet *);
static void emac_stop(struct ifnet *, int);
static void emac_watchdog(struct ifnet *);
+ static int emac_set_filter(struct emac_softc *);
static int emac_wol_intr(void *);
static int emac_serr_intr(void *);
***************
*** 794,799 ****
--- 798,804 ----
* dealt with here!
*/
EMAC_WRITE(sc, EMAC_RMR, RMR_IAE | RMR_RRP | RMR_SP |
+ (ifp->if_flags & IFF_PROMISC ? RMR_PME : 0) |
(ifp->if_flags & IFF_BROADCAST ? RMR_BAE : 0));
/*
***************
*** 1010,1020 ****
* Multicast list has changed; set the hardware filter
* accordingly.
*/
! #if 0
! error = emac_set_filter(sc); /* XXX not done yet */
! #else
! error = emac_init(ifp);
! #endif
}
break;
}
--- 1015,1021 ----
* Multicast list has changed; set the hardware filter
* accordingly.
*/
! error = emac_set_filter(sc);
}
break;
}
***************
*** 1044,1049 ****
--- 1045,1107 ----
/* set the MAL config register */
mtdcr(DCR_MAL0_CFG, MAL0_CFG_PLBB | MAL0_CFG_OPBBL | MAL0_CFG_LEA |
MAL0_CFG_SD | MAL0_CFG_PLBLT);
+ }
+
+ static int
+ emac_set_filter(struct emac_softc *sc)
+ {
+ struct ether_multistep step;
+ struct ether_multi *enm;
+ struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+ u_int32_t rmr, crc, gaht[4] = {0, 0, 0, 0};
+ int category, cnt = 0;
+
+ rmr = EMAC_READ(sc, EMAC_RMR);
+ rmr &= ~(RMR_PMME | RMR_MAE);
+ ifp->if_flags &= ~IFF_ALLMULTI;
+
+ ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm);
+ while (enm != NULL) {
+ if (memcmp(enm->enm_addrlo,
+ enm->enm_addrhi, ETHER_ADDR_LEN) != 0) {
+ /*
+ * We must listen to a range of multicast addresses.
+ * For now, just accept all multicasts, rather than
+ * trying to set only those filter bits needed to match
+ * the range. (At this time, the only use of address
+ * ranges is for IP multicast routing, for which the
+ * range is big enough to require all bits set.)
+ */
+ gaht[0] = gaht[1] = gaht[2] = gaht[3] = 0xffff;
+ break;
+ }
+
+ crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN);
+
+ /* Just want the 6 most significant bits. */
+ category = crc >> 26;
+ EMAC_SET_FILTER(gaht, category);
+
+ ETHER_NEXT_MULTI(step, enm);
+ cnt ++;
+ }
+
+ if ((gaht[0] & gaht[1] & gaht[2] & gaht[3]) == 0xffff) {
+ /* all category is true */
+ ifp->if_flags |= IFF_ALLMULTI;
+ rmr |= RMR_PMME;
+ } else if (cnt != 0) {
+ /* some category is true */
+ EMAC_WRITE(sc, EMAC_GAHT1, gaht[0]);
+ EMAC_WRITE(sc, EMAC_GAHT2, gaht[1]);
+ EMAC_WRITE(sc, EMAC_GAHT3, gaht[2]);
+ EMAC_WRITE(sc, EMAC_GAHT4, gaht[3]);
+
+ rmr |= RMR_MAE;
+ }
+ EMAC_WRITE(sc, EMAC_RMR, rmr);
+
+ return (0);
}
/*
>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed
State-Changed-By: wiz
State-Changed-When: Sat Dec 27 00:55:52 UTC 2003
State-Changed-Why:
Duplicate of 23892.
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.