Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-1-6]: src/sys/dev/ic Pull up revision 1.67 (requested by taca in ...
details: https://anonhg.NetBSD.org/src/rev/b5b32a80468e
branches: netbsd-1-6
changeset: 529752:b5b32a80468e
user: he <he%NetBSD.org@localhost>
date: Thu Dec 12 21:34:39 2002 +0000
description:
Pull up revision 1.67 (requested by taca in ticket #992):
Fix multicast handling on 3C905B or later card;
o Handle IFF_ALLMULTI case correctly. This is necessary
to mrouted working.
o Clear unnecessary multicast hash bit. Otherwise,
unnecessary multicast packet is received.
diffstat:
sys/dev/ic/elinkxl.c | 62 +++++++++++++++++++++++++++++++++------------------
1 files changed, 40 insertions(+), 22 deletions(-)
diffs (93 lines):
diff -r 884f8217c197 -r b5b32a80468e sys/dev/ic/elinkxl.c
--- a/sys/dev/ic/elinkxl.c Thu Dec 12 21:33:59 2002 +0000
+++ b/sys/dev/ic/elinkxl.c Thu Dec 12 21:34:39 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: elinkxl.c,v 1.63 2002/05/12 15:48:38 wiz Exp $ */
+/* $NetBSD: elinkxl.c,v 1.63.4.1 2002/12/12 21:34:39 he Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: elinkxl.c,v 1.63 2002/05/12 15:48:38 wiz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: elinkxl.c,v 1.63.4.1 2002/12/12 21:34:39 he Exp $");
#include "bpfilter.h"
#include "rnd.h"
@@ -711,7 +711,9 @@
return (error);
}
-#define ex_mchash(addr) (ether_crc32_be((addr), ETHER_ADDR_LEN) & 0xff)
+#define MCHASHSIZE 256
+#define ex_mchash(addr) (ether_crc32_be((addr), ETHER_ADDR_LEN) & \
+ (MCHASHSIZE - 1))
/*
* Set multicast receive filter. Also take care of promiscuous mode
@@ -728,28 +730,44 @@
int i;
u_int16_t mask = FIL_INDIVIDUAL | FIL_BRDCST;
- if (ifp->if_flags & IFF_PROMISC)
+ if (ifp->if_flags & IFF_PROMISC) {
mask |= FIL_PROMISC;
+ goto allmulti;
+ }
- if (!(ifp->if_flags & IFF_MULTICAST))
- goto out;
+ ETHER_FIRST_MULTI(estep, ec, enm);
+ if (enm == NULL)
+ goto nomulti;
+
+ if ((sc->ex_conf & EX_CONF_90XB) == 0)
+ /* No multicast hash filtering. */
+ goto allmulti;
+
+ for (i = 0; i < MCHASHSIZE; i++)
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh,
+ ELINK_COMMAND, ELINK_CLEARHASHFILBIT | i);
- if (!(sc->ex_conf & EX_CONF_90XB) || ifp->if_flags & IFF_ALLMULTI) {
- mask |= (ifp->if_flags & IFF_MULTICAST) ? FIL_MULTICAST : 0;
- } else {
- ETHER_FIRST_MULTI(estep, ec, enm);
- while (enm != NULL) {
- if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
- ETHER_ADDR_LEN) != 0)
- goto out;
- i = ex_mchash(enm->enm_addrlo);
- bus_space_write_2(sc->sc_iot, sc->sc_ioh,
- ELINK_COMMAND, ELINK_SETHASHFILBIT | i);
- ETHER_NEXT_MULTI(estep, enm);
- }
- mask |= FIL_MULTIHASH;
- }
- out:
+ do {
+ if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
+ ETHER_ADDR_LEN) != 0)
+ goto allmulti;
+
+ i = ex_mchash(enm->enm_addrlo);
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh,
+ ELINK_COMMAND, ELINK_SETHASHFILBIT | i);
+ ETHER_NEXT_MULTI(estep, enm);
+ } while (enm != NULL);
+ mask |= FIL_MULTIHASH;
+
+nomulti:
+ ifp->if_flags &= ~IFF_ALLMULTI;
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh, ELINK_COMMAND,
+ SET_RX_FILTER | mask);
+ return;
+
+allmulti:
+ ifp->if_flags |= IFF_ALLMULTI;
+ mask |= FIL_MULTICAST;
bus_space_write_2(sc->sc_iot, sc->sc_ioh, ELINK_COMMAND,
SET_RX_FILTER | mask);
}
Home |
Main Index |
Thread Index |
Old Index