Module Name: src Committed By: riastradh Date: Thu Nov 2 13:50:02 UTC 2023
Modified Files: src/sys/dev/ic: dwc_eqos.c dwc_eqos_var.h Log Message: eqos(4): Fix locking around multicast filter updates. - Can't touch if_flags without IFNET_LOCK. - Can't take IFNET_LOCK in SIOCADDMULTI/SIOCDELMULTI path. Instead, cache IFF_PROMISC and IFF_ALLMULTI on if_init under a lock we can take in this path. XXX Is IFF_ALLMULTI relevant any more? Hasn't it been moved to ethercom flags? XXX Should not take sc_lock around if_init/stop -- IFNET_LOCK is enough. Should narrow scope of sc_lock to be just tick/mii/multi stuff. To generate a diff of this commit: cvs rdiff -u -r1.31 -r1.32 src/sys/dev/ic/dwc_eqos.c cvs rdiff -u -r1.8 -r1.9 src/sys/dev/ic/dwc_eqos_var.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/dwc_eqos.c diff -u src/sys/dev/ic/dwc_eqos.c:1.31 src/sys/dev/ic/dwc_eqos.c:1.32 --- src/sys/dev/ic/dwc_eqos.c:1.31 Thu Nov 2 13:49:49 2023 +++ src/sys/dev/ic/dwc_eqos.c Thu Nov 2 13:50:02 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_eqos.c,v 1.31 2023/11/02 13:49:49 riastradh Exp $ */ +/* $NetBSD: dwc_eqos.c,v 1.32 2023/11/02 13:50:02 riastradh Exp $ */ /*- * Copyright (c) 2022 Jared McNeill <jmcne...@invisible.ca> @@ -38,7 +38,7 @@ #include "opt_net_mpsafe.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: dwc_eqos.c,v 1.31 2023/11/02 13:49:49 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dwc_eqos.c,v 1.32 2023/11/02 13:50:02 riastradh Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -509,10 +509,10 @@ eqos_setup_rxfilter(struct eqos_softc *s GMAC_MAC_PACKET_FILTER_PCF_MASK); hash[0] = hash[1] = ~0U; - if ((ifp->if_flags & IFF_PROMISC) != 0) { + if (sc->sc_promisc) { pfil |= GMAC_MAC_PACKET_FILTER_PR | GMAC_MAC_PACKET_FILTER_PCF_ALL; - } else if ((ifp->if_flags & IFF_ALLMULTI) != 0) { + } else if (sc->sc_allmulti) { pfil |= GMAC_MAC_PACKET_FILTER_PM; } else { hash[0] = hash[1] = 0; @@ -617,6 +617,8 @@ eqos_init_locked(struct eqos_softc *sc) eqos_init_rings(sc, 0); /* Setup RX filter */ + sc->sc_promisc = ifp->if_flags & IFF_PROMISC; + sc->sc_allmulti = ifp->if_flags & IFF_ALLMULTI; /* XXX */ eqos_setup_rxfilter(sc); WR4(sc, GMAC_MAC_1US_TIC_COUNTER, (sc->sc_csr_clock / 1000000) - 1); @@ -1232,9 +1234,10 @@ eqos_ioctl(struct ifnet *ifp, u_long cmd error = (*ifp->if_init)(ifp); else if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI) ; - else if ((ifp->if_flags & IFF_RUNNING) != 0) { + else { EQOS_LOCK(sc); - eqos_setup_rxfilter(sc); + if (sc->sc_running) + eqos_setup_rxfilter(sc); EQOS_UNLOCK(sc); } break; Index: src/sys/dev/ic/dwc_eqos_var.h diff -u src/sys/dev/ic/dwc_eqos_var.h:1.8 src/sys/dev/ic/dwc_eqos_var.h:1.9 --- src/sys/dev/ic/dwc_eqos_var.h:1.8 Thu Nov 2 13:49:49 2023 +++ src/sys/dev/ic/dwc_eqos_var.h Thu Nov 2 13:50:02 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_eqos_var.h,v 1.8 2023/11/02 13:49:49 riastradh Exp $ */ +/* $NetBSD: dwc_eqos_var.h,v 1.9 2023/11/02 13:50:02 riastradh Exp $ */ /*- * Copyright (c) 2022 Jared McNeill <jmcne...@invisible.ca> @@ -72,6 +72,8 @@ struct eqos_softc { kmutex_t sc_txlock; bool sc_running; bool sc_txrunning; + bool sc_promisc; + bool sc_allmulti; struct eqos_ring sc_tx; struct eqos_ring sc_rx;