summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsg <jsg@openbsd.org>2009-02-25 13:10:38 +0000
committerjsg <jsg@openbsd.org>2009-02-25 13:10:38 +0000
commitd43e3cf7dc326cc70eb49b4e3b7924700e9112e0 (patch)
treebd7734e46bcd731021e0bceb5ea7ac5e85ab1c14
parentOn full mask revision 2 or later default to (diff)
downloadwireguard-openbsd-d43e3cf7dc326cc70eb49b4e3b7924700e9112e0.tar.xz
wireguard-openbsd-d43e3cf7dc326cc70eb49b4e3b7924700e9112e0.zip
Fix up multicast support, from brad.
ok deraadt@
-rw-r--r--sys/dev/pci/if_jme.c68
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]);