Module Name: src
Committed By: jmcneill
Date: Sat Feb 22 13:41:41 UTC 2020
Modified Files:
src/sys/dev/ic: bcmgenet.c bcmgenetreg.h
Log Message:
Add support for hardware rx filters.
To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/dev/ic/bcmgenet.c \
src/sys/dev/ic/bcmgenetreg.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/ic/bcmgenet.c
diff -u src/sys/dev/ic/bcmgenet.c:1.1 src/sys/dev/ic/bcmgenet.c:1.2
--- src/sys/dev/ic/bcmgenet.c:1.1 Sat Feb 22 00:28:35 2020
+++ src/sys/dev/ic/bcmgenet.c Sat Feb 22 13:41:40 2020
@@ -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 <[email protected]>
@@ -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 @@ CTASSERT(MCLBYTES == 2048);
#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 @@ genet_tick(void *softc)
}
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;
+
+ 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);
- /* Disable filters */
- WR4(sc, GENET_UMAC_MDF_CTRL, 0);
+ ETHER_UNLOCK(ec);
}
static int
@@ -465,10 +512,10 @@ genet_init_locked(struct genet_softc *sc
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 */
Index: src/sys/dev/ic/bcmgenetreg.h
diff -u src/sys/dev/ic/bcmgenetreg.h:1.1 src/sys/dev/ic/bcmgenetreg.h:1.2
--- src/sys/dev/ic/bcmgenetreg.h:1.1 Sat Feb 22 00:28:35 2020
+++ src/sys/dev/ic/bcmgenetreg.h Sat Feb 22 13:41:41 2020
@@ -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 <[email protected]>
@@ -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