Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic Add support for hardware rx filters.
details: https://anonhg.NetBSD.org/src/rev/78b42f146d41
branches: trunk
changeset: 745072:78b42f146d41
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sat Feb 22 13:41:40 2020 +0000
description:
Add support for hardware rx filters.
diffstat:
sys/dev/ic/bcmgenet.c | 71 +++++++++++++++++++++++++++++++++++++++--------
sys/dev/ic/bcmgenetreg.h | 4 ++-
2 files changed, 62 insertions(+), 13 deletions(-)
diffs (131 lines):
diff -r 7bc2a8d9ed7b -r 78b42f146d41 sys/dev/ic/bcmgenet.c
--- a/sys/dev/ic/bcmgenet.c Sat Feb 22 13:20:21 2020 +0000
+++ b/sys/dev/ic/bcmgenet.c Sat Feb 22 13:41:40 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bcmgenet.c,v 1.1 2020/02/22 00:28:35 jmcneill Exp $ */
+/* $NetBSD: bcmgenet.c,v 1.2 2020/02/22 13:41:40 jmcneill Exp $ */
/*-
* Copyright (c) 2020 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -34,7 +34,7 @@
#include "opt_ddb.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bcmgenet.c,v 1.1 2020/02/22 00:28:35 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bcmgenet.c,v 1.2 2020/02/22 13:41:40 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -80,6 +80,7 @@
#define TX_DESC_COUNT GENET_DMA_DESC_COUNT
#define RX_DESC_COUNT GENET_DMA_DESC_COUNT
#define MII_BUSY_RETRY 1000
+#define GENET_MAX_MDF_FILTER 17
#define GENET_LOCK(sc) mutex_enter(&(sc)->sc_lock)
#define GENET_UNLOCK(sc) mutex_exit(&(sc)->sc_lock)
@@ -323,19 +324,65 @@
}
static void
+genet_setup_rxfilter_mdf(struct genet_softc *sc, u_int n, const uint8_t *ea)
+{
+ uint32_t addr0 = (ea[0] << 8) | ea[1];
+ uint32_t addr1 = (ea[2] << 24) | (ea[3] << 16) | (ea[4] << 8) | ea[5];
+
+ WR4(sc, GENET_UMAC_MDF_ADDR0(n), addr0);
+ WR4(sc, GENET_UMAC_MDF_ADDR1(n), addr1);
+}
+
+static void
genet_setup_rxfilter(struct genet_softc *sc)
{
- uint32_t val;
+ struct ethercom *ec = &sc->sc_ec;
+ struct ifnet *ifp = &ec->ec_if;
+ struct ether_multistep step;
+ struct ether_multi *enm;
+ uint32_t cmd, mdf_ctrl;
+ u_int n;
GENET_ASSERT_LOCKED(sc);
- /* Enable promiscuous mode */
- val = RD4(sc, GENET_UMAC_CMD);
- val |= GENET_UMAC_CMD_PROMISC;
- WR4(sc, GENET_UMAC_CMD, val);
+ ETHER_LOCK(ec);
+
+ cmd = RD4(sc, GENET_UMAC_CMD);
+
+ /*
+ * Count the required number of hardware filters. We need one
+ * for each multicast address, plus one for our own address and
+ * the broadcast address.
+ */
+ ETHER_FIRST_MULTI(step, ec, enm);
+ for (n = 2; enm != NULL; n++)
+ ETHER_NEXT_MULTI(step, enm);
+
+ if (n > GENET_MAX_MDF_FILTER)
+ ifp->if_flags |= IFF_ALLMULTI;
+ else
+ ifp->if_flags &= ~IFF_ALLMULTI;
- /* Disable filters */
- WR4(sc, GENET_UMAC_MDF_CTRL, 0);
+ if ((ifp->if_flags & (IFF_PROMISC|IFF_ALLMULTI)) != 0) {
+ cmd |= GENET_UMAC_CMD_PROMISC;
+ mdf_ctrl = 0;
+ } else {
+ cmd &= ~GENET_UMAC_CMD_PROMISC;
+ genet_setup_rxfilter_mdf(sc, 0, ifp->if_broadcastaddr);
+ genet_setup_rxfilter_mdf(sc, 1, CLLADDR(ifp->if_sadl));
+ ETHER_FIRST_MULTI(step, ec, enm);
+ for (n = 2; enm != NULL; n++) {
+ genet_setup_rxfilter_mdf(sc, n, enm->enm_addrlo);
+ ETHER_NEXT_MULTI(step, enm);
+ }
+ mdf_ctrl = __BITS(GENET_MAX_MDF_FILTER - 1,
+ GENET_MAX_MDF_FILTER - n);
+ }
+
+ WR4(sc, GENET_UMAC_CMD, cmd);
+ WR4(sc, GENET_UMAC_MDF_CTRL, mdf_ctrl);
+
+ ETHER_UNLOCK(ec);
}
static int
@@ -465,10 +512,10 @@
GENET_SYS_PORT_MODE_EXT_GPHY);
/* Write hardware address */
- val = enaddr[0] | (enaddr[1] << 8) | (enaddr[2] << 16) |
- (enaddr[3] << 24);
+ val = enaddr[3] | (enaddr[2] << 8) | (enaddr[1] << 16) |
+ (enaddr[0] << 24);
WR4(sc, GENET_UMAC_MAC0, val);
- val = enaddr[4] | (enaddr[5] << 8);
+ val = enaddr[5] | (enaddr[4] << 8);
WR4(sc, GENET_UMAC_MAC1, val);
/* Setup RX filter */
diff -r 7bc2a8d9ed7b -r 78b42f146d41 sys/dev/ic/bcmgenetreg.h
--- a/sys/dev/ic/bcmgenetreg.h Sat Feb 22 13:20:21 2020 +0000
+++ b/sys/dev/ic/bcmgenetreg.h Sat Feb 22 13:41:40 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bcmgenetreg.h,v 1.1 2020/02/22 00:28:35 jmcneill Exp $ */
+/* $NetBSD: bcmgenetreg.h,v 1.2 2020/02/22 13:41:41 jmcneill Exp $ */
/*-
* Copyright (c) 2020 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -85,6 +85,8 @@
#define GENET_MDIO_PMD __BITS(25,21)
#define GENET_MDIO_REG __BITS(20,16)
#define GENET_UMAC_MDF_CTRL 0xe50
+#define GENET_UMAC_MDF_ADDR0(n) (0xe54 + (n) * 0x8)
+#define GENET_UMAC_MDF_ADDR1(n) (0xe58 + (n) * 0x8)
#define GENET_DMA_DESC_COUNT 256
#define GENET_DMA_DESC_SIZE 12
Home |
Main Index |
Thread Index |
Old Index