diff options
author | 2009-02-25 13:10:38 +0000 | |
---|---|---|
committer | 2009-02-25 13:10:38 +0000 | |
commit | d43e3cf7dc326cc70eb49b4e3b7924700e9112e0 (patch) | |
tree | bd7734e46bcd731021e0bceb5ea7ac5e85ab1c14 | |
parent | On full mask revision 2 or later default to (diff) | |
download | wireguard-openbsd-d43e3cf7dc326cc70eb49b4e3b7924700e9112e0.tar.xz wireguard-openbsd-d43e3cf7dc326cc70eb49b4e3b7924700e9112e0.zip |
Fix up multicast support, from brad.
ok deraadt@
-rw-r--r-- | sys/dev/pci/if_jme.c | 68 |
1 files changed, 27 insertions, 41 deletions
diff --git a/sys/dev/pci/if_jme.c b/sys/dev/pci/if_jme.c index cd06b251817..ec65cd86043 100644 --- a/sys/dev/pci/if_jme.c +++ b/sys/dev/pci/if_jme.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_jme.c,v 1.16 2009/02/25 11:41:58 jsg Exp $ */ +/* $OpenBSD: if_jme.c,v 1.17 2009/02/25 13:10:38 jsg Exp $ */ /*- * Copyright (c) 2008, Pyun YongHyeon <yongari@FreeBSD.org> * All rights reserved. @@ -1316,7 +1316,7 @@ jme_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { if (ifp->if_flags & IFF_RUNNING) - jme_set_filter(sc); + error = ENETRESET; else jme_init(ifp); } else { @@ -1325,19 +1325,6 @@ jme_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } break; - case SIOCADDMULTI: - case SIOCDELMULTI: - error = (cmd == SIOCADDMULTI) ? - ether_addmulti(ifr, &sc->sc_arpcom) : - ether_delmulti(ifr, &sc->sc_arpcom); - - if (error == ENETRESET) { - if (ifp->if_flags & IFF_RUNNING) - jme_set_filter(sc); - error = 0; - } - break; - case SIOCSIFMEDIA: case SIOCGIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd); @@ -2309,6 +2296,7 @@ jme_set_filter(struct jme_softc *sc) rxcfg = CSR_READ_4(sc, JME_RXMAC); rxcfg &= ~(RXMAC_BROADCAST | RXMAC_PROMISC | RXMAC_MULTICAST | RXMAC_ALLMULTI); + ifp->if_flags &= ~IFF_ALLMULTI; /* * Always accept frames destined to our station address. @@ -2316,39 +2304,37 @@ jme_set_filter(struct jme_softc *sc) */ rxcfg |= RXMAC_UNICAST | RXMAC_BROADCAST; - if (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) { + if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) { + ifp->if_flags |= IFF_ALLMULTI; if (ifp->if_flags & IFF_PROMISC) rxcfg |= RXMAC_PROMISC; - if (ifp->if_flags & IFF_ALLMULTI) + else rxcfg |= RXMAC_ALLMULTI; - CSR_WRITE_4(sc, JME_MAR0, 0xFFFFFFFF); - CSR_WRITE_4(sc, JME_MAR1, 0xFFFFFFFF); - CSR_WRITE_4(sc, JME_RXMAC, rxcfg); - return; - } - - /* - * Set up the multicast address filter by passing all multicast - * addresses through a CRC generator, and then using the low-order - * 6 bits as an index into the 64 bit multicast hash table. The - * high order bits select the register, while the rest of the bits - * select the bit within the register. - */ - rxcfg |= RXMAC_MULTICAST; - bzero(mchash, sizeof(mchash)); + mchash[0] = mchash[1] = 0xFFFFFFFF; + } else { + /* + * Set up the multicast address filter by passing all + * multicast addresses through a CRC generator, and then + * using the low-order 6 bits as an index into the 64 bit + * multicast hash table. The high order bits select the + * register, while the rest of the bits select the bit + * within the register. + */ + rxcfg |= RXMAC_MULTICAST; + bzero(mchash, sizeof(mchash)); - ETHER_FIRST_MULTI(step, ac, enm); - while (enm != NULL) { - crc = ether_crc32_be(LLADDR((struct sockaddr_dl *) - enm->enm_addrlo), ETHER_ADDR_LEN); + ETHER_FIRST_MULTI(step, ac, enm); + while (enm != NULL) { + crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN); - /* Just want the 6 least significant bits. */ - crc &= 0x3f; + /* Just want the 6 least significant bits. */ + crc &= 0x3f; - /* Set the corresponding bit in the hash table. */ - mchash[crc >> 5] |= 1 << (crc & 0x1f); + /* Set the corresponding bit in the hash table. */ + mchash[crc >> 5] |= 1 << (crc & 0x1f); - ETHER_NEXT_MULTI(step, enm); + ETHER_NEXT_MULTI(step, enm); + } } CSR_WRITE_4(sc, JME_MAR0, mchash[0]); |