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

Reply via email to