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