summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorSujith Manoharan <c_manoha@qca.qualcomm.com>2012-06-04 20:24:01 +0530
committerJohn W. Linville <linville@tuxdriver.com>2012-06-06 15:20:31 -0400
commitb74713d04effbacd3d126ce94cec18742187b6ce (patch)
treea6a12fc3a930bf384a88f9193991eee59d575c15 /drivers/net/wireless/ath
parent781b14a3153a722fec820374271316537881076e (diff)
downloadlinux-3.10-b74713d04effbacd3d126ce94cec18742187b6ce.tar.gz
linux-3.10-b74713d04effbacd3d126ce94cec18742187b6ce.tar.bz2
linux-3.10-b74713d04effbacd3d126ce94cec18742187b6ce.zip
ath9k: Handle fatal interrupts properly
When a fatal interrupt is received or it is detected that the baseband has hung, the chip has to be reset immediately. Otherwise, we end up processing spurious interrupts. Ensure that we bail out properly in the ISR when the reset work hasn't completed yet. Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c7
2 files changed, 7 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index ae43de1cbb0..02fc1c1e5ee 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -611,6 +611,7 @@ enum sc_op_flags {
SC_OP_TSF_RESET,
SC_OP_ANI_RUN,
SC_OP_PRIM_STA_VIF,
+ SC_OP_HW_RESET,
};
/* Powersave flags */
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index e4f7d0ea5f2..34d6f26c6bc 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -218,6 +218,8 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
ath9k_cmn_update_txpow(ah, sc->curtxpow,
sc->config.txpowlimit, &sc->curtxpow);
+
+ clear_bit(SC_OP_HW_RESET, &sc->sc_flags);
ath9k_hw_set_interrupts(ah);
ath9k_hw_enable_interrupts(ah);
@@ -362,6 +364,7 @@ void ath9k_tasklet(unsigned long data)
RESET_STAT_INC(sc, type);
#endif
+ set_bit(SC_OP_HW_RESET, &sc->sc_flags);
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
goto out;
}
@@ -438,12 +441,14 @@ irqreturn_t ath_isr(int irq, void *dev)
if (test_bit(SC_OP_INVALID, &sc->sc_flags))
return IRQ_NONE;
-
/* shared irq, not for us */
if (!ath9k_hw_intrpend(ah))
return IRQ_NONE;
+ if(test_bit(SC_OP_HW_RESET, &sc->sc_flags))
+ return IRQ_HANDLED;
+
/*
* Figure out the reason(s) for the interrupt. Note
* that the hal returns a pseudo-ISR that may include