On Tuesday 02 June 2009 20:44:25 Brad wrote:
> Please test the following diff with any rl(4) adapters using
> any apps making use of multicast (IPv6, OSPF, CARP, etc.) and/or
> promiscuous mode of operation.
>
> Please provide a dmesg.
Still looking for feedback.
> Index: rtl81x9.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/ic/rtl81x9.c,v
> retrieving revision 1.63
> diff -u -p -r1.63 rtl81x9.c
> --- rtl81x9.c 4 Feb 2009 19:54:44 -0000 1.63
> +++ rtl81x9.c 4 May 2009 06:07:47 -0000
> @@ -158,7 +158,7 @@ int rl_miibus_readreg(struct device *, i
> void rl_miibus_writereg(struct device *, int, int, int);
> void rl_miibus_statchg(struct device *);
>
> -void rl_setmulti(struct rl_softc *);
> +void rl_iff(struct rl_softc *);
> void rl_reset(struct rl_softc *);
> int rl_list_tx_init(struct rl_softc *);
>
> @@ -457,63 +457,56 @@ int rl_mii_writereg(sc, frame)
> return(0);
> }
>
> -/*
> - * Program the 64-bit multicast hash filter.
> - */
> -void rl_setmulti(sc)
> +void rl_iff(sc)
> struct rl_softc *sc;
> {
> - struct ifnet *ifp;
> + struct ifnet *ifp = &sc->sc_arpcom.ac_if;
> int h = 0;
> - u_int32_t hashes[2] = { 0, 0 };
> + u_int32_t hashes[2];
> struct arpcom *ac = &sc->sc_arpcom;
> struct ether_multi *enm;
> struct ether_multistep step;
> u_int32_t rxfilt;
> - int mcnt = 0;
> -
> - ifp = &sc->sc_arpcom.ac_if;
>
> rxfilt = CSR_READ_4(sc, RL_RXCFG);
> + rxfilt &= ~(RL_RXCFG_RX_ALLPHYS | RL_RXCFG_RX_BROAD |
> + RL_RXCFG_RX_INDIV | RL_RXCFG_RX_MULTI);
> + ifp->if_flags &= ~IFF_ALLMULTI;
>
> -allmulti:
> - if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
> + /*
> + * Always accept frames destined to our station address.
> + * Always accept broadcast frames.
> + */
> + rxfilt |= RL_RXCFG_RX_INDIV | RL_RXCFG_RX_BROAD;
> +
> + if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
> + ifp ->if_flags |= IFF_ALLMULTI;
> rxfilt |= RL_RXCFG_RX_MULTI;
> - CSR_WRITE_4(sc, RL_RXCFG, rxfilt);
> - CSR_WRITE_4(sc, RL_MAR0, 0xFFFFFFFF);
> - CSR_WRITE_4(sc, RL_MAR4, 0xFFFFFFFF);
> - return;
> - }
> + if (ifp->if_flags & IFF_PROMISC)
> + rxfilt |= RL_RXCFG_RX_ALLPHYS;
> + hashes[0] = hashes[1] = 0xFFFFFFFF;
> + } else {
> + rxfilt |= RL_RXCFG_RX_MULTI;
> + /* Program new filter. */
> + bzero(hashes, sizeof(hashes));
>
> - /* first, zot all the existing hash bits */
> - CSR_WRITE_4(sc, RL_MAR0, 0);
> - CSR_WRITE_4(sc, RL_MAR4, 0);
> -
> - /* now program new ones */
> - ETHER_FIRST_MULTI(step, ac, enm);
> - while (enm != NULL) {
> - if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
> - ifp->if_flags |= IFF_ALLMULTI;
> - goto allmulti;
> - }
> - mcnt++;
> - h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) >> 26;
> - if (h < 32)
> - hashes[0] |= (1 << h);
> - else
> - hashes[1] |= (1 << (h - 32));
> - mcnt++;
> - ETHER_NEXT_MULTI(step, enm);
> - }
> + ETHER_FIRST_MULTI(step, ac, enm);
> + while (enm != NULL) {
> + h = ether_crc32_be(enm->enm_addrlo,
> + ETHER_ADDR_LEN) >> 26;
> +
> + if (h < 32)
> + hashes[0] |= (1 << h);
> + else
> + hashes[1] |= (1 << (h - 32));
>
> - if (mcnt)
> - rxfilt |= RL_RXCFG_RX_MULTI;
> - else
> - rxfilt &= ~RL_RXCFG_RX_MULTI;
> + ETHER_NEXT_MULTI(step, enm);
> + }
> + }
>
> - CSR_WRITE_4(sc, RL_RXCFG, rxfilt);
> CSR_WRITE_4(sc, RL_MAR0, hashes[0]);
> CSR_WRITE_4(sc, RL_MAR4, hashes[1]);
> + CSR_WRITE_4(sc, RL_RXCFG, rxfilt);
> }
>
> void
> @@ -958,7 +951,6 @@ void rl_init(xsc)
> struct rl_softc *sc = xsc;
> struct ifnet *ifp = &sc->sc_arpcom.ac_if;
> int s;
> - u_int32_t rxcfg = 0;
>
> s = splnet();
>
> @@ -996,30 +988,10 @@ void rl_init(xsc)
> CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG);
> CSR_WRITE_4(sc, RL_RXCFG, RL_RXCFG_CONFIG);
>
> - /* Set the individual bit to receive frames for this host only. */
> - rxcfg = CSR_READ_4(sc, RL_RXCFG);
> - rxcfg |= RL_RXCFG_RX_INDIV;
> -
> - /* If we want promiscuous mode, set the allframes bit. */
> - if (ifp->if_flags & IFF_PROMISC)
> - rxcfg |= RL_RXCFG_RX_ALLPHYS;
> - else
> - rxcfg &= ~RL_RXCFG_RX_ALLPHYS;
> - CSR_WRITE_4(sc, RL_RXCFG, rxcfg);
> -
> /*
> - * Set capture broadcast bit to capture broadcast frames.
> + * Program promiscuous mode and multicast filters.
> */
> - if (ifp->if_flags & IFF_BROADCAST)
> - rxcfg |= RL_RXCFG_RX_BROAD;
> - else
> - rxcfg &= ~RL_RXCFG_RX_BROAD;
> - CSR_WRITE_4(sc, RL_RXCFG, rxcfg);
> -
> - /*
> - * Program the multicast filter, if necessary.
> - */
> - rl_setmulti(sc);
> + rl_iff(sc);
>
> /*
> * Enable interrupts.
> @@ -1089,38 +1061,38 @@ int rl_ioctl(ifp, command, data)
> switch(command) {
> case SIOCSIFADDR:
> ifp->if_flags |= IFF_UP;
> - switch (ifa->ifa_addr->sa_family) {
> -#ifdef INET
> - case AF_INET:
> + if (!(ifp->if_flags & IFF_RUNNING))
> rl_init(sc);
> +#ifdef INET
> + if (ifa->ifa_addr->sa_family == AF_INET)
> arp_ifinit(&sc->sc_arpcom, ifa);
> - break;
> #endif /* INET */
> - default:
> - rl_init(sc);
> - break;
> - }
> break;
> +
> case SIOCSIFFLAGS:
> if (ifp->if_flags & IFF_UP) {
> - rl_init(sc);
> + if (ifp->if_flags & IFF_RUNNING)
> + error = ENETRESET;
> + else
> + rl_init(sc);
> } else {
> if (ifp->if_flags & IFF_RUNNING)
> rl_stop(sc);
> }
> - error = 0;
> break;
> +
> case SIOCGIFMEDIA:
> case SIOCSIFMEDIA:
> error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, command);
> break;
> +
> default:
> error = ether_ioctl(ifp, &sc->sc_arpcom, command, data);
> }
>
> if (error == ENETRESET) {
> if (ifp->if_flags & IFF_RUNNING)
> - rl_setmulti(sc);
> + rl_iff(sc);
> error = 0;
> }
--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.