summaryrefslogtreecommitdiff
path: root/sys/arch/sparc
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>1998-10-02 17:42:25 +0000
committerJason Wright <jason@cvs.openbsd.org>1998-10-02 17:42:25 +0000
commit96ff0b3c34152b88160fb47d04d882bf4282d0ab (patch)
treea089fba59380ce4d4527b299199c6792e53c5519 /sys/arch/sparc
parent88ee0c04de3cd60e2f2fe2f908688fa10c279247 (diff)
Fixed multicast filter setup.
Diffstat (limited to 'sys/arch/sparc')
-rw-r--r--sys/arch/sparc/dev/be.c76
-rw-r--r--sys/arch/sparc/dev/hme.c78
2 files changed, 101 insertions, 53 deletions
diff --git a/sys/arch/sparc/dev/be.c b/sys/arch/sparc/dev/be.c
index 0dfcdd30e2a..5f491b2cc94 100644
--- a/sys/arch/sparc/dev/be.c
+++ b/sys/arch/sparc/dev/be.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: be.c,v 1.13 1998/09/28 05:12:22 jason Exp $ */
+/* $OpenBSD: be.c,v 1.14 1998/10/02 17:42:23 jason Exp $ */
/*
* Copyright (c) 1998 Theo de Raadt and Jason L. Wright.
@@ -1298,49 +1298,73 @@ be_mcreset(sc)
struct arpcom *ac = &sc->sc_arpcom;
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
struct be_bregs *br = sc->sc_br;
+ u_int32_t crc;
+ u_int16_t hash[4];
+ u_int8_t octet;
+ int i, j;
+ struct ether_multi *enm;
+ struct ether_multistep step;
if (ifp->if_flags & IFF_ALLMULTI) {
br->htable3 = 0xffff;
br->htable2 = 0xffff;
br->htable1 = 0xffff;
br->htable0 = 0xffff;
+ return;
}
- else if (ifp->if_flags & IFF_PROMISC) {
+
+ if (ifp->if_flags & IFF_PROMISC) {
br->rx_cfg |= BE_BR_RXCFG_PMISC;
+ return;
}
- else {
- struct ether_multi *enm;
- struct ether_multistep step;
- u_int16_t hash[4];
- u_int32_t crc = 0xffffffffU;
- br->htable3 = br->htable2 = br->htable1 = br->htable0 = 0;
- hash[3] = hash[2] = hash[1] = hash[0] = 0;
+ hash[3] = hash[2] = hash[1] = hash[0] = 0;
- ETHER_FIRST_MULTI(step, ac, enm);
- while (enm != NULL) {
- int i, j;
+ 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.)
+ */
+ br->htable3 = 0xffff;
+ br->htable2 = 0xffff;
+ br->htable1 = 0xffff;
+ br->htable0 = 0xffff;
+ ifp->if_flags |= IFF_ALLMULTI;
+ return;
+ }
- for (i = 0; i < ETHER_ADDR_LEN; i++) {
- u_int8_t octet = enm->enm_addrlo[i];
+ crc = 0xffffffff;
- for (j = 0; j < 8; j++) {
- u_int8_t bit;
+ for (i = 0; i < ETHER_ADDR_LEN; i++) {
+ octet = enm->enm_addrlo[i];
- bit = (octet << j) & 1;
+ for (j = 0; j < 8; j++) {
+ if ((crc & 1) ^ (octet & 1)) {
crc >>= 1;
- if ((bit ^ crc) & 1)
- crc = crc ^ MC_POLY_LE;
+ crc ^= MC_POLY_LE;
}
+ else
+ crc >>= 1;
+ octet >>= 1;
}
- crc >>= 26;
- hash[crc >> 4] |= 1 << (crc & 0x0f);
- ETHER_NEXT_MULTI(step, enm);
}
- br->htable0 = hash[0];
- br->htable1 = hash[1];
- br->htable2 = hash[2];
- br->htable3 = hash[3];
+ crc >>= 26;
+ hash[crc >> 4] |= 1 << (crc & 0xf);
+ ETHER_NEXT_MULTI(step, enm);
}
+
+ br->htable3 = hash[3];
+ br->htable2 = hash[2];
+ br->htable1 = hash[1];
+ br->htable0 = hash[0];
+ ifp->if_flags &= ~IFF_ALLMULTI;
}
diff --git a/sys/arch/sparc/dev/hme.c b/sys/arch/sparc/dev/hme.c
index 954edaa4401..59f93f793ae 100644
--- a/sys/arch/sparc/dev/hme.c
+++ b/sys/arch/sparc/dev/hme.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hme.c,v 1.11 1998/09/24 22:16:37 jason Exp $ */
+/* $OpenBSD: hme.c,v 1.12 1998/10/02 17:42:24 jason Exp $ */
/*
* Copyright (c) 1998 Jason L. Wright (jason@thought.net)
@@ -545,6 +545,7 @@ hmeinit(sc)
cr->jsize = HME_DEFAULT_JSIZE;
cr->ipkt_gap1 = HME_DEFAULT_IPKT_GAP1;
cr->ipkt_gap2 = HME_DEFAULT_IPKT_GAP2;
+
cr->htable3 = 0;
cr->htable2 = 0;
cr->htable1 = 0;
@@ -586,7 +587,7 @@ hmeinit(sc)
DELAY(20);
if (c != rxr->cfg) /* the receiver sometimes misses bits */
printf("%s: setting rxreg->cfg failed.\n", sc->sc_dev.dv_xname);
-
+
cr->rx_cfg = CR_RXCFG_HENABLE;
DELAY(10);
@@ -983,51 +984,74 @@ hme_mcreset(sc)
struct arpcom *ac = &sc->sc_arpcom;
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
struct hme_cr *cr = sc->sc_cr;
- struct ether_multi *enm;
- struct ether_multistep step;
- u_int16_t hash[4];
u_int32_t crc;
+ u_int16_t hash[4];
+ u_int8_t octet;
int i, j;
+ struct ether_multi *enm;
+ struct ether_multistep step;
if (ifp->if_flags & IFF_ALLMULTI) {
cr->htable3 = 0xffff;
cr->htable2 = 0xffff;
cr->htable1 = 0xffff;
cr->htable0 = 0xffff;
+ return;
}
- else if (ifp->if_flags & IFF_PROMISC) {
+
+ if (ifp->if_flags & IFF_PROMISC) {
cr->rx_cfg |= CR_RXCFG_PMISC;
+ return;
}
- else {
- cr->htable3 = cr->htable2 = cr->htable1 = cr->htable0 = 0;
- hash[3] = hash[2] = hash[1] = hash[0] = 0;
- crc = 0xffffffffU;
- ETHER_FIRST_MULTI(step, ac, enm);
- while (enm != NULL) {
+ hash[3] = hash[2] = hash[1] = hash[0] = 0;
- for (i = 0; i < ETHER_ADDR_LEN; i++) {
- u_int8_t octet = enm->enm_addrlo[i];
+ 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;
+ ifp->if_flags |= IFF_ALLMULTI;
+ return;
+ }
- for (j = 0; j < 8; j++) {
- u_int8_t bit;
+ crc = 0xffffffff;
- bit = (octet << j) & 1;
+ for (i = 0; i < ETHER_ADDR_LEN; i++) {
+ octet = enm->enm_addrlo[i];
+
+ for (j = 0; j < 8; j++) {
+ if ((crc & 1) ^ (octet & 1)) {
crc >>= 1;
- if ((bit ^ crc) & 1)
- crc = crc ^ MC_POLY_LE;
+ crc ^= MC_POLY_LE;
}
+ else
+ crc >>= 1;
+ octet >>= 1;
}
-
- crc >>=26;
- hash[crc >> 4] |= 1 << (crc & 0x0f);
- ETHER_NEXT_MULTI(step, enm);
}
- cr->htable3 = hash[3];
- cr->htable2 = hash[2];
- cr->htable1 = hash[1];
- cr->htable0 = hash[0];
+
+ 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];
+ cr->htable0 = hash[0];
+ ifp->if_flags &= ~IFF_ALLMULTI;
}
/*