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;

Reply via email to