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:
parent
e1ecc07c09
commit
7a9a30c5e7
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 |= 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. */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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, ®);
|
||||
|
@ -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 */
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 *);
|
||||
|
||||
|
|
|
@ -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 *);
|
||||
|
|
Loading…
Reference in New Issue