Define and implement a locking protocol for the ifmedia / mii layers:

- MP-safe drivers provide a mutex to ifmedia that is used to serialize
  access to media-related structures / hardware regsiters.  Converted
  drivers use the new ifmedia_init_with_lock() function for this.  The
  new name is provided to ease the transition.
- Un-converted drivers continue to call ifmedia_init(), which will supply
  a compatibility lock to be used instead.  Several media-related entry
  points must be aware of this compatibility lock, and are able to acquire
  it recursively a limited number of times, if needed.  This is a SPIN
  mutex with priority IPL_NET.
- This same lock is used to serialize access to PHY registers and other
  MII-related data structures.

The PHY drivers are modified to acquire and release the lock, as needed,
and assert the lock is held as a diagnostic aid.

The "usbnet" framework has had an overhaul of its internal locking
protocols to fit in with the media / mii changes, and the drivers adapted.

USB wifi drivers have been changed to provide their own adaptive mutex
to the ifmedia later via a new ieee80211_media_init_with_lock() function.
This is required because the USB drivers need an adaptive mutex.

Besised "usbnet", a few other drivers are converted: vmx, wm, ixgbe / ixv.

mcx also now calls ifmedia_init_with_lock() because it needs to also use
an adaptive mutex.  The mcx driver still needs to be fully converted to
NET_MPSAFE.
This commit is contained in:
thorpej 2020-03-15 23:04:50 +00:00
parent e1ecc07c09
commit 7a9a30c5e7
86 changed files with 1930 additions and 1153 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: gxlphy.c,v 1.2 2019/11/27 10:19:21 msaitoh Exp $ */
/* $NetBSD: gxlphy.c,v 1.3 2020/03/15 23:04:50 thorpej Exp $ */
/*
* Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca>
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: gxlphy.c,v 1.2 2019/11/27 10:19:21 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: gxlphy.c,v 1.3 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -169,6 +169,8 @@ gxlphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
gxl_writereg(sc, BANK_BIST, BIST_PLL_CTRL, 0x5);
@ -180,6 +182,8 @@ gxlphyattach(device_t parent, device_t self, void *aux)
if (sc->mii_capabilities & BMSR_EXTSTAT)
PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -189,6 +193,8 @@ gxlphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -241,6 +247,8 @@ gxlphy_status(struct mii_softc *sc)
{
uint16_t bmcr, bmsr, wol, lpa, aner;
KASSERT(mii_locked(sc->mii_pdata));
PHY_READ(sc, MII_BMCR, &bmcr);
if ((bmcr & BMCR_AUTOEN) == 0)
goto done;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_vmx.c,v 1.57 2020/02/02 05:27:21 thorpej Exp $ */
/* $NetBSD: if_vmx.c,v 1.58 2020/03/15 23:04:50 thorpej Exp $ */
/* $OpenBSD: if_vmx.c,v 1.16 2014/01/22 06:04:17 brad Exp $ */
/*
@ -19,7 +19,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_vmx.c,v 1.57 2020/02/02 05:27:21 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_vmx.c,v 1.58 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/cpu.h>
@ -1857,8 +1857,8 @@ vmxnet3_setup_interface(struct vmxnet3_softc *sc)
/* Initialize ifmedia structures. */
sc->vmx_ethercom.ec_ifmedia = &sc->vmx_media;
ifmedia_init(&sc->vmx_media, IFM_IMASK, vmxnet3_media_change,
vmxnet3_media_status);
ifmedia_init_with_lock(&sc->vmx_media, IFM_IMASK, vmxnet3_media_change,
vmxnet3_media_status, sc->vmx_mtx);
ifmedia_add(&sc->vmx_media, IFM_ETHER | IFM_AUTO, 0, NULL);
ifmedia_add(&sc->vmx_media, IFM_ETHER | IFM_10G_T | IFM_FDX, 0, NULL);
ifmedia_add(&sc->vmx_media, IFM_ETHER | IFM_10G_T, 0, NULL);
@ -3511,17 +3511,13 @@ vmxnet3_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
ifmr->ifm_status = IFM_AVALID;
ifmr->ifm_active = IFM_ETHER;
VMXNET3_CORE_LOCK(sc);
if (ifp->if_link_state != LINK_STATE_UP) {
VMXNET3_CORE_UNLOCK(sc);
if (ifp->if_link_state != LINK_STATE_UP)
return;
}
ifmr->ifm_status |= IFM_ACTIVE;
if (ifp->if_baudrate >= IF_Gbps(10ULL))
ifmr->ifm_active |= IFM_10G_T;
VMXNET3_CORE_UNLOCK(sc);
}
static int

View File

@ -1,4 +1,4 @@
/* $NetBSD: acphy.c,v 1.29 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: acphy.c,v 1.30 2020/03/15 23:04:50 thorpej Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: acphy.c,v 1.29 2019/11/27 10:19:20 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: acphy.c,v 1.30 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -111,17 +111,23 @@ acphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
/* XXX Check MCR_FX_SEL to set MIIF_HAVE_FIBER? */
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
aprint_normal_dev(sc->mii_dev, "");
mii_unlock(mii);
#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
if (sc->mii_flags & MIIF_HAVEFIBER) {
aprint_normal_dev(sc->mii_dev, "");
mii_lock(mii);
sc->mii_anegticks = MII_ANEGTICKS;
mii_unlock(mii);
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_FX, 0, sc->mii_inst),
MII_MEDIA_100_TX);
aprint_normal("100baseFX, ");
@ -140,6 +146,8 @@ acphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -194,6 +202,8 @@ acphy_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmsr, bmcr, dr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;

View File

@ -1,4 +1,4 @@
/* $NetBSD: amhphy.c,v 1.25 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: amhphy.c,v 1.26 2020/03/15 23:04:50 thorpej Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: amhphy.c,v 1.25 2019/11/27 10:19:20 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: amhphy.c,v 1.26 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -106,11 +106,15 @@ amhphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -120,6 +124,8 @@ amhphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -174,6 +180,8 @@ amhphy_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmsr, bmcr, ssr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;

View File

@ -1,4 +1,4 @@
/* $NetBSD: atphy.c,v 1.29 2020/03/13 18:57:49 msaitoh Exp $ */
/* $NetBSD: atphy.c,v 1.30 2020/03/15 23:04:50 thorpej Exp $ */
/* $OpenBSD: atphy.c,v 1.1 2008/09/25 20:47:16 brad Exp $ */
/*-
@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: atphy.c,v 1.29 2020/03/13 18:57:49 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: atphy.c,v 1.30 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -200,6 +200,8 @@ atphy_attach(device_t parent, device_t self, void *aux)
if (asc->mii_clk_25m != 0)
atphy_clk_25m(asc);
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &bmsr);
@ -208,6 +210,8 @@ atphy_attach(device_t parent, device_t self, void *aux)
if (atphy_is_gige(mpd) && (sc->mii_capabilities & BMSR_EXTSTAT))
PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -217,6 +221,8 @@ atphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t anar, bmcr, bmsr;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -338,6 +344,8 @@ atphy_status(struct mii_softc *sc)
struct mii_data *mii = sc->mii_pdata;
uint16_t bmsr, bmcr, gsr, ssr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -404,6 +412,8 @@ atphy_reset(struct mii_softc *sc)
uint16_t reg;
int i;
KASSERT(mii_locked(sc->mii_pdata));
/*
* Take PHY out of power down mode.
*
@ -468,6 +478,8 @@ atphy_mii_phy_auto(struct mii_softc *sc)
{
uint16_t anar;
KASSERT(mii_locked(sc->mii_pdata));
sc->mii_ticks = 0;
anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA;
if (sc->mii_flags & MIIF_DOPAUSE)

View File

@ -1,4 +1,4 @@
/* $NetBSD: bmtphy.c,v 1.36 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: bmtphy.c,v 1.37 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: bmtphy.c,v 1.36 2019/11/27 10:19:20 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: bmtphy.c,v 1.37 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -135,6 +135,8 @@ bmtphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
/* XXX Check AUX_STS_FX_MODE to set MIIF_HAVE_FIBER? */
@ -142,6 +144,8 @@ bmtphyattach(device_t parent, device_t self, void *aux)
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -151,6 +155,8 @@ bmtphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -205,6 +211,8 @@ bmtphy_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmsr, bmcr, aux_csr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -256,6 +264,8 @@ bmtphy_reset(struct mii_softc *sc)
{
uint16_t data;
KASSERT(mii_locked(sc->mii_pdata));
mii_phy_reset(sc);
if (sc->mii_mpd_model == MII_MODEL_xxBROADCOM_BCM5221) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: brgphy.c,v 1.87 2020/02/22 18:57:31 jmcneill Exp $ */
/* $NetBSD: brgphy.c,v 1.88 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: brgphy.c,v 1.87 2020/02/22 18:57:31 jmcneill Exp $");
__KERNEL_RCSID(0, "$NetBSD: brgphy.c,v 1.88 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -264,6 +264,8 @@ brgphyattach(device_t parent, device_t self, void *aux)
} else
sc->mii_funcs = &brgphy_copper_funcs;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
@ -271,7 +273,10 @@ brgphyattach(device_t parent, device_t self, void *aux)
if (sc->mii_capabilities & BMSR_EXTSTAT)
PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
mii_unlock(mii);
if (sc->mii_flags & MIIF_HAVEFIBER) {
mii_lock(mii);
sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOLOOP;
/*
@ -281,6 +286,7 @@ brgphyattach(device_t parent, device_t self, void *aux)
sc->mii_capabilities |= BMSR_ANEG;
sc->mii_capabilities &= ~BMSR_100T4;
sc->mii_extcapabilities |= EXTSR_1000XFDX;
mii_unlock(mii);
if (bsc->sc_isbnx) {
/*
@ -306,6 +312,8 @@ brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg, speed, gig;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -468,6 +476,8 @@ brgphy_copper_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmcr, bmsr, auxsts, gtsr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -553,6 +563,8 @@ brgphy_fiber_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmcr, bmsr, anar, anlpar, result;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -596,6 +608,8 @@ brgphy_5708s_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmcr, bmsr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -665,6 +679,8 @@ brgphy_5709s_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmcr, bmsr, auxsts;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -731,11 +747,13 @@ brgphy_5709s_status(struct mii_softc *sc)
mii->mii_media_active = ife->ifm_media;
}
int
static int
brgphy_mii_phy_auto(struct mii_softc *sc)
{
uint16_t anar, ktcr = 0;
KASSERT(mii_locked(sc->mii_pdata));
sc->mii_ticks = 0;
brgphy_loop(sc);
PHY_RESET(sc);
@ -763,12 +781,14 @@ brgphy_mii_phy_auto(struct mii_softc *sc)
return EJUSTRETURN;
}
void
static void
brgphy_loop(struct mii_softc *sc)
{
uint16_t bmsr;
int i;
KASSERT(mii_locked(sc->mii_pdata));
PHY_WRITE(sc, MII_BMCR, BMCR_LOOP);
for (i = 0; i < 15000; i++) {
PHY_READ(sc, MII_BMSR, &bmsr);
@ -784,6 +804,8 @@ brgphy_reset(struct mii_softc *sc)
struct brgphy_softc *bsc = device_private(sc->mii_dev);
uint16_t reg;
KASSERT(mii_locked(sc->mii_pdata));
mii_phy_reset(sc);
switch (sc->mii_mpd_oui) {
case MII_OUI_BROADCOM:
@ -1061,7 +1083,7 @@ brgphy_bcm5411_dspcode(struct mii_softc *sc)
PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val);
}
void
static void
brgphy_bcm5421_dspcode(struct mii_softc *sc)
{
uint16_t data;
@ -1080,7 +1102,7 @@ brgphy_bcm5421_dspcode(struct mii_softc *sc)
PHY_WRITE(sc, BRGPHY_MII_DSP_RW_PORT, data | 0x0200);
}
void
static void
brgphy_bcm54k2_dspcode(struct mii_softc *sc)
{
static const struct {
@ -1159,7 +1181,7 @@ brgphy_ber_bug(struct mii_softc *sc)
}
/* BCM5701 A0/B0 CRC bug workaround */
void
static void
brgphy_crc_bug(struct mii_softc *sc)
{
static const struct {

View File

@ -1,4 +1,4 @@
/* $NetBSD: ciphy.c,v 1.38 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: ciphy.c,v 1.39 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 2004
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ciphy.c,v 1.38 2019/11/27 10:19:20 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: ciphy.c,v 1.39 2020/03/15 23:04:50 thorpej Exp $");
/*
* Driver for the Cicada CS8201 10/100/1000 copper PHY.
@ -119,6 +119,8 @@ ciphyattach(device_t parent, device_t self, void *aux)
sc->mii_flags = ma->mii_flags;
sc->mii_flags |= MIIF_NOISOLATE;
mii_lock(mii);
ciphy_reset(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
@ -126,6 +128,8 @@ ciphyattach(device_t parent, device_t self, void *aux)
if (sc->mii_capabilities & BMSR_EXTSTAT)
PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -135,6 +139,8 @@ ciphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg, speed, gig;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -293,6 +299,8 @@ ciphy_status(struct mii_softc *sc)
struct mii_data *mii = sc->mii_pdata;
uint16_t bmsr, bmcr, gtsr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -348,6 +356,8 @@ static void
ciphy_reset(struct mii_softc *sc)
{
KASSERT(mii_locked(sc->mii_pdata));
mii_phy_reset(sc);
DELAY(1000);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: dmphy.c,v 1.46 2020/02/14 14:17:42 nisimura Exp $ */
/* $NetBSD: dmphy.c,v 1.47 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: dmphy.c,v 1.46 2020/02/14 14:17:42 nisimura Exp $");
__KERNEL_RCSID(0, "$NetBSD: dmphy.c,v 1.47 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -132,11 +132,15 @@ dmphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -146,6 +150,8 @@ dmphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -200,6 +206,8 @@ dmphy_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmsr, bmcr, dscsr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;

View File

@ -1,4 +1,4 @@
/* $NetBSD: etphy.c,v 1.8 2020/02/28 05:13:19 msaitoh Exp $ */
/* $NetBSD: etphy.c,v 1.9 2020/03/15 23:04:50 thorpej Exp $ */
/* $OpenBSD: etphy.c,v 1.4 2008/04/02 20:12:58 brad Exp $ */
/*
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: etphy.c,v 1.8 2020/02/28 05:13:19 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: etphy.c,v 1.9 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -166,6 +166,8 @@ etphy_attach(device_t parent, device_t self, void *aux)
sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOLOOP;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
@ -176,6 +178,8 @@ etphy_attach(device_t parent, device_t self, void *aux)
sc->mii_extcapabilities &= ~EXTSR_1000THDX;
}
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -185,6 +189,8 @@ etphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmcr;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -258,6 +264,8 @@ etphy_reset(struct mii_softc *sc)
uint16_t reg;
int i;
KASSERT(mii_locked(sc->mii_pdata));
if (sc->mii_mpd_model == MII_MODEL_AGERE_ET1011) {
mii_phy_reset(sc);
return;
@ -310,6 +318,8 @@ etphy_status(struct mii_softc *sc)
struct mii_data *mii = sc->mii_pdata;
uint16_t bmsr, bmcr, sr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;

View File

@ -1,4 +1,4 @@
/* $NetBSD: exphy.c,v 1.57 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: exphy.c,v 1.58 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@ -59,7 +59,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: exphy.c,v 1.57 2019/11/27 10:19:20 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: exphy.c,v 1.58 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -136,11 +136,15 @@ exphyattach(device_t parent, device_t self, void *aux)
}
sc->mii_flags |= MIIF_NOISOLATE;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -153,6 +157,8 @@ exphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
if (IFM_INST(ife->ifm_media) != sc->mii_inst)
panic("exphy_service: can't isolate 3Com PHY");
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
break;
@ -191,6 +197,8 @@ static void
exphy_reset(struct mii_softc *sc)
{
KASSERT(mii_locked(sc->mii_pdata));
mii_phy_reset(sc);
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: gentbi.c,v 1.30 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: gentbi.c,v 1.31 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: gentbi.c,v 1.30 2019/11/27 10:19:20 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: gentbi.c,v 1.31 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -105,14 +105,20 @@ gentbimatch(device_t parent, cfdata_t match, void *aux)
* - There is no media in the BMSR.
* - EXTSR has only 1000X.
*/
mii_lock(mii);
rv = (*mii->mii_readreg)(parent, ma->mii_phyno, MII_BMSR, &bmsr);
if ((rv != 0)
|| (bmsr & BMSR_EXTSTAT) == 0 || (bmsr & BMSR_MEDIAMASK) != 0)
|| (bmsr & BMSR_EXTSTAT) == 0 || (bmsr & BMSR_MEDIAMASK) != 0) {
mii_unlock(mii);
return 0;
}
rv = (*mii->mii_readreg)(parent, ma->mii_phyno, MII_EXTSR, &extsr);
if ((rv != 0) || ((extsr & (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0))
if ((rv != 0) || ((extsr & (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0)) {
mii_unlock(mii);
return 0;
}
mii_unlock(mii);
if (extsr & (EXTSR_1000XFDX | EXTSR_1000XHDX)) {
/*
@ -156,6 +162,8 @@ gentbiattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
/*
@ -168,6 +176,8 @@ gentbiattach(device_t parent, device_t self, void *aux)
if (sc->mii_capabilities & BMSR_EXTSTAT)
PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -177,6 +187,8 @@ gentbi_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -231,6 +243,8 @@ gentbi_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmsr, bmcr, anlpar;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;

View File

@ -1,4 +1,4 @@
/* $NetBSD: glxtphy.c,v 1.31 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: glxtphy.c,v 1.32 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -59,7 +59,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: glxtphy.c,v 1.31 2019/11/27 10:19:20 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: glxtphy.c,v 1.32 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -126,6 +126,8 @@ glxtphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
@ -133,6 +135,8 @@ glxtphyattach(device_t parent, device_t self, void *aux)
if (sc->mii_capabilities & BMSR_EXTSTAT)
PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -142,6 +146,8 @@ glxtphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -196,6 +202,8 @@ glxtphy_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmcr, qsr, gtsr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;

View File

@ -1,4 +1,4 @@
/* $NetBSD: gphyter.c,v 1.36 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: gphyter.c,v 1.37 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: gphyter.c,v 1.36 2019/11/27 10:19:20 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: gphyter.c,v 1.37 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -136,6 +136,8 @@ gphyterattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
@ -155,9 +157,13 @@ gphyterattach(device_t parent, device_t self, void *aux)
if (anar & ANAR_10_FD)
sc->mii_capabilities |= (BMSR_10TFDX & ma->mii_capmask);
mii_unlock(mii);
mii_phy_add_media(sc);
mii_lock(mii);
PHY_READ(sc, MII_GPHYTER_STRAP, &strap);
mii_unlock(mii);
aprint_normal_dev(self, "strapped to %s mode",
(strap & STRAP_MS_VAL) ? "master" : "slave");
if (strap & STRAP_NC_MODE)
@ -171,6 +177,8 @@ gphyter_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -225,6 +233,8 @@ gphyter_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmsr, bmcr, physup, gtsr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -292,6 +302,8 @@ gphyter_reset(struct mii_softc *sc)
int i;
uint16_t reg;
KASSERT(mii_locked(sc->mii_pdata));
if (sc->mii_flags & MIIF_NOISOLATE)
reg = BMCR_RESET;
else

View File

@ -1,4 +1,4 @@
/* $NetBSD: icsphy.c,v 1.55 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: icsphy.c,v 1.56 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: icsphy.c,v 1.55 2019/11/27 10:19:20 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: icsphy.c,v 1.56 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -131,11 +131,15 @@ icsphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -145,6 +149,8 @@ icsphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -199,6 +205,8 @@ icsphy_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmcr, qpr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -246,6 +254,8 @@ static void
icsphy_reset(struct mii_softc *sc)
{
KASSERT(mii_locked(sc->mii_pdata));
mii_phy_reset(sc);
/* Set powerdown feature */
switch (sc->mii_mpd_model) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: igphy.c,v 1.32 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: igphy.c,v 1.33 2020/03/15 23:04:50 thorpej Exp $ */
/*
* The Intel copyright applies to the analog register setup, and the
@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: igphy.c,v 1.32 2019/11/27 10:19:20 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: igphy.c,v 1.33 2020/03/15 23:04:50 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_mii.h"
@ -158,6 +158,8 @@ igphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
@ -165,6 +167,8 @@ igphyattach(device_t parent, device_t self, void *aux)
if (sc->mii_capabilities & BMSR_EXTSTAT)
PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -297,6 +301,8 @@ igphy_reset(struct mii_softc *sc)
struct igphy_softc *igsc = (struct igphy_softc *)sc;
uint16_t fused, fine, coarse;
KASSERT(mii_locked(sc->mii_pdata));
mii_phy_reset(sc);
delay(150);
@ -349,6 +355,8 @@ igphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -416,6 +424,8 @@ igphy_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmcr, pssr, gtsr, bmsr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ihphy.c,v 1.16 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: ihphy.c,v 1.17 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ihphy.c,v 1.16 2019/11/27 10:19:20 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: ihphy.c,v 1.17 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -136,6 +136,8 @@ ihphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
@ -143,13 +145,17 @@ ihphyattach(device_t parent, device_t self, void *aux)
if (sc->mii_capabilities & BMSR_EXTSTAT)
PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
mii_unlock(mii);
mii_phy_add_media(sc);
mii_lock(mii);
/* Link setup (as done by Intel's Linux driver for the 82577). */
PHY_READ(sc, IHPHY_MII_CFG, &reg);
reg |= IHPHY_CFG_TX_CRS;
reg |= IHPHY_CFG_DOWN_SHIFT;
PHY_WRITE(sc, IHPHY_MII_CFG, reg);
mii_unlock(mii);
}
static int
@ -158,6 +164,8 @@ ihphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -222,6 +230,8 @@ ihphy_status(struct mii_softc *sc)
struct mii_data *mii = sc->mii_pdata;
uint16_t esr, bmcr, gtsr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -283,6 +293,8 @@ ihphy_reset(struct mii_softc *sc)
int i;
uint16_t reg;
KASSERT(mii_locked(sc->mii_pdata));
PHY_WRITE(sc, MII_BMCR, BMCR_RESET | BMCR_ISO);
/* Wait another 100ms for it to complete. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ikphy.c,v 1.18 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: ikphy.c,v 1.19 2020/03/15 23:04:50 thorpej Exp $ */
/*******************************************************************************
Copyright (c) 2001-2005, Intel Corporation
@ -59,7 +59,7 @@ POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ikphy.c,v 1.18 2019/11/27 10:19:20 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: ikphy.c,v 1.19 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -129,6 +129,8 @@ ikphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
@ -136,6 +138,8 @@ ikphyattach(device_t parent, device_t self, void *aux)
if (sc->mii_capabilities & BMSR_EXTSTAT)
PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -145,6 +149,8 @@ ikphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -199,6 +205,8 @@ ikphy_setmedia(struct mii_softc *sc)
struct mii_data *mii = sc->mii_pdata;
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
KASSERT(mii_locked(mii));
/* Enable CRS on TX for half-duplex operation. */
PHY_READ(sc, GG82563_PHY_MAC_SPEC_CTRL, &phy_data);
phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
@ -276,6 +284,8 @@ ikphy_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t pssr, bmcr, gtsr, kmrn;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;

View File

@ -1,4 +1,4 @@
/* $NetBSD: inphy.c,v 1.59 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: inphy.c,v 1.60 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: inphy.c,v 1.59 2019/11/27 10:19:20 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: inphy.c,v 1.60 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -133,11 +133,15 @@ inphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -147,6 +151,8 @@ inphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -201,6 +207,8 @@ inphy_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmsr, bmcr, scr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;

View File

@ -1,4 +1,4 @@
/* $NetBSD: iophy.c,v 1.42 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: iophy.c,v 1.43 2020/03/15 23:04:50 thorpej Exp $ */
/*
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@ -59,7 +59,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: iophy.c,v 1.42 2019/11/27 10:19:20 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: iophy.c,v 1.43 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -125,11 +125,15 @@ iophyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -139,6 +143,8 @@ iophy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -193,6 +199,8 @@ iophy_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmsr, bmcr, ext0;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ipgphy.c,v 1.9 2020/01/14 09:49:26 msaitoh Exp $ */
/* $NetBSD: ipgphy.c,v 1.10 2020/03/15 23:04:50 thorpej Exp $ */
/* $OpenBSD: ipgphy.c,v 1.19 2015/07/19 06:28:12 yuo Exp $ */
/*-
@ -33,7 +33,7 @@
* Driver for the IC Plus IP1000A/IP1001 10/100/1000 PHY.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ipgphy.c,v 1.9 2020/01/14 09:49:26 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: ipgphy.c,v 1.10 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -121,6 +121,8 @@ ipgphy_attach(device_t parent, device_t self, void *aux)
&isc->need_loaddspcode);
}
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
@ -129,6 +131,8 @@ ipgphy_attach(device_t parent, device_t self, void *aux)
if (sc->mii_capabilities & BMSR_EXTSTAT)
PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -138,6 +142,8 @@ ipgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg, speed;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -254,6 +260,8 @@ ipgphy_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmsr, bmcr, stat, gtsr;
KASSERT(mii_locked(mii));
/* For IP1000A, use generic way */
if (sc->mii_mpd_model == MII_MODEL_xxICPLUS_IP1000A) {
ukphy_status(sc);
@ -318,6 +326,8 @@ ipgphy_mii_phy_auto(struct mii_softc *sc, u_int media)
uint16_t reg = 0;
u_int subtype = IFM_SUBTYPE(media);
KASSERT(mii_locked(sc->mii_pdata));
/* XXX Is it requreid ? */
if (sc->mii_mpd_model == MII_MODEL_xxICPLUS_IP1001) {
PHY_READ(sc, MII_ANAR, &reg);
@ -371,6 +381,8 @@ ipgphy_reset(struct mii_softc *sc)
struct ipgphy_softc *isc = device_private(sc->mii_dev);
uint16_t reg;
KASSERT(mii_locked(sc->mii_pdata));
mii_phy_reset(sc);
/* Clear autoneg/full-duplex as we don't want it after reset */

View File

@ -1,4 +1,4 @@
/* $NetBSD: jmphy.c,v 1.3 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: jmphy.c,v 1.4 2020/03/15 23:04:50 thorpej Exp $ */
/* $OpenBSD: jmphy.c,v 1.6 2015/03/14 03:38:48 jsg Exp $ */
/*-
* Copyright (c) 2008, Pyun YongHyeon <yongari@FreeBSD.org>
@ -103,6 +103,8 @@ jmphy_attach(device_t parent, device_t self, void *aux)
sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOLOOP;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
@ -110,6 +112,8 @@ jmphy_attach(device_t parent, device_t self, void *aux)
if (sc->mii_capabilities & BMSR_EXTSTAT)
PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -119,6 +123,8 @@ jmphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmcr, ssr;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -190,6 +196,8 @@ jmphy_status(struct mii_softc *sc)
struct mii_data *mii = sc->mii_pdata;
uint16_t bmcr, ssr, gtsr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -254,6 +262,8 @@ jmphy_reset(struct mii_softc *sc)
int i;
uint16_t val;
KASSERT(mii_locked(sc->mii_pdata));
/* Disable sleep mode. */
PHY_READ(sc, JMPHY_TMCTL, &val);
PHY_WRITE(sc, JMPHY_TMCTL, val & ~JMPHY_TMCTL_SLEEP_ENB);
@ -299,6 +309,8 @@ jmphy_auto(struct mii_softc *sc, struct ifmedia_entry *ife)
{
uint16_t anar, bmcr, gig;
KASSERT(mii_locked(sc->mii_pdata));
gig = 0;
PHY_READ(sc, MII_BMCR, &bmcr);
switch (IFM_SUBTYPE(ife->ifm_media)) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: lxtphy.c,v 1.54 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: lxtphy.c,v 1.55 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: lxtphy.c,v 1.54 2019/11/27 10:19:20 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: lxtphy.c,v 1.55 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -138,14 +138,20 @@ lxtphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
mii_unlock(mii);
if (sc->mii_flags & MIIF_HAVEFIBER) {
#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
mii_lock(mii);
sc->mii_anegticks = MII_ANEGTICKS;
mii_unlock(mii);
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_FX, 0, sc->mii_inst),
MII_MEDIA_100_TX);
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_FX, IFM_FDX, sc->mii_inst),
@ -163,6 +169,8 @@ lxtphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -222,6 +230,8 @@ lxtphy_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmcr, bmsr, csr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -270,6 +280,8 @@ lxtphy_reset(struct mii_softc *sc)
{
uint16_t ier;
KASSERT(mii_locked(sc->mii_pdata));
mii_phy_reset(sc);
PHY_READ(sc, MII_LXTPHY_IER, &ier);
ier &= ~IER_INTEN;

View File

@ -1,4 +1,4 @@
/* $NetBSD: makphy.c,v 1.64 2020/01/28 05:08:02 msaitoh Exp $ */
/* $NetBSD: makphy.c,v 1.65 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -59,7 +59,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: makphy.c,v 1.64 2020/01/28 05:08:02 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: makphy.c,v 1.65 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -181,6 +181,8 @@ makphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
switch (model) {
case MII_MODEL_xxMARVELL_E1000:
if ((maksc->sc_flags & MAKPHY_F_I210) != 0)
@ -255,6 +257,7 @@ page0:
sc->mii_flags &= ~MIIF_IS_1000X;
}
}
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -264,6 +267,8 @@ makphy_reset(struct mii_softc *sc)
struct makphy_softc *maksc = (struct makphy_softc *)sc;
uint16_t reg;
KASSERT(mii_locked(sc->mii_pdata));
mii_phy_reset(sc);
/* Initialize PHY Specific Control Register. */
@ -345,6 +350,8 @@ makphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
if (!device_is_active(sc->mii_dev))
return ENXIO;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -413,6 +420,8 @@ makphy_status(struct mii_softc *sc)
struct mii_data *mii = sc->mii_pdata;
uint16_t bmcr, gsr, pssr, essr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;

View File

@ -1,4 +1,4 @@
/* $NetBSD: micphy.c,v 1.12 2020/02/14 12:14:33 nisimura Exp $ */
/* $NetBSD: micphy.c,v 1.13 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@ -59,7 +59,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: micphy.c,v 1.12 2020/02/14 12:14:33 nisimura Exp $");
__KERNEL_RCSID(0, "$NetBSD: micphy.c,v 1.13 2020/03/15 23:04:50 thorpej Exp $");
#include "opt_mii.h"
@ -232,6 +232,8 @@ micphyattach(device_t parent, device_t self, void *aux)
} else
msc->sc_lstype = MICPHYF_LSTYPE_DEFAULT;
mii_lock(mii);
PHY_RESET(sc);
micphy_fixup(sc, model, rev, parent);
@ -241,6 +243,8 @@ micphyattach(device_t parent, device_t self, void *aux)
if (sc->mii_capabilities & BMSR_EXTSTAT)
PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
mii_unlock(mii);
aprint_normal_dev(self, "");
mii_phy_add_media(sc);
aprint_normal("\n");
@ -251,6 +255,8 @@ micphy_reset(struct mii_softc *sc)
{
uint16_t reg;
KASSERT(mii_locked(sc->mii_pdata));
/*
* The 8081 has no "sticky bits" that survive a soft reset; several
* bits in the Phy Control Register 2 must be preserved across the
@ -271,6 +277,8 @@ micphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -333,6 +341,9 @@ micphy_writexreg(struct mii_softc *sc, uint32_t reg, uint32_t wval)
static void
micphy_fixup(struct mii_softc *sc, int model, int rev, device_t parent)
{
KASSERT(mii_locked(sc->mii_pdata));
switch (model) {
case MII_MODEL_MICREL_KSZ9021_8001_8721:
if (!device_is_a(parent, "cpsw"))
@ -362,6 +373,8 @@ micphy_status(struct mii_softc *sc)
struct mii_data *mii = sc->mii_pdata;
uint16_t bmsr, bmcr, sr;
KASSERT(mii_locked(mii));
/* For unknown devices */
if (msc->sc_lstype == MICPHYF_LSTYPE_DEFAULT) {
ukphy_status(sc);

View File

@ -1,7 +1,7 @@
/* $NetBSD: mii.c,v 1.54 2019/04/09 11:28:45 msaitoh Exp $ */
/* $NetBSD: mii.c,v 1.55 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
* Copyright (c) 1998, 2000, 2020 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -36,7 +36,9 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mii.c,v 1.54 2019/04/09 11:28:45 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: mii.c,v 1.55 2020/03/15 23:04:50 thorpej Exp $");
#define __IFMEDIA_PRIVATE
#include <sys/param.h>
#include <sys/device.h>
@ -69,6 +71,8 @@ mii_attach(device_t parent, struct mii_data *mii, int capmask,
int locs[MIICF_NLOCS];
int rv;
KASSERT(mii->mii_media.ifm_lock != NULL);
if (phyloc != MII_PHY_ANY && offloc != MII_OFFSET_ANY)
panic("mii_attach: phyloc and offloc specified");
@ -78,11 +82,35 @@ mii_attach(device_t parent, struct mii_data *mii, int capmask,
} else
phymin = phymax = phyloc;
mii_lock(mii);
if ((mii->mii_flags & MIIF_INITDONE) == 0) {
LIST_INIT(&mii->mii_phys);
cv_init(&mii->mii_probe_cv, "mii_attach");
mii->mii_flags |= MIIF_INITDONE;
}
/*
* Probing temporarily unlocks the MII; wait until anyone
* else who might be doing this to finish.
*/
mii->mii_probe_waiters++;
for (;;) {
if (mii->mii_flags & MIIF_EXITING) {
mii->mii_probe_waiters--;
cv_signal(&mii->mii_probe_cv);
mii_unlock(mii);
return;
}
if ((mii->mii_flags & MIIF_PROBING) == 0)
break;
cv_wait(&mii->mii_probe_cv, mii->mii_media.ifm_lock);
}
mii->mii_probe_waiters--;
/* ...and old others off. */
mii->mii_flags |= MIIF_PROBING;
for (ma.mii_phyno = phymin; ma.mii_phyno <= phymax; ma.mii_phyno++) {
/*
* Make sure we haven't already configured a PHY at this
@ -142,33 +170,82 @@ mii_attach(device_t parent, struct mii_data *mii, int capmask,
locs[MIICF_PHY] = ma.mii_phyno;
mii_unlock(mii);
child = device_private(config_found_sm_loc(parent, "mii",
locs, &ma, mii_print, config_stdsubmatch));
if (child) {
/* Link it up in the parent's MII data. */
callout_init(&child->mii_nway_ch, 0);
mii_lock(mii);
LIST_INSERT_HEAD(&mii->mii_phys, child, mii_list);
child->mii_offset = offset;
mii->mii_instance++;
} else {
mii_lock(mii);
}
offset++;
}
/* All done! */
mii->mii_flags &= ~MIIF_PROBING;
cv_signal(&mii->mii_probe_cv);
mii_unlock(mii);
}
void
mii_detach(struct mii_data *mii, int phyloc, int offloc)
{
struct mii_softc *child, *nchild;
bool exiting = false;
if (phyloc != MII_PHY_ANY && offloc != MII_PHY_ANY)
panic("mii_detach: phyloc and offloc specified");
if ((mii->mii_flags & MIIF_INITDONE) == 0)
return;
mii_lock(mii);
for (child = LIST_FIRST(&mii->mii_phys);
child != NULL; child = nchild) {
nchild = LIST_NEXT(child, mii_list);
if ((mii->mii_flags & MIIF_INITDONE) == 0 ||
(mii->mii_flags & MIIF_EXITING) != 0) {
mii_unlock(mii);
return;
}
/*
* XXX This is probably not the best hueristic. Consider
* XXX adding an argument to mii_detach().
*/
if (phyloc == MII_PHY_ANY && MII_PHY_ANY == MII_OFFSET_ANY)
exiting = true;
if (exiting) {
mii->mii_flags |= MIIF_EXITING;
cv_broadcast(&mii->mii_probe_cv);
}
/* Wait for everyone else to get out. */
mii->mii_probe_waiters++;
for (;;) {
/*
* If we've been waiting to do a less-than-exit, and
* *someone else* initiated an exit, then get out.
*/
if (!exiting && (mii->mii_flags & MIIF_EXITING) != 0) {
mii->mii_probe_waiters--;
cv_signal(&mii->mii_probe_cv);
mii_unlock(mii);
return;
}
if ((mii->mii_flags & MIIF_PROBING) == 0 &&
(!exiting || (exiting && mii->mii_probe_waiters == 1)))
break;
cv_wait(&mii->mii_probe_cv, mii->mii_media.ifm_lock);
}
mii->mii_probe_waiters--;
if (!exiting)
mii->mii_flags |= MIIF_PROBING;
LIST_FOREACH_SAFE(child, &mii->mii_phys, mii_list, nchild) {
if (phyloc != MII_PHY_ANY || offloc != MII_OFFSET_ANY) {
if (phyloc != MII_PHY_ANY &&
phyloc != child->mii_phy)
@ -177,8 +254,20 @@ mii_detach(struct mii_data *mii, int phyloc, int offloc)
offloc != child->mii_offset)
continue;
}
LIST_REMOVE(child, mii_list);
mii_unlock(mii);
(void)config_detach(child->mii_dev, DETACH_FORCE);
mii_lock(mii);
}
if (exiting) {
cv_destroy(&mii->mii_probe_cv);
} else {
mii->mii_flags &= ~MIIF_PROBING;
cv_signal(&mii->mii_probe_cv);
}
mii_unlock(mii);
}
static int
@ -207,6 +296,9 @@ phy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
int
mii_ifmedia_change(struct mii_data *mii)
{
KASSERT(mii_locked(mii) ||
ifmedia_islegacy(&mii->mii_media));
return ifmedia_change(&mii->mii_media, mii->mii_ifp);
}
@ -217,7 +309,10 @@ int
mii_mediachg(struct mii_data *mii)
{
struct mii_softc *child;
int rv;
int rv = 0;
IFMEDIA_LOCK_FOR_LEGACY(&mii->mii_media);
KASSERT(mii_locked(mii));
mii->mii_media_status = 0;
mii->mii_media_active = IFM_NONE;
@ -225,9 +320,10 @@ mii_mediachg(struct mii_data *mii)
LIST_FOREACH(child, &mii->mii_phys, mii_list) {
rv = phy_service(child, mii, MII_MEDIACHG);
if (rv)
return rv;
break;
}
return 0;
IFMEDIA_UNLOCK_FOR_LEGACY(&mii->mii_media);
return rv;
}
/*
@ -238,8 +334,13 @@ mii_tick(struct mii_data *mii)
{
struct mii_softc *child;
IFMEDIA_LOCK_FOR_LEGACY(&mii->mii_media);
KASSERT(mii_locked(mii));
LIST_FOREACH(child, &mii->mii_phys, mii_list)
(void)phy_service(child, mii, MII_TICK);
IFMEDIA_UNLOCK_FOR_LEGACY(&mii->mii_media);
}
/*
@ -250,11 +351,16 @@ mii_pollstat(struct mii_data *mii)
{
struct mii_softc *child;
IFMEDIA_LOCK_FOR_LEGACY(&mii->mii_media);
KASSERT(mii_locked(mii));
mii->mii_media_status = 0;
mii->mii_media_active = IFM_NONE;
LIST_FOREACH(child, &mii->mii_phys, mii_list)
(void)phy_service(child, mii, MII_POLLSTAT);
IFMEDIA_UNLOCK_FOR_LEGACY(&mii->mii_media);
}
/*
@ -265,8 +371,13 @@ mii_down(struct mii_data *mii)
{
struct mii_softc *child;
IFMEDIA_LOCK_FOR_LEGACY(&mii->mii_media);
KASSERT(mii_locked(mii));
LIST_FOREACH(child, &mii->mii_phys, mii_list)
(void)phy_service(child, mii, MII_DOWN);
IFMEDIA_UNLOCK_FOR_LEGACY(&mii->mii_media);
}
static unsigned char

View File

@ -1,4 +1,4 @@
/* $NetBSD: mii_ethersubr.c,v 1.2 2019/03/25 07:09:54 msaitoh Exp $ */
/* $NetBSD: mii_ethersubr.c,v 1.3 2020/03/15 23:04:50 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -61,7 +61,9 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mii_ethersubr.c,v 1.2 2019/03/25 07:09:54 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: mii_ethersubr.c,v 1.3 2020/03/15 23:04:50 thorpej Exp $");
#define __IFMEDIA_PRIVATE
#include <sys/param.h>
#include <sys/systm.h>
@ -84,6 +86,8 @@ ether_mediachange(struct ifnet *ifp)
int rc;
KASSERT(ec->ec_mii != NULL);
KASSERT(mii_locked(ec->ec_mii) ||
ifmedia_islegacy(&ec->ec_mii->mii_media));
if ((ifp->if_flags & IFF_UP) == 0)
return 0;
@ -99,6 +103,8 @@ ether_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
struct mii_data *mii;
KASSERT(ec->ec_mii != NULL);
KASSERT(mii_locked(ec->ec_mii) ||
ifmedia_islegacy(&ec->ec_mii->mii_media));
#ifdef notyet
if ((ifp->if_flags & IFF_RUNNING) == 0) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: mii_physubr.c,v 1.89 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: mii_physubr.c,v 1.90 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mii_physubr.c,v 1.89 2019/11/27 10:19:20 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: mii_physubr.c,v 1.90 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/device.h>
@ -125,6 +125,7 @@ static const struct mii_media mii_media_table[MII_NMEDIA] = {
};
static void mii_phy_auto_timeout(void *);
static void mii_phy_auto_timeout_locked(struct mii_softc *);
void
mii_phy_setmedia(struct mii_softc *sc)
@ -133,6 +134,8 @@ mii_phy_setmedia(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmcr, anar, gtcr;
KASSERT(mii_locked(mii));
if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) {
/*
* Force renegotiation if MIIF_DOPAUSE.
@ -202,6 +205,8 @@ mii_phy_auto(struct mii_softc *sc, int waitfor)
struct mii_data *mii = sc->mii_pdata;
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
KASSERT(mii_locked(mii));
sc->mii_ticks = 0;
if ((sc->mii_flags & MIIF_DOINGAUTO) == 0) {
/*
@ -285,9 +290,10 @@ mii_phy_auto(struct mii_softc *sc, int waitfor)
* delays all the time while the system is running!
*/
if (sc->mii_flags & MIIF_AUTOTSLEEP) {
ASSERT_SLEEPABLE();
sc->mii_flags |= MIIF_DOINGAUTO;
tsleep(&sc->mii_flags, PZERO, "miiaut", hz >> 1);
mii_phy_auto_timeout(sc);
kpause("miiaut", false, hz >> 1, mii->mii_media.ifm_lock);
mii_phy_auto_timeout_locked(sc);
} else if ((sc->mii_flags & MIIF_DOINGAUTO) == 0) {
sc->mii_flags |= MIIF_DOINGAUTO;
callout_reset(&sc->mii_nway_ch, hz >> 1,
@ -297,20 +303,29 @@ mii_phy_auto(struct mii_softc *sc, int waitfor)
}
static void
mii_phy_auto_timeout(void *arg)
mii_phy_auto_timeout_locked(struct mii_softc *sc)
{
struct mii_softc *sc = arg;
int s;
if (!device_is_active(sc->mii_dev))
return;
s = splnet();
sc->mii_flags &= ~MIIF_DOINGAUTO;
/* Update the media status. */
(void) PHY_SERVICE(sc, sc->mii_pdata, MII_POLLSTAT);
splx(s);
}
static void
mii_phy_auto_timeout(void *arg)
{
struct mii_softc *sc = arg;
if (!device_is_active(sc->mii_dev))
return;
mii_lock(sc->mii_pdata);
mii_phy_auto_timeout_locked(sc);
mii_unlock(sc->mii_pdata);
}
int
@ -320,6 +335,8 @@ mii_phy_tick(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
/* Just bail now if the interface is down. */
if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
return EJUSTRETURN;
@ -385,6 +402,8 @@ mii_phy_reset(struct mii_softc *sc)
int i;
uint16_t reg;
KASSERT(mii_locked(sc->mii_pdata));
if (sc->mii_flags & MIIF_NOISOLATE)
reg = BMCR_RESET;
else
@ -407,6 +426,8 @@ void
mii_phy_down(struct mii_softc *sc)
{
KASSERT(mii_locked(sc->mii_pdata));
if (sc->mii_flags & MIIF_DOINGAUTO) {
sc->mii_flags &= ~MIIF_DOINGAUTO;
callout_stop(&sc->mii_nway_ch);
@ -417,6 +438,7 @@ void
mii_phy_status(struct mii_softc *sc)
{
KASSERT(mii_locked(sc->mii_pdata));
PHY_STATUS(sc);
}
@ -425,6 +447,8 @@ mii_phy_update(struct mii_softc *sc, int cmd)
{
struct mii_data *mii = sc->mii_pdata;
KASSERT(mii_locked(mii));
if (sc->mii_media_active != mii->mii_media_active ||
sc->mii_media_status != mii->mii_media_status ||
cmd == MII_MEDIACHG) {
@ -441,6 +465,8 @@ mii_phy_statusmsg(struct mii_softc *sc)
struct mii_data *mii = sc->mii_pdata;
struct ifnet *ifp = mii->mii_ifp;
KASSERT(mii_locked(mii));
if (mii->mii_media_status & IFM_AVALID) {
if (mii->mii_media_status & IFM_ACTIVE)
if_link_state_change(ifp, LINK_STATE_UP);
@ -449,6 +475,7 @@ mii_phy_statusmsg(struct mii_softc *sc)
} else
if_link_state_change(ifp, LINK_STATE_UNKNOWN);
/* XXX NET_MPSAFE */
ifp->if_baudrate = ifmedia_baudrate(mii->mii_media_active);
}
@ -476,11 +503,14 @@ mii_phy_add_media(struct mii_softc *sc)
* Set the autonegotiation timer for 10/100 media. Gigabit media is
* handled below.
*/
mii_lock(mii);
sc->mii_anegticks = MII_ANEGTICKS;
mii_unlock(mii);
#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
#define PRINT(n) aprint_normal("%s%s", sep, (n)); sep = ", "
/* This flag is static; no need to lock. */
if ((sc->mii_flags & MIIF_NOISOLATE) == 0)
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst),
MII_MEDIA_NONE);
@ -488,7 +518,8 @@ mii_phy_add_media(struct mii_softc *sc)
/*
* There are different interpretations for the bits in
* HomePNA PHYs. And there is really only one media type
* that is supported.
* that is supported. This flag is also static, and so
* no need to lock.
*/
if (sc->mii_flags & MIIF_IS_HPNA) {
if (sc->mii_capabilities & BMSR_10THDX) {
@ -538,15 +569,19 @@ mii_phy_add_media(struct mii_softc *sc)
* all the gigabit media types.
*/
if (sc->mii_extcapabilities & EXTSR_1000XHDX) {
mii_lock(mii);
sc->mii_anegticks = MII_ANEGTICKS_GIGE;
sc->mii_flags |= MIIF_IS_1000X;
mii_unlock(mii);
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, 0,
sc->mii_inst), MII_MEDIA_1000_X);
PRINT("1000baseSX");
}
if (sc->mii_extcapabilities & EXTSR_1000XFDX) {
mii_lock(mii);
sc->mii_anegticks = MII_ANEGTICKS_GIGE;
sc->mii_flags |= MIIF_IS_1000X;
mii_unlock(mii);
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX,
sc->mii_inst), MII_MEDIA_1000_X_FDX);
PRINT("1000baseSX-FDX");
@ -562,17 +597,21 @@ mii_phy_add_media(struct mii_softc *sc)
* All 1000baseT PHYs have a 1000baseT control register.
*/
if (sc->mii_extcapabilities & EXTSR_1000THDX) {
mii_lock(mii);
sc->mii_anegticks = MII_ANEGTICKS_GIGE;
sc->mii_flags |= MIIF_HAVE_GTCR;
mii->mii_media.ifm_mask |= IFM_ETH_MASTER;
mii_unlock(mii);
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0,
sc->mii_inst), MII_MEDIA_1000_T);
PRINT("1000baseT");
}
if (sc->mii_extcapabilities & EXTSR_1000TFDX) {
mii_lock(mii);
sc->mii_anegticks = MII_ANEGTICKS_GIGE;
sc->mii_flags |= MIIF_HAVE_GTCR;
mii->mii_media.ifm_mask |= IFM_ETH_MASTER;
mii_unlock(mii);
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX,
sc->mii_inst), MII_MEDIA_1000_T_FDX);
PRINT("1000baseT-FDX");
@ -587,8 +626,12 @@ mii_phy_add_media(struct mii_softc *sc)
}
#undef ADD
#undef PRINT
if (fdx != 0 && (sc->mii_flags & MIIF_DOPAUSE))
/* This flag is static; no need to lock. */
if (fdx != 0 && (sc->mii_flags & MIIF_DOPAUSE)) {
mii_lock(mii);
mii->mii_media.ifm_mask |= IFM_ETH_FMASK;
mii_unlock(mii);
}
out:
aprint_normal("\n");
if (!pmf_device_register(self, NULL, mii_phy_resume)) {
@ -623,15 +666,16 @@ mii_phy_detach(device_t self, int flags)
{
struct mii_softc *sc = device_private(self);
/* XXX Invalidate parent's media setting? */
if (sc->mii_flags & MIIF_DOINGAUTO)
callout_halt(&sc->mii_nway_ch, NULL);
mii_lock(sc->mii_pdata);
if (sc->mii_flags & MIIF_DOINGAUTO) {
callout_halt(&sc->mii_nway_ch,
sc->mii_pdata->mii_media.ifm_lock);
}
mii_unlock(sc->mii_pdata);
callout_destroy(&sc->mii_nway_ch);
mii_phy_delete_media(sc);
LIST_REMOVE(sc, mii_list);
return 0;
}
@ -656,6 +700,8 @@ mii_phy_flowstatus(struct mii_softc *sc)
{
uint16_t anar, anlpar;
KASSERT(mii_locked(sc->mii_pdata));
if ((sc->mii_flags & MIIF_DOPAUSE) == 0)
return 0;
@ -704,8 +750,12 @@ mii_phy_resume(device_t dv, const pmf_qual_t *qual)
{
struct mii_softc *sc = device_private(dv);
mii_lock(sc->mii_pdata);
PHY_RESET(sc);
return PHY_SERVICE(sc, sc->mii_pdata, MII_MEDIACHG) == 0;
bool rv = PHY_SERVICE(sc, sc->mii_pdata, MII_MEDIACHG) == 0;
mii_unlock(sc->mii_pdata);
return rv;
}

View File

@ -1,7 +1,7 @@
/* $NetBSD: miivar.h,v 1.69 2019/11/20 08:50:59 msaitoh Exp $ */
/* $NetBSD: miivar.h,v 1.70 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
* Copyright (c) 1998, 1999, 2000, 2001, 2020 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -35,6 +35,7 @@
#include <sys/queue.h>
#include <sys/callout.h>
#include <sys/condvar.h>
#include <dev/mii/mii.h>
#include <dev/mii/mii_verbose.h>
@ -57,32 +58,53 @@ typedef void (*mii_statchg_t)(struct ifnet *);
* A network interface driver has one of these structures in its softc.
* It is the interface from the network interface driver to the MII
* layer.
*
* LOCKING
* =======
*
* The MII shares the lock with its ifmedia (which in turn shares the
* lock with its driver).
*
* MII routines can be called from a driver's interrupt handler, as well
* as via administrative input (e.g. ifmedia_ioctl()). We therefore require
* that most MII APIs are called with the ifmedia lock HELD. (See below.)
*
* Field markings and the corresponding locks:
*
* m: ifmedia lock
* :: unlocked, stable
*/
struct mii_data {
struct ifmedia mii_media; /* media information */
struct ifnet *mii_ifp; /* pointer back to network interface */
struct ifmedia mii_media; /* m: media information */
struct ifnet *mii_ifp; /* :: pointer back to interface */
int mii_flags; /* misc. flags; see below */
kcondvar_t mii_probe_cv; /* m: serialize probing the MII */
u_int mii_probe_waiters; /* m: # threads waiting to probe */
int mii_flags; /* m: misc. flags; see below */
/*
* For network interfaces with multiple PHYs, a list of all
* m: For network interfaces with multiple PHYs, a list of all
* PHYs is required so they can all be notified when a media
* request is made.
*/
LIST_HEAD(mii_listhead, mii_softc) mii_phys;
u_int mii_instance;
/* PHY driver fills this in with active media status. */
/* m: PHY driver fills this in with active media status. */
int mii_media_status;
u_int mii_media_active;
/* Calls from MII layer into network interface driver. */
/* :: Calls from MII layer into network interface driver. */
mii_readreg_t mii_readreg;
mii_writereg_t mii_writereg;
mii_statchg_t mii_statchg;
};
typedef struct mii_data mii_data_t;
#define mii_lock(mii) ifmedia_lock(&(mii)->mii_media)
#define mii_unlock(mii) ifmedia_unlock(&(mii)->mii_media)
#define mii_locked(mii) ifmedia_locked(&(mii)->mii_media)
/*
* Functions provided by the PHY to perform various functions.
*/
@ -108,30 +130,30 @@ struct mii_phy_funcs {
struct mii_softc {
device_t mii_dev; /* generic device glue */
LIST_ENTRY(mii_softc) mii_list; /* entry on parent's PHY list */
LIST_ENTRY(mii_softc) mii_list; /* m: entry on parent's PHY list */
uint32_t mii_mpd_oui; /* the PHY's OUI (MII_OUI())*/
uint32_t mii_mpd_model; /* the PHY's model (MII_MODEL())*/
uint32_t mii_mpd_rev; /* the PHY's revision (MII_REV())*/
int mii_phy; /* our MII address */
int mii_offset; /* first PHY, second PHY, etc. */
u_int mii_inst; /* instance for ifmedia */
uint32_t mii_mpd_oui; /* :: the PHY's OUI (MII_OUI())*/
uint32_t mii_mpd_model; /* :: the PHY's model (MII_MODEL())*/
uint32_t mii_mpd_rev; /* :: the PHY's revision (MII_REV())*/
int mii_phy; /* :: our MII address */
int mii_offset; /* :: first PHY, second PHY, etc. */
u_int mii_inst; /* :: instance for ifmedia */
/* Our PHY functions. */
/* :: Our PHY functions. */
const struct mii_phy_funcs *mii_funcs;
struct mii_data *mii_pdata; /* pointer to parent's mii_data */
struct mii_data *mii_pdata; /* :: pointer to parent's mii_data */
int mii_flags; /* misc. flags; see below */
uint16_t mii_capabilities; /* capabilities from BMSR */
uint16_t mii_extcapabilities; /* extended capabilities from EXTSR */
int mii_ticks; /* MII_TICK counter */
int mii_anegticks; /* ticks before retrying aneg */
int mii_flags; /* m: misc. flags; see below */
uint16_t mii_capabilities; /* :: capabilities from BMSR */
uint16_t mii_extcapabilities; /* :: extended caps from EXTSR */
int mii_ticks; /* m: MII_TICK counter */
int mii_anegticks; /* m: ticks before retrying aneg */
struct callout mii_nway_ch; /* NWAY callout */
struct callout mii_nway_ch; /* m: NWAY callout */
u_int mii_media_active; /* last active media */
int mii_media_status; /* last active status */
u_int mii_media_active; /* m: last active media */
int mii_media_status; /* m: last active status */
};
typedef struct mii_softc mii_softc_t;
@ -144,13 +166,15 @@ typedef struct mii_softc mii_softc_t;
#define MIIF_NOISOLATE 0x0002 /* do not isolate the PHY */
#define MIIF_NOLOOP 0x0004 /* no loopback capability */
#define MIIF_DOINGAUTO 0x0008 /* doing autonegotiation (mii_softc) */
#define MIIF_AUTOTSLEEP 0x0010 /* use tsleep(), not callout() */
#define MIIF_AUTOTSLEEP 0x0010 /* use kpause(), not callout() */
#define MIIF_HAVEFIBER 0x0020 /* from parent: has fiber interface */
#define MIIF_HAVE_GTCR 0x0040 /* has 100base-T2/1000base-T CR */
#define MIIF_IS_1000X 0x0080 /* is a 1000BASE-X device */
#define MIIF_DOPAUSE 0x0100 /* advertise PAUSE capability */
#define MIIF_IS_HPNA 0x0200 /* is a HomePNA device */
#define MIIF_FORCEANEG 0x0400 /* force auto-negotiation */
#define MIIF_PROBING 0x0800 /* PHY probe in-progress */
#define MIIF_EXITING 0x1000 /* MII is exiting */
#define MIIF_INHERIT_MASK (MIIF_NOISOLATE | MIIF_NOLOOP | MIIF_AUTOTSLEEP)
@ -270,47 +294,54 @@ MMD_INDIRECT_WRITE(struct mii_softc *sc, uint16_t daddr, uint16_t regnum,
return PHY_WRITE(sc, MII_MMDAADR, val);
}
/* MII must be LOCKED. */
#define PHY_SERVICE(p, d, o) \
(*(p)->mii_funcs->pf_service)((p), (d), (o))
#define PHY_STATUS(p) \
(*(p)->mii_funcs->pf_status)((p))
#define PHY_RESET(p) \
(*(p)->mii_funcs->pf_reset)((p))
/* MII must be UNLOCKED */
void mii_attach(device_t, struct mii_data *, int, int, int, int);
void mii_detach(struct mii_data *, int, int);
bool mii_phy_resume(device_t, const pmf_qual_t *);
/* MII must be LOCKED. */
int mii_mediachg(struct mii_data *);
void mii_tick(struct mii_data *);
void mii_pollstat(struct mii_data *);
void mii_down(struct mii_data *);
uint16_t mii_anar(struct ifmedia_entry *);
int mii_ifmedia_change(struct mii_data *);
uint16_t mii_anar(struct ifmedia_entry *);
/* MII must be UNLOCKED */
int mii_phy_activate(device_t, enum devact);
int mii_phy_detach(device_t, int);
bool mii_phy_resume(device_t, const pmf_qual_t *);
const struct mii_phydesc *mii_phy_match(const struct mii_attach_args *,
const struct mii_phydesc *);
/* MII must be UNLOCKED */
void mii_phy_add_media(struct mii_softc *);
void mii_phy_delete_media(struct mii_softc *);
/* MII must be LOCKED */
void mii_phy_setmedia(struct mii_softc *);
int mii_phy_auto(struct mii_softc *, int);
void mii_phy_reset(struct mii_softc *);
void mii_phy_down(struct mii_softc *);
int mii_phy_tick(struct mii_softc *);
/* MII must be LOCKED */
void mii_phy_status(struct mii_softc *);
void mii_phy_update(struct mii_softc *, int);
/* MII must be LOCKED */
u_int mii_phy_flowstatus(struct mii_softc *);
/* MII must be LOCKED */
void ukphy_status(struct mii_softc *);
u_int mii_oui(uint16_t, uint16_t);

View File

@ -1,4 +1,4 @@
/* $NetBSD: mvphy.c,v 1.14 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: mvphy.c,v 1.15 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 2006 Sam Leffler, Errno Consulting
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mvphy.c,v 1.14 2019/11/27 10:19:20 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: mvphy.c,v 1.15 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -192,6 +192,8 @@ mvphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
if (MV_PORT(sc) == 0) { /* NB: only when attaching first PHY */
/*
* Set the global switch settings and configure the
@ -207,6 +209,8 @@ mvphyattach(device_t parent, device_t self, void *aux)
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -215,6 +219,8 @@ mvphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
{
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -267,6 +273,8 @@ mvphy_status(struct mii_softc *sc)
struct mii_data *mii = sc->mii_pdata;
uint16_t hwstatus;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -292,6 +300,8 @@ static void
mvphy_reset(struct mii_softc *sc)
{
KASSERT(mii_locked(sc->mii_pdata));
/* XXX handle fixed media config */
PHY_WRITE(sc, MII_BMCR, BMCR_RESET | BMCR_AUTOEN);
mvphy_switchconfig(sc, MV_PORT(sc));

View File

@ -1,4 +1,4 @@
/* $NetBSD: nsphy.c,v 1.65 2019/11/27 10:19:20 msaitoh Exp $ */
/* $NetBSD: nsphy.c,v 1.66 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nsphy.c,v 1.65 2019/11/27 10:19:20 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: nsphy.c,v 1.66 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -127,11 +127,15 @@ nsphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -141,6 +145,8 @@ nsphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -230,6 +236,8 @@ nsphy_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmsr, bmcr, aner, anar, par, anlpar, result;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -305,6 +313,8 @@ nsphy_reset(struct mii_softc *sc)
int i;
uint16_t reg;
KASSERT(mii_locked(sc->mii_pdata));
if (sc->mii_flags & MIIF_NOISOLATE)
reg = BMCR_RESET;
else

View File

@ -1,4 +1,4 @@
/* $NetBSD: nsphyter.c,v 1.44 2019/11/27 10:19:21 msaitoh Exp $ */
/* $NetBSD: nsphyter.c,v 1.45 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -63,7 +63,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nsphyter.c,v 1.44 2019/11/27 10:19:21 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: nsphyter.c,v 1.45 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -134,11 +134,15 @@ nsphyterattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -148,6 +152,8 @@ nsphyter_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -202,6 +208,8 @@ nsphyter_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmsr, bmcr, physts;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -253,6 +261,8 @@ nsphyter_reset(struct mii_softc *sc)
int i;
uint16_t reg;
KASSERT(mii_locked(sc->mii_pdata));
if (sc->mii_flags & MIIF_NOISOLATE)
reg = BMCR_RESET;
else

View File

@ -1,4 +1,4 @@
/* $NetBSD: pnaphy.c,v 1.25 2019/11/27 10:19:21 msaitoh Exp $ */
/* $NetBSD: pnaphy.c,v 1.26 2020/03/15 23:04:50 thorpej Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@ -47,7 +47,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pnaphy.c,v 1.25 2019/11/27 10:19:21 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: pnaphy.c,v 1.26 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -116,11 +116,15 @@ pnaphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags | MIIF_IS_HPNA; /* Force HomePNA */
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -130,6 +134,8 @@ pnaphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -184,6 +190,8 @@ pnaphy_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmsr, bmcr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;

View File

@ -1,4 +1,4 @@
/* $NetBSD: qsphy.c,v 1.54 2019/11/27 10:19:21 msaitoh Exp $ */
/* $NetBSD: qsphy.c,v 1.55 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: qsphy.c,v 1.54 2019/11/27 10:19:21 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: qsphy.c,v 1.55 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -126,11 +126,15 @@ qsphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -140,6 +144,8 @@ qsphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -194,6 +200,8 @@ qsphy_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmsr, bmcr, pctl;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -249,6 +257,8 @@ static void
qsphy_reset(struct mii_softc *sc)
{
KASSERT(mii_locked(sc->mii_pdata));
mii_phy_reset(sc);
PHY_WRITE(sc, MII_QSPHY_IMASK, 0);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: rdcphy.c,v 1.6 2020/02/05 06:39:13 msaitoh Exp $ */
/* $NetBSD: rdcphy.c,v 1.7 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 2010, Pyun YongHyeon <yongari@FreeBSD.org>
@ -33,7 +33,7 @@
* Driver for the RDC Semiconductor R6040 10/100 PHY.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rdcphy.c,v 1.6 2020/02/05 06:39:13 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: rdcphy.c,v 1.7 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -110,6 +110,8 @@ rdcphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
@ -117,6 +119,8 @@ rdcphyattach(device_t parent, device_t self, void *aux)
if (sc->mii_capabilities & BMSR_EXTSTAT)
PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -126,6 +130,8 @@ rdcphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct rdcphy_softc *rsc = (struct rdcphy_softc *)sc;
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
break;
@ -197,6 +203,8 @@ rdcphy_status(struct mii_softc *sc)
struct mii_data *mii = sc->mii_pdata;
uint16_t bmsr, bmcr, physts;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;

View File

@ -1,4 +1,4 @@
/* $NetBSD: rgephy.c,v 1.58 2019/11/27 10:19:21 msaitoh Exp $ */
/* $NetBSD: rgephy.c,v 1.59 2020/03/15 23:04:50 thorpej Exp $ */
/*
* Copyright (c) 2003
@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rgephy.c,v 1.58 2019/11/27 10:19:21 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: rgephy.c,v 1.59 2020/03/15 23:04:50 thorpej Exp $");
/*
@ -110,15 +110,17 @@ rgephy_attach(device_t parent, device_t self, void *aux)
struct mii_attach_args *ma = aux;
struct mii_data *mii = ma->mii_data;
const struct mii_phydesc *mpd;
int rev;
rev = MII_REV(ma->mii_id2);
mpd = mii_phy_match(ma, rgephys);
aprint_naive(": Media interface\n");
sc->mii_dev = self;
sc->mii_inst = mii->mii_instance;
sc->mii_phy = ma->mii_phyno;
sc->mii_funcs = &rgephy_funcs;
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
sc->mii_mpd_oui = MII_OUI(ma->mii_id1, ma->mii_id2);
sc->mii_mpd_model = MII_MODEL(ma->mii_id2);
sc->mii_mpd_rev = MII_REV(ma->mii_id2);
@ -128,13 +130,10 @@ rgephy_attach(device_t parent, device_t self, void *aux)
if (sc->mii_mpd_rev != 0)
aprint_normal("%c",'@' + sc->mii_mpd_rev);
aprint_normal(" 1000BASE-T media interface\n");
} else
aprint_normal(": %s, rev. %d\n", mpd->mpd_name, rev);
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
sc->mii_funcs = &rgephy_funcs;
} else {
aprint_normal(": %s, rev. %d\n", mpd->mpd_name,
sc->mii_mpd_rev);
}
prop_dictionary_get_bool(prop, "no-rx-delay", &rsc->mii_no_rx_delay);
@ -143,6 +142,10 @@ rgephy_attach(device_t parent, device_t self, void *aux)
BMCR_LOOP | BMCR_S100);
#endif
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
/* RTL8169S does not report auto-sense; add manually. */
@ -155,9 +158,9 @@ rgephy_attach(device_t parent, device_t self, void *aux)
if (sc->mii_capabilities & BMSR_EXTSTAT)
PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
mii_phy_add_media(sc);
mii_unlock(mii);
rgephy_reset(sc);
mii_phy_add_media(sc);
}
static int
@ -166,6 +169,8 @@ rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg, speed, gig, anar;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -344,6 +349,8 @@ rgephy_status(struct mii_softc *sc)
struct mii_data *mii = sc->mii_pdata;
uint16_t gstat, bmsr, bmcr, gtsr, physr, ssr;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -620,6 +627,8 @@ rgephy_reset(struct mii_softc *sc)
struct rgephy_softc *rsc = (struct rgephy_softc *)sc;
uint16_t ssr, phycr1;
KASSERT(mii_locked(sc->mii_pdata));
mii_phy_reset(sc);
DELAY(1000);

View File

@ -1,4 +1,4 @@
/* $NetBSD: rlphy.c,v 1.38 2019/11/27 10:19:21 msaitoh Exp $ */
/* $NetBSD: rlphy.c,v 1.39 2020/03/15 23:04:50 thorpej Exp $ */
/* $OpenBSD: rlphy.c,v 1.20 2005/07/31 05:27:30 pvalchev Exp $ */
/*
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rlphy.c,v 1.38 2019/11/27 10:19:21 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: rlphy.c,v 1.39 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -140,11 +140,15 @@ rlphyattach(device_t parent, device_t self, void *aux)
sc->mii_flags |= MIIF_NOISOLATE;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -157,6 +161,8 @@ rlphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
if (IFM_INST(ife->ifm_media) != sc->mii_inst)
panic("rlphy_service: attempt to isolate phy");
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
break;
@ -205,6 +211,8 @@ rlphy_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmsr, bmcr, anar, anlpar, result, reg;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -303,6 +311,8 @@ static void
rlphy_reset(struct mii_softc *sc)
{
KASSERT(mii_locked(sc->mii_pdata));
mii_phy_reset(sc);
/*

View File

@ -108,11 +108,15 @@ smscphy_attach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -136,6 +140,8 @@ smscphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife;
uint16_t reg;
KASSERT(mii_locked(mii));
ife = mii->mii_media.ifm_cur;
switch (cmd) {
@ -208,6 +214,8 @@ smscphy_status(struct mii_softc *sc)
struct mii_data *mii = sc->mii_pdata;
uint16_t bmcr, bmsr, status;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sqphy.c,v 1.55 2019/11/27 10:19:21 msaitoh Exp $ */
/* $NetBSD: sqphy.c,v 1.56 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sqphy.c,v 1.55 2019/11/27 10:19:21 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: sqphy.c,v 1.56 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -143,11 +143,15 @@ sqphyattach(device_t parent, device_t self, void *aux)
sc->mii_funcs = &sqphy_funcs;
}
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -157,6 +161,8 @@ sqphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -211,6 +217,8 @@ sqphy_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmsr, bmcr, status;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@ -257,6 +265,8 @@ sqphy_84220_reset(struct mii_softc *sc)
{
uint16_t reg;
KASSERT(mii_locked(sc->mii_pdata));
mii_phy_reset(sc);
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: tlphy.c,v 1.67 2019/11/27 10:19:21 msaitoh Exp $ */
/* $NetBSD: tlphy.c,v 1.68 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@ -59,7 +59,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tlphy.c,v 1.67 2019/11/27 10:19:21 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: tlphy.c,v 1.68 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -144,6 +144,8 @@ tlphyattach(device_t parent, device_t self, void *aux)
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
mii_lock(mii);
PHY_RESET(sc);
/*
@ -159,12 +161,15 @@ tlphyattach(device_t parent, device_t self, void *aux)
} else
sc->mii_capabilities = 0;
mii_unlock(mii);
#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
#define PRINT(str) aprint_normal("%s%s", sep, str); sep = ", "
if (tsc->sc_tlphycap) {
mii_lock(mii);
sc->mii_anegticks = MII_ANEGTICKS;
mii_unlock(mii);
aprint_normal_dev(self, "");
if (tsc->sc_tlphycap & TLPHY_MEDIA_10_2) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_2, 0, sc->mii_inst),
@ -203,6 +208,8 @@ tlphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
if ((sc->mii_flags & MIIF_DOINGAUTO) == 0 && tsc->sc_need_acomp)
tlphy_acomp(tsc);
@ -283,6 +290,8 @@ tlphy_status(struct mii_softc *sc)
struct mii_data *mii = sc->mii_pdata;
uint16_t bmsr, bmcr, tlctrl;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;

View File

@ -1,4 +1,4 @@
/* $NetBSD: tqphy.c,v 1.44 2019/11/27 10:19:21 msaitoh Exp $ */
/* $NetBSD: tqphy.c,v 1.45 2020/03/15 23:04:50 thorpej Exp $ */
/*
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tqphy.c,v 1.44 2019/11/27 10:19:21 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: tqphy.c,v 1.45 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -137,11 +137,15 @@ tqphyattach(device_t parent, device_t self, void *aux)
/* Apparently, we can't do loopback on this PHY. */
sc->mii_flags |= MIIF_NOLOOP;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
sc->mii_capabilities &= ma->mii_capmask;
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -151,6 +155,8 @@ tqphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */
@ -205,6 +211,8 @@ tqphy_status(struct mii_softc *sc)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmsr, bmcr, diag;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ukphy.c,v 1.52 2019/11/27 10:19:21 msaitoh Exp $ */
/* $NetBSD: ukphy.c,v 1.53 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@ -59,7 +59,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ukphy.c,v 1.52 2019/11/27 10:19:21 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: ukphy.c,v 1.53 2020/03/15 23:04:50 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_mii.h"
@ -135,6 +135,8 @@ ukphyattach(device_t parent, device_t self, void *aux)
*/
sc->mii_flags |= MIIF_NOLOOP;
mii_lock(mii);
PHY_RESET(sc);
PHY_READ(sc, MII_BMSR, &sc->mii_capabilities);
@ -142,6 +144,8 @@ ukphyattach(device_t parent, device_t self, void *aux)
if (sc->mii_capabilities & BMSR_EXTSTAT)
PHY_READ(sc, MII_EXTSR, &sc->mii_extcapabilities);
mii_unlock(mii);
mii_phy_add_media(sc);
}
@ -151,6 +155,8 @@ ukphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t reg;
KASSERT(mii_locked(mii));
switch (cmd) {
case MII_POLLSTAT:
/* If we're not polling our PHY instance, just return. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ukphy_subr.c,v 1.16 2019/10/24 03:37:58 msaitoh Exp $ */
/* $NetBSD: ukphy_subr.c,v 1.17 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ukphy_subr.c,v 1.16 2019/10/24 03:37:58 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: ukphy_subr.c,v 1.17 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -60,6 +60,8 @@ ukphy_status(struct mii_softc *phy)
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
uint16_t bmsr, bmcr, anar, anlpar, gtcr, gtsr, result;
KASSERT(mii_locked(mii));
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_mcx.c,v 1.11 2020/02/29 18:07:57 thorpej Exp $ */
/* $NetBSD: if_mcx.c,v 1.12 2020/03/15 23:04:50 thorpej Exp $ */
/* $OpenBSD: if_mcx.c,v 1.33 2019/09/12 04:23:59 jmatthew Exp $ */
/*
@ -52,12 +52,13 @@
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
#ifdef NET_MPSAFE
#define MCX_MPSAFE 1
#define CALLOUT_FLAGS CALLOUT_MPSAFE
#else
/* XXX This driver is not yet MP-safe; don't claim to be! */
/* #ifdef NET_MPSAFE */
/* #define MCX_MPSAFE 1 */
/* #define CALLOUT_FLAGS CALLOUT_MPSAFE */
/* #else */
#define CALLOUT_FLAGS 0
#endif
/* #endif */
#define MCX_MAX_NINTR 1
@ -1941,6 +1942,7 @@ struct mcx_softc {
struct ifmedia sc_media;
uint64_t sc_media_status;
uint64_t sc_media_active;
kmutex_t sc_media_mutex;
pci_chipset_tag_t sc_pc;
pci_intr_handle_t *sc_intrs;
@ -2231,6 +2233,8 @@ mcx_attach(device_t parent, device_t self, void *aux)
pci_aprint_devinfo(pa, "Ethernet controller");
mutex_init(&sc->sc_media_mutex, MUTEX_DEFAULT, IPL_SOFTNET);
if (mcx_version(sc) != 0) {
/* error printed by mcx_version */
goto unmap;
@ -2420,8 +2424,8 @@ mcx_attach(device_t parent, device_t self, void *aux)
sc->sc_ec.ec_capabilities = ETHERCAP_VLAN_MTU | ETHERCAP_JUMBO_MTU;
sc->sc_ec.ec_ifmedia = &sc->sc_media;
ifmedia_init(&sc->sc_media, IFM_IMASK, mcx_media_change,
mcx_media_status);
ifmedia_init_with_lock(&sc->sc_media, IFM_IMASK, mcx_media_change,
mcx_media_status, &sc->sc_media_mutex);
mcx_media_add_types(sc);
ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_wm.c,v 1.668 2020/02/18 04:07:14 msaitoh Exp $ */
/* $NetBSD: if_wm.c,v 1.669 2020/03/15 23:04:50 thorpej Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@ -82,7 +82,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.668 2020/02/18 04:07:14 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.669 2020/03/15 23:04:50 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@ -759,7 +759,7 @@ static void wm_init_sysctls(struct wm_softc *);
static void wm_unset_stopping_flags(struct wm_softc *);
static void wm_set_stopping_flags(struct wm_softc *);
static void wm_stop(struct ifnet *, int);
static void wm_stop_locked(struct ifnet *, int);
static void wm_stop_locked(struct ifnet *, bool, bool);
static void wm_dump_mbuf_chain(struct wm_softc *, struct mbuf *);
static void wm_82547_txfifo_stall(void *);
static int wm_82547_txfifo_bugchk(struct wm_softc *, struct mbuf *);
@ -1832,6 +1832,7 @@ wm_attach(device_t parent, device_t self, void *aux)
sc->sc_dev = self;
callout_init(&sc->sc_tick_ch, CALLOUT_FLAGS);
callout_setfunc(&sc->sc_tick_ch, wm_tick, sc);
sc->sc_core_stopping = false;
wmp = wm_lookup(pa);
@ -2880,6 +2881,12 @@ alloc_retry:
snprintb(buf, sizeof(buf), WM_FLAGS, sc->sc_flags);
aprint_verbose_dev(sc->sc_dev, "%s\n", buf);
#ifdef WM_MPSAFE
sc->sc_core_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
#else
sc->sc_core_lock = NULL;
#endif
/* Initialize the media structures accordingly. */
if (sc->sc_mediatype == WM_MEDIATYPE_COPPER)
wm_gmii_mediainit(sc, wmp->wmp_product);
@ -3016,12 +3023,6 @@ alloc_retry:
sc->sc_rx_process_limit = WM_RX_PROCESS_LIMIT_DEFAULT;
sc->sc_rx_intr_process_limit = WM_RX_INTR_PROCESS_LIMIT_DEFAULT;
#ifdef WM_MPSAFE
sc->sc_core_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
#else
sc->sc_core_lock = NULL;
#endif
/* Attach the interface. */
error = if_initialize(ifp);
if (error != 0) {
@ -3102,13 +3103,13 @@ wm_detach(device_t self, int flags __unused)
mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
/* Delete all remaining media. */
ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
ether_ifdetach(ifp);
if_detach(ifp);
if_percpuq_destroy(sc->sc_ipq);
/* Delete all remaining media. */
ifmedia_fini(&sc->sc_mii.mii_media);
/* Unload RX dmamaps and free mbufs */
for (i = 0; i < sc->sc_nqueues; i++) {
struct wm_rxqueue *rxq = &sc->sc_queue[i].wmq_rxq;
@ -3379,7 +3380,7 @@ wm_tick(void *arg)
wm_watchdog(ifp);
callout_reset(&sc->sc_tick_ch, hz, wm_tick, sc);
callout_schedule(&sc->sc_tick_ch, hz);
}
static int
@ -5844,7 +5845,7 @@ wm_init_locked(struct ifnet *ifp)
#endif /* __NO_STRICT_ALIGNMENT */
/* Cancel any pending I/O. */
wm_stop_locked(ifp, 0);
wm_stop_locked(ifp, false, false);
/* Update statistics before reset */
if_statadd2(ifp, if_collisions, CSR_READ(sc, WMREG_COLC),
@ -6378,7 +6379,7 @@ wm_init_locked(struct ifnet *ifp)
wm_unset_stopping_flags(sc);
/* Start the one second link check clock. */
callout_reset(&sc->sc_tick_ch, hz, wm_tick, sc);
callout_schedule(&sc->sc_tick_ch, hz);
/* ...all done! */
ifp->if_flags |= IFF_RUNNING;
@ -6404,8 +6405,10 @@ wm_stop(struct ifnet *ifp, int disable)
{
struct wm_softc *sc = ifp->if_softc;
ASSERT_SLEEPABLE();
WM_CORE_LOCK(sc);
wm_stop_locked(ifp, disable);
wm_stop_locked(ifp, disable ? true : false, true);
WM_CORE_UNLOCK(sc);
/*
@ -6420,7 +6423,7 @@ wm_stop(struct ifnet *ifp, int disable)
}
static void
wm_stop_locked(struct ifnet *ifp, int disable)
wm_stop_locked(struct ifnet *ifp, bool disable, bool wait)
{
struct wm_softc *sc = ifp->if_softc;
struct wm_txsoft *txs;
@ -6432,13 +6435,6 @@ wm_stop_locked(struct ifnet *ifp, int disable)
wm_set_stopping_flags(sc);
/* Stop the one second clock. */
callout_stop(&sc->sc_tick_ch);
/* Stop the 82547 Tx FIFO stall check timer. */
if (sc->sc_type == WM_T_82547)
callout_stop(&sc->sc_txfifo_ch);
if (sc->sc_flags & WM_F_HAS_MII) {
/* Down the MII. */
mii_down(&sc->sc_mii);
@ -6470,6 +6466,26 @@ wm_stop_locked(struct ifnet *ifp, int disable)
CSR_WRITE(sc, WMREG_EIAC_82574, 0);
}
/*
* Stop callouts after interrupts are disabled; if we have
* to wait for them, we will be releasing the CORE_LOCK
* briefly, which will unblock interrupts on the current CPU.
*/
/* Stop the one second clock. */
if (wait)
callout_halt(&sc->sc_tick_ch, sc->sc_core_lock);
else
callout_stop(&sc->sc_tick_ch);
/* Stop the 82547 Tx FIFO stall check timer. */
if (sc->sc_type == WM_T_82547) {
if (wait)
callout_halt(&sc->sc_txfifo_ch, sc->sc_core_lock);
else
callout_stop(&sc->sc_txfifo_ch);
}
/* Release any queued transmit buffers. */
for (qidx = 0; qidx < sc->sc_nqueues; qidx++) {
struct wm_queue *wmq = &sc->sc_queue[qidx];
@ -10423,8 +10439,8 @@ wm_gmii_mediainit(struct wm_softc *sc, pci_product_id_t prodid)
wm_gmii_reset(sc);
sc->sc_ethercom.ec_mii = &sc->sc_mii;
ifmedia_init(&mii->mii_media, IFM_IMASK, wm_gmii_mediachange,
wm_gmii_mediastatus);
ifmedia_init_with_lock(&mii->mii_media, IFM_IMASK, wm_gmii_mediachange,
wm_gmii_mediastatus, sc->sc_core_lock);
if ((sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576)
|| (sc->sc_type == WM_T_82580)
@ -11970,12 +11986,14 @@ wm_tbi_mediainit(struct wm_softc *sc)
sc->sc_ethercom.ec_mii = &sc->sc_mii;
if (((sc->sc_type >= WM_T_82575) && (sc->sc_type <= WM_T_I211))
&& (sc->sc_mediatype == WM_MEDIATYPE_SERDES))
ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK,
wm_serdes_mediachange, wm_serdes_mediastatus);
else
ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK,
wm_tbi_mediachange, wm_tbi_mediastatus);
&& (sc->sc_mediatype == WM_MEDIATYPE_SERDES)) {
ifmedia_init_with_lock(&sc->sc_mii.mii_media, IFM_IMASK,
wm_serdes_mediachange, wm_serdes_mediastatus,
sc->sc_core_lock);
} else {
ifmedia_init_with_lock(&sc->sc_mii.mii_media, IFM_IMASK,
wm_tbi_mediachange, wm_tbi_mediastatus, sc->sc_core_lock);
}
/*
* SWD Pins:

View File

@ -1,4 +1,4 @@
/* $NetBSD: ixgbe.c,v 1.226 2020/02/06 06:28:49 thorpej Exp $ */
/* $NetBSD: ixgbe.c,v 1.227 2020/03/15 23:04:50 thorpej Exp $ */
/******************************************************************************
@ -1387,8 +1387,8 @@ ixgbe_setup_interface(device_t dev, struct adapter *adapter)
* callbacks to update media and link information
*/
ec->ec_ifmedia = &adapter->media;
ifmedia_init(&adapter->media, IFM_IMASK, ixgbe_media_change,
ixgbe_media_status);
ifmedia_init_with_lock(&adapter->media, IFM_IMASK, ixgbe_media_change,
ixgbe_media_status, &adapter->core_mtx);
adapter->phy_layer = ixgbe_get_supported_physical_layer(&adapter->hw);
ixgbe_add_media_types(adapter);
@ -2816,7 +2816,6 @@ ixgbe_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
int layer;
INIT_DEBUGOUT("ixgbe_media_status: begin");
IXGBE_CORE_LOCK(adapter);
ixgbe_update_link_status(adapter);
ifmr->ifm_status = IFM_AVALID;
@ -2824,7 +2823,6 @@ ixgbe_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
if (adapter->link_active != LINK_STATE_UP) {
ifmr->ifm_active |= IFM_NONE;
IXGBE_CORE_UNLOCK(adapter);
return;
}
@ -2945,8 +2943,6 @@ ixgbe_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
hw->fc.current_mode == ixgbe_fc_full)
ifmr->ifm_active |= IFM_ETH_TXPAUSE;
IXGBE_CORE_UNLOCK(adapter);
return;
} /* ixgbe_media_status */
@ -2975,7 +2971,6 @@ ixgbe_media_change(struct ifnet *ifp)
if (hw->phy.media_type == ixgbe_media_type_backplane)
return (EPERM);
IXGBE_CORE_LOCK(adapter);
/*
* We don't actually need to check against the supported
* media types of the adapter; ifmedia will take care of
@ -2988,7 +2983,6 @@ ixgbe_media_change(struct ifnet *ifp)
if (err != IXGBE_SUCCESS) {
device_printf(adapter->dev, "Unable to determine "
"supported advertise speeds\n");
IXGBE_CORE_UNLOCK(adapter);
return (ENODEV);
}
speed |= link_caps;
@ -3046,12 +3040,10 @@ ixgbe_media_change(struct ifnet *ifp)
adapter->advertise |= 1 << 5;
}
IXGBE_CORE_UNLOCK(adapter);
return (0);
invalid:
device_printf(adapter->dev, "Invalid media type!\n");
IXGBE_CORE_UNLOCK(adapter);
return (EINVAL);
} /* ixgbe_media_change */

View File

@ -1,4 +1,4 @@
/*$NetBSD: ixv.c,v 1.146 2020/02/05 10:07:47 msaitoh Exp $*/
/*$NetBSD: ixv.c,v 1.147 2020/03/15 23:04:50 thorpej Exp $*/
/******************************************************************************
@ -989,7 +989,6 @@ ixv_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
struct adapter *adapter = ifp->if_softc;
INIT_DEBUGOUT("ixv_media_status: begin");
IXGBE_CORE_LOCK(adapter);
ixv_update_link_status(adapter);
ifmr->ifm_status = IFM_AVALID;
@ -997,7 +996,6 @@ ixv_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
if (adapter->link_active != LINK_STATE_UP) {
ifmr->ifm_active |= IFM_NONE;
IXGBE_CORE_UNLOCK(adapter);
return;
}
@ -1025,8 +1023,6 @@ ixv_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
}
ifp->if_baudrate = ifmedia_baudrate(ifmr->ifm_active);
IXGBE_CORE_UNLOCK(adapter);
} /* ixv_media_status */
/************************************************************************
@ -1631,8 +1627,8 @@ ixv_setup_interface(device_t dev, struct adapter *adapter)
* callbacks to update media and link information
*/
ec->ec_ifmedia = &adapter->media;
ifmedia_init(&adapter->media, IFM_IMASK, ixv_media_change,
ixv_media_status);
ifmedia_init_with_lock(&adapter->media, IFM_IMASK, ixv_media_change,
ixv_media_status, &adapter->core_mtx);
ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL);
ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO);

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_atu.c,v 1.71 2020/03/13 18:17:40 christos Exp $ */
/* $NetBSD: if_atu.c,v 1.72 2020/03/15 23:04:50 thorpej Exp $ */
/* $OpenBSD: if_atu.c,v 1.48 2004/12/30 01:53:21 dlg Exp $ */
/*
* Copyright (c) 2003, 2004
@ -48,7 +48,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_atu.c,v 1.71 2020/03/13 18:17:40 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_atu.c,v 1.72 2020/03/15 23:04:50 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -1456,7 +1456,10 @@ atu_complete_attach(struct atu_softc *sc)
ic->ic_newstate = atu_newstate;
/* setup ifmedia interface */
ieee80211_media_init(ic, atu_media_change, atu_media_status);
/* XXX media locking needs revisiting */
mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTUSB);
ieee80211_media_init_with_lock(ic,
atu_media_change, atu_media_status, &sc->sc_media_mtx);
usb_init_task(&sc->sc_task, atu_task, sc, 0);

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_atureg.h,v 1.11 2016/04/23 10:15:31 skrll Exp $ */
/* $NetBSD: if_atureg.h,v 1.12 2020/03/15 23:04:50 thorpej Exp $ */
/* $OpenBSD: if_atureg.h,v 1.21 2004/12/23 13:19:38 dlg Exp $ */
/*
* Copyright (c) 2003
@ -138,6 +138,8 @@ struct atu_softc {
int (*sc_newstate)(struct ieee80211com *,
enum ieee80211_state, int);
kmutex_t sc_media_mtx; /* XXX */
char sc_state;
#define ATU_S_DEAD 0
#define ATU_S_OK 1

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_aue.c,v 1.167 2020/03/14 03:01:36 christos Exp $ */
/* $NetBSD: if_aue.c,v 1.168 2020/03/15 23:04:50 thorpej Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000
@ -76,7 +76,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.167 2020/03/14 03:01:36 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.168 2020/03/15 23:04:50 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -239,27 +239,27 @@ CFATTACH_DECL_NEW(aue, sizeof(struct aue_softc), aue_match, aue_attach,
static void aue_reset_pegasus_II(struct aue_softc *);
static void aue_stop_cb(struct ifnet *, int);
static int aue_ioctl_cb(struct ifnet *, u_long, void *);
static int aue_mii_read_reg(struct usbnet *, int, int, uint16_t *);
static int aue_mii_write_reg(struct usbnet *, int, int, uint16_t);
static void aue_mii_statchg(struct ifnet *);
static unsigned aue_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static void aue_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
static int aue_init(struct ifnet *);
static void aue_intr(struct usbnet *, usbd_status);
static void aue_uno_stop(struct ifnet *, int);
static int aue_uno_ioctl(struct ifnet *, u_long, void *);
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 *);
static unsigned aue_uno_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static void aue_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
static int aue_uno_init(struct ifnet *);
static void aue_uno_intr(struct usbnet *, usbd_status);
static const struct usbnet_ops aue_ops = {
.uno_stop = aue_stop_cb,
.uno_ioctl = aue_ioctl_cb,
.uno_read_reg = aue_mii_read_reg,
.uno_write_reg = aue_mii_write_reg,
.uno_statchg = aue_mii_statchg,
.uno_tx_prepare = aue_tx_prepare,
.uno_rx_loop = aue_rx_loop,
.uno_init = aue_init,
.uno_intr = aue_intr,
.uno_stop = aue_uno_stop,
.uno_ioctl = aue_uno_ioctl,
.uno_read_reg = aue_uno_mii_read_reg,
.uno_write_reg = aue_uno_mii_write_reg,
.uno_statchg = aue_uno_mii_statchg,
.uno_tx_prepare = aue_uno_tx_prepare,
.uno_rx_loop = aue_uno_rx_loop,
.uno_init = aue_uno_init,
.uno_intr = aue_uno_intr,
};
static uint32_t aue_crc(void *);
@ -284,7 +284,7 @@ aue_csr_read_1(struct aue_softc *sc, int reg)
usbd_status err;
uByte val = 0;
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return 0;
@ -315,7 +315,7 @@ aue_csr_read_2(struct aue_softc *sc, int reg)
usbd_status err;
uWord val;
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return 0;
@ -346,7 +346,7 @@ aue_csr_write_1(struct aue_softc *sc, int reg, int aval)
usbd_status err;
uByte val;
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return 0;
@ -378,7 +378,7 @@ aue_csr_write_2(struct aue_softc *sc, int reg, int aval)
usbd_status err;
uWord val;
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return 0;
@ -440,7 +440,7 @@ aue_read_mac(struct usbnet *un)
int off = 0;
int word;
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
AUEHIST_FUNC();
AUEHIST_CALLARGS("aue%jd: enter",
@ -454,15 +454,13 @@ aue_read_mac(struct usbnet *un)
}
static int
aue_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
aue_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
{
struct aue_softc *sc = usbnet_softc(un);
int i;
AUEHIST_FUNC();
usbnet_isowned_mii(un);
#if 0
/*
* The Am79C901 HomePNA PHY actually contains
@ -504,13 +502,11 @@ aue_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
}
static int
aue_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
aue_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
{
struct aue_softc *sc = usbnet_softc(un);
int i;
usbnet_isowned_mii(un);
AUEHIST_FUNC();
AUEHIST_CALLARGSN(11, "aue%jd: phy=%jd reg=%jd data=0x%04jx",
device_unit(un->un_dev), phy, reg, val);
@ -542,7 +538,7 @@ aue_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
}
static void
aue_mii_statchg(struct ifnet *ifp)
aue_uno_mii_statchg(struct ifnet *ifp)
{
struct usbnet *un = ifp->if_softc;
struct aue_softc *sc = usbnet_softc(un);
@ -553,7 +549,6 @@ aue_mii_statchg(struct ifnet *ifp)
AUEHIST_CALLARGSN(5, "aue%jd: ifp=%#jx link=%jd",
device_unit(un->un_dev), (uintptr_t)ifp, hadlink, 0);
usbnet_lock_mii(un);
AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB);
if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) {
@ -581,10 +576,9 @@ aue_mii_statchg(struct ifnet *ifp)
*/
if (!usbnet_isdying(un) && (un->un_flags & LSYS)) {
uint16_t auxmode;
aue_mii_read_reg(un, 0, 0x1b, &auxmode);
aue_mii_write_reg(un, 0, 0x1b, auxmode | 0x04);
aue_uno_mii_read_reg(un, 0, 0x1b, &auxmode);
aue_uno_mii_write_reg(un, 0, 0x1b, auxmode | 0x04);
}
usbnet_unlock_mii(un);
if (usbnet_havelink(un) != hadlink) {
DPRINTFN(5, "aue%jd: exit link %jd",
@ -626,7 +620,7 @@ aue_setiff_locked(struct usbnet *un)
AUEHIST_FUNC();
AUEHIST_CALLARGSN(5, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0);
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
if (ifp->if_flags & IFF_PROMISC) {
allmulti:
@ -660,14 +654,6 @@ allmulti:
ifp->if_flags &= ~IFF_ALLMULTI;
}
static void
aue_setiff(struct usbnet *un)
{
usbnet_lock_mii(un);
aue_setiff_locked(un);
usbnet_unlock_mii(un);
}
static void
aue_reset_pegasus_II(struct aue_softc *sc)
{
@ -864,20 +850,20 @@ aue_attach(device_t parent, device_t self, void *aux)
/* First level attach. */
usbnet_attach(un, "auedet");
usbnet_lock_mii(un);
usbnet_lock_core(un);
/* Reset the adapter and get station address from the EEPROM. */
aue_reset(sc);
aue_read_mac(un);
usbnet_unlock_mii(un);
usbnet_unlock_core(un);
usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
0, &unm);
}
static void
aue_intr(struct usbnet *un, usbd_status status)
aue_uno_intr(struct usbnet *un, usbd_status status)
{
struct ifnet *ifp = usbnet_ifp(un);
struct aue_softc *sc = usbnet_softc(un);
@ -895,7 +881,7 @@ aue_intr(struct usbnet *un, usbd_status status)
}
static void
aue_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
aue_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
{
struct ifnet *ifp = usbnet_ifp(un);
uint8_t *buf = c->unc_buf;
@ -906,8 +892,6 @@ aue_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
AUEHIST_CALLARGSN(10, "aue%jd: enter len %ju",
device_unit(un->un_dev), total_len, 0, 0);
usbnet_isowned_rx(un);
if (total_len <= 4 + ETHER_CRC_LEN) {
if_statinc(ifp, if_ierrors);
return;
@ -929,7 +913,7 @@ aue_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
}
static unsigned
aue_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
aue_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
{
uint8_t *buf = c->unc_buf;
int total_len;
@ -938,8 +922,6 @@ aue_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
AUEHIST_CALLARGSN(10, "aue%jd: enter pktlen=%jd",
device_unit(un->un_dev), m->m_pkthdr.len, 0, 0);
usbnet_isowned_tx(un);
if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - 2)
return 0;
@ -984,8 +966,6 @@ aue_init_locked(struct ifnet *ifp)
if (ifp->if_flags & IFF_RUNNING)
return 0;
usbnet_lock_mii_un_locked(un);
/* Reset the interface. */
aue_reset(sc);
@ -999,9 +979,7 @@ aue_init_locked(struct ifnet *ifp)
else
AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
usbnet_unlock_mii_un_locked(un);
rv = usbnet_init_rx_tx(un);
usbnet_lock_mii_un_locked(un);
/* Load the multicast filter. */
aue_setiff_locked(un);
@ -1011,30 +989,29 @@ aue_init_locked(struct ifnet *ifp)
AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_TX_ENB);
AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_EP3_CLR);
usbnet_unlock_mii_un_locked(un);
//mii_mediachg(mii);
return rv;
}
static int
aue_init(struct ifnet *ifp)
aue_uno_init(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;
int rv;
usbnet_lock(un);
usbnet_lock_core(un);
usbnet_busy(un);
rv = aue_init_locked(ifp);
usbnet_unlock(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
return rv;
}
static int
aue_ioctl_cb(struct ifnet *ifp, u_long cmd, void *data)
aue_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
{
struct usbnet * const un = ifp->if_softc;
AUEHIST_FUNC();
AUEHIST_CALLARGSN(5, "aue%jd: enter cmd %#jx data %#jx",
@ -1043,8 +1020,7 @@ aue_ioctl_cb(struct ifnet *ifp, u_long cmd, void *data)
switch (cmd) {
case SIOCADDMULTI:
case SIOCDELMULTI:
aue_init(ifp);
aue_setiff(un);
aue_uno_init(ifp);
break;
default:
break;
@ -1054,7 +1030,7 @@ aue_ioctl_cb(struct ifnet *ifp, u_long cmd, void *data)
}
static void
aue_stop_cb(struct ifnet *ifp, int disable)
aue_uno_stop(struct ifnet *ifp, int disable)
{
struct usbnet * const un = ifp->if_softc;
struct aue_softc * const sc = usbnet_softc(un);
@ -1062,11 +1038,9 @@ aue_stop_cb(struct ifnet *ifp, int disable)
AUEHIST_FUNC();
AUEHIST_CALLARGSN(5, "aue%jd: enter", device_unit(un->un_dev), 0, 0, 0);
usbnet_lock_mii_un_locked(un);
aue_csr_write_1(sc, AUE_CTL0, 0);
aue_csr_write_1(sc, AUE_CTL1, 0);
aue_reset(sc);
usbnet_unlock_mii_un_locked(un);
}
#ifdef _MODULE

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_axe.c,v 1.129 2020/03/01 12:23:12 nisimura Exp $ */
/* $NetBSD: if_axe.c,v 1.130 2020/03/15 23:04:50 thorpej 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.129 2020/03/01 12:23:12 nisimura Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.130 2020/03/15 23:04:50 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -258,15 +258,16 @@ static void axe_attach(device_t, device_t, void *);
CFATTACH_DECL_NEW(axe, sizeof(struct axe_softc),
axe_match, axe_attach, usbnet_detach, usbnet_activate);
static void axe_stop(struct ifnet *, int);
static int axe_ioctl(struct ifnet *, u_long, void *);
static int axe_init(struct ifnet *);
static int axe_mii_read_reg(struct usbnet *, int, int, uint16_t *);
static int axe_mii_write_reg(struct usbnet *, int, int, uint16_t);
static void axe_mii_statchg(struct ifnet *);
static void axe_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
static unsigned axe_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static void axe_uno_stop(struct ifnet *, int);
static int axe_uno_ioctl(struct ifnet *, u_long, void *);
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);
static void axe_uno_mii_statchg(struct ifnet *);
static void axe_uno_rx_loop(struct usbnet *, struct usbnet_chain *,
uint32_t);
static unsigned axe_uno_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static void axe_ax88178_init(struct axe_softc *);
static void axe_ax88772_init(struct axe_softc *);
@ -274,14 +275,14 @@ static void axe_ax88772a_init(struct axe_softc *);
static void axe_ax88772b_init(struct axe_softc *);
static const struct usbnet_ops axe_ops = {
.uno_stop = axe_stop,
.uno_ioctl = axe_ioctl,
.uno_read_reg = axe_mii_read_reg,
.uno_write_reg = axe_mii_write_reg,
.uno_statchg = axe_mii_statchg,
.uno_tx_prepare = axe_tx_prepare,
.uno_rx_loop = axe_rx_loop,
.uno_init = axe_init,
.uno_stop = axe_uno_stop,
.uno_ioctl = axe_uno_ioctl,
.uno_read_reg = axe_uno_mii_read_reg,
.uno_write_reg = axe_uno_mii_write_reg,
.uno_statchg = axe_uno_mii_statchg,
.uno_tx_prepare = axe_uno_tx_prepare,
.uno_rx_loop = axe_uno_rx_loop,
.uno_init = axe_uno_init,
};
static usbd_status
@ -292,7 +293,7 @@ axe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf)
usb_device_request_t req;
usbd_status err;
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return -1;
@ -316,7 +317,7 @@ axe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf)
}
static int
axe_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
axe_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
{
AXEHIST_FUNC(); AXEHIST_CALLED();
struct axe_softc * const sc = usbnet_softc(un);
@ -355,7 +356,7 @@ axe_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
}
static int
axe_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
axe_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
{
struct axe_softc * const sc = usbnet_softc(un);
usbd_status err;
@ -376,7 +377,7 @@ axe_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
}
static void
axe_mii_statchg(struct ifnet *ifp)
axe_uno_mii_statchg(struct ifnet *ifp)
{
AXEHIST_FUNC(); AXEHIST_CALLED();
@ -419,9 +420,7 @@ axe_mii_statchg(struct ifnet *ifp)
}
DPRINTF("val=%#jx", val, 0, 0, 0);
usbnet_lock_mii(un);
err = axe_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL);
usbnet_unlock_mii(un);
if (err)
aprint_error_dev(un->un_dev, "media change failed\n");
}
@ -439,8 +438,6 @@ axe_setiff_locked(struct usbnet *un)
uint16_t rxmode;
uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
usbnet_isowned_mii(un);
if (usbnet_isdying(un))
return;
@ -488,14 +485,6 @@ axe_setiff_locked(struct usbnet *un)
axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
}
static void
axe_setiff(struct usbnet *un)
{
usbnet_lock_mii(un);
axe_setiff_locked(un);
usbnet_unlock_mii(un);
}
static void
axe_ax_init(struct usbnet *un)
{
@ -527,7 +516,7 @@ static void
axe_reset(struct usbnet *un)
{
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return;
@ -667,11 +656,11 @@ axe_ax88178_init(struct axe_softc *sc)
AXE_GPIO_WRITE(val | AXE_GPIO2_EN, hz / 4);
AXE_GPIO_WRITE(val | AXE_GPIO2 | AXE_GPIO2_EN, hz / 32);
if (phymode == AXE_PHY_MODE_REALTEK_8211CL) {
axe_mii_write_reg(un, un->un_phyno, 0x1F, 0x0005);
axe_mii_write_reg(un, un->un_phyno, 0x0C, 0x0000);
axe_mii_read_reg(un, un->un_phyno, 0x0001, &val);
axe_mii_write_reg(un, un->un_phyno, 0x01, val | 0x0080);
axe_mii_write_reg(un, un->un_phyno, 0x1F, 0x0000);
axe_uno_mii_write_reg(un, un->un_phyno, 0x1F, 0x0005);
axe_uno_mii_write_reg(un, un->un_phyno, 0x0C, 0x0000);
axe_uno_mii_read_reg(un, un->un_phyno, 0x0001, &val);
axe_uno_mii_write_reg(un, un->un_phyno, 0x01, val | 0x0080);
axe_uno_mii_write_reg(un, un->un_phyno, 0x1F, 0x0000);
}
break;
default:
@ -944,10 +933,12 @@ axe_attach(device_t parent, device_t self, void *aux)
usbnet_attach(un, "axedet");
/* We need the PHYID for init dance in some cases */
usbnet_lock_mii(un);
usbnet_lock_core(un);
usbnet_busy(un);
if (axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, &sc->axe_phyaddrs)) {
aprint_error_dev(self, "failed to read phyaddrs\n");
usbnet_unbusy(un);
usbnet_unlock_core(un);
return;
}
@ -977,12 +968,14 @@ axe_attach(device_t parent, device_t self, void *aux)
} else {
if (axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, sc->axe_ipgs)) {
aprint_error_dev(self, "failed to read ipg\n");
usbnet_unlock_mii(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
return;
}
}
usbnet_unlock_mii(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
if (!AXE_IS_172(un))
usbnet_ec(un)->ec_capabilities = ETHERCAP_VLAN_MTU;
@ -1011,7 +1004,7 @@ axe_attach(device_t parent, device_t self, void *aux)
}
static void
axe_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
axe_uno_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
{
AXEHIST_FUNC(); AXEHIST_CALLED();
struct axe_softc * const sc = usbnet_softc(un);
@ -1144,7 +1137,7 @@ axe_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
}
static unsigned
axe_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
axe_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
{
AXEHIST_FUNC(); AXEHIST_CALLED();
struct axe_sframe_hdr hdr, tlr;
@ -1234,7 +1227,7 @@ axe_init_locked(struct ifnet *ifp)
struct axe_softc * const sc = usbnet_softc(un);
int rxmode;
usbnet_isowned(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return EIO;
@ -1242,8 +1235,6 @@ axe_init_locked(struct ifnet *ifp)
/* Cancel pending I/O */
usbnet_stop(un, ifp, 1);
usbnet_lock_mii_un_locked(un);
/* Reset the ethernet interface. */
axe_reset(un);
@ -1322,48 +1313,52 @@ axe_init_locked(struct ifnet *ifp)
/* Accept multicast frame or run promisc. mode */
axe_setiff_locked(un);
usbnet_unlock_mii_un_locked(un);
return usbnet_init_rx_tx(un);
}
static int
axe_init(struct ifnet *ifp)
axe_uno_init(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;
usbnet_lock(un);
usbnet_lock_core(un);
usbnet_busy(un);
int ret = axe_init_locked(ifp);
usbnet_unlock(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
return ret;
}
static int
axe_ioctl(struct ifnet *ifp, u_long cmd, void *data)
axe_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
{
struct usbnet * const un = ifp->if_softc;
usbnet_lock_core(un);
usbnet_busy(un);
switch (cmd) {
case SIOCADDMULTI:
case SIOCDELMULTI:
axe_setiff(un);
axe_setiff_locked(un);
break;
default:
break;
}
usbnet_unbusy(un);
usbnet_unlock_core(un);
return 0;
}
static void
axe_stop(struct ifnet *ifp, int disable)
axe_uno_stop(struct ifnet *ifp, int disable)
{
struct usbnet * const un = ifp->if_softc;
usbnet_lock_mii_un_locked(un);
axe_reset(un);
usbnet_unlock_mii_un_locked(un);
}
#ifdef _MODULE

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_axen.c,v 1.72 2020/03/14 02:35:33 christos Exp $ */
/* $NetBSD: if_axen.c,v 1.73 2020/03/15 23:04:50 thorpej 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.72 2020/03/14 02:35:33 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_axen.c,v 1.73 2020/03/15 23:04:50 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -78,25 +78,26 @@ static void axen_reset(struct usbnet *);
static int axen_get_eaddr(struct usbnet *, void *);
static void axen_ax88179_init(struct usbnet *);
static void axen_stop_cb(struct ifnet *, int);
static int axen_ioctl_cb(struct ifnet *, u_long, void *);
static int axen_mii_read_reg(struct usbnet *, int, int, uint16_t *);
static int axen_mii_write_reg(struct usbnet *, int, int, uint16_t);
static void axen_mii_statchg(struct ifnet *);
static void axen_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
static unsigned axen_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static int axen_init(struct ifnet *);
static void axen_uno_stop(struct ifnet *, int);
static int axen_uno_ioctl(struct ifnet *, u_long, void *);
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 *);
static void axen_uno_rx_loop(struct usbnet *, struct usbnet_chain *,
uint32_t);
static unsigned axen_uno_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static int axen_uno_init(struct ifnet *);
static const struct usbnet_ops axen_ops = {
.uno_stop = axen_stop_cb,
.uno_ioctl = axen_ioctl_cb,
.uno_read_reg = axen_mii_read_reg,
.uno_write_reg = axen_mii_write_reg,
.uno_statchg = axen_mii_statchg,
.uno_tx_prepare = axen_tx_prepare,
.uno_rx_loop = axen_rx_loop,
.uno_init = axen_init,
.uno_stop = axen_uno_stop,
.uno_ioctl = axen_uno_ioctl,
.uno_read_reg = axen_uno_mii_read_reg,
.uno_write_reg = axen_uno_mii_write_reg,
.uno_statchg = axen_uno_mii_statchg,
.uno_tx_prepare = axen_uno_tx_prepare,
.uno_rx_loop = axen_uno_rx_loop,
.uno_init = axen_uno_init,
};
static int
@ -105,7 +106,7 @@ axen_cmd(struct usbnet *un, int cmd, int index, int val, void *buf)
usb_device_request_t req;
usbd_status err;
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return 0;
@ -132,7 +133,7 @@ axen_cmd(struct usbnet *un, int cmd, int index, int val, void *buf)
}
static int
axen_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
axen_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
{
uint16_t data;
@ -151,7 +152,7 @@ axen_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
}
static int
axen_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
axen_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
{
uint16_t uval = htole16(val);
@ -166,7 +167,7 @@ axen_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
}
static void
axen_mii_statchg(struct ifnet *ifp)
axen_uno_mii_statchg(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;
struct mii_data * const mii = usbnet_mii(un);
@ -216,9 +217,7 @@ axen_mii_statchg(struct ifnet *ifp)
DPRINTF(("%s: val=%#x\n", __func__, val));
wval = htole16(val);
usbnet_lock_mii(un);
err = axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval);
usbnet_unlock_mii(un);
if (err)
aprint_error_dev(un->un_dev, "media change failed\n");
}
@ -238,7 +237,7 @@ axen_setiff_locked(struct usbnet *un)
if (usbnet_isdying(un))
return;
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
rxmode = 0;
@ -291,18 +290,10 @@ allmulti:
axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval);
}
static void
axen_setiff(struct usbnet *un)
{
usbnet_lock_mii(un);
axen_setiff_locked(un);
usbnet_unlock_mii(un);
}
static void
axen_reset(struct usbnet *un)
{
usbnet_isowned(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return;
/* XXX What to reset? */
@ -374,7 +365,8 @@ axen_ax88179_init(struct usbnet *un)
uint16_t wval;
uint8_t val;
usbnet_lock_mii(un);
usbnet_lock_core(un);
usbnet_busy(un);
/* XXX: ? */
axen_cmd(un, AXEN_CMD_MAC_READ, 1, AXEN_UNK_05, &val);
@ -458,7 +450,8 @@ axen_ax88179_init(struct usbnet *un)
default:
aprint_error_dev(un->un_dev, "unknown uplink bus:0x%02x\n",
val);
usbnet_unlock_mii(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
return;
}
axen_cmd(un, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL, &qctrl);
@ -498,8 +491,6 @@ axen_ax88179_init(struct usbnet *un)
axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_MEDIUM_STATUS, &wval);
DPRINTF(("axen: current medium mode: 0x%04x\n", le16toh(wval)));
usbnet_unlock_mii(un);
#if 0 /* XXX: TBD.... */
#define GMII_LED_ACTIVE 0x1a
#define GMII_PHY_PAGE_SEL 0x1e
@ -518,6 +509,9 @@ axen_ax88179_init(struct usbnet *un)
usbnet_mii_writereg(un->un_dev, un->un_phyno, 0x01, wval | 0x0080);
usbnet_mii_writereg(un->un_dev, un->un_phyno, 0x1F, 0x0000);
#endif
usbnet_unbusy(un);
usbnet_unlock_core(un);
}
static void
@ -527,7 +521,7 @@ axen_setoe_locked(struct usbnet *un)
uint64_t enabled = ifp->if_capenable;
uint8_t val;
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
val = AXEN_RXCOE_OFF;
if (enabled & IFCAP_CSUM_IPv4_Rx)
@ -556,34 +550,31 @@ axen_setoe_locked(struct usbnet *un)
axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_TX_COE, &val);
}
static void
axen_setoe(struct usbnet *un)
{
usbnet_lock_mii(un);
axen_setoe_locked(un);
usbnet_unlock_mii(un);
}
static int
axen_ioctl_cb(struct ifnet *ifp, u_long cmd, void *data)
axen_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
{
struct usbnet * const un = ifp->if_softc;
usbnet_lock_core(un);
usbnet_busy(un);
switch (cmd) {
case SIOCSIFFLAGS:
case SIOCSETHERCAP:
case SIOCADDMULTI:
case SIOCDELMULTI:
axen_setiff(un);
axen_setiff_locked(un);
break;
case SIOCSIFCAP:
axen_setoe(un);
axen_setoe_locked(un);
break;
default:
break;
}
usbnet_unbusy(un);
usbnet_unlock_core(un);
return 0;
}
@ -684,13 +675,16 @@ axen_attach(device_t parent, device_t self, void *aux)
DPRINTF(("%s: phyno %d\n", device_xname(self), un->un_phyno));
/* Get station address. */
usbnet_lock_mii(un);
usbnet_lock_core(un);
usbnet_busy(un);
if (axen_get_eaddr(un, &un->un_eaddr)) {
usbnet_unlock_mii(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
printf("EEPROM checksum error\n");
return;
}
usbnet_unlock_mii(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
axen_ax88179_init(un);
@ -764,7 +758,7 @@ axen_csum_flags_rx(struct ifnet *ifp, uint32_t pkt_hdr)
}
static void
axen_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
axen_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
{
struct ifnet *ifp = usbnet_ifp(un);
uint8_t *buf = c->unc_buf;
@ -774,8 +768,6 @@ axen_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
size_t pkt_len;
size_t temp;
usbnet_isowned_rx(un);
if (total_len < sizeof(pkt_hdr)) {
aprint_error_dev(un->un_dev, "rxeof: too short transfer\n");
if_statinc(ifp, if_ierrors);
@ -863,13 +855,11 @@ nextpkt:
}
static unsigned
axen_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
axen_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
{
struct axen_sframe_hdr hdr;
u_int length, boundary;
usbnet_isowned_tx(un);
if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - sizeof(hdr))
return 0;
length = m->m_pkthdr.len + sizeof(hdr);
@ -911,7 +901,7 @@ axen_init_locked(struct ifnet *ifp)
uint16_t wval;
uint8_t bval;
usbnet_isowned(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return EIO;
@ -922,8 +912,6 @@ axen_init_locked(struct ifnet *ifp)
/* Reset the ethernet interface. */
axen_reset(un);
usbnet_lock_mii_un_locked(un);
/* XXX: ? */
bval = 0x01;
axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_UNK_28, &bval);
@ -941,25 +929,25 @@ axen_init_locked(struct ifnet *ifp)
wval = htole16(rxmode);
axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval);
usbnet_unlock_mii_un_locked(un);
return usbnet_init_rx_tx(un);
}
static int
axen_init(struct ifnet *ifp)
axen_uno_init(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;
usbnet_lock(un);
usbnet_lock_core(un);
usbnet_busy(un);
int ret = axen_init_locked(ifp);
usbnet_unlock(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
return ret;
}
static void
axen_stop_cb(struct ifnet *ifp, int disable)
axen_uno_stop(struct ifnet *ifp, int disable)
{
struct usbnet * const un = ifp->if_softc;
uint16_t rxmode, wval;
@ -967,13 +955,11 @@ axen_stop_cb(struct ifnet *ifp, int disable)
axen_reset(un);
/* Disable receiver, set RX mode */
usbnet_lock_mii_un_locked(un);
axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_MAC_RXCTL, &wval);
rxmode = le16toh(wval);
rxmode &= ~AXEN_RXCTL_START;
wval = htole16(rxmode);
axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval);
usbnet_unlock_mii_un_locked(un);
}
#ifdef _MODULE

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_cdce.c,v 1.69 2020/01/29 06:26:32 thorpej Exp $ */
/* $NetBSD: if_cdce.c,v 1.70 2020/03/15 23:04:50 thorpej Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul <wpaul@windriver.com>
@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_cdce.c,v 1.69 2020/01/29 06:26:32 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_cdce.c,v 1.70 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
@ -78,15 +78,16 @@ static void cdce_attach(device_t, device_t, void *);
CFATTACH_DECL_NEW(cdce, sizeof(struct usbnet), cdce_match, cdce_attach,
usbnet_detach, usbnet_activate);
static void cdce_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
static unsigned cdce_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static int cdce_init(struct ifnet *);
static void cdce_uno_rx_loop(struct usbnet *, struct usbnet_chain *,
uint32_t);
static unsigned cdce_uno_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static int cdce_uno_init(struct ifnet *);
static const struct usbnet_ops cdce_ops = {
.uno_tx_prepare = cdce_tx_prepare,
.uno_rx_loop = cdce_rx_loop,
.uno_init = cdce_init,
.uno_tx_prepare = cdce_uno_tx_prepare,
.uno_rx_loop = cdce_uno_rx_loop,
.uno_init = cdce_uno_init,
};
static int
@ -252,12 +253,12 @@ cdce_attach(device_t parent, device_t self, void *aux)
}
static int
cdce_init(struct ifnet *ifp)
cdce_uno_init(struct ifnet *ifp)
{
struct usbnet *un = ifp->if_softc;
int rv;
usbnet_lock(un);
usbnet_lock_core(un);
if (usbnet_isdying(un))
rv = EIO;
else {
@ -265,13 +266,13 @@ cdce_init(struct ifnet *ifp)
rv = usbnet_init_rx_tx(un);
usbnet_set_link(un, rv == 0);
}
usbnet_unlock(un);
usbnet_unlock_core(un);
return rv;
}
static void
cdce_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
cdce_uno_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
{
struct ifnet *ifp = usbnet_ifp(un);
@ -290,15 +291,13 @@ cdce_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
}
static unsigned
cdce_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
cdce_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
{
/* Zaurus wants a 32-bit CRC appended to every frame */
uint32_t crc;
unsigned extra = 0;
unsigned length;
usbnet_isowned_tx(un);
if (un->un_flags & CDCE_ZAURUS)
extra = sizeof(crc);

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_cue.c,v 1.90 2020/03/13 18:17:40 christos Exp $ */
/* $NetBSD: if_cue.c,v 1.91 2020/03/15 23:04:50 thorpej Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000
@ -57,7 +57,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_cue.c,v 1.90 2020/03/13 18:17:40 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_cue.c,v 1.91 2020/03/15 23:04:50 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@ -138,21 +138,21 @@ static void cue_attach(device_t, device_t, void *);
CFATTACH_DECL_NEW(cue, sizeof(struct cue_softc), cue_match, cue_attach,
usbnet_detach, usbnet_activate);
static unsigned cue_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static void cue_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
static int cue_ioctl_cb(struct ifnet *, u_long, void *);
static void cue_stop_cb(struct ifnet *, int);
static int cue_init(struct ifnet *);
static void cue_tick(struct usbnet *);
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_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_stop_cb,
.uno_ioctl = cue_ioctl_cb,
.uno_tx_prepare = cue_tx_prepare,
.uno_rx_loop = cue_rx_loop,
.uno_init = cue_init,
.uno_tick = cue_tick,
.uno_stop = cue_uno_stop,
.uno_ioctl = cue_uno_ioctl,
.uno_tx_prepare = cue_uno_tx_prepare,
.uno_rx_loop = cue_uno_rx_loop,
.uno_init = cue_uno_init,
.uno_tick = cue_uno_tick,
};
#ifdef CUE_DEBUG
@ -357,7 +357,7 @@ cue_crc(const char *addr)
}
static void
cue_setiff(struct usbnet *un)
cue_setiff_locked(struct usbnet *un)
{
struct cue_softc *sc = usbnet_softc(un);
struct ethercom *ec = usbnet_ec(un);
@ -541,10 +541,12 @@ cue_attach(device_t parent, device_t self, void *aux)
}
static void
cue_tick(struct usbnet *un)
cue_uno_tick(struct usbnet *un)
{
struct ifnet *ifp = usbnet_ifp(un);
usbnet_lock_core(un);
net_stat_ref_t nsr = IF_STAT_GETREF(ifp);
if (cue_csr_read_2(un, CUE_RX_FRAMEERR))
if_statinc_ref(nsr, if_ierrors);
@ -556,10 +558,12 @@ cue_tick(struct usbnet *un)
if_statadd_ref(nsr, if_collisions,
cue_csr_read_2(un, CUE_TX_EXCESSCOLL));
IF_STAT_PUTREF(ifp);
usbnet_unlock_core(un);
}
static void
cue_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
cue_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
{
struct ifnet *ifp = usbnet_ifp(un);
uint8_t *buf = c->unc_buf;
@ -582,7 +586,7 @@ cue_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
}
static unsigned
cue_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
cue_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
{
unsigned total_len;
@ -644,7 +648,7 @@ cue_init_locked(struct ifnet *ifp)
cue_csr_write_1(un, CUE_ETHCTL, ctl);
/* Load the multicast filter. */
cue_setiff(un);
cue_setiff_locked(un);
/*
* Set the number of RX and TX buffers that we want
@ -664,38 +668,46 @@ cue_init_locked(struct ifnet *ifp)
}
static int
cue_init(struct ifnet *ifp)
cue_uno_init(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;
int rv;
usbnet_lock(un);
usbnet_lock_core(un);
usbnet_busy(un);
rv = cue_init_locked(ifp);
usbnet_unlock(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
return rv;
}
static int
cue_ioctl_cb(struct ifnet *ifp, u_long cmd, void *data)
cue_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
{
struct usbnet * const un = ifp->if_softc;
usbnet_lock_core(un);
usbnet_busy(un);
switch (cmd) {
case SIOCADDMULTI:
case SIOCDELMULTI:
cue_setiff(un);
cue_setiff_locked(un);
break;
default:
break;
}
usbnet_unbusy(un);
usbnet_unlock_core(un);
return 0;
}
/* Stop and reset the adapter. */
static void
cue_stop_cb(struct ifnet *ifp, int disable)
cue_uno_stop(struct ifnet *ifp, int disable)
{
struct usbnet * const un = ifp->if_softc;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_kue.c,v 1.102 2020/01/29 06:26:32 thorpej Exp $ */
/* $NetBSD: if_kue.c,v 1.103 2020/03/15 23:04:50 thorpej Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000
@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_kue.c,v 1.102 2020/01/29 06:26:32 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_kue.c,v 1.103 2020/03/15 23:04:50 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@ -171,20 +171,19 @@ static int kue_detach(device_t, int);
CFATTACH_DECL_NEW(kue, sizeof(struct kue_softc), kue_match, kue_attach,
kue_detach, usbnet_activate);
static void kue_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
static unsigned kue_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static int kue_ioctl_cb(struct ifnet *, u_long, void *);
static int kue_init(struct ifnet *);
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 int kue_uno_init(struct ifnet *);
static const struct usbnet_ops kue_ops = {
.uno_ioctl = kue_ioctl_cb,
.uno_tx_prepare = kue_tx_prepare,
.uno_rx_loop = kue_rx_loop,
.uno_init = kue_init,
.uno_ioctl = kue_uno_ioctl,
.uno_tx_prepare = kue_uno_tx_prepare,
.uno_rx_loop = kue_uno_rx_loop,
.uno_init = kue_uno_init,
};
static void kue_setiff(struct usbnet *);
static void kue_reset(struct usbnet *);
static usbd_status kue_ctl(struct usbnet *, int, uint8_t,
@ -319,7 +318,7 @@ kue_load_fw(struct usbnet *un)
}
static void
kue_setiff(struct usbnet *un)
kue_setiff_locked(struct usbnet *un)
{
struct ethercom * ec = usbnet_ec(un);
struct kue_softc * sc = usbnet_softc(un);
@ -532,7 +531,7 @@ kue_detach(device_t self, int flags)
* the higher level protocols.
*/
static void
kue_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
kue_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
{
struct ifnet *ifp = usbnet_ifp(un);
uint8_t *buf = c->unc_buf;
@ -561,7 +560,7 @@ kue_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
}
static unsigned
kue_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
kue_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
{
unsigned total_len, pkt_len;
@ -623,39 +622,46 @@ kue_init_locked(struct ifnet *ifp)
kue_setword(un, KUE_CMD_SET_URB_SIZE, 64);
/* Load the multicast filter. */
kue_setiff(un);
kue_setiff_locked(un);
return usbnet_init_rx_tx(un);
}
static int
kue_init(struct ifnet *ifp)
kue_uno_init(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;
int rv;
usbnet_lock(un);
usbnet_lock_core(un);
usbnet_busy(un);
rv = kue_init_locked(ifp);
usbnet_unlock(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
return rv;
}
static int
kue_ioctl_cb(struct ifnet *ifp, u_long cmd, void *data)
kue_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
{
struct usbnet * const un = ifp->if_softc;
usbnet_lock_core(un);
usbnet_busy(un);
switch (cmd) {
case SIOCADDMULTI:
case SIOCDELMULTI:
//kue_init(ifp);
kue_setiff(un);
kue_setiff_locked(un);
break;
default:
break;
}
usbnet_unbusy(un);
usbnet_unlock_core(un);
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_mos.c,v 1.4 2020/01/29 06:26:32 thorpej Exp $ */
/* $NetBSD: if_mos.c,v 1.5 2020/03/15 23:04:50 thorpej 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.4 2020/01/29 06:26:32 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_mos.c,v 1.5 2020/03/15 23:04:50 thorpej Exp $");
#include <sys/param.h>
@ -142,16 +142,16 @@ static void mos_attach(device_t, device_t, void *);
CFATTACH_DECL_NEW(mos, sizeof(struct usbnet),
mos_match, mos_attach, usbnet_detach, usbnet_activate);
static void mos_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
static unsigned mos_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static int mos_ioctl(struct ifnet *, u_long, void *);
static int mos_init(struct ifnet *);
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 int mos_uno_init(struct ifnet *);
static void mos_chip_init(struct usbnet *);
static void mos_stop(struct ifnet *ifp, int disable);
static int mos_mii_read_reg(struct usbnet *, int, int, uint16_t *);
static int mos_mii_write_reg(struct usbnet *, int, int, uint16_t);
static void mos_mii_statchg(struct ifnet *);
static void mos_uno_stop(struct ifnet *ifp, int disable);
static int mos_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *);
static int mos_uno_mii_write_reg(struct usbnet *, int, int, uint16_t);
static void mos_uno_mii_statchg(struct ifnet *);
static void mos_reset(struct usbnet *);
static int mos_reg_read_1(struct usbnet *, int);
@ -163,14 +163,14 @@ static int mos_writemac(struct usbnet *);
static int mos_write_mcast(struct usbnet *, uint8_t *);
static const struct usbnet_ops mos_ops = {
.uno_stop = mos_stop,
.uno_ioctl = mos_ioctl,
.uno_read_reg = mos_mii_read_reg,
.uno_write_reg = mos_mii_write_reg,
.uno_statchg = mos_mii_statchg,
.uno_tx_prepare = mos_tx_prepare,
.uno_rx_loop = mos_rx_loop,
.uno_init = mos_init,
.uno_stop = mos_uno_stop,
.uno_ioctl = mos_uno_ioctl,
.uno_read_reg = mos_uno_mii_read_reg,
.uno_write_reg = mos_uno_mii_write_reg,
.uno_statchg = mos_uno_mii_statchg,
.uno_tx_prepare = mos_uno_tx_prepare,
.uno_rx_loop = mos_uno_rx_loop,
.uno_init = mos_uno_init,
};
static int
@ -353,7 +353,7 @@ mos_write_mcast(struct usbnet *un, uint8_t *hashtbl)
}
static int
mos_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
mos_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
{
int i, res;
@ -382,7 +382,7 @@ mos_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
}
static int
mos_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
mos_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
{
int i;
@ -408,7 +408,7 @@ mos_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
}
void
mos_mii_statchg(struct ifnet *ifp)
mos_uno_mii_statchg(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;
struct mii_data * const mii = usbnet_mii(un);
@ -419,8 +419,6 @@ mos_mii_statchg(struct ifnet *ifp)
DPRINTFN(10,("%s: %s: enter\n", device_xname(un->un_dev), __func__));
usbnet_lock_mii(un);
/* disable RX, TX prior to changing FDX, SPEEDSEL */
val = mos_reg_read_1(un, MOS_CTL);
val &= ~(MOS_CTL_TX_ENB | MOS_CTL_RX_ENB);
@ -450,7 +448,6 @@ mos_mii_statchg(struct ifnet *ifp)
/* re-enable TX, RX */
val |= (MOS_CTL_TX_ENB | MOS_CTL_RX_ENB);
err = mos_reg_write_1(un, MOS_CTL, val);
usbnet_unlock_mii(un);
if (err)
aprint_error_dev(un->un_dev, "media change failed\n");
@ -511,14 +508,6 @@ allmulti:
mos_reg_write_1(un, MOS_CTL, rxmode);
}
static void
mos_setiff(struct usbnet *un)
{
usbnet_lock_mii(un);
mos_setiff_locked(un);
usbnet_unlock_mii(un);
}
static void
mos_reset(struct usbnet *un)
{
@ -669,7 +658,7 @@ mos_attach(device_t parent, device_t self, void *aux)
* the higher level protocols.
*/
void
mos_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
mos_uno_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
{
struct ifnet *ifp = usbnet_ifp(un);
uint8_t *buf = c->unc_buf;
@ -714,12 +703,10 @@ mos_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
}
static unsigned
mos_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
mos_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
{
int length;
usbnet_isowned_tx(un);
if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz)
return 0;
@ -745,8 +732,6 @@ mos_init_locked(struct ifnet *ifp)
/* Cancel pending I/O */
usbnet_stop(un, ifp, 1);
usbnet_lock_mii_un_locked(un);
/* Reset the ethernet interface. */
mos_reset(un);
@ -768,46 +753,50 @@ mos_init_locked(struct ifnet *ifp)
rxmode &= ~(MOS_CTL_SLEEP);
mos_reg_write_1(un, MOS_CTL, rxmode);
usbnet_unlock_mii_un_locked(un);
return usbnet_init_rx_tx(un);
}
static int
mos_init(struct ifnet *ifp)
mos_uno_init(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;
usbnet_lock(un);
usbnet_lock_core(un);
usbnet_busy(un);
int ret = mos_init_locked(ifp);
usbnet_unlock(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
return ret;
}
static int
mos_ioctl(struct ifnet *ifp, u_long cmd, void *data)
mos_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
{
struct usbnet * const un = ifp->if_softc;
usbnet_lock_core(un);
usbnet_busy(un);
switch (cmd) {
case SIOCADDMULTI:
case SIOCDELMULTI:
mos_setiff(un);
mos_setiff_locked(un);
break;
default:
break;
}
usbnet_unbusy(un);
usbnet_unlock_core(un);
return 0;
}
void
mos_stop(struct ifnet *ifp, int disable)
mos_uno_stop(struct ifnet *ifp, int disable)
{
struct usbnet * const un = ifp->if_softc;
usbnet_lock_mii_un_locked(un);
mos_reset(un);
usbnet_unlock_mii_un_locked(un);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_mue.c,v 1.58 2020/03/13 18:17:40 christos Exp $ */
/* $NetBSD: if_mue.c,v 1.59 2020/03/15 23:04:50 thorpej 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.58 2020/03/13 18:17:40 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_mue.c,v 1.59 2020/03/15 23:04:50 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -92,30 +92,31 @@ static int mue_chip_init(struct usbnet *);
static void mue_set_macaddr(struct usbnet *);
static int mue_get_macaddr(struct usbnet *, prop_dictionary_t);
static int mue_prepare_tso(struct usbnet *, struct mbuf *);
static void mue_setiff(struct usbnet *);
static void mue_sethwcsum(struct usbnet *);
static void mue_setmtu(struct usbnet *);
static void mue_setiff_locked(struct usbnet *);
static void mue_sethwcsum_locked(struct usbnet *);
static void mue_setmtu_locked(struct usbnet *);
static void mue_reset(struct usbnet *);
static void mue_stop_cb(struct ifnet *, int);
static int mue_ioctl_cb(struct ifnet *, u_long, void *);
static int mue_mii_read_reg(struct usbnet *, int, int, uint16_t *);
static int mue_mii_write_reg(struct usbnet *, int, int, uint16_t);
static void mue_mii_statchg(struct ifnet *);
static void mue_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
static unsigned mue_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static int mue_init(struct ifnet *);
static void mue_uno_stop(struct ifnet *, int);
static int mue_uno_ioctl(struct ifnet *, u_long, void *);
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 *);
static void mue_uno_rx_loop(struct usbnet *, struct usbnet_chain *,
uint32_t);
static unsigned mue_uno_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static int mue_uno_init(struct ifnet *);
static const struct usbnet_ops mue_ops = {
.uno_stop = mue_stop_cb,
.uno_ioctl = mue_ioctl_cb,
.uno_read_reg = mue_mii_read_reg,
.uno_write_reg = mue_mii_write_reg,
.uno_statchg = mue_mii_statchg,
.uno_tx_prepare = mue_tx_prepare,
.uno_rx_loop = mue_rx_loop,
.uno_init = mue_init,
.uno_stop = mue_uno_stop,
.uno_ioctl = mue_uno_ioctl,
.uno_read_reg = mue_uno_mii_read_reg,
.uno_write_reg = mue_uno_mii_write_reg,
.uno_statchg = mue_uno_mii_statchg,
.uno_tx_prepare = mue_uno_tx_prepare,
.uno_rx_loop = mue_uno_rx_loop,
.uno_init = mue_uno_init,
};
#define MUE_SETBIT(un, reg, x) \
@ -211,12 +212,10 @@ mue_wait_for_bits(struct usbnet *un, uint32_t reg,
}
static int
mue_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
mue_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
{
uint32_t data;
usbnet_isowned_mii(un);
if (un->un_phyno != phy)
return EINVAL;
@ -241,9 +240,8 @@ mue_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
}
static int
mue_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
mue_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
{
usbnet_isowned_mii(un);
if (un->un_phyno != phy)
return EINVAL;
@ -267,7 +265,7 @@ mue_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
}
static void
mue_mii_statchg(struct ifnet *ifp)
mue_uno_mii_statchg(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;
struct mii_data * const mii = usbnet_mii(un);
@ -891,7 +889,7 @@ mue_attach(device_t parent, device_t self, void *aux)
}
static unsigned
mue_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
mue_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
{
struct ifnet * const ifp = usbnet_ifp(un);
struct mue_txbuf_hdr hdr;
@ -899,8 +897,6 @@ mue_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
int csum, len, rv;
bool tso, ipe, tpe;
usbnet_isowned_tx(un);
if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - sizeof(hdr))
return 0;
@ -997,7 +993,7 @@ mue_prepare_tso(struct usbnet *un, struct mbuf *m)
}
static void
mue_setiff(struct usbnet *un)
mue_setiff_locked(struct usbnet *un)
{
struct ethercom *ec = usbnet_ec(un);
struct ifnet * const ifp = usbnet_ifp(un);
@ -1088,7 +1084,7 @@ allmulti: rxfilt |= MUE_RFE_CTL_MULTICAST;
}
static void
mue_sethwcsum(struct usbnet *un)
mue_sethwcsum_locked(struct usbnet *un)
{
struct ifnet * const ifp = usbnet_ifp(un);
uint32_t reg, val;
@ -1120,7 +1116,7 @@ mue_sethwcsum(struct usbnet *un)
}
static void
mue_setmtu(struct usbnet *un)
mue_setmtu_locked(struct usbnet *un)
{
struct ifnet * const ifp = usbnet_ifp(un);
uint32_t val;
@ -1135,7 +1131,7 @@ mue_setmtu(struct usbnet *un)
}
static void
mue_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
mue_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
{
struct ifnet * const ifp = usbnet_ifp(un);
struct mue_rxbuf_hdr *hdrp;
@ -1145,8 +1141,6 @@ mue_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
uint8_t *buf = c->unc_buf;
bool v6;
usbnet_isowned_rx(un);
KASSERTMSG(total_len <= un->un_rx_bufsz, "%u vs %u",
total_len, un->un_rx_bufsz);
@ -1244,52 +1238,60 @@ mue_init_locked(struct ifnet *ifp)
mue_set_macaddr(un);
/* Load the multicast filter. */
mue_setiff(un);
mue_setiff_locked(un);
/* TCP/UDP checksum offload engines. */
mue_sethwcsum(un);
mue_sethwcsum_locked(un);
/* Set MTU. */
mue_setmtu(un);
mue_setmtu_locked(un);
return usbnet_init_rx_tx(un);
}
static int
mue_init(struct ifnet *ifp)
mue_uno_init(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;
int rv;
usbnet_lock(un);
usbnet_lock_core(un);
usbnet_busy(un);
rv = mue_init_locked(ifp);
usbnet_unlock(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
return rv;
}
static int
mue_ioctl_cb(struct ifnet *ifp, u_long cmd, void *data)
mue_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
{
struct usbnet * const un = ifp->if_softc;
usbnet_lock_core(un);
usbnet_busy(un);
switch (cmd) {
case SIOCSIFFLAGS:
case SIOCSETHERCAP:
case SIOCADDMULTI:
case SIOCDELMULTI:
mue_setiff(un);
mue_setiff_locked(un);
break;
case SIOCSIFCAP:
mue_sethwcsum(un);
mue_sethwcsum_locked(un);
break;
case SIOCSIFMTU:
mue_setmtu(un);
mue_setmtu_locked(un);
break;
default:
break;
}
usbnet_unbusy(un);
usbnet_unlock_core(un);
return 0;
}
@ -1306,7 +1308,7 @@ mue_reset(struct usbnet *un)
}
static void
mue_stop_cb(struct ifnet *ifp, int disable)
mue_uno_stop(struct ifnet *ifp, int disable)
{
struct usbnet * const un = ifp->if_softc;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_otus.c,v 1.43 2020/03/14 02:35:33 christos Exp $ */
/* $NetBSD: if_otus.c,v 1.44 2020/03/15 23:04:50 thorpej Exp $ */
/* $OpenBSD: if_otus.c,v 1.18 2010/08/27 17:08:00 jsg Exp $ */
/*-
@ -23,7 +23,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_otus.c,v 1.43 2020/03/14 02:35:33 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_otus.c,v 1.44 2020/03/15 23:04:50 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -880,7 +880,11 @@ otus_attachhook(device_t arg)
/* Override state transition machine. */
sc->sc_newstate = ic->ic_newstate;
ic->ic_newstate = otus_newstate;
ieee80211_media_init(ic, otus_media_change, ieee80211_media_status);
/* XXX media locking needs revisiting */
mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTUSB);
ieee80211_media_init_with_lock(ic,
otus_media_change, ieee80211_media_status, &sc->sc_media_mtx);
bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_otusvar.h,v 1.11 2020/01/15 08:20:13 skrll Exp $ */
/* $NetBSD: if_otusvar.h,v 1.12 2020/03/15 23:04:50 thorpej Exp $ */
/* $OpenBSD: if_otusreg.h,v 1.6 2009/04/06 18:17:01 damien Exp $ */
/*-
@ -205,6 +205,7 @@ struct otus_softc {
kmutex_t sc_task_mtx;
kmutex_t sc_write_mtx;
kmutex_t sc_tx_mtx;
kmutex_t sc_media_mtx; /* XXX */
const uint32_t *sc_phy_vals;

View File

@ -1,5 +1,5 @@
/* $OpenBSD: if_rum.c,v 1.40 2006/09/18 16:20:20 damien Exp $ */
/* $NetBSD: if_rum.c,v 1.68 2020/03/14 02:35:33 christos Exp $ */
/* $NetBSD: if_rum.c,v 1.69 2020/03/15 23:04:50 thorpej Exp $ */
/*-
* Copyright (c) 2005-2007 Damien Bergamini <damien.bergamini@free.fr>
@ -24,7 +24,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_rum.c,v 1.68 2020/03/14 02:35:33 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_rum.c,v 1.69 2020/03/15 23:04:50 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -456,7 +456,11 @@ rum_attach(device_t parent, device_t self, void *aux)
/* override state transition machine */
sc->sc_newstate = ic->ic_newstate;
ic->ic_newstate = rum_newstate;
ieee80211_media_init(ic, rum_media_change, ieee80211_media_status);
/* XXX media locking needs revisiting */
mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTUSB);
ieee80211_media_init_with_lock(ic,
rum_media_change, ieee80211_media_status, &sc->sc_media_mtx);
bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_rumvar.h,v 1.11 2019/10/05 23:27:20 mrg Exp $ */
/* $NetBSD: if_rumvar.h,v 1.12 2020/03/15 23:04:50 thorpej Exp $ */
/* $OpenBSD: if_rumvar.h,v 1.7 2006/11/13 20:06:38 damien Exp $ */
/*-
@ -78,6 +78,8 @@ struct rum_softc {
int (*sc_newstate)(struct ieee80211com *,
enum ieee80211_state, int);
kmutex_t sc_media_mtx; /* XXX */
struct usbd_device * sc_udev;
struct usbd_interface * sc_iface;
int sc_flags;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_run.c,v 1.38 2020/03/14 02:35:33 christos Exp $ */
/* $NetBSD: if_run.c,v 1.39 2020/03/15 23:04:51 thorpej Exp $ */
/* $OpenBSD: if_run.c,v 1.90 2012/03/24 15:11:04 jsg Exp $ */
/*-
@ -23,7 +23,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_run.c,v 1.38 2020/03/14 02:35:33 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_run.c,v 1.39 2020/03/15 23:04:51 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -733,7 +733,11 @@ run_attach(device_t parent, device_t self, void *aux)
/* override state transition machine */
sc->sc_newstate = ic->ic_newstate;
ic->ic_newstate = run_newstate;
ieee80211_media_init(ic, run_media_change, ieee80211_media_status);
/* XXX media locking needs revisiting */
mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTUSB);
ieee80211_media_init_with_lock(ic,
run_media_change, ieee80211_media_status, &sc->sc_media_mtx);
bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_runvar.h,v 1.7 2020/01/04 22:30:06 mlelstv Exp $ */
/* $NetBSD: if_runvar.h,v 1.8 2020/03/15 23:04:51 thorpej Exp $ */
/* $OpenBSD: if_runvar.h,v 1.8 2010/02/08 18:46:47 damien Exp $ */
/*-
@ -144,6 +144,8 @@ struct run_softc {
int (*sc_srom_read)(struct run_softc *,
uint16_t, uint16_t *);
kmutex_t sc_media_mtx; /* XXX */
struct usbd_device * sc_udev;
struct usbd_interface * sc_iface;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_smsc.c,v 1.67 2020/03/14 03:01:36 christos Exp $ */
/* $NetBSD: if_smsc.c,v 1.68 2020/03/15 23:04:51 thorpej 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.67 2020/03/14 03:01:36 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_smsc.c,v 1.68 2020/03/15 23:04:51 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -173,33 +173,34 @@ CFATTACH_DECL_NEW(usmsc, sizeof(struct smsc_softc),
static int smsc_chip_init(struct usbnet *);
static int smsc_setmacaddress(struct usbnet *, const uint8_t *);
static int smsc_init(struct ifnet *);
static int smsc_uno_init(struct ifnet *);
static int smsc_init_locked(struct ifnet *);
static void smsc_stop_cb(struct ifnet *, int);
static void smsc_uno_stop(struct ifnet *, int);
static void smsc_reset(struct smsc_softc *);
static void smsc_miibus_statchg(struct ifnet *);
static void smsc_uno_miibus_statchg(struct ifnet *);
static int smsc_readreg(struct usbnet *, uint32_t, uint32_t *);
static int smsc_writereg(struct usbnet *, uint32_t, uint32_t);
static int smsc_wait_for_bits(struct usbnet *, uint32_t, uint32_t);
static int smsc_miibus_readreg(struct usbnet *, int, int, uint16_t *);
static int smsc_miibus_writereg(struct usbnet *, int, int, uint16_t);
static int smsc_uno_miibus_readreg(struct usbnet *, int, int, uint16_t *);
static int smsc_uno_miibus_writereg(struct usbnet *, int, int, uint16_t);
static int smsc_ioctl_cb(struct ifnet *, u_long, void *);
static unsigned smsc_tx_prepare(struct usbnet *, struct mbuf *,
static int smsc_uno_ioctl(struct ifnet *, u_long, void *);
static unsigned smsc_uno_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static void smsc_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
static void smsc_uno_rx_loop(struct usbnet *, struct usbnet_chain *,
uint32_t);
static const struct usbnet_ops smsc_ops = {
.uno_stop = smsc_stop_cb,
.uno_ioctl = smsc_ioctl_cb,
.uno_read_reg = smsc_miibus_readreg,
.uno_write_reg = smsc_miibus_writereg,
.uno_statchg = smsc_miibus_statchg,
.uno_tx_prepare = smsc_tx_prepare,
.uno_rx_loop = smsc_rx_loop,
.uno_init = smsc_init,
.uno_stop = smsc_uno_stop,
.uno_ioctl = smsc_uno_ioctl,
.uno_read_reg = smsc_uno_miibus_readreg,
.uno_write_reg = smsc_uno_miibus_writereg,
.uno_statchg = smsc_uno_miibus_statchg,
.uno_tx_prepare = smsc_uno_tx_prepare,
.uno_rx_loop = smsc_uno_rx_loop,
.uno_init = smsc_uno_init,
};
static int
@ -209,7 +210,7 @@ smsc_readreg(struct usbnet *un, uint32_t off, uint32_t *data)
uint32_t buf;
usbd_status err;
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return 0;
@ -236,7 +237,7 @@ smsc_writereg(struct usbnet *un, uint32_t off, uint32_t data)
uint32_t buf;
usbd_status err;
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return 0;
@ -274,13 +275,11 @@ smsc_wait_for_bits(struct usbnet *un, uint32_t reg, uint32_t bits)
}
static int
smsc_miibus_readreg(struct usbnet *un, int phy, int reg, uint16_t *val)
smsc_uno_miibus_readreg(struct usbnet *un, int phy, int reg, uint16_t *val)
{
uint32_t addr;
uint32_t data = 0;
usbnet_isowned_mii(un);
if (un->un_phyno != phy)
return EINVAL;
@ -304,12 +303,10 @@ smsc_miibus_readreg(struct usbnet *un, int phy, int reg, uint16_t *val)
}
static int
smsc_miibus_writereg(struct usbnet *un, int phy, int reg, uint16_t val)
smsc_uno_miibus_writereg(struct usbnet *un, int phy, int reg, uint16_t val)
{
uint32_t addr;
usbnet_isowned_mii(un);
if (un->un_phyno != phy)
return EINVAL;
@ -332,7 +329,7 @@ smsc_miibus_writereg(struct usbnet *un, int phy, int reg, uint16_t val)
}
static void
smsc_miibus_statchg(struct ifnet *ifp)
smsc_uno_miibus_statchg(struct ifnet *ifp)
{
USMSCHIST_FUNC(); USMSCHIST_CALLED();
struct usbnet * const un = ifp->if_softc;
@ -364,9 +361,7 @@ smsc_miibus_statchg(struct ifnet *ifp)
if (!usbnet_havelink(un))
return;
usbnet_lock_mii(un);
int err = smsc_readreg(un, SMSC_AFC_CFG, &afc_cfg);
usbnet_unlock_mii(un);
if (err) {
smsc_warn_printf(un, "failed to read initial AFC_CFG, "
"error %d\n", err);
@ -397,11 +392,9 @@ smsc_miibus_statchg(struct ifnet *ifp)
afc_cfg |= 0xf;
}
usbnet_lock_mii(un);
err = smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr);
err += smsc_writereg(un, SMSC_FLOW, flow);
err += smsc_writereg(un, SMSC_AFC_CFG, afc_cfg);
usbnet_unlock_mii(un);
if (err)
smsc_warn_printf(un, "media change failed, error %d\n", err);
@ -426,7 +419,7 @@ smsc_setiff_locked(struct usbnet *un)
uint32_t hashtbl[2] = { 0, 0 };
uint32_t hash;
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return;
@ -473,14 +466,6 @@ allmulti:
smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr);
}
static void
smsc_setiff(struct usbnet *un)
{
usbnet_lock_mii(un);
smsc_setiff_locked(un);
usbnet_unlock_mii(un);
}
static int
smsc_setoe_locked(struct usbnet *un)
{
@ -489,7 +474,7 @@ smsc_setoe_locked(struct usbnet *un)
uint32_t val;
int err;
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
err = smsc_readreg(un, SMSC_COE_CTRL, &val);
if (err != 0) {
@ -522,16 +507,6 @@ smsc_setoe_locked(struct usbnet *un)
return 0;
}
static void
smsc_setoe(struct usbnet *un)
{
usbnet_lock_mii(un);
smsc_setoe_locked(un);
usbnet_unlock_mii(un);
}
static int
smsc_setmacaddress(struct usbnet *un, const uint8_t *addr)
{
@ -561,7 +536,7 @@ smsc_reset(struct smsc_softc *sc)
{
struct usbnet * const un = &sc->smsc_un;
usbnet_isowned(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return;
@ -573,13 +548,15 @@ smsc_reset(struct smsc_softc *sc)
}
static int
smsc_init(struct ifnet *ifp)
smsc_uno_init(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;
usbnet_lock(un);
usbnet_lock_core(un);
usbnet_busy(un);
int ret = smsc_init_locked(ifp);
usbnet_unlock(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
return ret;
}
@ -590,6 +567,8 @@ smsc_init_locked(struct ifnet *ifp)
struct usbnet * const un = ifp->if_softc;
struct smsc_softc * const sc = usbnet_softc(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return EIO;
@ -599,21 +578,17 @@ smsc_init_locked(struct ifnet *ifp)
/* Reset the ethernet interface. */
smsc_reset(sc);
usbnet_lock_mii_un_locked(un);
/* Load the multicast filter. */
smsc_setiff_locked(un);
/* TCP/UDP checksum offload engines. */
smsc_setoe_locked(un);
usbnet_unlock_mii_un_locked(un);
return usbnet_init_rx_tx(un);
}
static void
smsc_stop_cb(struct ifnet *ifp, int disable)
smsc_uno_stop(struct ifnet *ifp, int disable)
{
struct usbnet * const un = ifp->if_softc;
struct smsc_softc * const sc = usbnet_softc(un);
@ -630,7 +605,7 @@ smsc_chip_init(struct usbnet *un)
int burst_cap;
int err;
usbnet_lock_mii_un_locked(un);
usbnet_isowned_core(un);
/* Enter H/W config mode */
smsc_writereg(un, SMSC_HW_CFG, SMSC_HW_CFG_LRST);
@ -765,35 +740,39 @@ smsc_chip_init(struct usbnet *un)
*/
sc->sc_mac_csr |= SMSC_MAC_CSR_RXEN;
smsc_writereg(un, SMSC_MAC_CSR, sc->sc_mac_csr);
usbnet_unlock_mii_un_locked(un);
return 0;
init_failed:
usbnet_unlock_mii_un_locked(un);
smsc_err_printf(un, "smsc_chip_init failed (err=%d)\n", err);
return err;
}
static int
smsc_ioctl_cb(struct ifnet *ifp, u_long cmd, void *data)
smsc_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
{
struct usbnet * const un = ifp->if_softc;
usbnet_lock_core(un);
usbnet_busy(un);
switch (cmd) {
case SIOCSIFFLAGS:
case SIOCSETHERCAP:
case SIOCADDMULTI:
case SIOCDELMULTI:
smsc_setiff(un);
smsc_setiff_locked(un);
break;
case SIOCSIFCAP:
smsc_setoe(un);
smsc_setoe_locked(un);
break;
default:
break;
}
usbnet_unbusy(un);
usbnet_unlock_core(un);
return 0;
}
@ -902,7 +881,8 @@ smsc_attach(device_t parent, device_t self, void *aux)
/* Setup some of the basics */
un->un_phyno = 1;
usbnet_lock_mii(un);
usbnet_lock_core(un);
usbnet_busy(un);
/*
* Attempt to get the mac address, if an EEPROM is not attached this
* will just return FF:FF:FF:FF:FF:FF, so in such cases we invent a MAC
@ -930,22 +910,21 @@ smsc_attach(device_t parent, device_t self, void *aux)
un->un_eaddr[0] = (uint8_t)((mac_l) & 0xff);
}
}
usbnet_unlock_mii(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
0, &unm);
}
static void
smsc_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
smsc_uno_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
{
USMSCHIST_FUNC(); USMSCHIST_CALLED();
struct smsc_softc * const sc = usbnet_softc(un);
struct ifnet *ifp = usbnet_ifp(un);
uint8_t *buf = c->unc_buf;
usbnet_isowned_rx(un);
DPRINTF("total_len %jd/%#jx", total_len, total_len, 0, 0);
while (total_len != 0) {
uint32_t rxhdr;
@ -1070,13 +1049,11 @@ smsc_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
}
static unsigned
smsc_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
smsc_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
{
uint32_t txhdr;
uint32_t frm_len = 0;
usbnet_isowned_tx(un);
const size_t hdrsz = sizeof(txhdr) * 2;
if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - hdrsz)

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_udav.c,v 1.76 2020/03/14 02:35:33 christos Exp $ */
/* $NetBSD: if_udav.c,v 1.77 2020/03/15 23:04:51 thorpej 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.76 2020/03/14 02:35:33 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.77 2020/03/15 23:04:51 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -65,16 +65,15 @@ CFATTACH_DECL_NEW(udav, sizeof(struct usbnet), udav_match, udav_attach,
static void udav_chip_init(struct usbnet *);
static unsigned udav_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static void udav_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
static void udav_stop_cb(struct ifnet *, int);
static int udav_ioctl_cb(struct ifnet *, u_long, void *);
static int udav_mii_read_reg(struct usbnet *, int, int, uint16_t *);
static int udav_mii_write_reg(struct usbnet *, int, int, uint16_t);
static void udav_mii_statchg(struct ifnet *);
static int udav_init(struct ifnet *);
static void udav_setiff(struct usbnet *);
static unsigned udav_uno_tx_prepare(struct usbnet *, struct mbuf *,
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 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 *);
static int udav_uno_init(struct ifnet *);
static void udav_setiff_locked(struct usbnet *);
static void udav_reset(struct usbnet *);
@ -132,14 +131,14 @@ static const struct udav_type {
#define udav_lookup(v, p) ((const struct udav_type *)usb_lookup(udav_devs, v, p))
static const struct usbnet_ops udav_ops = {
.uno_stop = udav_stop_cb,
.uno_ioctl = udav_ioctl_cb,
.uno_read_reg = udav_mii_read_reg,
.uno_write_reg = udav_mii_write_reg,
.uno_statchg = udav_mii_statchg,
.uno_tx_prepare = udav_tx_prepare,
.uno_rx_loop = udav_rx_loop,
.uno_init = udav_init,
.uno_stop = udav_uno_stop,
.uno_ioctl = udav_uno_ioctl,
.uno_read_reg = udav_uno_mii_read_reg,
.uno_write_reg = udav_uno_mii_write_reg,
.uno_statchg = udav_uno_mii_statchg,
.uno_tx_prepare = udav_uno_tx_prepare,
.uno_rx_loop = udav_uno_rx_loop,
.uno_init = udav_uno_init,
};
/* Probe */
@ -238,15 +237,18 @@ udav_attach(device_t parent, device_t self, void *aux)
/* Not supported yet. */
un->un_ed[USBNET_ENDPT_INTR] = 0;
usbnet_lock_core(un);
usbnet_busy(un);
// /* reset the adapter */
// udav_reset(un);
usbnet_attach(un, "udavdet");
/* Get Ethernet Address */
usbnet_lock_mii(un);
err = udav_csr_read(un, UDAV_PAR, un->un_eaddr, ETHER_ADDR_LEN);
usbnet_unlock_mii(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
if (err) {
aprint_error_dev(self, "read MAC address failed\n");
return;
@ -365,7 +367,7 @@ udav_csr_read(struct usbnet *un, int offset, void *buf, int len)
usb_device_request_t req;
usbd_status err;
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
KASSERT(!usbnet_isdying(un));
DPRINTFN(0x200,
@ -396,7 +398,7 @@ udav_csr_write(struct usbnet *un, int offset, void *buf, int len)
usb_device_request_t req;
usbd_status err;
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
KASSERT(!usbnet_isdying(un));
DPRINTFN(0x200,
@ -425,7 +427,7 @@ udav_csr_read1(struct usbnet *un, int offset)
{
uint8_t val = 0;
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
DPRINTFN(0x200,
("%s: %s: enter\n", device_xname(un->un_dev), __func__));
@ -443,7 +445,7 @@ udav_csr_write1(struct usbnet *un, int offset, unsigned char ch)
usb_device_request_t req;
usbd_status err;
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
KASSERT(!usbnet_isdying(un));
DPRINTFN(0x200,
@ -467,7 +469,7 @@ udav_csr_write1(struct usbnet *un, int offset, unsigned char ch)
}
static int
udav_init(struct ifnet *ifp)
udav_uno_init(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;
struct mii_data * const mii = usbnet_mii(un);
@ -476,10 +478,10 @@ udav_init(struct ifnet *ifp)
DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
usbnet_lock(un);
usbnet_lock_core(un);
if (usbnet_isdying(un)) {
usbnet_unlock(un);
usbnet_unlock_core(un);
return EIO;
}
@ -487,7 +489,7 @@ udav_init(struct ifnet *ifp)
if (ifp->if_flags & IFF_RUNNING)
usbnet_stop(un, ifp, 1);
usbnet_lock_mii_un_locked(un);
usbnet_busy(un);
memcpy(eaddr, CLLADDR(ifp->if_sadl), sizeof(eaddr));
udav_csr_write(un, UDAV_PAR, eaddr, ETHER_ADDR_LEN);
@ -515,21 +517,22 @@ udav_init(struct ifnet *ifp)
UDAV_SETBIT(un, UDAV_GPCR, UDAV_GPCR_GEP_CNTL0);
UDAV_CLRBIT(un, UDAV_GPR, UDAV_GPR_GEPIO0);
usbnet_unlock_mii_un_locked(un);
usbnet_unlock(un);
if (mii && (rc = mii_mediachg(mii)) == ENXIO)
rc = 0;
if (rc != 0)
if (rc != 0) {
usbnet_unbusy(un);
usbnet_unlock_core(un);
return rc;
}
usbnet_lock(un);
if (usbnet_isdying(un))
rc = EIO;
else
rc = usbnet_init_rx_tx(un);
usbnet_unlock(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
return rc;
}
@ -537,7 +540,7 @@ udav_init(struct ifnet *ifp)
static void
udav_reset(struct usbnet *un)
{
usbnet_isowned(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return;
@ -550,7 +553,7 @@ udav_reset(struct usbnet *un)
static void
udav_chip_init(struct usbnet *un)
{
usbnet_lock_mii_un_locked(un);
usbnet_isowned_core(un);
/* Select PHY */
#if 1
@ -575,8 +578,6 @@ udav_chip_init(struct usbnet *un)
delay(10); /* XXX */
}
delay(10000); /* XXX */
usbnet_unlock_mii_un_locked(un);
}
#define UDAV_BITS 6
@ -596,7 +597,7 @@ udav_setiff_locked(struct usbnet *un)
DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return;
@ -647,23 +648,12 @@ allmulti:
udav_csr_write(un, UDAV_MAR, hashes, sizeof(hashes));
}
static void
udav_setiff(struct usbnet *un)
{
usbnet_lock_mii(un);
udav_setiff_locked(un);
usbnet_unlock_mii(un);
}
static unsigned
udav_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
udav_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
{
int total_len;
uint8_t *buf = c->unc_buf;
usbnet_isowned_tx(un);
DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - 2)
@ -690,7 +680,7 @@ udav_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
}
static void
udav_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
udav_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
{
struct ifnet *ifp = usbnet_ifp(un);
uint8_t *buf = c->unc_buf;
@ -732,26 +722,31 @@ udav_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
}
static int
udav_ioctl_cb(struct ifnet *ifp, u_long cmd, void *data)
udav_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
{
struct usbnet * const un = ifp->if_softc;
usbnet_lock_core(un);
usbnet_busy(un);
switch (cmd) {
case SIOCADDMULTI:
case SIOCDELMULTI:
udav_setiff(un);
udav_setiff_locked(un);
break;
default:
break;
}
usbnet_unbusy(un);
usbnet_unlock_core(un);
return 0;
}
/* Stop the adapter and free any mbufs allocated to the RX and TX lists. */
static void
udav_stop_cb(struct ifnet *ifp, int disable)
udav_uno_stop(struct ifnet *ifp, int disable)
{
struct usbnet * const un = ifp->if_softc;
@ -761,12 +756,10 @@ udav_stop_cb(struct ifnet *ifp, int disable)
}
static int
udav_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
udav_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
{
uint8_t data[2];
usbnet_isowned_mii(un);
DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n",
device_xname(un->un_dev), __func__, phy, reg));
@ -809,12 +802,10 @@ udav_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
}
static int
udav_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
udav_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
{
uint8_t data[2];
usbnet_isowned_mii(un);
DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x val=0x%04hx\n",
device_xname(un->un_dev), __func__, phy, reg, val));
@ -854,7 +845,7 @@ udav_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
}
static void
udav_mii_statchg(struct ifnet *ifp)
udav_uno_mii_statchg(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;
struct mii_data * const mii = usbnet_mii(un);

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_upgt.c,v 1.30 2020/03/14 02:35:33 christos Exp $ */
/* $NetBSD: if_upgt.c,v 1.31 2020/03/15 23:04:51 thorpej Exp $ */
/* $OpenBSD: if_upgt.c,v 1.49 2010/04/20 22:05:43 tedu Exp $ */
/*
@ -18,7 +18,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_upgt.c,v 1.30 2020/03/14 02:35:33 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_upgt.c,v 1.31 2020/03/15 23:04:51 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -461,7 +461,11 @@ upgt_attach_hook(device_t arg)
sc->sc_newstate = ic->ic_newstate;
ic->ic_newstate = upgt_newstate;
ieee80211_media_init(ic, upgt_media_change, ieee80211_media_status);
/* XXX media locking needs revisiting */
mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTUSB);
ieee80211_media_init_with_lock(ic,
upgt_media_change, ieee80211_media_status, &sc->sc_media_mtx);
bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_upgtvar.h,v 1.5 2020/01/15 08:20:13 skrll Exp $ */
/* $NetBSD: if_upgtvar.h,v 1.6 2020/03/15 23:04:51 thorpej Exp $ */
/* $OpenBSD: if_upgtvar.h,v 1.15 2009/08/10 20:02:19 deraadt Exp $ */
/*
@ -418,6 +418,8 @@ struct upgt_softc {
kmutex_t sc_mtx;
kcondvar_t sc_cv;
kmutex_t sc_media_mtx; /* XXX */
uint8_t sc_device_type;
struct ieee80211com sc_ic;
enum ieee80211_state sc_state;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_upl.c,v 1.70 2020/01/29 06:35:28 thorpej Exp $ */
/* $NetBSD: if_upl.c,v 1.71 2020/03/15 23:04:51 thorpej Exp $ */
/*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_upl.c,v 1.70 2020/01/29 06:35:28 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_upl.c,v 1.71 2020/03/15 23:04:51 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@ -105,21 +105,21 @@ CFATTACH_DECL_NEW(upl, sizeof(struct usbnet), upl_match, upl_attach,
usbnet_detach, usbnet_activate);
#if 0
static void upl_intr_cb(struct usbnet *, usbd_status);
static void upl_uno_intr(struct usbnet *, usbd_status);
#endif
static void upl_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
static unsigned upl_tx_prepare(struct usbnet *, struct mbuf *,
static void upl_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
static unsigned upl_uno_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static int upl_ioctl_cb(struct ifnet *, u_long, void *);
static int upl_init(struct ifnet *);
static int upl_uno_ioctl(struct ifnet *, u_long, void *);
static int upl_uno_init(struct ifnet *);
static const struct usbnet_ops upl_ops = {
.uno_init = upl_init,
.uno_tx_prepare = upl_tx_prepare,
.uno_rx_loop = upl_rx_loop,
.uno_ioctl = upl_ioctl_cb,
.uno_init = upl_uno_init,
.uno_tx_prepare = upl_uno_tx_prepare,
.uno_rx_loop = upl_uno_rx_loop,
.uno_ioctl = upl_uno_ioctl,
#if 0
.uno_intr = upl_intr_cb,
.uno_intr = upl_uno_intr,
#endif
};
@ -225,9 +225,8 @@ upl_attach(device_t parent, device_t self, void *aux)
}
static void
upl_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
upl_uno_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
{
usbnet_isowned_rx(un);
DPRINTFN(9,("%s: %s: enter length=%d\n",
device_xname(un->un_dev), __func__, total_len));
@ -236,7 +235,7 @@ upl_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
}
static unsigned
upl_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
upl_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
{
int total_len;
@ -253,23 +252,23 @@ upl_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
}
static int
upl_init(struct ifnet *ifp)
upl_uno_init(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;
int rv;
usbnet_lock(un);
usbnet_lock_core(un);
if (usbnet_isdying(un))
rv = EIO;
else
rv = usbnet_init_rx_tx(un);
usbnet_unlock(un);
usbnet_unlock_core(un);
return rv;
}
static int
upl_ioctl_cb(struct ifnet *ifp, u_long cmd, void *data)
upl_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
{
if (cmd == SIOCSIFMTU) {
struct ifreq *ifr = data;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_ural.c,v 1.64 2020/03/14 02:35:33 christos Exp $ */
/* $NetBSD: if_ural.c,v 1.65 2020/03/15 23:04:51 thorpej Exp $ */
/* $FreeBSD: /repoman/r/ncvs/src/sys/dev/usb/if_ural.c,v 1.40 2006/06/02 23:14:40 sam Exp $ */
/*-
@ -24,7 +24,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_ural.c,v 1.64 2020/03/14 02:35:33 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_ural.c,v 1.65 2020/03/15 23:04:51 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -499,7 +499,11 @@ ural_attach(device_t parent, device_t self, void *aux)
/* override state transition machine */
sc->sc_newstate = ic->ic_newstate;
ic->ic_newstate = ural_newstate;
ieee80211_media_init(ic, ural_media_change, ieee80211_media_status);
/* XXX media locking needs revisiting */
mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTUSB);
ieee80211_media_init_with_lock(ic,
ural_media_change, ieee80211_media_status, &sc->sc_media_mtx);
bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
sizeof(struct ieee80211_frame) + 64, &sc->sc_drvbpf);

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_uralvar.h,v 1.14 2019/10/05 23:27:20 mrg Exp $ */
/* $NetBSD: if_uralvar.h,v 1.15 2020/03/15 23:04:51 thorpej Exp $ */
/* $OpenBSD: if_ralvar.h,v 1.2 2005/05/13 18:42:50 damien Exp $ */
/*-
@ -83,6 +83,8 @@ struct ural_softc {
int (*sc_newstate)(struct ieee80211com *,
enum ieee80211_state, int);
kmutex_t sc_media_mtx; /* XXX */
struct usbd_device * sc_udev;
struct usbd_interface * sc_iface;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_ure.c,v 1.37 2020/03/13 19:17:27 martin Exp $ */
/* $NetBSD: if_ure.c,v 1.38 2020/03/15 23:04:51 thorpej 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.37 2020/03/13 19:17:27 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_ure.c,v 1.38 2020/03/15 23:04:51 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -85,15 +85,16 @@ static void ure_rtl8153_init(struct usbnet *);
static void ure_disable_teredo(struct usbnet *);
static void ure_init_fifo(struct usbnet *);
static void ure_stop_cb(struct ifnet *, int);
static int ure_ioctl_cb(struct ifnet *, u_long, void *);
static int ure_mii_read_reg(struct usbnet *, int, int, uint16_t *);
static int ure_mii_write_reg(struct usbnet *, int, int, uint16_t);
static void ure_miibus_statchg(struct ifnet *);
static unsigned ure_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static void ure_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
static int ure_init(struct ifnet *);
static void ure_uno_stop(struct ifnet *, int);
static int ure_uno_ioctl(struct ifnet *, u_long, void *);
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 *);
static unsigned ure_uno_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static void ure_uno_rx_loop(struct usbnet *, struct usbnet_chain *,
uint32_t);
static int ure_uno_init(struct ifnet *);
static int ure_match(device_t, cfdata_t, void *);
static void ure_attach(device_t, device_t, void *);
@ -102,14 +103,14 @@ CFATTACH_DECL_NEW(ure, sizeof(struct usbnet), ure_match, ure_attach,
usbnet_detach, usbnet_activate);
static const struct usbnet_ops ure_ops = {
.uno_stop = ure_stop_cb,
.uno_ioctl = ure_ioctl_cb,
.uno_read_reg = ure_mii_read_reg,
.uno_write_reg = ure_mii_write_reg,
.uno_statchg = ure_miibus_statchg,
.uno_tx_prepare = ure_tx_prepare,
.uno_rx_loop = ure_rx_loop,
.uno_init = ure_init,
.uno_stop = ure_uno_stop,
.uno_ioctl = ure_uno_ioctl,
.uno_read_reg = ure_uno_mii_read_reg,
.uno_write_reg = ure_uno_mii_write_reg,
.uno_statchg = ure_uno_miibus_statchg,
.uno_tx_prepare = ure_uno_tx_prepare,
.uno_rx_loop = ure_uno_rx_loop,
.uno_init = ure_uno_init,
};
static int
@ -273,9 +274,8 @@ ure_ocp_reg_write(struct usbnet *un, uint16_t addr, uint16_t data)
}
static int
ure_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
ure_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
{
usbnet_isowned_mii(un);
if (un->un_phyno != phy)
return EINVAL;
@ -292,9 +292,8 @@ ure_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
}
static int
ure_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
ure_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
{
usbnet_isowned_mii(un);
if (un->un_phyno != phy)
return EINVAL;
@ -305,7 +304,7 @@ ure_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
}
static void
ure_miibus_statchg(struct ifnet *ifp)
ure_uno_miibus_statchg(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;
struct mii_data * const mii = usbnet_mii(un);
@ -342,7 +341,7 @@ ure_setiff_locked(struct usbnet *un)
uint32_t hash;
uint32_t rxmode;
usbnet_isowned(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return;
@ -399,21 +398,12 @@ allmulti:
ure_write_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA, rxmode);
}
static void
ure_setiff(struct usbnet *un)
{
usbnet_lock(un);
ure_setiff_locked(un);
usbnet_unlock(un);
}
static void
ure_reset(struct usbnet *un)
{
int i;
usbnet_isowned(un);
usbnet_isowned_core(un);
ure_write_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA, URE_CR_RST);
@ -433,7 +423,7 @@ ure_init_locked(struct ifnet *ifp)
struct usbnet * const un = ifp->if_softc;
uint8_t eaddr[8];
usbnet_isowned(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return EIO;
@ -474,19 +464,21 @@ ure_init_locked(struct ifnet *ifp)
}
static int
ure_init(struct ifnet *ifp)
ure_uno_init(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;
usbnet_lock(un);
usbnet_lock_core(un);
usbnet_busy(un);
int ret = ure_init_locked(ifp);
usbnet_unlock(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
return ret;
}
static void
ure_stop_cb(struct ifnet *ifp, int disable __unused)
ure_uno_stop(struct ifnet *ifp, int disable __unused)
{
struct usbnet * const un = ifp->if_softc;
@ -814,19 +806,25 @@ ure_init_fifo(struct usbnet *un)
}
static int
ure_ioctl_cb(struct ifnet *ifp, u_long cmd, void *data)
ure_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
{
struct usbnet * const un = ifp->if_softc;
usbnet_lock_core(un);
usbnet_busy(un);
switch (cmd) {
case SIOCADDMULTI:
case SIOCDELMULTI:
ure_setiff(un);
ure_setiff_locked(un);
break;
default:
break;
}
usbnet_unbusy(un);
usbnet_unlock_core(un);
return 0;
}
@ -940,7 +938,7 @@ ure_attach(device_t parent, device_t self, void *aux)
(un->un_flags != 0) ? "" : "unknown ",
ver);
usbnet_lock(un);
usbnet_lock_core(un);
if (un->un_flags & URE_FLAG_8152)
ure_rtl8152_init(un);
else
@ -953,7 +951,7 @@ ure_attach(device_t parent, device_t self, void *aux)
else
ure_read_mem(un, URE_PLA_BACKUP, URE_MCU_TYPE_PLA, eaddr,
sizeof(eaddr));
usbnet_unlock(un);
usbnet_unlock_core(un);
if (ETHER_IS_ZERO(eaddr)) {
maclo = 0x00f2 | (cprng_strong32() & 0xffff0000);
machi = cprng_strong32() & 0xffff;
@ -994,7 +992,7 @@ ure_attach(device_t parent, device_t self, void *aux)
}
static void
ure_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
ure_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
{
struct ifnet *ifp = usbnet_ifp(un);
uint8_t *buf = c->unc_buf;
@ -1002,8 +1000,6 @@ ure_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
uint16_t pkt_count = 0;
struct ure_rxpkt rxhdr;
usbnet_isowned_rx(un);
do {
if (total_len < sizeof(rxhdr)) {
DPRINTF(("too few bytes left for a packet header\n"));
@ -1078,14 +1074,12 @@ ure_rxcsum(struct ifnet *ifp, struct ure_rxpkt *rp)
}
static unsigned
ure_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
ure_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
{
struct ure_txpkt txhdr;
uint32_t frm_len = 0;
uint8_t *buf = c->unc_buf;
usbnet_isowned_tx(un);
if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - sizeof(txhdr))
return 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_url.c,v 1.75 2020/03/14 02:35:33 christos Exp $ */
/* $NetBSD: if_url.c,v 1.76 2020/03/15 23:04:51 thorpej Exp $ */
/*
* Copyright (c) 2001, 2002
@ -44,7 +44,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_url.c,v 1.75 2020/03/14 02:35:33 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_url.c,v 1.76 2020/03/15 23:04:51 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@ -72,17 +72,16 @@ static void url_attach(device_t, device_t, void *);
CFATTACH_DECL_NEW(url, sizeof(struct usbnet), url_match, url_attach,
usbnet_detach, usbnet_activate);
static unsigned url_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static void url_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
static int url_int_mii_read_reg(struct usbnet *, int, int, uint16_t *);
static int url_int_mii_write_reg(struct usbnet *, int, int, uint16_t);
static int url_ioctl_cb(struct ifnet *, u_long, void *);
static void url_stop_cb(struct ifnet *, int);
static void url_mii_statchg_cb(struct ifnet *);
static int url_init(struct ifnet *);
static unsigned url_uno_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
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_stop(struct ifnet *, int);
static void url_uno_mii_statchg(struct ifnet *);
static int url_uno_init(struct ifnet *);
static void url_setiff_locked(struct usbnet *);
static void url_setiff(struct usbnet *);
static void url_reset(struct usbnet *);
static int url_csr_read_1(struct usbnet *, int);
@ -93,14 +92,14 @@ static int url_csr_write_4(struct usbnet *, int, int);
static int url_mem(struct usbnet *, int, int, void *, int);
static const struct usbnet_ops url_ops = {
.uno_stop = url_stop_cb,
.uno_ioctl = url_ioctl_cb,
.uno_read_reg = url_int_mii_read_reg,
.uno_write_reg = url_int_mii_write_reg,
.uno_statchg = url_mii_statchg_cb,
.uno_tx_prepare = url_tx_prepare,
.uno_rx_loop = url_rx_loop,
.uno_init = url_init,
.uno_stop = url_uno_stop,
.uno_ioctl = url_uno_ioctl,
.uno_read_reg = url_uno_mii_read_reg,
.uno_write_reg = url_uno_mii_write_reg,
.uno_statchg = url_uno_mii_statchg,
.uno_tx_prepare = url_uno_tx_prepare,
.uno_rx_loop = url_uno_rx_loop,
.uno_init = url_uno_init,
};
/* Macros */
@ -244,16 +243,17 @@ url_attach(device_t parent, device_t self, void *aux)
/* Set these up now for url_mem(). */
usbnet_attach(un, "urldet");
usbnet_lock_core(un);
usbnet_busy(un);
/* reset the adapter */
usbnet_lock(un);
url_reset(un);
usbnet_unlock(un);
/* Get Ethernet Address */
usbnet_lock_mii(un);
err = url_mem(un, URL_CMD_READMEM, URL_IDR0, (void *)un->un_eaddr,
ETHER_ADDR_LEN);
usbnet_unlock_mii(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
if (err) {
aprint_error_dev(self, "read MAC address failed\n");
goto bad;
@ -277,7 +277,7 @@ url_mem(struct usbnet *un, int cmd, int offset, void *buf, int len)
usb_device_request_t req;
usbd_status err;
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
DPRINTFN(0x200,
("%s: %s: enter\n", device_xname(un->un_dev), __func__));
@ -379,7 +379,7 @@ url_init_locked(struct ifnet *ifp)
DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
usbnet_isowned(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return EIO;
@ -387,8 +387,6 @@ url_init_locked(struct ifnet *ifp)
/* Cancel pending I/O and free all TX/RX buffers */
usbnet_stop(un, ifp, 1);
usbnet_lock_mii_un_locked(un);
eaddr = CLLADDR(ifp->if_sadl);
for (i = 0; i < ETHER_ADDR_LEN; i++)
url_csr_write_1(un, URL_IDR0 + i, eaddr[i]);
@ -418,19 +416,19 @@ url_init_locked(struct ifnet *ifp)
/* Enable RX and TX */
URL_SETBIT(un, URL_CR, URL_CR_TE | URL_CR_RE);
usbnet_unlock_mii_un_locked(un);
return usbnet_init_rx_tx(un);
}
static int
url_init(struct ifnet *ifp)
url_uno_init(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;
usbnet_lock(un);
usbnet_lock_core(un);
usbnet_busy(un);
int ret = url_init_locked(ifp);
usbnet_unlock(un);
usbnet_unbusy(un);
usbnet_unlock_core(un);
return ret;
}
@ -445,7 +443,6 @@ url_reset(struct usbnet *un)
if (usbnet_isdying(un))
return;
usbnet_lock_mii_un_locked(un);
URL_SETBIT(un, URL_CR, URL_CR_SOFT_RST);
for (i = 0; i < URL_TX_TIMEOUT; i++) {
@ -455,7 +452,6 @@ url_reset(struct usbnet *un)
}
delay(10000); /* XXX */
usbnet_unlock_mii_un_locked(un);
}
#define url_calchash(addr) (ether_crc32_be((addr), ETHER_ADDR_LEN) >> 26)
@ -473,7 +469,7 @@ url_setiff_locked(struct usbnet *un)
DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
usbnet_isowned_mii(un);
usbnet_isowned_core(un);
if (usbnet_isdying(un))
return;
@ -526,23 +522,11 @@ allmulti:
url_csr_write_4(un, URL_MAR4, hashes[1]);
}
static void
url_setiff(struct usbnet *un)
{
usbnet_lock(un);
usbnet_lock_mii_un_locked(un);
url_setiff_locked(un);
usbnet_unlock_mii_un_locked(un);
usbnet_unlock(un);
}
static unsigned
url_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
url_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
{
int total_len;
usbnet_isowned_tx(un);
DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev),__func__));
KASSERT(un->un_tx_bufsz >= URL_MIN_FRAME_LEN);
@ -566,13 +550,11 @@ url_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
}
static void
url_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
url_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
{
struct ifnet *ifp = usbnet_ifp(un);
url_rxhdr_t rxhdr;
usbnet_isowned_rx(un);
DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev),__func__));
if (total_len <= ETHER_CRC_LEN || total_len <= sizeof(rxhdr)) {
@ -609,43 +591,45 @@ static void url_intr(void)
#endif
static int
url_ioctl_cb(struct ifnet *ifp, u_long cmd, void *data)
url_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data)
{
struct usbnet * const un = ifp->if_softc;
usbnet_lock_core(un);
usbnet_busy(un);
switch (cmd) {
case SIOCADDMULTI:
case SIOCDELMULTI:
url_setiff(un);
url_setiff_locked(un);
break;
default:
break;
}
usbnet_unbusy(un);
usbnet_unlock_core(un);
return 0;
}
/* Stop the adapter and free any mbufs allocated to the RX and TX lists. */
static void
url_stop_cb(struct ifnet *ifp, int disable)
url_uno_stop(struct ifnet *ifp, int disable)
{
struct usbnet * const un = ifp->if_softc;
usbnet_isowned(un);
DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__));
url_reset(un);
}
static int
url_int_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
url_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
{
uint16_t data;
usbd_status err = USBD_NORMAL_COMPLETION;
usbnet_isowned_mii(un);
DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n",
device_xname(un->un_dev), __func__, phy, reg));
@ -697,9 +681,8 @@ url_int_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
}
static int
url_int_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
url_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
{
usbnet_isowned_mii(un);
DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x val=0x%04hx\n",
device_xname(un->un_dev), __func__, phy, reg, val));
@ -745,7 +728,7 @@ url_int_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
}
static void
url_mii_statchg_cb(struct ifnet *ifp)
url_uno_mii_statchg(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_urndis.c,v 1.38 2020/03/13 18:17:40 christos Exp $ */
/* $NetBSD: if_urndis.c,v 1.39 2020/03/15 23:04:51 thorpej Exp $ */
/* $OpenBSD: if_urndis.c,v 1.31 2011/07/03 15:47:17 matthew Exp $ */
/*
@ -21,7 +21,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_urndis.c,v 1.38 2020/03/13 18:17:40 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_urndis.c,v 1.39 2020/03/15 23:04:51 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -66,10 +66,11 @@ struct urndis_softc {
static void urndis_watchdog(struct ifnet *);
#endif
static int urndis_init(struct ifnet *);
static void urndis_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t);
static unsigned urndis_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static int urndis_uno_init(struct ifnet *);
static void urndis_uno_rx_loop(struct usbnet *, struct usbnet_chain *,
uint32_t);
static unsigned urndis_uno_tx_prepare(struct usbnet *, struct mbuf *,
struct usbnet_chain *);
static int urndis_init_un(struct ifnet *, struct usbnet *);
@ -89,9 +90,9 @@ static int urndis_match(device_t, cfdata_t, void *);
static void urndis_attach(device_t, device_t, void *);
static const struct usbnet_ops urndis_ops = {
.uno_init = urndis_init,
.uno_tx_prepare = urndis_tx_prepare,
.uno_rx_loop = urndis_rx_loop,
.uno_init = urndis_uno_init,
.uno_tx_prepare = urndis_uno_tx_prepare,
.uno_rx_loop = urndis_uno_rx_loop,
};
CFATTACH_DECL_NEW(urndis, sizeof(struct urndis_softc),
@ -713,12 +714,10 @@ urndis_ctrl_keepalive(struct usbnet *un)
#endif
static unsigned
urndis_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
urndis_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
{
struct rndis_packet_msg *msg;
usbnet_isowned_tx(un);
if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - sizeof(*msg))
return 0;
@ -746,7 +745,8 @@ urndis_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
}
static void
urndis_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len)
urndis_uno_rx_loop(struct usbnet * un, struct usbnet_chain *c,
uint32_t total_len)
{
struct rndis_packet_msg *msg;
struct ifnet *ifp = usbnet_ifp(un);
@ -866,7 +866,7 @@ urndis_init_un(struct ifnet *ifp, struct usbnet *un)
if (err != RNDIS_STATUS_SUCCESS)
return EIO;
usbnet_lock(un);
usbnet_lock_core(un);
if (usbnet_isdying(un))
err = EIO;
else {
@ -874,13 +874,13 @@ urndis_init_un(struct ifnet *ifp, struct usbnet *un)
err = usbnet_init_rx_tx(un);
usbnet_set_link(un, err == 0);
}
usbnet_unlock(un);
usbnet_unlock_core(un);
return err;
}
static int
urndis_init(struct ifnet *ifp)
urndis_uno_init(struct ifnet *ifp)
{
struct usbnet *un = ifp->if_softc;
@ -1057,9 +1057,9 @@ urndis_attach(device_t parent, device_t self, void *aux)
&buf, &bufsz) != RNDIS_STATUS_SUCCESS) {
aprint_error("%s: unable to get hardware address\n",
DEVNAME(un));
usbnet_lock(un);
usbnet_lock_core(un);
usbnet_stop(un, ifp, 1);
usbnet_unlock(un);
usbnet_unlock_core(un);
return;
}
@ -1070,9 +1070,9 @@ urndis_attach(device_t parent, device_t self, void *aux)
aprint_error("%s: invalid address\n", DEVNAME(un));
if (buf && bufsz)
kmem_free(buf, bufsz);
usbnet_lock(un);
usbnet_lock_core(un);
usbnet_stop(un, ifp, 1);
usbnet_unlock(un);
usbnet_unlock_core(un);
return;
}
@ -1083,16 +1083,16 @@ urndis_attach(device_t parent, device_t self, void *aux)
if (urndis_ctrl_set(un, OID_GEN_CURRENT_PACKET_FILTER, &filter,
sizeof(filter)) != RNDIS_STATUS_SUCCESS) {
aprint_error("%s: unable to set data filters\n", DEVNAME(un));
usbnet_lock(un);
usbnet_lock_core(un);
usbnet_stop(un, ifp, 1);
usbnet_unlock(un);
usbnet_unlock_core(un);
return;
}
/* Turn off again now it has been identified. */
usbnet_lock(un);
usbnet_lock_core(un);
usbnet_stop(un, ifp, 1);
usbnet_unlock(un);
usbnet_unlock_core(un);
usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
0, NULL);

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_urtw.c,v 1.23 2020/03/14 02:35:33 christos Exp $ */
/* $NetBSD: if_urtw.c,v 1.24 2020/03/15 23:04:51 thorpej Exp $ */
/* $OpenBSD: if_urtw.c,v 1.39 2011/07/03 15:47:17 matthew Exp $ */
/*-
@ -19,7 +19,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_urtw.c,v 1.23 2020/03/14 02:35:33 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_urtw.c,v 1.24 2020/03/15 23:04:51 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -740,7 +740,11 @@ urtw_attach(device_t parent, device_t self, void *aux)
/* override state transition machine */
sc->sc_newstate = ic->ic_newstate;
ic->ic_newstate = urtw_newstate;
ieee80211_media_init(ic, urtw_media_change, ieee80211_media_status);
/* XXX media locking needs revisiting */
mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTUSB);
ieee80211_media_init_with_lock(ic,
urtw_media_change, ieee80211_media_status, &sc->sc_media_mtx);
bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_urtwn.c,v 1.83 2020/03/14 02:35:33 christos Exp $ */
/* $NetBSD: if_urtwn.c,v 1.84 2020/03/15 23:04:51 thorpej Exp $ */
/* $OpenBSD: if_urtwn.c,v 1.42 2015/02/10 23:25:46 mpi Exp $ */
/*-
@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_urtwn.c,v 1.83 2020/03/14 02:35:33 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_urtwn.c,v 1.84 2020/03/15 23:04:51 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@ -519,7 +519,11 @@ urtwn_attach(device_t parent, device_t self, void *aux)
/* Override state transition machine. */
sc->sc_newstate = ic->ic_newstate;
ic->ic_newstate = urtwn_newstate;
ieee80211_media_init(ic, urtwn_media_change, ieee80211_media_status);
/* XXX media locking needs revisiting */
mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTUSB);
ieee80211_media_init_with_lock(ic,
urtwn_media_change, ieee80211_media_status, &sc->sc_media_mtx);
bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_urtwnvar.h,v 1.15 2020/01/15 08:20:13 skrll Exp $ */
/* $NetBSD: if_urtwnvar.h,v 1.16 2020/03/15 23:04:51 thorpej Exp $ */
/* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $ */
/*-
@ -134,6 +134,7 @@ struct urtwn_softc {
kmutex_t sc_tx_mtx;
kmutex_t sc_rx_mtx;
kmutex_t sc_write_mtx;
kmutex_t sc_media_mtx; /* XXX */
struct usbd_pipe * rx_pipe[R92C_MAX_EPIN];
int rx_npipe;

View File

@ -324,6 +324,8 @@ struct urtw_softc {
struct ethercom sc_ec;
#define sc_if sc_ec.ec_if
kmutex_t sc_media_mtx; /* XXX */
enum {
URTW_INIT_NONE,
URTW_INIT_INITED

View File

@ -1,5 +1,5 @@
/* $OpenBSD: if_zyd.c,v 1.52 2007/02/11 00:08:04 jsg Exp $ */
/* $NetBSD: if_zyd.c,v 1.58 2020/03/14 02:35:33 christos Exp $ */
/* $NetBSD: if_zyd.c,v 1.59 2020/03/15 23:04:51 thorpej Exp $ */
/*-
* Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr>
@ -23,7 +23,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_zyd.c,v 1.58 2020/03/14 02:35:33 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_zyd.c,v 1.59 2020/03/15 23:04:51 thorpej Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@ -433,7 +433,11 @@ zyd_complete_attach(struct zyd_softc *sc)
/* override state transition machine */
sc->sc_newstate = ic->ic_newstate;
ic->ic_newstate = zyd_newstate;
ieee80211_media_init(ic, zyd_media_change, ieee80211_media_status);
/* XXX media locking needs revisiting */
mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTUSB);
ieee80211_media_init_with_lock(ic,
zyd_media_change, ieee80211_media_status, &sc->sc_media_mtx);
bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,

View File

@ -1,5 +1,5 @@
/* $OpenBSD: if_zydreg.h,v 1.19 2006/11/30 19:28:07 damien Exp $ */
/* $NetBSD: if_zydreg.h,v 1.11 2020/01/15 08:20:13 skrll Exp $ */
/* $NetBSD: if_zydreg.h,v 1.12 2020/03/15 23:04:51 thorpej Exp $ */
/*-
* Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr>
@ -1182,6 +1182,8 @@ struct zyd_softc {
enum ieee80211_state, int);
struct zyd_rf sc_rf;
kmutex_t sc_media_mtx; /* XXX */
struct usb_task sc_task;
struct usbd_device * sc_udev;
struct usbd_interface * sc_iface;

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbnet.c,v 1.37 2020/03/14 03:01:36 christos Exp $ */
/* $NetBSD: usbnet.c,v 1.38 2020/03/15 23:04:51 thorpej Exp $ */
/*
* Copyright (c) 2019 Matthew R. Green
@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.37 2020/03/14 03:01:36 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.38 2020/03/15 23:04:51 thorpej Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@ -54,21 +54,18 @@ struct usbnet_cdata {
struct usbnet_private {
/*
* - unp_lock protects most of the structure, and the public one
* - unp_miilock must be held to access this device's MII bus
* - unp_core_lock protects most of this structure, the public one,
* and the MII / media data.
* - unp_rxlock protects the rx path and its data
* - unp_txlock protects the tx path and its data
* - unp_detachcv handles detach vs open references
*
* the lock ordering is:
* ifnet lock -> unp_lock -> unp_rxlock -> unp_txlock
* unp_lock -> unp_miilock
* and unp_lock may be dropped after taking unp_miilock.
* - ifnet lock is not needed for unp_lock, but if ifnet lock is
* ifnet lock -> unp_core_lock -> unp_rxlock -> unp_txlock
* - ifnet lock is not needed for unp_core_lock, but if ifnet lock is
* involved, it must be taken first
*/
kmutex_t unp_lock;
kmutex_t unp_miilock;
kmutex_t unp_core_lock;
kmutex_t unp_rxlock;
kmutex_t unp_txlock;
kcondvar_t unp_detachcv;
@ -154,6 +151,7 @@ fail:
static void
uno_stop(struct usbnet *un, struct ifnet *ifp, int disable)
{
usbnet_isowned_core(un);
if (un->un_ops->uno_stop)
(*un->un_ops->uno_stop)(ifp, disable);
}
@ -161,6 +159,11 @@ uno_stop(struct usbnet *un, struct ifnet *ifp, int disable)
static int
uno_ioctl(struct usbnet *un, struct ifnet *ifp, u_long cmd, void *data)
{
/*
* There are cases where IFNET_LOCK will not be held when we
* are called (e.g. add/delete multicast address), so we can't
* assert it.
*/
if (un->un_ops->uno_ioctl)
return (*un->un_ops->uno_ioctl)(ifp, cmd, data);
return 0;
@ -169,42 +172,49 @@ uno_ioctl(struct usbnet *un, struct ifnet *ifp, u_long cmd, void *data)
static int
uno_override_ioctl(struct usbnet *un, struct ifnet *ifp, u_long cmd, void *data)
{
/* See above. */
return (*un->un_ops->uno_override_ioctl)(ifp, cmd, data);
}
static int
uno_init(struct usbnet *un, struct ifnet *ifp)
{
KASSERT(IFNET_LOCKED(ifp));
return (*un->un_ops->uno_init)(ifp);
}
static int
uno_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
{
usbnet_isowned_core(un);
return (*un->un_ops->uno_read_reg)(un, phy, reg, val);
}
static int
uno_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
{
usbnet_isowned_core(un);
return (*un->un_ops->uno_write_reg)(un, phy, reg, val);
}
static void
uno_mii_statchg(struct usbnet *un, struct ifnet *ifp)
{
usbnet_isowned_core(un);
(*un->un_ops->uno_statchg)(ifp);
}
static unsigned
uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
{
usbnet_isowned_tx(un);
return (*un->un_ops->uno_tx_prepare)(un, m, c);
}
static void
uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
{
usbnet_isowned_rx(un);
(*un->un_ops->uno_rx_loop)(un, c, total_len);
}
@ -548,7 +558,7 @@ usbnet_start_locked(struct ifnet *ifp)
}
static void
usbnet_start(struct ifnet *ifp)
usbnet_if_start(struct ifnet *ifp)
{
struct usbnet * const un = ifp->if_softc;
struct usbnet_private * const unp = un->un_pri;
@ -802,12 +812,13 @@ usbnet_init_rx_tx(struct usbnet * const un)
usbd_status err;
int error = 0;
usbnet_isowned(un);
usbnet_isowned_core(un);
if (unp->unp_dying) {
return EIO;
}
unp->unp_refcnt++;
usbnet_busy(un);
/* Open RX and TX pipes. */
err = usbnet_ep_open_pipes(un);
@ -850,75 +861,36 @@ out:
usbnet_tx_list_fini(un);
usbnet_ep_close_pipes(un);
}
if (--unp->unp_refcnt < 0)
cv_broadcast(&unp->unp_detachcv);
usbnet_unbusy(un);
usbnet_isowned(un);
usbnet_isowned_core(un);
return error;
}
void
usbnet_busy(struct usbnet *un)
{
struct usbnet_private * const unp = un->un_pri;
usbnet_isowned_core(un);
unp->unp_refcnt++;
}
void
usbnet_unbusy(struct usbnet *un)
{
struct usbnet_private * const unp = un->un_pri;
usbnet_isowned_core(un);
if (--unp->unp_refcnt < 0)
cv_broadcast(&unp->unp_detachcv);
}
/* MII management. */
/*
* Access functions for MII. Take the MII lock to call access MII regs.
* Two forms: usbnet (softc) lock currently held or not.
*/
void
usbnet_lock_mii(struct usbnet *un)
{
struct usbnet_private * const unp = un->un_pri;
mutex_enter(&unp->unp_lock);
unp->unp_refcnt++;
mutex_exit(&unp->unp_lock);
mutex_enter(&unp->unp_miilock);
}
void
usbnet_lock_mii_un_locked(struct usbnet *un)
{
struct usbnet_private * const unp = un->un_pri;
usbnet_isowned(un);
unp->unp_refcnt++;
mutex_enter(&unp->unp_miilock);
}
void
usbnet_unlock_mii(struct usbnet *un)
{
struct usbnet_private * const unp = un->un_pri;
mutex_exit(&unp->unp_miilock);
mutex_enter(&unp->unp_lock);
if (--unp->unp_refcnt < 0)
cv_broadcast(&unp->unp_detachcv);
mutex_exit(&unp->unp_lock);
}
void
usbnet_unlock_mii_un_locked(struct usbnet *un)
{
struct usbnet_private * const unp = un->un_pri;
usbnet_isowned(un);
mutex_exit(&unp->unp_miilock);
if (--unp->unp_refcnt < 0)
cv_broadcast(&unp->unp_detachcv);
}
kmutex_t *
usbnet_mutex_mii(struct usbnet *un)
{
struct usbnet_private * const unp = un->un_pri;
return &unp->unp_miilock;
}
int
usbnet_mii_readreg(device_t dev, int phy, int reg, uint16_t *val)
{
@ -927,16 +899,16 @@ usbnet_mii_readreg(device_t dev, int phy, int reg, uint16_t *val)
struct usbnet_private * const unp = un->un_pri;
int err;
mutex_enter(&unp->unp_lock);
/* MII layer ensures core_lock is held. */
usbnet_isowned_core(un);
if (unp->unp_dying) {
mutex_exit(&unp->unp_lock);
return EIO;
}
usbnet_lock_mii_un_locked(un);
mutex_exit(&unp->unp_lock);
usbnet_busy(un);
err = uno_read_reg(un, phy, reg, val);
usbnet_unlock_mii(un);
usbnet_unbusy(un);
if (err) {
USBNETHIST_CALLARGS("%jd: read PHY failed: %jd",
@ -955,16 +927,16 @@ usbnet_mii_writereg(device_t dev, int phy, int reg, uint16_t val)
struct usbnet_private * const unp = un->un_pri;
int err;
mutex_enter(&unp->unp_lock);
/* MII layer ensures core_lock is held. */
usbnet_isowned_core(un);
if (unp->unp_dying) {
mutex_exit(&unp->unp_lock);
return EIO;
}
usbnet_lock_mii_un_locked(un);
mutex_exit(&unp->unp_lock);
usbnet_busy(un);
err = uno_write_reg(un, phy, reg, val);
usbnet_unlock_mii(un);
usbnet_unbusy(un);
if (err) {
USBNETHIST_CALLARGS("%jd: write PHY failed: %jd",
@ -981,7 +953,12 @@ usbnet_mii_statchg(struct ifnet *ifp)
USBNETHIST_FUNC(); USBNETHIST_CALLED();
struct usbnet * const un = ifp->if_softc;
/* MII layer ensures core_lock is held. */
usbnet_isowned_core(un);
usbnet_busy(un);
uno_mii_statchg(un, ifp);
usbnet_unbusy(un);
}
static int
@ -992,6 +969,9 @@ usbnet_media_upd(struct ifnet *ifp)
struct usbnet_private * const unp = un->un_pri;
struct mii_data * const mii = usbnet_mii(un);
/* ifmedia layer ensures core_lock is held. */
usbnet_isowned_core(un);
if (unp->unp_dying)
return EIO;
@ -1018,7 +998,7 @@ usbnet_ifflags_cb(struct ethercom *ec)
struct usbnet_private * const unp = un->un_pri;
int rv = 0;
mutex_enter(&unp->unp_lock);
mutex_enter(&unp->unp_core_lock);
const u_short changed = ifp->if_flags ^ unp->unp_if_flags;
if ((changed & ~(IFF_CANTCHANGE | IFF_DEBUG)) == 0) {
@ -1029,13 +1009,13 @@ usbnet_ifflags_cb(struct ethercom *ec)
rv = ENETRESET;
}
mutex_exit(&unp->unp_lock);
mutex_exit(&unp->unp_core_lock);
return rv;
}
static int
usbnet_ioctl(struct ifnet *ifp, u_long cmd, void *data)
usbnet_if_ioctl(struct ifnet *ifp, u_long cmd, void *data)
{
USBNETHIST_FUNC();
struct usbnet * const un = ifp->if_softc;
@ -1066,7 +1046,7 @@ usbnet_ioctl(struct ifnet *ifp, u_long cmd, void *data)
*
* usbnet_stop() is exported for drivers to use, expects lock held.
*
* usbnet_stop_ifp() is for the if_stop handler.
* usbnet_if_stop() is for the if_stop handler.
*/
void
usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable)
@ -1075,7 +1055,9 @@ usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable)
USBNETHIST_FUNC(); USBNETHIST_CALLED();
usbnet_isowned(un);
usbnet_isowned_core(un);
usbnet_busy(un);
mutex_enter(&unp->unp_rxlock);
mutex_enter(&unp->unp_txlock);
@ -1089,15 +1071,15 @@ usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable)
* XXXSMP Would like to
* KASSERT(IFNET_LOCKED(ifp))
* here but the locking order is:
* ifnet -> unlock -> rxlock -> txlock
* and unlock is already held.
* ifnet -> core_lock -> rxlock -> txlock
* and core_lock is already held.
*/
ifp->if_flags &= ~IFF_RUNNING;
unp->unp_timer = 0;
callout_halt(&unp->unp_stat_ch, &unp->unp_lock);
callout_halt(&unp->unp_stat_ch, &unp->unp_core_lock);
usb_rem_task_wait(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER,
&unp->unp_lock);
&unp->unp_core_lock);
/* Stop transfers. */
usbnet_ep_stop_pipes(un);
@ -1108,17 +1090,19 @@ usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable)
/* Close pipes. */
usbnet_ep_close_pipes(un);
usbnet_unbusy(un);
}
static void
usbnet_stop_ifp(struct ifnet *ifp, int disable)
usbnet_if_stop(struct ifnet *ifp, int disable)
{
struct usbnet * const un = ifp->if_softc;
struct usbnet_private * const unp = un->un_pri;
mutex_enter(&unp->unp_lock);
mutex_enter(&unp->unp_core_lock);
usbnet_stop(un, ifp, disable);
mutex_exit(&unp->unp_lock);
mutex_exit(&unp->unp_core_lock);
}
/*
@ -1180,9 +1164,9 @@ usbnet_tick_task(void *arg)
USBNETHIST_CALLARGSN(8, "%jd: enter", unp->unp_number, 0, 0, 0);
mutex_enter(&unp->unp_lock);
mutex_enter(&unp->unp_core_lock);
if (unp->unp_stopping || unp->unp_dying) {
mutex_exit(&unp->unp_lock);
mutex_exit(&unp->unp_core_lock);
return;
}
@ -1191,32 +1175,33 @@ usbnet_tick_task(void *arg)
KASSERT(ifp != NULL); /* embedded member */
unp->unp_refcnt++;
mutex_exit(&unp->unp_lock);
usbnet_busy(un);
mutex_exit(&unp->unp_core_lock);
if (unp->unp_timer != 0 && --unp->unp_timer == 0)
usbnet_watchdog(ifp);
DPRINTFN(8, "mii %#jx ifp %#jx", (uintptr_t)mii, (uintptr_t)ifp, 0, 0);
if (mii) {
mutex_enter(&unp->unp_core_lock);
mii_tick(mii);
if (!unp->unp_link)
(*mii->mii_statchg)(ifp);
mutex_exit(&unp->unp_core_lock);
}
/* Call driver if requested. */
uno_tick(un);
mutex_enter(&unp->unp_lock);
if (--unp->unp_refcnt < 0)
cv_broadcast(&unp->unp_detachcv);
mutex_enter(&unp->unp_core_lock);
usbnet_unbusy(un);
if (!unp->unp_stopping && !unp->unp_dying)
callout_schedule(&unp->unp_stat_ch, hz);
mutex_exit(&unp->unp_lock);
mutex_exit(&unp->unp_core_lock);
}
static int
usbnet_init(struct ifnet *ifp)
usbnet_if_init(struct ifnet *ifp)
{
USBNETHIST_FUNC(); USBNETHIST_CALLED();
struct usbnet * const un = ifp->if_softc;
@ -1285,21 +1270,21 @@ usbnet_isdying(struct usbnet *un)
/* Locking. */
void
usbnet_lock(struct usbnet *un)
usbnet_lock_core(struct usbnet *un)
{
mutex_enter(&un->un_pri->unp_lock);
mutex_enter(&un->un_pri->unp_core_lock);
}
void
usbnet_unlock(struct usbnet *un)
usbnet_unlock_core(struct usbnet *un)
{
mutex_exit(&un->un_pri->unp_lock);
mutex_exit(&un->un_pri->unp_core_lock);
}
kmutex_t *
usbnet_mutex(struct usbnet *un)
usbnet_mutex_core(struct usbnet *un)
{
return &un->un_pri->unp_lock;
return &un->un_pri->unp_core_lock;
}
void
@ -1386,10 +1371,9 @@ usbnet_attach(struct usbnet *un,
callout_init(&unp->unp_stat_ch, CALLOUT_MPSAFE);
callout_setfunc(&unp->unp_stat_ch, usbnet_tick, un);
mutex_init(&unp->unp_miilock, MUTEX_DEFAULT, IPL_NONE);
mutex_init(&unp->unp_txlock, MUTEX_DEFAULT, IPL_SOFTUSB);
mutex_init(&unp->unp_rxlock, MUTEX_DEFAULT, IPL_SOFTUSB);
mutex_init(&unp->unp_lock, MUTEX_DEFAULT, IPL_NONE);
mutex_init(&unp->unp_core_lock, MUTEX_DEFAULT, IPL_NONE);
cv_init(&unp->unp_detachcv, detname);
rnd_attach_source(&unp->unp_rndsrc, device_xname(un->un_dev),
@ -1422,7 +1406,8 @@ usbnet_attach_mii(struct usbnet *un, const struct usbnet_mii *unm)
mii->mii_flags = MIIF_AUTOTSLEEP;
usbnet_ec(un)->ec_mii = mii;
ifmedia_init(&mii->mii_media, 0, usbnet_media_upd, ether_mediastatus);
ifmedia_init_with_lock(&mii->mii_media, 0,
usbnet_media_upd, ether_mediastatus, usbnet_mutex_core(un));
mii_attach(un->un_dev, mii, unm->un_mii_capmask, unm->un_mii_phyloc,
unm->un_mii_offset, unm->un_mii_flags);
@ -1448,10 +1433,10 @@ usbnet_attach_ifp(struct usbnet *un,
strlcpy(ifp->if_xname, device_xname(un->un_dev), IFNAMSIZ);
ifp->if_flags = if_flags;
ifp->if_extflags = IFEF_MPSAFE | if_extflags;
ifp->if_ioctl = usbnet_ioctl;
ifp->if_start = usbnet_start;
ifp->if_init = usbnet_init;
ifp->if_stop = usbnet_stop_ifp;
ifp->if_ioctl = usbnet_if_ioctl;
ifp->if_start = usbnet_if_start;
ifp->if_init = usbnet_if_init;
ifp->if_stop = usbnet_if_stop;
if (unm)
usbnet_attach_mii(un, unm);
@ -1506,13 +1491,13 @@ usbnet_detach(device_t self, int flags)
struct ifnet * const ifp = usbnet_ifp(un);
struct mii_data * const mii = usbnet_mii(un);
mutex_enter(&unp->unp_lock);
mutex_enter(&unp->unp_core_lock);
unp->unp_dying = true;
mutex_exit(&unp->unp_lock);
mutex_exit(&unp->unp_core_lock);
if (ifp->if_flags & IFF_RUNNING) {
IFNET_LOCK(ifp);
usbnet_stop_ifp(ifp, 1);
usbnet_if_stop(ifp, 1);
IFNET_UNLOCK(ifp);
}
@ -1520,13 +1505,13 @@ usbnet_detach(device_t self, int flags)
usb_rem_task_wait(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER,
NULL);
mutex_enter(&unp->unp_lock);
mutex_enter(&unp->unp_core_lock);
unp->unp_refcnt--;
while (unp->unp_refcnt >= 0) {
/* Wait for processes to go away */
cv_wait(&unp->unp_detachcv, &unp->unp_lock);
cv_wait(&unp->unp_detachcv, &unp->unp_core_lock);
}
mutex_exit(&unp->unp_lock);
mutex_exit(&unp->unp_core_lock);
usbnet_rx_list_free(un);
usbnet_tx_list_free(un);
@ -1548,10 +1533,9 @@ usbnet_detach(device_t self, int flags)
usbnet_ec(un)->ec_mii = NULL;
cv_destroy(&unp->unp_detachcv);
mutex_destroy(&unp->unp_lock);
mutex_destroy(&unp->unp_core_lock);
mutex_destroy(&unp->unp_rxlock);
mutex_destroy(&unp->unp_txlock);
mutex_destroy(&unp->unp_miilock);
pmf_device_deregister(un->un_dev);
@ -1575,9 +1559,9 @@ usbnet_activate(device_t self, devact_t act)
case DVACT_DEACTIVATE:
if_deactivate(ifp);
mutex_enter(&unp->unp_lock);
mutex_enter(&unp->unp_core_lock);
unp->unp_dying = true;
mutex_exit(&unp->unp_lock);
mutex_exit(&unp->unp_core_lock);
mutex_enter(&unp->unp_rxlock);
mutex_enter(&unp->unp_txlock);

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbnet.h,v 1.16 2020/01/07 06:42:26 maxv Exp $ */
/* $NetBSD: usbnet.h,v 1.17 2020/03/15 23:04:51 thorpej Exp $ */
/*
* Copyright (c) 2019 Matthew R. Green
@ -156,18 +156,40 @@ typedef void (*usbnet_tick_cb)(struct usbnet *);
/* Interrupt pipe callback. */
typedef void (*usbnet_intr_cb)(struct usbnet *, usbd_status);
/*
* LOCKING
* =======
*
* The following annotations indicate which locks are held when
* usbnet_ops functions are invoked:
*
* I -> IFNET_LOCK (if_ioctl_lock)
* C -> CORE_LOCK (usbnet core_lock)
* T -> TX_LOCK (usbnet tx_lock)
* R -> RX_LOCK (usbnet rx_lock)
* n -> no locks held
*
* 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).
*
* 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;
usbnet_ioctl_cb uno_ioctl;
usbnet_ioctl_cb uno_override_ioctl;
usbnet_init_cb uno_init;
usbnet_mii_read_reg_cb uno_read_reg;
usbnet_mii_write_reg_cb uno_write_reg;
usbnet_mii_statchg_cb uno_statchg;
usbnet_tx_prepare_cb uno_tx_prepare;
usbnet_rx_loop_cb uno_rx_loop;
usbnet_tick_cb uno_tick;
usbnet_intr_cb uno_intr;
usbnet_stop_cb uno_stop; /* C */
usbnet_ioctl_cb uno_ioctl; /* I (maybe) */
usbnet_ioctl_cb uno_override_ioctl; /* I (maybe) */
usbnet_init_cb uno_init; /* I */
usbnet_mii_read_reg_cb uno_read_reg; /* C */
usbnet_mii_write_reg_cb uno_write_reg; /* C */
usbnet_mii_statchg_cb uno_statchg; /* C */
usbnet_tx_prepare_cb uno_tx_prepare; /* T */
usbnet_rx_loop_cb uno_rx_loop; /* R */
usbnet_tick_cb uno_tick; /* n */
usbnet_intr_cb uno_intr; /* n */
};
/*
@ -277,15 +299,18 @@ bool usbnet_isdying(struct usbnet *);
* Locking. Note that the isowned() are implemented here so that
* empty-KASSERT() causes them to be elided for non-DIAG builds.
*/
void usbnet_lock(struct usbnet *);
void usbnet_unlock(struct usbnet *);
kmutex_t *usbnet_mutex(struct usbnet *);
void usbnet_lock_core(struct usbnet *);
void usbnet_unlock_core(struct usbnet *);
kmutex_t *usbnet_mutex_core(struct usbnet *);
static __inline__ void
usbnet_isowned(struct usbnet *un)
usbnet_isowned_core(struct usbnet *un)
{
KASSERT(mutex_owned(usbnet_mutex(un)));
KASSERT(mutex_owned(usbnet_mutex_core(un)));
}
void usbnet_busy(struct usbnet *);
void usbnet_unbusy(struct usbnet *);
void usbnet_lock_rx(struct usbnet *);
void usbnet_unlock_rx(struct usbnet *);
kmutex_t *usbnet_mutex_rx(struct usbnet *);
@ -320,18 +345,6 @@ usbnet_isowned_tx(struct usbnet *un)
int usbnet_init_rx_tx(struct usbnet * const);
/* MII. */
void usbnet_lock_mii(struct usbnet *);
void usbnet_lock_mii_un_locked(struct usbnet *);
void usbnet_unlock_mii(struct usbnet *);
void usbnet_unlock_mii_un_locked(struct usbnet *);
kmutex_t *usbnet_mutex_mii(struct usbnet *);
static __inline__ void
usbnet_isowned_mii(struct usbnet *un)
{
KASSERT(mutex_owned(usbnet_mutex_mii(un)));
}
int usbnet_mii_readreg(device_t, int, int, uint16_t *);
int usbnet_mii_writereg(device_t, int, int, uint16_t);
void usbnet_mii_statchg(struct ifnet *);

View File

@ -1,7 +1,7 @@
/* $NetBSD: if_media.c,v 1.51 2020/02/01 20:56:16 thorpej Exp $ */
/* $NetBSD: if_media.c,v 1.52 2020/03/15 23:04:51 thorpej Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* Copyright (c) 1998, 2020 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -76,7 +76,9 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_media.c,v 1.51 2020/02/01 20:56:16 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_media.c,v 1.52 2020/03/15 23:04:51 thorpej Exp $");
#define __IFMEDIA_PRIVATE
#include <sys/param.h>
#include <sys/systm.h>
@ -90,9 +92,9 @@ __KERNEL_RCSID(0, "$NetBSD: if_media.c,v 1.51 2020/02/01 20:56:16 thorpej Exp $"
#include <net/netisr.h>
static void ifmedia_status(struct ifmedia *, struct ifnet *,
struct ifmediareq *);
static int ifmedia_ioctl_locked(struct ifnet *, struct ifreq *,
struct ifmedia *, u_long);
struct ifmediareq *);
static struct ifmedia_entry *
ifmedia_match_locked(struct ifmedia *, u_int, u_int);
/*
* Compile-time options:
@ -106,20 +108,113 @@ int ifmedia_debug = 0;
static void ifmedia_printword(int);
#endif
/*
* We need to implement a recursive mutex to handle the un-converted
* driver case. For a fully MP-safe driver, the media lock will be
* held before calling any of the entry points that require it. However,
* this is not necessarily the case for a driver that hasn't yet been
* converted, and the entry point calls may be nested (for example
* mii_ifmedia_change -> ether_mediachange -> mii_mediachg). Luckily,
* the nesting won't be very deep, and 4 nested holds should be plenty.
*/
#define IFM_L_OWNLOCK 0x01
#define IFM_L_COUNT_MASK 0x3UL
#define IFM_L_CPU_MASK ~(IFM_L_COUNT_MASK)
void
ifmedia_lock_for_legacy(struct ifmedia *ifm)
{
uintptr_t cnt = IFM_L_OWNLOCK;
uintptr_t ci;
if (mutex_tryenter(ifm->ifm_lock)) {
goto gotit;
}
kpreempt_disable();
ci = (uintptr_t)curcpu();
if ((ifm->ifm_legacy & IFM_L_CPU_MASK) == ci) {
cnt = ifm->ifm_legacy & IFM_L_COUNT_MASK;
KASSERT(cnt < IFM_L_COUNT_MASK);
cnt++;
kpreempt_enable();
goto gotit;
}
kpreempt_enable();
mutex_enter(ifm->ifm_lock);
gotit:
KASSERT(kpreempt_disabled());
ci = (uintptr_t)curcpu();
KASSERT((ci & IFM_L_CPU_MASK) == ci);
ifm->ifm_legacy = ci | cnt;
}
void
ifmedia_unlock_for_legacy(struct ifmedia *ifm)
{
uintptr_t cnt;
uintptr_t ci = (uintptr_t)curcpu();
KASSERT(kpreempt_disabled());
KASSERT((ifm->ifm_legacy & IFM_L_CPU_MASK) == ci);
cnt = ifm->ifm_legacy & IFM_L_COUNT_MASK;
KASSERT(cnt != 0);
if (cnt == IFM_L_OWNLOCK) {
ifm->ifm_legacy = IFM_L_OWNLOCK;
mutex_exit(ifm->ifm_lock);
return;
}
cnt--;
ifm->ifm_legacy = ci | cnt;
}
/*
* Initialize if_media struct for a specific interface instance.
*/
void
ifmedia_init(struct ifmedia *ifm, int dontcare_mask,
ifm_change_cb_t change_callback, ifm_stat_cb_t status_callback)
ifmedia_init_with_lock(struct ifmedia *ifm, int dontcare_mask,
ifm_change_cb_t change_callback, ifm_stat_cb_t status_callback,
kmutex_t *lock)
{
/*
* XXX Would really like to assert:
*
* !if_is_mpsafe(ifp) || ((if_is_mpsafe(ifp) && lock != NULL)
*
* ...but we don't have acccess to the ifnet here.
*/
TAILQ_INIT(&ifm->ifm_list);
ifm->ifm_cur = NULL;
ifm->ifm_media = IFM_NONE;
ifm->ifm_mask = dontcare_mask; /* IF don't-care bits */
ifm->ifm_change = change_callback;
ifm->ifm_status = status_callback;
ifm->ifm_legacy = 0;
if (lock == NULL) {
/*
* This is to support drivers that are not yet MP-safe
* with regard to the ifmedia layer. In these cases,
* we supply the lock and we ensure it's taken upon entry
* to various routines that expect it to be held. When
* we do this, we expect that the driver is in general a
* non-MP-safe driver and has already gone to splnet().
*/
lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
ifm->ifm_legacy = IFM_L_OWNLOCK;
}
ifm->ifm_lock = lock;
}
void
ifmedia_init(struct ifmedia *ifm, int dontcare_mask,
ifm_change_cb_t change_callback, ifm_stat_cb_t status_callback)
{
ifmedia_init_with_lock(ifm, dontcare_mask, change_callback,
status_callback, NULL);
}
/*
@ -130,21 +225,36 @@ ifmedia_fini(struct ifmedia *ifm)
{
ifmedia_removeall(ifm);
if (ifm->ifm_legacy) {
KASSERT(ifm->ifm_legacy == IFM_L_OWNLOCK);
mutex_obj_free(ifm->ifm_lock);
}
ifm->ifm_legacy = 0;
ifm->ifm_lock = NULL;
}
int
ifmedia_change(struct ifmedia *ifm, struct ifnet *ifp)
{
int rv;
if (ifm->ifm_change == NULL)
return -1;
return (*ifm->ifm_change)(ifp);
IFMEDIA_LOCK_FOR_LEGACY(ifm);
KASSERT(ifmedia_locked(ifm));
if (ifm->ifm_change)
rv = (*ifm->ifm_change)(ifp);
else
rv = -1;
IFMEDIA_UNLOCK_FOR_LEGACY(ifm);
return rv;
}
static void
ifmedia_status(struct ifmedia *ifm, struct ifnet *ifp, struct ifmediareq *ifmr)
{
KASSERT(ifmedia_locked(ifm));
if (ifm->ifm_status == NULL)
return;
(*ifm->ifm_status)(ifp, ifmr);
@ -154,10 +264,10 @@ ifmedia_status(struct ifmedia *ifm, struct ifnet *ifp, struct ifmediareq *ifmr)
* Add a media configuration to the list of supported media
* for a specific interface instance.
*/
void
ifmedia_add(struct ifmedia *ifm, int mword, int data, void *aux)
static void
ifmedia_add_entry(struct ifmedia *ifm, int mword, int data, void *aux,
struct ifmedia_entry *entry)
{
struct ifmedia_entry *entry;
#ifdef IFMEDIA_DEBUG
if (ifmedia_debug) {
@ -170,13 +280,23 @@ ifmedia_add(struct ifmedia *ifm, int mword, int data, void *aux)
}
#endif
entry = kmem_zalloc(sizeof(*entry), KM_SLEEP);
entry->ifm_media = mword;
entry->ifm_data = data;
entry->ifm_aux = aux;
TAILQ_INSERT_TAIL(&ifm->ifm_list, entry, ifm_list);
}
void
ifmedia_add(struct ifmedia *ifm, int mword, int data, void *aux)
{
struct ifmedia_entry *entry;
entry = kmem_zalloc(sizeof(*entry), KM_SLEEP);
ifmedia_lock(ifm);
ifmedia_add_entry(ifm, mword, data, aux, entry);
ifmedia_unlock(ifm);
}
/*
* Add an array of media configurations to the list of
* supported media for a specific interface instance.
@ -201,9 +321,10 @@ ifmedia_list_add(struct ifmedia *ifm, struct ifmedia_entry *lp, int count)
void
ifmedia_set(struct ifmedia *ifm, int target)
{
struct ifmedia_entry *match;
struct ifmedia_entry *match, *entry = NULL;
match = ifmedia_match(ifm, target, ifm->ifm_mask);
ifmedia_lock(ifm);
match = ifmedia_match_locked(ifm, target, ifm->ifm_mask);
/*
* If we didn't find the requested media, then we try to fall
@ -223,15 +344,28 @@ ifmedia_set(struct ifmedia *ifm, int target)
printf("ifmedia_set: no match for 0x%x/0x%x\n",
target, ~ifm->ifm_mask);
target = (target & IFM_NMASK) | IFM_NONE;
match = ifmedia_match(ifm, target, ifm->ifm_mask);
match = ifmedia_match_locked(ifm, target, ifm->ifm_mask);
if (match == NULL) {
ifmedia_add(ifm, target, 0, NULL);
match = ifmedia_match(ifm, target, ifm->ifm_mask);
ifmedia_unlock(ifm);
entry = kmem_zalloc(sizeof(*entry), KM_SLEEP);
ifmedia_lock(ifm);
match = ifmedia_match_locked(ifm, target,
ifm->ifm_mask);
if (match == NULL) {
ifmedia_add_entry(ifm, target, 0, NULL, entry);
entry = NULL;
}
match = ifmedia_match_locked(ifm, target,
ifm->ifm_mask);
if (match == NULL)
panic("ifmedia_set failed");
}
}
ifm->ifm_cur = match;
ifmedia_unlock(ifm);
if (entry)
kmem_free(entry, sizeof(*entry));
#ifdef IFMEDIA_DEBUG
if (ifmedia_debug) {
@ -249,6 +383,8 @@ ifmedia_getwords(struct ifmedia * const ifm, int *words, int maxwords)
struct ifmedia_entry *ep;
int nwords = 0;
KASSERT(ifmedia_locked(ifm));
TAILQ_FOREACH(ep, &ifm->ifm_list, ifm_list) {
if (words != NULL && nwords < maxwords) {
words[nwords] = ep->ifm_media;
@ -259,11 +395,27 @@ ifmedia_getwords(struct ifmedia * const ifm, int *words, int maxwords)
return nwords;
}
#define IFMEDIA_IOCTL_LOCK(ifm) \
do { \
if (ifmedia_islegacy(ifm)) \
ifmedia_lock_for_legacy(ifm); \
else \
ifmedia_lock(ifm); \
} while (/*CONSTCOND*/0)
#define IFMEDIA_IOCTL_UNLOCK(ifm) \
do { \
if (ifmedia_islegacy(ifm)) \
ifmedia_unlock_for_legacy(ifm); \
else \
ifmedia_unlock(ifm); \
} while (/*CONSTCOND*/0)
/*
* Device-independent media ioctl support function.
*/
static int
ifmedia_ioctl_locked(struct ifnet *ifp, struct ifreq *ifr, struct ifmedia *ifm,
int
ifmedia_ioctl(struct ifnet *ifp, struct ifreq *ifr, struct ifmedia *ifm,
u_long cmd)
{
struct ifmedia_entry *match;
@ -273,6 +425,8 @@ ifmedia_ioctl_locked(struct ifnet *ifp, struct ifreq *ifr, struct ifmedia *ifm,
if (ifp == NULL || ifr == NULL || ifm == NULL)
return EINVAL;
KERNEL_LOCK_UNLESS_IFP_MPSAFE(ifp);
switch (cmd) {
case SIOCSIFMEDIA: /* Set the current media. */
{
@ -280,7 +434,9 @@ ifmedia_ioctl_locked(struct ifnet *ifp, struct ifreq *ifr, struct ifmedia *ifm,
u_int oldmedia;
u_int newmedia = ifr->ifr_media;
match = ifmedia_match(ifm, newmedia, ifm->ifm_mask);
IFMEDIA_IOCTL_LOCK(ifm);
match = ifmedia_match_locked(ifm, newmedia, ifm->ifm_mask);
if (match == NULL) {
#ifdef IFMEDIA_DEBUG
if (ifmedia_debug) {
@ -288,7 +444,9 @@ ifmedia_ioctl_locked(struct ifnet *ifp, struct ifreq *ifr, struct ifmedia *ifm,
"0x%08x\n", newmedia);
}
#endif
return EINVAL;
IFMEDIA_IOCTL_UNLOCK(ifm);
error = EINVAL;
break;
}
/*
@ -298,8 +456,10 @@ ifmedia_ioctl_locked(struct ifnet *ifp, struct ifreq *ifr, struct ifmedia *ifm,
* Similarly, if best match changed (kernel debugger?).
*/
if ((IFM_SUBTYPE(newmedia) != IFM_AUTO) &&
(newmedia == ifm->ifm_media) && (match == ifm->ifm_cur))
return 0;
(newmedia == ifm->ifm_media) && (match == ifm->ifm_cur)) {
IFMEDIA_IOCTL_UNLOCK(ifm);
break;
}
/*
* We found a match, now make the driver switch to it.
@ -322,6 +482,7 @@ ifmedia_ioctl_locked(struct ifnet *ifp, struct ifreq *ifr, struct ifmedia *ifm,
ifm->ifm_cur = oldentry;
ifm->ifm_media = oldmedia;
}
IFMEDIA_IOCTL_UNLOCK(ifm);
break;
}
@ -330,9 +491,12 @@ ifmedia_ioctl_locked(struct ifnet *ifp, struct ifreq *ifr, struct ifmedia *ifm,
{
int nwords1, nwords2;
if (ifmr->ifm_count < 0)
return EINVAL;
if (ifmr->ifm_count < 0) {
error = EINVAL;
break;
}
IFMEDIA_IOCTL_LOCK(ifm);
ifmr->ifm_active = ifmr->ifm_current = ifm->ifm_cur ?
ifm->ifm_cur->ifm_media : IFM_NONE;
ifmr->ifm_mask = ifm->ifm_mask;
@ -340,17 +504,20 @@ ifmedia_ioctl_locked(struct ifnet *ifp, struct ifreq *ifr, struct ifmedia *ifm,
ifmedia_status(ifm, ifp, ifmr);
/*
* Count them so we know a-priori how much is the max we'll
* Count them so we know how much is the max we'll
* need.
*/
nwords1 = nwords2 = ifmedia_getwords(ifm, NULL, 0);
IFMEDIA_IOCTL_UNLOCK(ifm);
if (ifmr->ifm_count != 0) {
int maxwords = MIN(nwords1, ifmr->ifm_count);
int *kptr = kmem_zalloc(maxwords * sizeof(int),
KM_SLEEP);
ifmedia_lock(ifm);
nwords2 = ifmedia_getwords(ifm, kptr, maxwords);
ifmedia_unlock(ifm);
error = copyout(kptr, ifmr->ifm_ulist,
maxwords * sizeof(int));
if (error == 0 && nwords2 > nwords1)
@ -363,42 +530,20 @@ ifmedia_ioctl_locked(struct ifnet *ifp, struct ifreq *ifr, struct ifmedia *ifm,
}
default:
return EINVAL;
error = EINVAL;
break;
}
KERNEL_UNLOCK_UNLESS_IFP_MPSAFE(ifp);
return error;
}
int
ifmedia_ioctl(struct ifnet *ifp, struct ifreq *ifr, struct ifmedia *ifm,
u_long cmd)
{
int e;
/*
* If if_is_mpsafe(ifp), KERNEL_LOCK isn't held here and
* ipl will not have been raised (well, maybe it has, but
* it doesn't matter), but ifmedia_ioctl_locked isn't MP-safe
* yet, so we go to splnet and grab the KERNEL_LOCK.
*
* In the non-mpsafe case, the interface's ioctl routine
* will already be running at splnet() and so raising it
* again is redundant, but also harmless.
*/
int s = splnet();
KERNEL_LOCK_IF_IFP_MPSAFE(ifp);
e = ifmedia_ioctl_locked(ifp, ifr, ifm, cmd);
KERNEL_UNLOCK_IF_IFP_MPSAFE(ifp);
splx(s);
return e;
}
/*
* Find media entry matching a given ifm word.
*/
struct ifmedia_entry *
ifmedia_match(struct ifmedia *ifm, u_int target, u_int mask)
static struct ifmedia_entry *
ifmedia_match_locked(struct ifmedia *ifm, u_int target, u_int mask)
{
struct ifmedia_entry *match, *next;
@ -422,6 +567,22 @@ ifmedia_match(struct ifmedia *ifm, u_int target, u_int mask)
return match;
}
struct ifmedia_entry *
ifmedia_match(struct ifmedia *ifm, u_int target, u_int mask)
{
struct ifmedia_entry *match;
/*
* N.B. We expect the caller is responsible fot the lifecycle
* of the media entries. Use with extreme caution.
*/
ifmedia_lock(ifm);
match = ifmedia_match_locked(ifm, target, mask);
ifmedia_unlock(ifm);
return match;
}
/*
* Delete all media for a given instance.
*/
@ -429,7 +590,11 @@ void
ifmedia_delete_instance(struct ifmedia *ifm, u_int inst)
{
struct ifmedia_entry *ife, *nife;
TAILQ_HEAD(, ifmedia_entry) dead_entries;
TAILQ_INIT(&dead_entries);
ifmedia_lock(ifm);
TAILQ_FOREACH_SAFE(ife, &ifm->ifm_list, ifm_list, nife) {
if (inst == IFM_INST_ANY ||
inst == IFM_INST(ife->ifm_media)) {
@ -438,9 +603,15 @@ ifmedia_delete_instance(struct ifmedia *ifm, u_int inst)
ifm->ifm_media = IFM_NONE;
}
TAILQ_REMOVE(&ifm->ifm_list, ife, ifm_list);
kmem_free(ife, sizeof(*ife));
TAILQ_INSERT_TAIL(&dead_entries, ife, ifm_list);
}
}
ifmedia_unlock(ifm);
TAILQ_FOREACH_SAFE(ife, &dead_entries, ifm_list, nife) {
TAILQ_REMOVE(&dead_entries, ife, ifm_list);
kmem_free(ife, sizeof(*ife));
}
}
void
@ -450,7 +621,6 @@ ifmedia_removeall(struct ifmedia *ifm)
ifmedia_delete_instance(ifm, IFM_INST_ANY);
}
/*
* Compute the interface `baudrate' from the media, for the interface
* metrics (used by routing daemons).

View File

@ -1,7 +1,7 @@
/* $NetBSD: if_media.h,v 1.70 2020/02/17 15:51:25 msaitoh Exp $ */
/* $NetBSD: if_media.h,v 1.71 2020/03/15 23:04:51 thorpej Exp $ */
/*-
* Copyright (c) 1998, 2000, 2001 The NetBSD Foundation, Inc.
* Copyright (c) 1998, 2000, 2001, 2020 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -79,10 +79,6 @@
* to implement this interface.
*/
#ifdef _KERNEL
#include <sys/queue.h>
#endif /*_KERNEL */
/*
* Status bits. THIS IS NOT A MEDIA WORD.
*/
@ -893,6 +889,9 @@ struct ifmedia_status_description {
}
#ifdef _KERNEL
#include <sys/mutex.h>
#include <sys/queue.h>
/*
* Driver callbacks for media status and change requests.
*/
@ -912,30 +911,79 @@ struct ifmedia_entry {
/*
* One of these goes into a network interface's softc structure.
* It is used to keep general media state.
*
* LOCKING
* =======
* The ifmedia is protected by a lock provided by the interface
* driver. All ifmedia API entry points (with the exception of one)
* are expect to be called with this mutex NOT HELD.
*
* ifmedia_ioctl() is called with the interface's if_ioctl_lock held,
* and thus the locking order is:
*
* IFNET_LOCK -> ifm_lock
*
* Driver callbacks (ifm_change / ifm_status) are called with ifm_lock HELD.
*
* Field markings and the corresponding locks:
*
* m: ifm_lock
* :: unlocked, stable
*/
struct ifmedia {
u_int ifm_mask; /* IFMWD: mask of changes we don't care */
kmutex_t *ifm_lock; /* :: mutex (provided by interface driver) */
u_int ifm_mask; /* :: IFMWD: mask of changes we don't care */
u_int ifm_media; /*
* IFMWD: current use-set media word.
* m: IFMWD: current user-set media word.
*
* XXX some drivers misuse this entry as
* current active media word. Don't use this
* entry as this purpose but use driver
* specific entry if you don't use mii(4).
*/
struct ifmedia_entry *ifm_cur; /* current user-selected media entry */
TAILQ_HEAD(, ifmedia_entry) ifm_list; /* list of all supported media */
ifm_change_cb_t ifm_change; /* media change driver callback */
ifm_stat_cb_t ifm_status; /* media status driver callback */
struct ifmedia_entry *ifm_cur; /*
* m: entry corresponding to
* ifm_media
*/
TAILQ_HEAD(, ifmedia_entry) ifm_list; /*
* m: list of all supported
* media
*/
ifm_change_cb_t ifm_change; /* :: media change driver callback */
ifm_stat_cb_t ifm_status; /* :: media status driver callback */
uintptr_t ifm_legacy; /* m: legacy driver handling */
};
#define ifmedia_lock(ifm) mutex_enter((ifm)->ifm_lock)
#define ifmedia_unlock(ifm) mutex_exit((ifm)->ifm_lock)
#define ifmedia_locked(ifm) mutex_owned((ifm)->ifm_lock)
#ifdef __IFMEDIA_PRIVATE
#define ifmedia_islegacy(ifm) ((ifm)->ifm_legacy)
void ifmedia_lock_for_legacy(struct ifmedia *);
void ifmedia_unlock_for_legacy(struct ifmedia *);
#define IFMEDIA_LOCK_FOR_LEGACY(ifm) \
do { \
if (ifmedia_islegacy(ifm)) \
ifmedia_lock_for_legacy(ifm); \
} while (/*CONSTCOND*/0)
#define IFMEDIA_UNLOCK_FOR_LEGACY(ifm) \
do { \
if (ifmedia_islegacy(ifm)) \
ifmedia_unlock_for_legacy(ifm); \
} while (/*CONSTCOND*/0)
#endif /* __IFMEDIA_PRIVATE */
/* Initialize an interface's struct if_media field. */
void ifmedia_init(struct ifmedia *, int, ifm_change_cb_t, ifm_stat_cb_t);
void ifmedia_init_with_lock(struct ifmedia *, int, ifm_change_cb_t,
ifm_stat_cb_t, kmutex_t *);
/* Release resourecs associated with an ifmedia. */
void ifmedia_fini(struct ifmedia *);
int ifmedia_change(struct ifmedia *, struct ifnet *);
/* Add one supported medium to a struct ifmedia. */
void ifmedia_add(struct ifmedia *, int, int, void *);
@ -955,11 +1003,20 @@ struct ifmedia_entry *ifmedia_match(struct ifmedia *, u_int, u_int);
/* Delete all media for a given media instance */
void ifmedia_delete_instance(struct ifmedia *, u_int);
/* Remove all media */
void ifmedia_removeall(struct ifmedia *);
/* Compute baudrate for a given media. */
uint64_t ifmedia_baudrate(int);
/* Remove all media */
void ifmedia_removeall(struct ifmedia *);
/*
* This is a thin wrapper around the ifmedia "change" callback that
* is available to drivers to use within their own initialization
* routines.
*
* IFMEDIA must be LOCKED.
*/
int ifmedia_change(struct ifmedia *, struct ifnet *);
#else
/* Functions for converting media to/from strings, in libutil/if_media.c */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ieee80211.c,v 1.58 2020/02/04 05:46:32 thorpej Exp $ */
/* $NetBSD: ieee80211.c,v 1.59 2020/03/15 23:04:51 thorpej Exp $ */
/*-
* Copyright (c) 2001 Atsushi Onoe
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
@ -36,7 +36,7 @@
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211.c,v 1.22 2005/08/10 16:22:29 sam Exp $");
#endif
#ifdef __NetBSD__
__KERNEL_RCSID(0, "$NetBSD: ieee80211.c,v 1.58 2020/02/04 05:46:32 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: ieee80211.c,v 1.59 2020/03/15 23:04:51 thorpej Exp $");
#endif
/*
@ -346,8 +346,9 @@ ieee80211_ieee2mhz(u_int chan, u_int flags)
* ieee80211_attach and before most anything else.
*/
void
ieee80211_media_init(struct ieee80211com *ic,
ifm_change_cb_t media_change, ifm_stat_cb_t media_stat)
ieee80211_media_init_with_lock(struct ieee80211com *ic,
ifm_change_cb_t media_change, ifm_stat_cb_t media_stat,
ieee80211_media_lock_t *lock)
{
#define ADD(_ic, _s, _o) \
ifmedia_add(&(_ic)->ic_media, \
@ -371,7 +372,8 @@ ieee80211_media_init(struct ieee80211com *ic,
/*
* Fill in media characteristics.
*/
ifmedia_init(&ic->ic_media, 0, media_change, media_stat);
ifmedia_init_with_lock(&ic->ic_media, 0,
media_change, media_stat, lock);
maxrate = 0;
memset(&allrates, 0, sizeof(allrates));
for (mode = IEEE80211_MODE_AUTO; mode < IEEE80211_MODE_MAX; mode++) {
@ -454,6 +456,14 @@ ieee80211_media_init(struct ieee80211com *ic,
#undef ADD
}
void
ieee80211_media_init(struct ieee80211com *ic,
ifm_change_cb_t media_change, ifm_stat_cb_t media_stat)
{
ieee80211_media_init_with_lock(ic, media_change, media_stat, NULL);
}
void
ieee80211_announce(struct ieee80211com *ic)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: ieee80211_netbsd.h,v 1.22 2018/12/22 13:55:56 maxv Exp $ */
/* $NetBSD: ieee80211_netbsd.h,v 1.23 2020/03/15 23:04:51 thorpej Exp $ */
/*-
* Copyright (c) 2003-2005 Sam Leffler, Errno Consulting
* All rights reserved.
@ -153,6 +153,11 @@ typedef kmutex_t acl_lock_t;
#define ACL_UNLOCK(_as) IEEE80211_UNLOCK_IMPL(_as, as_lock)
#define ACL_LOCK_ASSERT(_as) IEEE80211_LOCK_ASSERT_IMPL(_as, as_lock)
/*
* Media locking definitions.
*/
typedef kmutex_t ieee80211_media_lock_t;
struct ifqueue;
void ieee80211_drain_ifq(struct ifqueue *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: ieee80211_var.h,v 1.33 2018/05/08 07:02:07 maxv Exp $ */
/* $NetBSD: ieee80211_var.h,v 1.34 2020/03/15 23:04:51 thorpej Exp $ */
/*-
* Copyright (c) 2001 Atsushi Onoe
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
@ -297,6 +297,8 @@ void ieee80211_ifdetach(struct ieee80211com *);
void ieee80211_announce(struct ieee80211com *);
void ieee80211_media_init(struct ieee80211com *,
ifm_change_cb_t, ifm_stat_cb_t);
void ieee80211_media_init_with_lock(struct ieee80211com *,
ifm_change_cb_t, ifm_stat_cb_t, ieee80211_media_lock_t *);
struct ieee80211com *ieee80211_find_vap(const u_int8_t mac[IEEE80211_ADDR_LEN]);
int ieee80211_media_change(struct ifnet *);
void ieee80211_media_status(struct ifnet *, struct ifmediareq *);