mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-19 10:53:58 +00:00
Remove link state change callback handler. There is no need to
register both status change and link state change callbacks. Implement checking valid link in state change callback and poll active link state in vr_tick(). This allows immediate detection of lost link as well as protecting driver from frequent link flips during link renegotiation. taskq implementation was removed because driver now needs to poll link state in vr_tick(). While I'm here do not report current link state if interface is not running. Tested by: n_hibma MFC after: 1 week
This commit is contained in:
parent
32638a3a01
commit
161bc8e475
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=223405
@ -185,7 +185,6 @@ static int vr_miibus_readreg(device_t, int, int);
|
||||
static int vr_miibus_writereg(device_t, int, int, int);
|
||||
static void vr_miibus_statchg(device_t);
|
||||
|
||||
static void vr_link_task(void *, int);
|
||||
static void vr_cam_mask(struct vr_softc *, uint32_t, int);
|
||||
static int vr_cam_data(struct vr_softc *, int, int, uint8_t *);
|
||||
static void vr_set_filter(struct vr_softc *);
|
||||
@ -226,7 +225,6 @@ static device_method_t vr_methods[] = {
|
||||
DEVMETHOD(miibus_readreg, vr_miibus_readreg),
|
||||
DEVMETHOD(miibus_writereg, vr_miibus_writereg),
|
||||
DEVMETHOD(miibus_statchg, vr_miibus_statchg),
|
||||
DEVMETHOD(miibus_linkchg, vr_miibus_statchg),
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
@ -290,22 +288,13 @@ vr_miibus_writereg(device_t dev, int phy, int reg, int data)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
vr_miibus_statchg(device_t dev)
|
||||
{
|
||||
struct vr_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
taskqueue_enqueue(taskqueue_swi, &sc->vr_link_task);
|
||||
}
|
||||
|
||||
/*
|
||||
* In order to fiddle with the
|
||||
* 'full-duplex' and '100Mbps' bits in the netconfig register, we
|
||||
* first have to put the transmit and/or receive logic in the idle state.
|
||||
*/
|
||||
static void
|
||||
vr_link_task(void *arg, int pending)
|
||||
vr_miibus_statchg(device_t dev)
|
||||
{
|
||||
struct vr_softc *sc;
|
||||
struct mii_data *mii;
|
||||
@ -313,22 +302,25 @@ vr_link_task(void *arg, int pending)
|
||||
int lfdx, mfdx;
|
||||
uint8_t cr0, cr1, fc;
|
||||
|
||||
sc = (struct vr_softc *)arg;
|
||||
|
||||
VR_LOCK(sc);
|
||||
sc = device_get_softc(dev);
|
||||
mii = device_get_softc(sc->vr_miibus);
|
||||
ifp = sc->vr_ifp;
|
||||
if (mii == NULL || ifp == NULL ||
|
||||
(ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
|
||||
VR_UNLOCK(sc);
|
||||
(ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (mii->mii_media_status & IFM_ACTIVE) {
|
||||
if (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)
|
||||
sc->vr_link = 0;
|
||||
if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
|
||||
(IFM_ACTIVE | IFM_AVALID)) {
|
||||
switch (IFM_SUBTYPE(mii->mii_media_active)) {
|
||||
case IFM_10_T:
|
||||
case IFM_100_TX:
|
||||
sc->vr_link = 1;
|
||||
} else
|
||||
sc->vr_link = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->vr_link != 0) {
|
||||
cr0 = CSR_READ_1(sc, VR_CR0);
|
||||
@ -384,11 +376,8 @@ vr_link_task(void *arg, int pending)
|
||||
"%s: Tx/Rx shutdown error -- resetting\n",
|
||||
__func__);
|
||||
sc->vr_flags |= VR_F_RESTART;
|
||||
VR_UNLOCK(sc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
VR_UNLOCK(sc);
|
||||
}
|
||||
|
||||
|
||||
@ -621,7 +610,6 @@ vr_attach(device_t dev)
|
||||
mtx_init(&sc->vr_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
MTX_DEF);
|
||||
callout_init_mtx(&sc->vr_stat_callout, &sc->vr_mtx, 0);
|
||||
TASK_INIT(&sc->vr_link_task, 0, vr_link_task, sc);
|
||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
|
||||
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
|
||||
OID_AUTO, "stats", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
|
||||
@ -841,7 +829,6 @@ vr_detach(device_t dev)
|
||||
vr_stop(sc);
|
||||
VR_UNLOCK(sc);
|
||||
callout_drain(&sc->vr_stat_callout);
|
||||
taskqueue_drain(taskqueue_swi, &sc->vr_link_task);
|
||||
ether_ifdetach(ifp);
|
||||
}
|
||||
if (sc->vr_miibus)
|
||||
@ -1559,6 +1546,8 @@ vr_tick(void *xsc)
|
||||
|
||||
mii = device_get_softc(sc->vr_miibus);
|
||||
mii_tick(mii);
|
||||
if (sc->vr_link == 0)
|
||||
vr_miibus_statchg(sc->vr_dev);
|
||||
vr_watchdog(sc);
|
||||
callout_reset(&sc->vr_stat_callout, hz, vr_tick, sc);
|
||||
}
|
||||
@ -2161,6 +2150,10 @@ vr_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
|
||||
sc = ifp->if_softc;
|
||||
mii = device_get_softc(sc->vr_miibus);
|
||||
VR_LOCK(sc);
|
||||
if ((ifp->if_flags & IFF_UP) == 0) {
|
||||
VR_UNLOCK(sc);
|
||||
return;
|
||||
}
|
||||
mii_pollstat(mii);
|
||||
VR_UNLOCK(sc);
|
||||
ifmr->ifm_active = mii->mii_media_active;
|
||||
|
@ -723,7 +723,6 @@ struct vr_softc {
|
||||
uint8_t vr_flags; /* See VR_F_* below */
|
||||
#define VR_F_RESTART 0x01 /* Restart unit on next tick */
|
||||
int vr_if_flags;
|
||||
struct task vr_link_task;
|
||||
struct vr_chain_data vr_cdata;
|
||||
struct vr_ring_data vr_rdata;
|
||||
struct vr_statistics vr_stat;
|
||||
|
Loading…
Reference in New Issue
Block a user