Module Name:    src
Committed By:   riastradh
Date:           Thu Mar  3 05:51:06 UTC 2022

Modified Files:
        src/sys/dev/usb: if_aue.c if_axe.c if_axen.c if_cue.c if_kue.c if_mos.c
            if_mue.c if_smsc.c if_udav.c if_ure.c if_url.c usbnet.c usbnet.h

Log Message:
usbnet: Split multicast filter reprogramming into separate operation.


To generate a diff of this commit:
cvs rdiff -u -r1.173 -r1.174 src/sys/dev/usb/if_aue.c
cvs rdiff -u -r1.133 -r1.134 src/sys/dev/usb/if_axe.c
cvs rdiff -u -r1.75 -r1.76 src/sys/dev/usb/if_axen.c
cvs rdiff -u -r1.93 -r1.94 src/sys/dev/usb/if_cue.c
cvs rdiff -u -r1.106 -r1.107 src/sys/dev/usb/if_kue.c
cvs rdiff -u -r1.9 -r1.10 src/sys/dev/usb/if_mos.c
cvs rdiff -u -r1.65 -r1.66 src/sys/dev/usb/if_mue.c
cvs rdiff -u -r1.73 -r1.74 src/sys/dev/usb/if_smsc.c
cvs rdiff -u -r1.80 -r1.81 src/sys/dev/usb/if_udav.c src/sys/dev/usb/if_url.c
cvs rdiff -u -r1.42 -r1.43 src/sys/dev/usb/if_ure.c
cvs rdiff -u -r1.74 -r1.75 src/sys/dev/usb/usbnet.c
cvs rdiff -u -r1.23 -r1.24 src/sys/dev/usb/usbnet.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/usb/if_aue.c
diff -u src/sys/dev/usb/if_aue.c:1.173 src/sys/dev/usb/if_aue.c:1.174
--- src/sys/dev/usb/if_aue.c:1.173	Thu Mar  3 05:50:57 2022
+++ src/sys/dev/usb/if_aue.c	Thu Mar  3 05:51:06 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_aue.c,v 1.173 2022/03/03 05:50:57 riastradh Exp $	*/
+/*	$NetBSD: if_aue.c,v 1.174 2022/03/03 05:51:06 riastradh Exp $	*/
 
 /*
  * Copyright (c) 1997, 1998, 1999, 2000
@@ -76,7 +76,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.173 2022/03/03 05:50:57 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.174 2022/03/03 05:51:06 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -240,7 +240,7 @@ CFATTACH_DECL_NEW(aue, sizeof(struct aue
 static void aue_reset_pegasus_II(struct aue_softc *);
 
 static void aue_uno_stop(struct ifnet *, int);
-static int aue_uno_ioctl(struct ifnet *, u_long, void *);
+static void aue_uno_mcast(struct ifnet *);
 static int aue_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *);
 static int aue_uno_mii_write_reg(struct usbnet *, int, int, uint16_t);
 static void aue_uno_mii_statchg(struct ifnet *);
@@ -252,7 +252,7 @@ static void aue_uno_intr(struct usbnet *
 
 static const struct usbnet_ops aue_ops = {
 	.uno_stop = aue_uno_stop,
-	.uno_ioctl = aue_uno_ioctl,
+	.uno_mcast = aue_uno_mcast,
 	.uno_read_reg = aue_uno_mii_read_reg,
 	.uno_write_reg = aue_uno_mii_write_reg,
 	.uno_statchg = aue_uno_mii_statchg,
@@ -1013,28 +1013,23 @@ aue_uno_init(struct ifnet *ifp)
 	return rv;
 }
 
-static int
-aue_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
+static void
+aue_uno_mcast(struct ifnet *ifp)
 {
 	struct usbnet * const un = ifp->if_softc;
 
 	AUEHIST_FUNC();
-	AUEHIST_CALLARGSN(5, "aue%jd: enter cmd %#jx data %#jx",
+	AUEHIST_CALLARGSN(5, "aue%jd: enter",
 	    device_unit(((struct usbnet *)(ifp->if_softc))->un_dev),
-	    cmd, (uintptr_t)data, 0);
+	    0, 0, 0);
 
-	switch (cmd) {
-	case SIOCADDMULTI:
-	case SIOCDELMULTI:
-		usbnet_lock_core(un);
-		aue_uno_init(ifp);
-		usbnet_unlock_core(un);
-		break;
-	default:
-		break;
-	}
-
-	return 0;
+	/*
+	 * XXX I feel like this is pretty heavy-handed!  Maybe we could
+	 * make do with aue_setiff_locked instead?
+	 */
+	usbnet_lock_core(un);
+	aue_uno_init(ifp);
+	usbnet_unlock_core(un);
 }
 
 static void

Index: src/sys/dev/usb/if_axe.c
diff -u src/sys/dev/usb/if_axe.c:1.133 src/sys/dev/usb/if_axe.c:1.134
--- src/sys/dev/usb/if_axe.c:1.133	Thu Mar  3 05:50:22 2022
+++ src/sys/dev/usb/if_axe.c	Thu Mar  3 05:51:06 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_axe.c,v 1.133 2022/03/03 05:50:22 riastradh Exp $	*/
+/*	$NetBSD: if_axe.c,v 1.134 2022/03/03 05:51:06 riastradh Exp $	*/
 /*	$OpenBSD: if_axe.c,v 1.137 2016/04/13 11:03:37 mpi Exp $ */
 
 /*
@@ -87,7 +87,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.133 2022/03/03 05:50:22 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.134 2022/03/03 05:51:06 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -259,7 +259,7 @@ CFATTACH_DECL_NEW(axe, sizeof(struct axe
 	axe_match, axe_attach, usbnet_detach, usbnet_activate);
 
 static void	axe_uno_stop(struct ifnet *, int);
-static int	axe_uno_ioctl(struct ifnet *, u_long, void *);
+static void	axe_uno_mcast(struct ifnet *);
 static int	axe_uno_init(struct ifnet *);
 static int	axe_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *);
 static int	axe_uno_mii_write_reg(struct usbnet *, int, int, uint16_t);
@@ -276,7 +276,7 @@ static void	axe_ax88772b_init(struct axe
 
 static const struct usbnet_ops axe_ops = {
 	.uno_stop = axe_uno_stop,
-	.uno_ioctl = axe_uno_ioctl,
+	.uno_mcast = axe_uno_mcast,
 	.uno_read_reg = axe_uno_mii_read_reg,
 	.uno_write_reg = axe_uno_mii_write_reg,
 	.uno_statchg = axe_uno_mii_statchg,
@@ -1324,27 +1324,18 @@ axe_uno_init(struct ifnet *ifp)
 	return ret;
 }
 
-static int
-axe_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
+static void
+axe_uno_mcast(struct ifnet *ifp)
 {
 	struct usbnet * const un = ifp->if_softc;
 
 	usbnet_lock_core(un);
 	usbnet_busy(un);
 
-	switch (cmd) {
-	case SIOCADDMULTI:
-	case SIOCDELMULTI:
-		axe_rcvfilt_locked(un);
-		break;
-	default:
-		break;
-	}
+	axe_rcvfilt_locked(un);
 
 	usbnet_unbusy(un);
 	usbnet_unlock_core(un);
-
-	return 0;
 }
 
 static void

Index: src/sys/dev/usb/if_axen.c
diff -u src/sys/dev/usb/if_axen.c:1.75 src/sys/dev/usb/if_axen.c:1.76
--- src/sys/dev/usb/if_axen.c:1.75	Thu Mar  3 05:50:22 2022
+++ src/sys/dev/usb/if_axen.c	Thu Mar  3 05:51:06 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_axen.c,v 1.75 2022/03/03 05:50:22 riastradh Exp $	*/
+/*	$NetBSD: if_axen.c,v 1.76 2022/03/03 05:51:06 riastradh Exp $	*/
 /*	$OpenBSD: if_axen.c,v 1.3 2013/10/21 10:10:22 yuo Exp $	*/
 
 /*
@@ -23,7 +23,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_axen.c,v 1.75 2022/03/03 05:50:22 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_axen.c,v 1.76 2022/03/03 05:51:06 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -80,6 +80,7 @@ static void	axen_ax88179_init(struct usb
 
 static void	axen_uno_stop(struct ifnet *, int);
 static int	axen_uno_ioctl(struct ifnet *, u_long, void *);
+static void	axen_uno_mcast(struct ifnet *);
 static int	axen_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *);
 static int	axen_uno_mii_write_reg(struct usbnet *, int, int, uint16_t);
 static void	axen_uno_mii_statchg(struct ifnet *);
@@ -92,6 +93,7 @@ static int	axen_uno_init(struct ifnet *)
 static const struct usbnet_ops axen_ops = {
 	.uno_stop = axen_uno_stop,
 	.uno_ioctl = axen_uno_ioctl,
+	.uno_mcast = axen_uno_mcast,
 	.uno_read_reg = axen_uno_mii_read_reg,
 	.uno_write_reg = axen_uno_mii_write_reg,
 	.uno_statchg = axen_uno_mii_statchg,
@@ -559,10 +561,6 @@ axen_uno_ioctl(struct ifnet *ifp, u_long
 	usbnet_busy(un);
 
 	switch (cmd) {
-	case SIOCADDMULTI:
-	case SIOCDELMULTI:
-		axen_setiff_locked(un);
-		break;
 	case SIOCSIFCAP:
 		axen_setoe_locked(un);
 		break;
@@ -576,6 +574,20 @@ axen_uno_ioctl(struct ifnet *ifp, u_long
 	return 0;
 }
 
+static void
+axen_uno_mcast(struct ifnet *ifp)
+{
+	struct usbnet * const un = ifp->if_softc;
+
+	usbnet_lock_core(un);
+	usbnet_busy(un);
+
+	axen_setiff_locked(un);
+
+	usbnet_unbusy(un);
+	usbnet_unlock_core(un);
+}
+
 static int
 axen_match(device_t parent, cfdata_t match, void *aux)
 {

Index: src/sys/dev/usb/if_cue.c
diff -u src/sys/dev/usb/if_cue.c:1.93 src/sys/dev/usb/if_cue.c:1.94
--- src/sys/dev/usb/if_cue.c:1.93	Thu Mar  3 05:50:22 2022
+++ src/sys/dev/usb/if_cue.c	Thu Mar  3 05:51:06 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_cue.c,v 1.93 2022/03/03 05:50:22 riastradh Exp $	*/
+/*	$NetBSD: if_cue.c,v 1.94 2022/03/03 05:51:06 riastradh Exp $	*/
 
 /*
  * Copyright (c) 1997, 1998, 1999, 2000
@@ -57,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_cue.c,v 1.93 2022/03/03 05:50:22 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_cue.c,v 1.94 2022/03/03 05:51:06 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -141,14 +141,14 @@ CFATTACH_DECL_NEW(cue, sizeof(struct cue
 static unsigned cue_uno_tx_prepare(struct usbnet *, struct mbuf *,
 				   struct usbnet_chain *);
 static void cue_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
-static int cue_uno_ioctl(struct ifnet *, u_long, void *);
+static void cue_uno_mcast(struct ifnet *);
 static void cue_uno_stop(struct ifnet *, int);
 static int cue_uno_init(struct ifnet *);
 static void cue_uno_tick(struct usbnet *);
 
 static const struct usbnet_ops cue_ops = {
 	.uno_stop = cue_uno_stop,
-	.uno_ioctl = cue_uno_ioctl,
+	.uno_mcast = cue_uno_mcast,
 	.uno_tx_prepare = cue_uno_tx_prepare,
 	.uno_rx_loop = cue_uno_rx_loop,
 	.uno_init = cue_uno_init,
@@ -680,27 +680,18 @@ cue_uno_init(struct ifnet *ifp)
 	return rv;
 }
 
-static int
-cue_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
+static void
+cue_uno_mcast(struct ifnet *ifp)
 {
 	struct usbnet * const	un = ifp->if_softc;
 
 	usbnet_lock_core(un);
 	usbnet_busy(un);
 
-	switch (cmd) {
-	case SIOCADDMULTI:
-	case SIOCDELMULTI:
-		cue_setiff_locked(un);
-		break;
-	default:
-		break;
-	}
+	cue_setiff_locked(un);
 
 	usbnet_unbusy(un);
 	usbnet_unlock_core(un);
-
-	return 0;
 }
 
 /* Stop and reset the adapter.  */

Index: src/sys/dev/usb/if_kue.c
diff -u src/sys/dev/usb/if_kue.c:1.106 src/sys/dev/usb/if_kue.c:1.107
--- src/sys/dev/usb/if_kue.c:1.106	Thu Mar  3 05:50:22 2022
+++ src/sys/dev/usb/if_kue.c	Thu Mar  3 05:51:06 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_kue.c,v 1.106 2022/03/03 05:50:22 riastradh Exp $	*/
+/*	$NetBSD: if_kue.c,v 1.107 2022/03/03 05:51:06 riastradh Exp $	*/
 
 /*
  * Copyright (c) 1997, 1998, 1999, 2000
@@ -71,7 +71,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_kue.c,v 1.106 2022/03/03 05:50:22 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_kue.c,v 1.107 2022/03/03 05:51:06 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -174,11 +174,11 @@ CFATTACH_DECL_NEW(kue, sizeof(struct kue
 static void kue_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
 static unsigned kue_uno_tx_prepare(struct usbnet *, struct mbuf *,
 				   struct usbnet_chain *);
-static int kue_uno_ioctl(struct ifnet *, u_long, void *);
+static void kue_uno_mcast(struct ifnet *);
 static int kue_uno_init(struct ifnet *);
 
 static const struct usbnet_ops kue_ops = {
-	.uno_ioctl = kue_uno_ioctl,
+	.uno_mcast = kue_uno_mcast,
 	.uno_tx_prepare = kue_uno_tx_prepare,
 	.uno_rx_loop = kue_uno_rx_loop,
 	.uno_init = kue_uno_init,
@@ -640,27 +640,18 @@ kue_uno_init(struct ifnet *ifp)
 	return rv;
 }
 
-static int
-kue_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
+static void
+kue_uno_mcast(struct ifnet *ifp)
 {
 	struct usbnet * const	un = ifp->if_softc;
 
 	usbnet_lock_core(un);
 	usbnet_busy(un);
 
-	switch (cmd) {
-	case SIOCADDMULTI:
-	case SIOCDELMULTI:
-		kue_setiff_locked(un);
-		break;
-	default:
-		break;
-	}
+	kue_setiff_locked(un);
 
 	usbnet_unbusy(un);
 	usbnet_unlock_core(un);
-
-	return 0;
 }
 
 #ifdef _MODULE

Index: src/sys/dev/usb/if_mos.c
diff -u src/sys/dev/usb/if_mos.c:1.9 src/sys/dev/usb/if_mos.c:1.10
--- src/sys/dev/usb/if_mos.c:1.9	Thu Mar  3 05:50:57 2022
+++ src/sys/dev/usb/if_mos.c	Thu Mar  3 05:51:06 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_mos.c,v 1.9 2022/03/03 05:50:57 riastradh Exp $	*/
+/*	$NetBSD: if_mos.c,v 1.10 2022/03/03 05:51:06 riastradh Exp $	*/
 /*	$OpenBSD: if_mos.c,v 1.40 2019/07/07 06:40:10 kevlo Exp $	*/
 
 /*
@@ -72,7 +72,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_mos.c,v 1.9 2022/03/03 05:50:57 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_mos.c,v 1.10 2022/03/03 05:51:06 riastradh Exp $");
 
 #include <sys/param.h>
 
@@ -145,7 +145,7 @@ CFATTACH_DECL_NEW(mos, sizeof(struct usb
 static void mos_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
 static unsigned mos_uno_tx_prepare(struct usbnet *, struct mbuf *,
 				   struct usbnet_chain *);
-static int mos_uno_ioctl(struct ifnet *, u_long, void *);
+static void mos_uno_mcast(struct ifnet *);
 static int mos_uno_init(struct ifnet *);
 static void mos_chip_init(struct usbnet *);
 static void mos_uno_stop(struct ifnet *ifp, int disable);
@@ -164,7 +164,7 @@ static int mos_write_mcast(struct usbnet
 
 static const struct usbnet_ops mos_ops = {
 	.uno_stop = mos_uno_stop,
-	.uno_ioctl = mos_uno_ioctl,
+	.uno_mcast = mos_uno_mcast,
 	.uno_read_reg = mos_uno_mii_read_reg,
 	.uno_write_reg = mos_uno_mii_write_reg,
 	.uno_statchg = mos_uno_mii_statchg,
@@ -771,27 +771,18 @@ mos_uno_init(struct ifnet *ifp)
 	return ret;
 }
 
-static int
-mos_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
+static void
+mos_uno_mcast(struct ifnet *ifp)
 {
 	struct usbnet * const un = ifp->if_softc;
 
 	usbnet_lock_core(un);
 	usbnet_busy(un);
 
-	switch (cmd) {
-	case SIOCADDMULTI:
-	case SIOCDELMULTI:
-		mos_rcvfilt_locked(un);
-		break;
-	default:
-		break;
-	}
+	mos_rcvfilt_locked(un);
 
 	usbnet_unbusy(un);
 	usbnet_unlock_core(un);
-
-	return 0;
 }
 
 void

Index: src/sys/dev/usb/if_mue.c
diff -u src/sys/dev/usb/if_mue.c:1.65 src/sys/dev/usb/if_mue.c:1.66
--- src/sys/dev/usb/if_mue.c:1.65	Thu Mar  3 05:50:57 2022
+++ src/sys/dev/usb/if_mue.c	Thu Mar  3 05:51:06 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_mue.c,v 1.65 2022/03/03 05:50:57 riastradh Exp $	*/
+/*	$NetBSD: if_mue.c,v 1.66 2022/03/03 05:51:06 riastradh Exp $	*/
 /*	$OpenBSD: if_mue.c,v 1.3 2018/08/04 16:42:46 jsg Exp $	*/
 
 /*
@@ -20,7 +20,7 @@
 /* Driver for Microchip LAN7500/LAN7800 chipsets. */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_mue.c,v 1.65 2022/03/03 05:50:57 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_mue.c,v 1.66 2022/03/03 05:51:06 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -99,6 +99,7 @@ static void	mue_reset(struct usbnet *);
 
 static void	mue_uno_stop(struct ifnet *, int);
 static int	mue_uno_ioctl(struct ifnet *, u_long, void *);
+static void	mue_uno_mcast(struct ifnet *);
 static int	mue_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *);
 static int	mue_uno_mii_write_reg(struct usbnet *, int, int, uint16_t);
 static void	mue_uno_mii_statchg(struct ifnet *);
@@ -111,6 +112,7 @@ static int	mue_uno_init(struct ifnet *);
 static const struct usbnet_ops mue_ops = {
 	.uno_stop = mue_uno_stop,
 	.uno_ioctl = mue_uno_ioctl,
+	.uno_mcast = mue_uno_mcast,
 	.uno_read_reg = mue_uno_mii_read_reg,
 	.uno_write_reg = mue_uno_mii_write_reg,
 	.uno_statchg = mue_uno_mii_statchg,
@@ -1273,10 +1275,6 @@ mue_uno_ioctl(struct ifnet *ifp, u_long 
 	usbnet_busy(un);
 
 	switch (cmd) {
-	case SIOCADDMULTI:
-	case SIOCDELMULTI:
-		mue_setiff_locked(un);
-		break;
 	case SIOCSIFCAP:
 		mue_sethwcsum_locked(un);
 		break;
@@ -1294,6 +1292,20 @@ mue_uno_ioctl(struct ifnet *ifp, u_long 
 }
 
 static void
+mue_uno_mcast(struct ifnet *ifp)
+{
+	struct usbnet * const un = ifp->if_softc;
+
+	usbnet_lock_core(un);
+	usbnet_busy(un);
+
+	mue_setiff_locked(un);
+
+	usbnet_unbusy(un);
+	usbnet_unlock_core(un);
+}
+
+static void
 mue_reset(struct usbnet *un)
 {
 	if (usbnet_isdying(un))

Index: src/sys/dev/usb/if_smsc.c
diff -u src/sys/dev/usb/if_smsc.c:1.73 src/sys/dev/usb/if_smsc.c:1.74
--- src/sys/dev/usb/if_smsc.c:1.73	Thu Mar  3 05:50:57 2022
+++ src/sys/dev/usb/if_smsc.c	Thu Mar  3 05:51:06 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_smsc.c,v 1.73 2022/03/03 05:50:57 riastradh Exp $	*/
+/*	$NetBSD: if_smsc.c,v 1.74 2022/03/03 05:51:06 riastradh Exp $	*/
 
 /*	$OpenBSD: if_smsc.c,v 1.4 2012/09/27 12:38:11 jsg Exp $	*/
 /*	$FreeBSD: src/sys/dev/usb/net/if_smsc.c,v 1.1 2012/08/15 04:03:55 gonzo Exp $ */
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_smsc.c,v 1.73 2022/03/03 05:50:57 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_smsc.c,v 1.74 2022/03/03 05:51:06 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -187,6 +187,7 @@ static int	 smsc_uno_miibus_readreg(stru
 static int	 smsc_uno_miibus_writereg(struct usbnet *, int, int, uint16_t);
 
 static int	 smsc_uno_ioctl(struct ifnet *, u_long, void *);
+static void	 smsc_uno_mcast(struct ifnet *);
 static unsigned	 smsc_uno_tx_prepare(struct usbnet *, struct mbuf *,
 		     struct usbnet_chain *);
 static void	 smsc_uno_rx_loop(struct usbnet *, struct usbnet_chain *,
@@ -195,6 +196,7 @@ static void	 smsc_uno_rx_loop(struct usb
 static const struct usbnet_ops smsc_ops = {
 	.uno_stop = smsc_uno_stop,
 	.uno_ioctl = smsc_uno_ioctl,
+	.uno_mcast = smsc_uno_mcast,
 	.uno_read_reg = smsc_uno_miibus_readreg,
 	.uno_write_reg = smsc_uno_miibus_writereg,
 	.uno_statchg = smsc_uno_miibus_statchg,
@@ -757,10 +759,6 @@ smsc_uno_ioctl(struct ifnet *ifp, u_long
 	usbnet_busy(un);
 
 	switch (cmd) {
-	case SIOCADDMULTI:
-	case SIOCDELMULTI:
-		smsc_setiff_locked(un);
-		break;
 	case SIOCSIFCAP:
 		smsc_setoe_locked(un);
 		break;
@@ -774,6 +772,20 @@ smsc_uno_ioctl(struct ifnet *ifp, u_long
 	return 0;
 }
 
+static void
+smsc_uno_mcast(struct ifnet *ifp)
+{
+	struct usbnet * const un = ifp->if_softc;
+
+	usbnet_lock_core(un);
+	usbnet_busy(un);
+
+	smsc_setiff_locked(un);
+
+	usbnet_unbusy(un);
+	usbnet_unlock_core(un);
+}
+
 static int
 smsc_match(device_t parent, cfdata_t match, void *aux)
 {

Index: src/sys/dev/usb/if_udav.c
diff -u src/sys/dev/usb/if_udav.c:1.80 src/sys/dev/usb/if_udav.c:1.81
--- src/sys/dev/usb/if_udav.c:1.80	Thu Mar  3 05:50:57 2022
+++ src/sys/dev/usb/if_udav.c	Thu Mar  3 05:51:06 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_udav.c,v 1.80 2022/03/03 05:50:57 riastradh Exp $	*/
+/*	$NetBSD: if_udav.c,v 1.81 2022/03/03 05:51:06 riastradh Exp $	*/
 /*	$nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $	*/
 
 /*
@@ -45,7 +45,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.80 2022/03/03 05:50:57 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.81 2022/03/03 05:51:06 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -69,7 +69,7 @@ static unsigned udav_uno_tx_prepare(stru
 				    struct usbnet_chain *);
 static void udav_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
 static void udav_uno_stop(struct ifnet *, int);
-static int udav_uno_ioctl(struct ifnet *, u_long, void *);
+static void udav_uno_mcast(struct ifnet *);
 static int udav_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *);
 static int udav_uno_mii_write_reg(struct usbnet *, int, int, uint16_t);
 static void udav_uno_mii_statchg(struct ifnet *);
@@ -132,7 +132,7 @@ static const struct udav_type {
 
 static const struct usbnet_ops udav_ops = {
 	.uno_stop = udav_uno_stop,
-	.uno_ioctl = udav_uno_ioctl,
+	.uno_mcast = udav_uno_mcast,
 	.uno_read_reg = udav_uno_mii_read_reg,
 	.uno_write_reg = udav_uno_mii_write_reg,
 	.uno_statchg = udav_uno_mii_statchg,
@@ -718,27 +718,18 @@ udav_uno_rx_loop(struct usbnet *un, stru
 	usbnet_enqueue(un, buf, pkt_len, 0, 0, 0);
 }
 
-static int
-udav_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
+static void
+udav_uno_mcast(struct ifnet *ifp)
 {
 	struct usbnet * const un = ifp->if_softc;
 
 	usbnet_lock_core(un);
 	usbnet_busy(un);
 
-	switch (cmd) {
-	case SIOCADDMULTI:
-	case SIOCDELMULTI:
-		udav_setiff_locked(un);
-		break;
-	default:
-		break;
-	}
+	udav_setiff_locked(un);
 
 	usbnet_unbusy(un);
 	usbnet_unlock_core(un);
-
-	return 0;
 }
 
 /* Stop the adapter and free any mbufs allocated to the RX and TX lists. */
Index: src/sys/dev/usb/if_url.c
diff -u src/sys/dev/usb/if_url.c:1.80 src/sys/dev/usb/if_url.c:1.81
--- src/sys/dev/usb/if_url.c:1.80	Thu Mar  3 05:50:57 2022
+++ src/sys/dev/usb/if_url.c	Thu Mar  3 05:51:06 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_url.c,v 1.80 2022/03/03 05:50:57 riastradh Exp $	*/
+/*	$NetBSD: if_url.c,v 1.81 2022/03/03 05:51:06 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2001, 2002
@@ -44,7 +44,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_url.c,v 1.80 2022/03/03 05:50:57 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_url.c,v 1.81 2022/03/03 05:51:06 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -77,7 +77,7 @@ static unsigned	url_uno_tx_prepare(struc
 static void url_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
 static int url_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *);
 static int url_uno_mii_write_reg(struct usbnet *, int, int, uint16_t);
-static int url_uno_ioctl(struct ifnet *, u_long, void *);
+static void url_uno_mcast(struct ifnet *);
 static void url_uno_stop(struct ifnet *, int);
 static void url_uno_mii_statchg(struct ifnet *);
 static int url_uno_init(struct ifnet *);
@@ -93,7 +93,7 @@ static int url_mem(struct usbnet *, int,
 
 static const struct usbnet_ops url_ops = {
 	.uno_stop = url_uno_stop,
-	.uno_ioctl = url_uno_ioctl,
+	.uno_mcast = url_uno_mcast,
 	.uno_read_reg = url_uno_mii_read_reg,
 	.uno_write_reg = url_uno_mii_write_reg,
 	.uno_statchg = url_uno_mii_statchg,
@@ -559,27 +559,18 @@ static void url_intr(void)
 }
 #endif
 
-static int
-url_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
+static void
+url_uno_mcast(struct ifnet *ifp)
 {
 	struct usbnet * const un = ifp->if_softc;
 
 	usbnet_lock_core(un);
 	usbnet_busy(un);
 
-	switch (cmd) {
-	case SIOCADDMULTI:
-	case SIOCDELMULTI:
-		url_rcvfilt_locked(un);
-		break;
-	default:
-		break;
-	}
+	url_rcvfilt_locked(un);
 
 	usbnet_unbusy(un);
 	usbnet_unlock_core(un);
-
-	return 0;
 }
 
 /* Stop the adapter and free any mbufs allocated to the RX and TX lists. */

Index: src/sys/dev/usb/if_ure.c
diff -u src/sys/dev/usb/if_ure.c:1.42 src/sys/dev/usb/if_ure.c:1.43
--- src/sys/dev/usb/if_ure.c:1.42	Thu Mar  3 05:50:57 2022
+++ src/sys/dev/usb/if_ure.c	Thu Mar  3 05:51:06 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_ure.c,v 1.42 2022/03/03 05:50:57 riastradh Exp $	*/
+/*	$NetBSD: if_ure.c,v 1.43 2022/03/03 05:51:06 riastradh Exp $	*/
 /*	$OpenBSD: if_ure.c,v 1.10 2018/11/02 21:32:30 jcs Exp $	*/
 
 /*-
@@ -30,7 +30,7 @@
 /* RealTek RTL8152/RTL8153 10/100/Gigabit USB Ethernet device */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ure.c,v 1.42 2022/03/03 05:50:57 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ure.c,v 1.43 2022/03/03 05:51:06 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -86,7 +86,7 @@ static void	ure_disable_teredo(struct us
 static void	ure_init_fifo(struct usbnet *);
 
 static void	ure_uno_stop(struct ifnet *, int);
-static int	ure_uno_ioctl(struct ifnet *, u_long, void *);
+static void	ure_uno_mcast(struct ifnet *);
 static int	ure_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *);
 static int	ure_uno_mii_write_reg(struct usbnet *, int, int, uint16_t);
 static void	ure_uno_miibus_statchg(struct ifnet *);
@@ -104,7 +104,7 @@ CFATTACH_DECL_NEW(ure, sizeof(struct usb
 
 static const struct usbnet_ops ure_ops = {
 	.uno_stop = ure_uno_stop,
-	.uno_ioctl = ure_uno_ioctl,
+	.uno_mcast = ure_uno_mcast,
 	.uno_read_reg = ure_uno_mii_read_reg,
 	.uno_write_reg = ure_uno_mii_write_reg,
 	.uno_statchg = ure_uno_miibus_statchg,
@@ -802,27 +802,18 @@ ure_init_fifo(struct usbnet *un)
 	    URE_TXFIFO_THR_NORMAL);
 }
 
-static int
-ure_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
+static void
+ure_uno_mcast(struct ifnet *ifp)
 {
 	struct usbnet * const un = ifp->if_softc;
 
 	usbnet_lock_core(un);
 	usbnet_busy(un);
 
-	switch (cmd) {
-	case SIOCADDMULTI:
-	case SIOCDELMULTI:
-		ure_rcvfilt_locked(un);
-		break;
-	default:
-		break;
-	}
+	ure_rcvfilt_locked(un);
 
 	usbnet_unbusy(un);
 	usbnet_unlock_core(un);
-
-	return 0;
 }
 
 static int

Index: src/sys/dev/usb/usbnet.c
diff -u src/sys/dev/usb/usbnet.c:1.74 src/sys/dev/usb/usbnet.c:1.75
--- src/sys/dev/usb/usbnet.c:1.74	Thu Mar  3 05:50:47 2022
+++ src/sys/dev/usb/usbnet.c	Thu Mar  3 05:51:06 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbnet.c,v 1.74 2022/03/03 05:50:47 riastradh Exp $	*/
+/*	$NetBSD: usbnet.c,v 1.75 2022/03/03 05:51:06 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2019 Matthew R. Green
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.74 2022/03/03 05:50:47 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.75 2022/03/03 05:51:06 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -162,13 +162,9 @@ static int
 uno_ioctl(struct usbnet *un, struct ifnet *ifp, u_long cmd, void *data)
 {
 
-	switch (cmd) {
-	case SIOCADDMULTI:
-	case SIOCDELMULTI:
-		break;
-	default:
-		KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname);
-	}
+	KASSERTMSG(cmd != SIOCADDMULTI, "%s", ifp->if_xname);
+	KASSERTMSG(cmd != SIOCDELMULTI, "%s", ifp->if_xname);
+	KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname);
 
 	if (un->un_ops->uno_ioctl)
 		return (*un->un_ops->uno_ioctl)(ifp, cmd, data);
@@ -1076,7 +1072,6 @@ usbnet_mcast_task(void *arg)
 	USBNETHIST_FUNC();
 	struct usbnet * const un = arg;
 	struct ifnet * const ifp = usbnet_ifp(un);
-	struct ifreq ifr;
 
 	USBNETHIST_CALLARGSN(10, "%jd: enter",
 	    un->un_pri->unp_number, 0, 0, 0);
@@ -1094,16 +1089,15 @@ usbnet_mcast_task(void *arg)
 		return;
 
 	/*
-	 * Pass a bogus ifr with SIOCDELMULTI -- the goal is to just
-	 * notify the driver to reprogram any hardware multicast
-	 * filter, according to what's already stored in the ethercom.
-	 * None of the drivers actually examine this argument, so it
-	 * doesn't change the ABI as far as they can tell.
+	 * If the hardware is running, ask the driver to reprogram the
+	 * multicast filter.  If the hardware is not running, the
+	 * driver is responsible for programming the multicast filter
+	 * as part of its uno_init routine to bring the hardware up.
 	 */
 	IFNET_LOCK(ifp);
 	if (ifp->if_flags & IFF_RUNNING) {
-		memset(&ifr, 0, sizeof(ifr));
-		(void)uno_ioctl(un, ifp, SIOCDELMULTI, &ifr);
+		if (un->un_ops->uno_mcast)
+			(*un->un_ops->uno_mcast)(ifp);
 	}
 	IFNET_UNLOCK(ifp);
 }

Index: src/sys/dev/usb/usbnet.h
diff -u src/sys/dev/usb/usbnet.h:1.23 src/sys/dev/usb/usbnet.h:1.24
--- src/sys/dev/usb/usbnet.h:1.23	Thu Mar  3 05:48:14 2022
+++ src/sys/dev/usb/usbnet.h	Thu Mar  3 05:51:06 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbnet.h,v 1.23 2022/03/03 05:48:14 riastradh Exp $	*/
+/*	$NetBSD: usbnet.h,v 1.24 2022/03/03 05:51:06 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2019 Matthew R. Green
@@ -131,6 +131,8 @@ enum usbnet_ep {
 typedef void (*usbnet_stop_cb)(struct ifnet *, int);
 /* Interface ioctl callback. */
 typedef int (*usbnet_ioctl_cb)(struct ifnet *, u_long, void *);
+/* Reprogram multicast filters callback. */
+typedef void (*usbnet_mcast_cb)(struct ifnet *);
 /* Initialise device callback. */
 typedef int (*usbnet_init_cb)(struct ifnet *);
 
@@ -170,16 +172,20 @@ typedef void (*usbnet_intr_cb)(struct us
  * Note that when CORE_LOCK is held, IFNET_LOCK may or may not also
  * be held.
  *
- * Note that the IFNET_LOCK **may not be held** for some ioctl
- * operations (add/delete multicast addresses, for example).
+ * Note that the IFNET_LOCK **may not be held** for the ioctl commands
+ * SIOCADDMULTI/SIOCDELMULTI.  These commands are only passed
+ * explicitly to uno_override_ioctl; for all other devices, they are
+ * handled inside usbnet by scheduling a task to asynchronously call
+ * uno_mcast with IFNET_LOCK held.
  *
  * Busy reference counts are maintained across calls to: uno_stop,
  * uno_read_reg, uno_write_reg, uno_statchg, and uno_tick.
  */
 struct usbnet_ops {
 	usbnet_stop_cb		uno_stop;		/* C */
-	usbnet_ioctl_cb		uno_ioctl;		/* I (maybe) */
-	usbnet_ioctl_cb		uno_override_ioctl;	/* I (maybe) */
+	usbnet_ioctl_cb		uno_ioctl;		/* I */
+	usbnet_ioctl_cb		uno_override_ioctl;	/* I (except mcast) */
+	usbnet_mcast_cb		uno_mcast;		/* I */
 	usbnet_init_cb		uno_init;		/* I */
 	usbnet_mii_read_reg_cb	uno_read_reg;		/* C */
 	usbnet_mii_write_reg_cb uno_write_reg;		/* C */

Reply via email to