Implement miibus_statchg handler. It detects whether rl(4)
established a valid link or not. In rl_start_locked, don't try to send packets unless we have valid link. While I'm here add a check that verifies whether driver can accept Tx requests by inspecting IFF_DRV_OACTIVE/IFF_DRV_RUNNING flag.
This commit is contained in:
parent
9b85e175fd
commit
0960e62f83
@ -636,6 +636,34 @@ rl_miibus_writereg(device_t dev, int phy, int reg, int data)
|
||||
static void
|
||||
rl_miibus_statchg(device_t dev)
|
||||
{
|
||||
struct rl_softc *sc;
|
||||
struct ifnet *ifp;
|
||||
struct mii_data *mii;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
mii = device_get_softc(sc->rl_miibus);
|
||||
ifp = sc->rl_ifp;
|
||||
if (mii == NULL || ifp == NULL ||
|
||||
(ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
||||
return;
|
||||
|
||||
sc->rl_flags &= ~RL_FLAG_LINK;
|
||||
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->rl_flags |= RL_FLAG_LINK;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* RealTek controllers do not provide any interface to
|
||||
* Tx/Rx MACs for resolved speed, duplex and flow-control
|
||||
* parameters.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1545,6 +1573,10 @@ rl_start_locked(struct ifnet *ifp)
|
||||
|
||||
RL_LOCK_ASSERT(sc);
|
||||
|
||||
if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
|
||||
IFF_DRV_RUNNING || (sc->rl_flags & RL_FLAG_LINK) == 0)
|
||||
return;
|
||||
|
||||
while (RL_CUR_TXMBUF(sc) == NULL) {
|
||||
|
||||
IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
|
||||
@ -1686,6 +1718,7 @@ rl_init_locked(struct rl_softc *sc)
|
||||
/* Enable receiver and transmitter. */
|
||||
CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB);
|
||||
|
||||
sc->rl_flags &= ~RL_FLAG_LINK;
|
||||
mii_mediachg(mii);
|
||||
|
||||
CSR_WRITE_1(sc, RL_CFG1, RL_CFG1_DRVLOAD|RL_CFG1_FULLDUPLEX);
|
||||
@ -1831,6 +1864,7 @@ rl_stop(struct rl_softc *sc)
|
||||
sc->rl_watchdog_timer = 0;
|
||||
callout_stop(&sc->rl_stat_callout);
|
||||
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
|
||||
sc->rl_flags &= ~RL_FLAG_LINK;
|
||||
|
||||
CSR_WRITE_1(sc, RL_COMMAND, 0x00);
|
||||
CSR_WRITE_2(sc, RL_IMR, 0x0000);
|
||||
|
Loading…
Reference in New Issue
Block a user