From db55051729066a8b162fe2f05e0e2b6c29907e8b Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Fri, 25 Aug 2023 11:36:35 -0400 Subject: [PATCH] dtsec: Support multicast receive. Implemented based on the tsec(4) multicast support. This is the minimum required to support VLANs. The hardware does support vlan tagging, among other acceleration features, which will be added at a later time. MFC after: 2 weeks --- sys/dev/dpaa/if_dtsec.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/sys/dev/dpaa/if_dtsec.c b/sys/dev/dpaa/if_dtsec.c index 2c0dee05a03..de5ca75c9a7 100644 --- a/sys/dev/dpaa/if_dtsec.c +++ b/sys/dev/dpaa/if_dtsec.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include "fman.h" @@ -69,6 +70,7 @@ #define DTSEC_MAX_FRAME_SIZE 9600 #define DTSEC_REG_MAXFRM 0x110 +#define DTSEC_REG_GADDR(i) (0x0a0 + 4*(i)) /** * @group dTSEC private defines. @@ -338,6 +340,33 @@ dtsec_set_mtu(struct dtsec_softc *sc, unsigned int mtu) return (0); } +static u_int +dtsec_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt) +{ + struct dtsec_softc *sc = arg; + + FM_MAC_AddHashMacAddr(sc->sc_mach, (t_EnetAddr *)LLADDR(sdl)); + + return (1); +} + +static void +dtsec_setup_multicast(struct dtsec_softc *sc) +{ + int i; + + if (if_getflags(sc->sc_ifnet) & IFF_ALLMULTI) { + for (i = 0; i < 8; i++) + bus_write_4(sc->sc_mem, DTSEC_REG_GADDR(i), 0xFFFFFFFF); + + return; + } + + fman_dtsec_reset_filter_table(rman_get_virtual(sc->sc_mem), + true, false); + if_foreach_llmaddr(sc->sc_ifnet, dtsec_hash_maddr, sc); +} + static int dtsec_if_enable_locked(struct dtsec_softc *sc) { @@ -357,6 +386,8 @@ dtsec_if_enable_locked(struct dtsec_softc *sc) if (error != E_OK) return (EIO); + dtsec_setup_multicast(sc); + if_setdrvflagbits(sc->sc_ifnet, IFF_DRV_RUNNING, 0); /* Refresh link state */ @@ -686,7 +717,7 @@ dtsec_attach(device_t dev) if_setsoftc(ifp, sc); - if_setflags(ifp, IFF_SIMPLEX | IFF_BROADCAST); + if_setflags(ifp, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST); if_setinitfn(ifp, dtsec_if_init); if_setstartfn(ifp, dtsec_if_start); if_setioctlfn(ifp, dtsec_if_ioctl);