Honor link up/down state in stge_start().

While I'm here move MAC control settings to stge_link_task, a task
queue which handles link state and duplex/flow controls.
This commit is contained in:
Pyun YongHyeon 2007-05-01 03:35:48 +00:00
parent eb7a67da1a
commit 7ef4ec5d34
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=169158
2 changed files with 20 additions and 24 deletions

View File

@ -479,32 +479,9 @@ static void
stge_miibus_statchg(device_t dev)
{
struct stge_softc *sc;
struct mii_data *mii;
sc = device_get_softc(dev);
mii = device_get_softc(sc->sc_miibus);
STGE_MII_LOCK(sc);
if (IFM_SUBTYPE(mii->mii_media_active) == IFM_NONE) {
STGE_MII_UNLOCK(sc);
return;
}
sc->sc_MACCtrl = 0;
if (((mii->mii_media_active & IFM_GMASK) & IFM_FDX) != 0)
sc->sc_MACCtrl |= MC_DuplexSelect;
if (((mii->mii_media_active & IFM_GMASK) & IFM_FLAG0) != 0)
sc->sc_MACCtrl |= MC_RxFlowControlEnable;
if (((mii->mii_media_active & IFM_GMASK) & IFM_FLAG1) != 0)
sc->sc_MACCtrl |= MC_TxFlowControlEnable;
/*
* We can't access STGE_MACCtrl register in this context due to
* the races between MII layer and driver which accesses this
* register to program MAC. In order to solve the race, we defer
* STGE_MACCtrl programming until we know we are out of MII.
*/
taskqueue_enqueue(taskqueue_swi, &sc->sc_link_task);
STGE_MII_UNLOCK(sc);
}
/*
@ -1317,7 +1294,7 @@ stge_start_locked(struct ifnet *ifp)
STGE_LOCK_ASSERT(sc);
if ((ifp->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) !=
IFF_DRV_RUNNING)
IFF_DRV_RUNNING || sc->sc_link == 0)
return;
for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd); ) {
@ -1491,11 +1468,27 @@ static void
stge_link_task(void *arg, int pending)
{
struct stge_softc *sc;
struct mii_data *mii;
uint32_t v, ac;
int i;
sc = (struct stge_softc *)arg;
STGE_LOCK(sc);
mii = device_get_softc(sc->sc_miibus);
if (mii->mii_media_status & IFM_ACTIVE) {
if (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)
sc->sc_link = 1;
} else
sc->sc_link = 0;
sc->sc_MACCtrl = 0;
if (((mii->mii_media_active & IFM_GMASK) & IFM_FDX) != 0)
sc->sc_MACCtrl |= MC_DuplexSelect;
if (((mii->mii_media_active & IFM_GMASK) & IFM_FLAG0) != 0)
sc->sc_MACCtrl |= MC_RxFlowControlEnable;
if (((mii->mii_media_active & IFM_GMASK) & IFM_FLAG1) != 0)
sc->sc_MACCtrl |= MC_TxFlowControlEnable;
/*
* Update STGE_MACCtrl register depending on link status.
* (duplex, flow control etc)
@ -2247,6 +2240,7 @@ stge_init_locked(struct stge_softc *sc)
stge_start_tx(sc);
stge_start_rx(sc);
sc->sc_link = 0;
/*
* Set the current media.
*/
@ -2369,6 +2363,7 @@ stge_stop(struct stge_softc *sc)
*/
ifp = sc->sc_ifp;
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
sc->sc_link = 0;
}
static void

View File

@ -652,6 +652,7 @@ struct stge_softc {
int sc_rxint_dmawait;
int sc_nerr;
int sc_watchdog_timer;
int sc_link;
struct task sc_link_task;
struct mtx sc_mii_mtx; /* MII mutex */