Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/qbus Set up multicast (input) filter on qt (DELQA-Tu...
details: https://anonhg.NetBSD.org/src/rev/6ea33fcc5ed2
branches: trunk
changeset: 1029066:6ea33fcc5ed2
user: rhialto <rhialto%NetBSD.org@localhost>
date: Mon Dec 20 17:12:41 2021 +0000
description:
Set up multicast (input) filter on qt (DELQA-Turbo).
diffstat:
sys/dev/qbus/if_qt.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++--
sys/dev/qbus/if_qtreg.h | 26 ++++++++--------
2 files changed, 81 insertions(+), 16 deletions(-)
diffs (146 lines):
diff -r 0b2be7f95c45 -r 6ea33fcc5ed2 sys/dev/qbus/if_qt.c
--- a/sys/dev/qbus/if_qt.c Mon Dec 20 14:52:25 2021 +0000
+++ b/sys/dev/qbus/if_qt.c Mon Dec 20 17:12:41 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_qt.c,v 1.25 2020/01/29 05:57:21 thorpej Exp $ */
+/* $NetBSD: if_qt.c,v 1.26 2021/12/20 17:12:41 rhialto Exp $ */
/*
* Copyright (c) 1992 Steven M. Schultz
* All rights reserved.
@@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_qt.c,v 1.25 2020/01/29 05:57:21 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_qt.c,v 1.26 2021/12/20 17:12:41 rhialto Exp $");
#include "opt_inet.h"
@@ -162,6 +162,7 @@
static int qtmatch(device_t, cfdata_t, void *);
static void qtattach(device_t, device_t, void *);
+static void lance_setladrf(struct ethercom *ec, uint16_t *af);
static void qtintr(void *);
static int qtinit(struct ifnet *);
static int qtioctl(struct ifnet *, u_long, void *);
@@ -332,6 +333,67 @@
return(1);
}
+#define ETHER_CMP(a,b) memcmp((a), (b), 6)
+
+/*
+ * Set up the logical address filter.
+ */
+void
+lance_setladrf(struct ethercom *ec, uint16_t *af)
+{
+ struct ifnet *ifp = &ec->ec_if;
+ struct ether_multi *enm;
+ uint32_t crc;
+ struct ether_multistep step;
+
+ /*
+ * Set up multicast address filter by passing all multicast addresses
+ * through a crc generator, and then using the high order 6 bits as an
+ * index into the 64 bit logical address filter. The high order bit
+ * selects the word, while the rest of the bits select the bit within
+ * the word.
+ */
+
+ if (ifp->if_flags & IFF_PROMISC)
+ goto allmulti;
+
+ af[0] = af[1] = af[2] = af[3] = 0x0000;
+
+ ETHER_LOCK(ec);
+ ETHER_FIRST_MULTI(step, ec, enm);
+ while (enm != NULL) {
+ if (ETHER_CMP(enm->enm_addrlo, enm->enm_addrhi)) {
+ /*
+ * 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.)
+ */
+ ETHER_UNLOCK(ec);
+ goto allmulti;
+ }
+
+ crc = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN);
+
+ /* Just want the 6 most significant bits. */
+ crc >>= 26;
+
+ /* Set the corresponding bit in the filter. */
+ af[crc >> 4] |= 1 << (crc & 0xf);
+
+ ETHER_NEXT_MULTI(step, enm);
+ }
+ ETHER_UNLOCK(ec);
+ ifp->if_flags &= ~IFF_ALLMULTI;
+ return;
+
+allmulti:
+ ifp->if_flags |= IFF_ALLMULTI;
+ af[0] = af[1] = af[2] = af[3] = 0xffff;
+}
+
int
qtinit(struct ifnet *ifp)
{
@@ -388,7 +450,10 @@
}
iniblk = &sc->sc_ib->qc_init;
iniblk->mode = ifp->if_flags & IFF_PROMISC ? INIT_MODE_PRO : 0;
-
+/*
+ * The multicast filter works "like LANCE".
+ */
+ lance_setladrf(&sc->is_ec, iniblk->laddr);
/*
* Now initialize the receive ring descriptors. Because this routine can be
diff -r 0b2be7f95c45 -r 6ea33fcc5ed2 sys/dev/qbus/if_qtreg.h
--- a/sys/dev/qbus/if_qtreg.h Mon Dec 20 14:52:25 2021 +0000
+++ b/sys/dev/qbus/if_qtreg.h Mon Dec 20 17:12:41 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_qtreg.h,v 1.5 2005/12/11 12:23:29 christos Exp $ */
+/* $NetBSD: if_qtreg.h,v 1.6 2021/12/20 17:12:41 rhialto Exp $ */
/*
* Copyright (c) 1992 Steven M. Schultz
* All rights reserved.
@@ -207,18 +207,18 @@
struct qt_init
{
- short mode;
- u_char paddr[6]; /* 48 bit physical address */
- u_char laddr[8]; /* 64 bit logical address filter */
- u_short rx_lo; /* low 16 bits of receive ring addr */
- u_short rx_hi; /* high 6 bits of receive ring addr */
- u_short tx_lo; /* low 16 bits of transmit ring addr */
- u_short tx_hi; /* high 6 bits of transmit ring addr */
- u_short options;
- u_short vector;
- u_short hit;
- char passwd[6];
- char pad[4]; /* even on 40 byte for alignment */
+ int16_t mode;
+ u_char paddr[6]; /* 48 bit physical address */
+ uint16_t laddr[4]; /* 64 bit logical address filter */
+ uint16_t rx_lo; /* low 16 bits of receive ring addr */
+ uint16_t rx_hi; /* high 6 bits of receive ring addr */
+ uint16_t tx_lo; /* low 16 bits of transmit ring addr */
+ uint16_t tx_hi; /* high 6 bits of transmit ring addr */
+ uint16_t options;
+ uint16_t vector;
+ uint16_t hit;
+ char passwd[6];
+ char pad[4]; /* even on 40 byte for alignment */
};
#define INIT_MODE_PRO 0x8000 /* Promiscuous mode */
Home |
Main Index |
Thread Index |
Old Index