On Tuesday 28 July 2009 19:36:18 Brad wrote:
> Please test the following diff to rewrite the promisc mode / multicast
> handling code for the sparc hme(4) driver and is based off of the MI
> hme(4) driver.
I'm still looking for someone to test this..
>
> Index: hme.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/sparc/dev/hme.c,v
> retrieving revision 1.61
> diff -u -p -r1.61 hme.c
> --- hme.c 16 Jul 2009 07:18:47 -0000 1.61
> +++ hme.c 17 Jul 2009 21:58:10 -0000
> @@ -126,7 +126,7 @@ int hme_mii_read(struct device *, int, i
> void hme_mii_write(struct device *, int, int, int);
> void hme_mii_statchg(struct device *);
>
> -void hme_mcreset(struct hme_softc *);
> +void hme_iff(struct hme_softc *);
>
> struct cfattach hme_ca = {
> sizeof (struct hme_softc), hmematch, hmeattach
> @@ -445,7 +445,7 @@ hmeioctl(ifp, cmd, data)
>
> if (error == ENETRESET) {
> if (ifp->if_flags & IFF_RUNNING)
> - hme_mcreset(sc);
> + hme_iff(sc);
> error = 0;
> }
>
> @@ -575,7 +575,7 @@ hmeinit(sc)
> printf("%s: setting rxreg->cfg failed.\n", sc->sc_dev.dv_xname);
>
> cr->rx_cfg = 0;
> - hme_mcreset(sc);
> + hme_iff(sc);
> DELAY(10);
>
> cr->tx_cfg |= CR_TXCFG_DGIVEUP;
> @@ -959,89 +959,52 @@ hme_read(sc, idx, len, flags)
> ether_input_mbuf(ifp, m);
> }
>
> -/*
> - * Program the multicast receive filter.
> - */
> void
> -hme_mcreset(sc)
> +hme_iff(sc)
> struct hme_softc *sc;
> {
> struct arpcom *ac = &sc->sc_arpcom;
> struct ifnet *ifp = &sc->sc_arpcom.ac_if;
> struct hme_cr *cr = sc->sc_cr;
> - u_int32_t crc;
> - u_int16_t hash[4];
> - u_int8_t octet;
> - int i, j;
> struct ether_multi *enm;
> struct ether_multistep step;
> + u_int32_t rxfg, crc;
> + u_int32_t hash[4];
>
> - if (ifp->if_flags & IFF_PROMISC) {
> - cr->rx_cfg |= CR_RXCFG_PMISC;
> - return;
> - }
> - else
> - cr->rx_cfg &= ~CR_RXCFG_PMISC;
> + rxcfg = cr->rx_cfg;
> + rxcfg &= ~(CR_RXCFG_HENABLE | CR_RXCFG_PMISC);
> + if->if_flags &= ~IFF_ALLMULTI;
> + /* Clear hash table */
> + hash[0] = hash[1] = hash[2] = hash[3] = 0;
>
> - if (ifp->if_flags & IFF_ALLMULTI) {
> - cr->htable3 = 0xffff;
> - cr->htable2 = 0xffff;
> - cr->htable1 = 0xffff;
> - cr->htable0 = 0xffff;
> - cr->rx_cfg |= CR_RXCFG_HENABLE;
> - return;
> - }
> -
> - hash[3] = hash[2] = hash[1] = hash[0] = 0;
> -
> - ETHER_FIRST_MULTI(step, ac, enm);
> - while (enm != NULL) {
> - if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
> - /*
> - * 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.)
> - */
> - cr->htable3 = 0xffff;
> - cr->htable2 = 0xffff;
> - cr->htable1 = 0xffff;
> - cr->htable0 = 0xffff;
> - cr->rx_cfg |= CR_RXCFG_HENABLE;
> - ifp->if_flags |= IFF_ALLMULTI;
> - return;
> - }
> -
> - crc = 0xffffffff;
> + if (ifp->if_flags & IFF_PROMISC) {
> + ifp->if_flags |= IFF_ALLMULTI;
> + rxcfg |= CR_RXCFG_PMISC;
> + } else if (ac->ac_multirangecnt > 0) {
> + ifp->if_flags |= IFF_ALLMULTI;
> + rxcfg |= CR_RXFG_HENABLE;
> + hash[0] = hash[1] = hash[2] = hash[3] = 0xffff;
> + } else {
> + rxcfg |= CR_RXFG_HENABLE;
> +
> + ETHER_FIRST_MULTI(step, ac, enm);
> + while (enm != NULL) {
> + crc = ether_crc32_le(enm->enm_addrlo,
> + ETHER_ADDR_LEN) >> 26;
>
> - for (i = 0; i < ETHER_ADDR_LEN; i++) {
> - octet = enm->enm_addrlo[i];
> + /* Set the corresponding bit in the filter. */
> + hash[crc >> 4] |= 1 << (crc & 0xf);
>
> - for (j = 0; j < 8; j++) {
> - if ((crc & 1) ^ (octet & 1)) {
> - crc >>= 1;
> - crc ^= ETHER_CRC_POLY_LE;
> - }
> - else
> - crc >>= 1;
> - octet >>= 1;
> - }
> + ETHER_NEXT_MULTI(step, enm);
> }
> -
> - crc >>=26;
> - hash[crc >> 4] |= 1 << (crc & 0xf);
> - ETHER_NEXT_MULTI(step, enm);
> }
> - cr->htable3 = hash[3];
> - cr->htable2 = hash[2];
> - cr->htable1 = hash[1];
> +
> + /* Now load the hash table into the chip */
> cr->htable0 = hash[0];
> - cr->rx_cfg |= CR_RXCFG_HENABLE;
> - ifp->if_flags &= ~IFF_ALLMULTI;
> + cr->htable1 = hash[1];
> + cr->htable2 = hash[2];
> + cr->htable3 = hash[3];
> + cr->rx_cfg = rxcfg;
> }
>
> /*
--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.