diff options
author | damien <damien@FreeBSD.org> | 2006-03-21 21:15:43 +0000 |
---|---|---|
committer | damien <damien@FreeBSD.org> | 2006-03-21 21:15:43 +0000 |
commit | 01ea11e4890bb7b1baf1ee0486027a6d2e74d411 (patch) | |
tree | 36912797f23a688af2251f8ba715ef9e2abe7899 /sys/dev/ral/rt2560.c | |
parent | 0eedf7d0eafb75db3d07df0ba65ab2bea328b167 (diff) | |
download | FreeBSD-src-01ea11e4890bb7b1baf1ee0486027a6d2e74d411.zip FreeBSD-src-01ea11e4890bb7b1baf1ee0486027a6d2e74d411.tar.gz |
o fixes the locking of if_init().
o don't send management frames if the IFF_DRV_RUNNING flag is not set.
this prevents the timeout watchdog from being potentially re-armed
when the interface is brought down.
fixes a crash that occurs with RT2661 based adapters.
reported by Arnaud Lacombe.
Diffstat (limited to 'sys/dev/ral/rt2560.c')
-rw-r--r-- | sys/dev/ral/rt2560.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/sys/dev/ral/rt2560.c b/sys/dev/ral/rt2560.c index 9676406..b5f08db 100644 --- a/sys/dev/ral/rt2560.c +++ b/sys/dev/ral/rt2560.c @@ -1368,6 +1368,7 @@ void rt2560_intr(void *arg) { struct rt2560_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; uint32_t r; RAL_LOCK(sc); @@ -1375,6 +1376,12 @@ rt2560_intr(void *arg) /* disable interrupts */ RAL_WRITE(sc, RT2560_CSR8, 0xffffffff); + /* don't re-enable interrupts if we're shutting down */ + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + RAL_UNLOCK(sc); + return; + } + r = RAL_READ(sc, RT2560_CSR7); RAL_WRITE(sc, RT2560_CSR7, r); @@ -1937,6 +1944,12 @@ rt2560_start(struct ifnet *ifp) RAL_LOCK(sc); + /* prevent management frames from being sent if we're not ready */ + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + RAL_UNLOCK(sc); + return; + } + for (;;) { IF_POLL(&ic->ic_mgtq, m0); if (m0 != NULL) { @@ -2592,6 +2605,8 @@ rt2560_init(void *priv) uint32_t tmp; int i; + RAL_LOCK(sc); + rt2560_stop(sc); /* setup tx rings */ @@ -2634,6 +2649,7 @@ rt2560_init(void *priv) if (rt2560_bbp_init(sc) != 0) { rt2560_stop(sc); + RAL_UNLOCK(sc); return; } @@ -2669,6 +2685,8 @@ rt2560_init(void *priv) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); } else ieee80211_new_state(ic, IEEE80211_S_RUN, -1); + + RAL_UNLOCK(sc); #undef N } @@ -2679,12 +2697,12 @@ rt2560_stop(void *priv) struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = ic->ic_ifp; - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); - sc->sc_tx_timer = 0; ifp->if_timer = 0; ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + ieee80211_new_state(ic, IEEE80211_S_INIT, -1); + /* abort Tx */ RAL_WRITE(sc, RT2560_TXCSR0, RT2560_ABORT_TX); |