From mboxrd@z Thu Jan 1 00:00:00 1970 From: Lucio De Re To: 9fans mailing list <9fans@cse.psu.edu> Message-ID: <20020430090223.V13019@cackle.proxima.alt.za> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Subject: [9fans] A snippet from a NetBSD mailing list Date: Tue, 30 Apr 2002 09:02:24 +0200 Topicbox-Message-UUID: 8124cc60-eaca-11e9-9e20-41e7f4b1d025 I think congratulations and heartfelt thanks are in order for the Plan 9 team. I haven't yet tried to install 4ed, but from all reports, it seems formidable. To return to the subject of my mail, I wonder if the message below is pertinent. I know I have a 3Com 3C905CX-TXM that neither NetBSD nor Plan 9 (3ed) knew how to handle. I know the patch isn't useful outside of NetBSD, but perhaps the pertinent details can be extracted from it. Of course, I don't know that this hasn't been fixed in 4ed :-( ++L ----- Forwarded message from enami tsugutomo ----- From: enami tsugutomo To: tech-net@netbsd.org Subject: changes to elinkxl.c:ex_set_mc() Sender: tech-net-owner@netbsd.org Precedence: list Hi, all. In the function ex_set_mc() defined in elinkxl.c, there is two possible bugs. One is that it assumes someone set IFF_ALLMULTI for us, but actually it's not true. We need to set by our self. Other is that for newer cards which supports multicast hash filtering, we need to clear hash bit before programming them. Appened diff is created by me and Frank. But since I have only pre-905B card, I can't test the latter. So, I beg someone to test or at least review this. enami. Index: elinkxl.c =================================================================== RCS file: /cvsroot/syssrc/sys/dev/ic/elinkxl.c,v retrieving revision 1.62 diff -u -r1.62 elinkxl.c --- elinkxl.c 2002/04/06 19:28:01 1.62 +++ elinkxl.c 2002/04/30 06:28:17 @@ -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) || 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: + 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); + + 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); } Index: elinkxlreg.h =================================================================== RCS file: /cvsroot/syssrc/sys/dev/ic/elinkxlreg.h,v retrieving revision 1.10 diff -u -r1.10 elinkxlreg.h --- elinkxlreg.h 2001/12/28 20:35:47 1.10 +++ elinkxlreg.h 2002/04/30 06:28:17 @@ -164,6 +164,7 @@ #define ELINK_DNUNSTALL 0x3003 #define ELINK_TXRECLTHRESH 0xc000 #define ELINK_TXSTARTTHRESH 0x9800 +#define ELINK_CLEARHASHFILBIT 0xc800 #define ELINK_SETHASHFILBIT 0xcc00 /* ----- End forwarded message -----