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.
This commit is contained in:
parent
0eedf7d0ea
commit
01ea11e489
@ -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);
|
||||
|
||||
|
@ -1209,6 +1209,7 @@ void
|
||||
rt2661_intr(void *arg)
|
||||
{
|
||||
struct rt2661_softc *sc = arg;
|
||||
struct ifnet *ifp = sc->sc_ifp;
|
||||
uint32_t r1, r2;
|
||||
|
||||
RAL_LOCK(sc);
|
||||
@ -1217,6 +1218,12 @@ rt2661_intr(void *arg)
|
||||
RAL_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffff7f);
|
||||
RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff);
|
||||
|
||||
/* don't re-enable interrupts if we're shutting down */
|
||||
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
|
||||
RAL_UNLOCK(sc);
|
||||
return;
|
||||
}
|
||||
|
||||
r1 = RAL_READ(sc, RT2661_INT_SOURCE_CSR);
|
||||
RAL_WRITE(sc, RT2661_INT_SOURCE_CSR, r1);
|
||||
|
||||
@ -1758,6 +1765,12 @@ rt2661_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) {
|
||||
@ -2469,6 +2482,8 @@ rt2661_init(void *priv)
|
||||
uint32_t tmp, sta[3];
|
||||
int i, ntries;
|
||||
|
||||
RAL_LOCK(sc);
|
||||
|
||||
rt2661_stop(sc);
|
||||
|
||||
/* initialize Tx rings */
|
||||
@ -2530,11 +2545,13 @@ rt2661_init(void *priv)
|
||||
if (ntries == 1000) {
|
||||
printf("timeout waiting for BBP/RF to wakeup\n");
|
||||
rt2661_stop(sc);
|
||||
RAL_UNLOCK(sc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rt2661_bbp_init(sc) != 0) {
|
||||
rt2661_stop(sc);
|
||||
RAL_UNLOCK(sc);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2583,6 +2600,9 @@ rt2661_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
|
||||
}
|
||||
|
||||
void
|
||||
@ -2611,9 +2631,13 @@ rt2661_stop(void *priv)
|
||||
RAL_WRITE(sc, RT2661_MAC_CSR1, 0);
|
||||
|
||||
/* disable interrupts */
|
||||
RAL_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffff7f);
|
||||
RAL_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffffff);
|
||||
RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff);
|
||||
|
||||
/* clear any pending interrupt */
|
||||
RAL_WRITE(sc, RT2661_INT_SOURCE_CSR, 0xffffffff);
|
||||
RAL_WRITE(sc, RT2661_MCU_INT_SOURCE_CSR, 0xffffffff);
|
||||
|
||||
/* reset Tx and Rx rings */
|
||||
rt2661_reset_tx_ring(sc, &sc->txq[0]);
|
||||
rt2661_reset_tx_ring(sc, &sc->txq[1]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user