summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorriastradh <riastradh@NetBSD.org>2022-03-03 05:53:14 +0000
committerriastradh <riastradh@NetBSD.org>2022-03-03 05:53:14 +0000
commitc013c2df70dc7be60e8e3e2082e4418d2573efab (patch)
tree06d53aaeef721c2c7c8f77931cf4142c7de55d82 /sys/dev
parent284e8032487635f4c40af16e3bff1e84d64ce1a5 (diff)
usbnet drivers: Stop abusing ifp->if_flags & IFF_ALLMULTI.
This legacy flag is a figment of userland's imagination. The actual kernel state is ec->ec_flags & ETHER_F_ALLMULTI, protected by the ETHER_LOCK, so that multicast filter updates -- which run without IFNET_LOCK -- need not attempt to write racily to ifp->if_flags.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/if_aue.c16
-rw-r--r--sys/dev/usb/if_cue.c12
-rw-r--r--sys/dev/usb/if_kue.c12
-rw-r--r--sys/dev/usb/if_mue.c13
-rw-r--r--sys/dev/usb/if_smsc.c12
-rw-r--r--sys/dev/usb/if_udav.c16
6 files changed, 43 insertions, 38 deletions
diff --git a/sys/dev/usb/if_aue.c b/sys/dev/usb/if_aue.c
index 6506abf49bd..6c3c5501feb 100644
--- a/sys/dev/usb/if_aue.c
+++ b/sys/dev/usb/if_aue.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_aue.c,v 1.179 2022/03/03 05:53:04 riastradh Exp $ */
+/* $NetBSD: if_aue.c,v 1.180 2022/03/03 05:53:14 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.179 2022/03/03 05:53:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.180 2022/03/03 05:53:14 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -627,21 +627,20 @@ aue_uno_mcast(struct ifnet *ifp)
usbnet_isowned_core(un);
if (ifp->if_flags & IFF_PROMISC) {
+ ETHER_LOCK(ec);
allmulti:
- ifp->if_flags |= IFF_ALLMULTI;
+ ec->ec_flags |= ETHER_F_ALLMULTI;
+ ETHER_UNLOCK(ec);
AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
return;
}
- AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
-
/* now program new ones */
ETHER_LOCK(ec);
ETHER_FIRST_MULTI(step, ec, enm);
while (enm != NULL) {
if (memcmp(enm->enm_addrlo,
enm->enm_addrhi, ETHER_ADDR_LEN) != 0) {
- ETHER_UNLOCK(ec);
goto allmulti;
}
@@ -649,13 +648,14 @@ allmulti:
hashtbl[h >> 3] |= 1 << (h & 0x7);
ETHER_NEXT_MULTI(step, enm);
}
+ ec->ec_flags &= ~ETHER_F_ALLMULTI;
ETHER_UNLOCK(ec);
+ AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
+
/* write the hashtable */
for (i = 0; i < 8; i++)
aue_csr_write_1(sc, AUE_MAR0 + i, hashtbl[i]);
-
- ifp->if_flags &= ~IFF_ALLMULTI;
}
static void
diff --git a/sys/dev/usb/if_cue.c b/sys/dev/usb/if_cue.c
index 1e6c03292b6..24488eb0320 100644
--- a/sys/dev/usb/if_cue.c
+++ b/sys/dev/usb/if_cue.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_cue.c,v 1.99 2022/03/03 05:53:04 riastradh Exp $ */
+/* $NetBSD: if_cue.c,v 1.100 2022/03/03 05:53:14 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.99 2022/03/03 05:53:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_cue.c,v 1.100 2022/03/03 05:53:14 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -370,8 +370,10 @@ cue_uno_mcast(struct ifnet *ifp)
device_xname(un->un_dev), ifp->if_flags));
if (ifp->if_flags & IFF_PROMISC) {
+ ETHER_LOCK(ec);
allmulti:
- ifp->if_flags |= IFF_ALLMULTI;
+ ec->ec_flags |= ETHER_F_ALLMULTI;
+ ETHER_UNLOCK(ec);
for (i = 0; i < CUE_MCAST_TABLE_LEN; i++)
sc->cue_mctab[i] = 0xFF;
cue_mem(un, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,
@@ -389,7 +391,6 @@ allmulti:
while (enm != NULL) {
if (memcmp(enm->enm_addrlo,
enm->enm_addrhi, ETHER_ADDR_LEN) != 0) {
- ETHER_UNLOCK(ec);
goto allmulti;
}
@@ -397,10 +398,9 @@ allmulti:
sc->cue_mctab[h >> 3] |= 1 << (h & 0x7);
ETHER_NEXT_MULTI(step, enm);
}
+ ec->ec_flags &= ~ETHER_F_ALLMULTI;
ETHER_UNLOCK(ec);
- ifp->if_flags &= ~IFF_ALLMULTI;
-
/*
* Also include the broadcast address in the filter
* so we can receive broadcast frames.
diff --git a/sys/dev/usb/if_kue.c b/sys/dev/usb/if_kue.c
index 286c642015d..b7b745a33cc 100644
--- a/sys/dev/usb/if_kue.c
+++ b/sys/dev/usb/if_kue.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_kue.c,v 1.112 2022/03/03 05:53:04 riastradh Exp $ */
+/* $NetBSD: if_kue.c,v 1.113 2022/03/03 05:53:14 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.112 2022/03/03 05:53:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_kue.c,v 1.113 2022/03/03 05:53:14 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -336,8 +336,10 @@ kue_uno_mcast(struct ifnet *ifp)
sc->kue_rxfilt &= ~KUE_RXFILT_PROMISC;
if (ifp->if_flags & IFF_PROMISC) {
+ ETHER_LOCK(ec);
allmulti:
- ifp->if_flags |= IFF_ALLMULTI;
+ ec->ec_flags |= ETHER_F_ALLMULTI;
+ ETHER_UNLOCK(ec);
sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI|KUE_RXFILT_PROMISC;
sc->kue_rxfilt &= ~KUE_RXFILT_MULTICAST;
kue_setword(un, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
@@ -353,7 +355,6 @@ allmulti:
if (i == KUE_MCFILTCNT(sc) ||
memcmp(enm->enm_addrlo, enm->enm_addrhi,
ETHER_ADDR_LEN) != 0) {
- ETHER_UNLOCK(ec);
goto allmulti;
}
@@ -361,10 +362,9 @@ allmulti:
ETHER_NEXT_MULTI(step, enm);
i++;
}
+ ec->ec_flags &= ~ETHER_F_ALLMULTI;
ETHER_UNLOCK(ec);
- ifp->if_flags &= ~IFF_ALLMULTI;
-
sc->kue_rxfilt |= KUE_RXFILT_MULTICAST;
kue_ctl(un, KUE_CTL_WRITE, KUE_CMD_SET_MCAST_FILTERS,
i, sc->kue_mcfilters, i * ETHER_ADDR_LEN);
diff --git a/sys/dev/usb/if_mue.c b/sys/dev/usb/if_mue.c
index fac8d60d336..54d16b06501 100644
--- a/sys/dev/usb/if_mue.c
+++ b/sys/dev/usb/if_mue.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_mue.c,v 1.72 2022/03/03 05:53:04 riastradh Exp $ */
+/* $NetBSD: if_mue.c,v 1.73 2022/03/03 05:53:14 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.72 2022/03/03 05:53:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_mue.c,v 1.73 2022/03/03 05:53:14 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -1023,10 +1023,11 @@ mue_uno_mcast(struct ifnet *ifp)
/* Always accept broadcast frames. */
rxfilt |= MUE_RFE_CTL_BROADCAST;
+ ETHER_LOCK(ec);
if (ifp->if_flags & IFF_PROMISC) {
rxfilt |= MUE_RFE_CTL_UNICAST;
allmulti: rxfilt |= MUE_RFE_CTL_MULTICAST;
- ifp->if_flags |= IFF_ALLMULTI;
+ ec->ec_flags |= ETHER_F_ALLMULTI;
if (ifp->if_flags & IFF_PROMISC)
DPRINTF(un, "promisc\n");
else
@@ -1036,7 +1037,6 @@ allmulti: rxfilt |= MUE_RFE_CTL_MULTICAST;
pfiltbl[0][0] = MUE_ENADDR_HI(enaddr) | MUE_ADDR_FILTX_VALID;
pfiltbl[0][1] = MUE_ENADDR_LO(enaddr);
i = 1;
- ETHER_LOCK(ec);
ETHER_FIRST_MULTI(step, ec, enm);
while (enm != NULL) {
if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
@@ -1044,7 +1044,6 @@ allmulti: rxfilt |= MUE_RFE_CTL_MULTICAST;
memset(pfiltbl, 0, sizeof(pfiltbl));
memset(hashtbl, 0, sizeof(hashtbl));
rxfilt &= ~MUE_RFE_CTL_MULTICAST_HASH;
- ETHER_UNLOCK(ec);
goto allmulti;
}
if (i < MUE_NUM_ADDR_FILTX) {
@@ -1062,14 +1061,14 @@ allmulti: rxfilt |= MUE_RFE_CTL_MULTICAST;
i++;
ETHER_NEXT_MULTI(step, enm);
}
- ETHER_UNLOCK(ec);
+ ec->ec_flags &= ~ETHER_F_ALLMULTI;
rxfilt |= MUE_RFE_CTL_PERFECT;
- ifp->if_flags &= ~IFF_ALLMULTI;
if (rxfilt & MUE_RFE_CTL_MULTICAST_HASH)
DPRINTF(un, "perfect filter and hash tables\n");
else
DPRINTF(un, "perfect filter\n");
}
+ ETHER_UNLOCK(ec);
for (i = 0; i < MUE_NUM_ADDR_FILTX; i++) {
hireg = (un->un_flags & LAN7500) ?
diff --git a/sys/dev/usb/if_smsc.c b/sys/dev/usb/if_smsc.c
index fb03ad1d46f..43e03491b6f 100644
--- a/sys/dev/usb/if_smsc.c
+++ b/sys/dev/usb/if_smsc.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_smsc.c,v 1.81 2022/03/03 05:53:04 riastradh Exp $ */
+/* $NetBSD: if_smsc.c,v 1.82 2022/03/03 05:53:14 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.81 2022/03/03 05:53:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_smsc.c,v 1.82 2022/03/03 05:53:14 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -427,8 +427,11 @@ smsc_uno_mcast(struct ifnet *ifp)
if (usbnet_isdying(un))
return;
- if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) {
+ if (ifp->if_flags & IFF_PROMISC) {
+ ETHER_LOCK(ec);
allmulti:
+ ec->ec_flags |= ETHER_F_ALLMULTI;
+ ETHER_UNLOCK(ec);
DPRINTF("receive all multicast enabled", 0, 0, 0, 0);
sc->sc_mac_csr |= SMSC_MAC_CSR_MCPAS;
sc->sc_mac_csr &= ~SMSC_MAC_CSR_HPFILT;
@@ -443,7 +446,6 @@ allmulti:
ETHER_FIRST_MULTI(step, ec, enm);
while (enm != NULL) {
if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
- ETHER_UNLOCK(ec);
goto allmulti;
}
@@ -451,6 +453,7 @@ allmulti:
hashtbl[hash >> 5] |= 1 << (hash & 0x1F);
ETHER_NEXT_MULTI(step, enm);
}
+ ec->ec_flags &= ~ETHER_F_ALLMULTI;
ETHER_UNLOCK(ec);
/* Debug */
@@ -463,7 +466,6 @@ allmulti:
/* Write the hash table and mac control registers */
//XXX should we be doing this?
- ifp->if_flags &= ~IFF_ALLMULTI;
smsc_writereg(un, SMSC_HASHH, hashtbl[1]);
smsc_writereg(un, SMSC_HASHL, hashtbl[0]);
smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr);
diff --git a/sys/dev/usb/if_udav.c b/sys/dev/usb/if_udav.c
index 3b7c0ac5176..aed305f83f4 100644
--- a/sys/dev/usb/if_udav.c
+++ b/sys/dev/usb/if_udav.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_udav.c,v 1.86 2022/03/03 05:53:04 riastradh Exp $ */
+/* $NetBSD: if_udav.c,v 1.87 2022/03/03 05:53:14 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.86 2022/03/03 05:53:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.87 2022/03/03 05:53:14 riastradh Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -598,11 +598,16 @@ udav_uno_mcast(struct ifnet *ifp)
}
if (ifp->if_flags & IFF_PROMISC) {
+ ETHER_LOCK(ec);
+ ec->ec_flags |= ETHER_F_ALLMULTI;
+ ETHER_UNLOCK(ec);
UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC);
return;
- } else if (ifp->if_flags & IFF_ALLMULTI) {
+ } else if (ifp->if_flags & IFF_ALLMULTI) { /* XXX ??? Can't happen? */
+ ETHER_LOCK(ec);
allmulti:
- ifp->if_flags |= IFF_ALLMULTI;
+ ec->ec_flags |= ETHER_F_ALLMULTI;
+ ETHER_UNLOCK(ec);
UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL);
UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_PRMSC);
return;
@@ -619,7 +624,6 @@ allmulti:
while (enm != NULL) {
if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
ETHER_ADDR_LEN) != 0) {
- ETHER_UNLOCK(ec);
goto allmulti;
}
@@ -627,10 +631,10 @@ allmulti:
hashes[h>>3] |= 1 << (h & 0x7);
ETHER_NEXT_MULTI(step, enm);
}
+ ec->ec_flags &= ~ETHER_F_ALLMULTI;
ETHER_UNLOCK(ec);
/* disable all multicast */
- ifp->if_flags &= ~IFF_ALLMULTI;
UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_ALL);
/* write hash value to the register */