summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath9k/main.c
diff options
context:
space:
mode:
authorSujith Manoharan <c_manoha@qca.qualcomm.com>2014-01-13 13:55:11 +0530
committerJohn W. Linville <linville@tuxdriver.com>2014-01-13 14:50:05 -0500
commit071aa9a8b2e724679ac2cf14f31b781a3783c377 (patch)
treef5d4c736442430eabab669795fddc1b5c35bf27a /drivers/net/wireless/ath/ath9k/main.c
parent9d89cadd39f78eb4dd70d522dc3fd17b3c41de58 (diff)
downloadlwn-071aa9a8b2e724679ac2cf14f31b781a3783c377.tar.gz
lwn-071aa9a8b2e724679ac2cf14f31b781a3783c377.zip
ath9k: Process GTT interrupts
Global Transmission Timeout interrupts are generated by the HW when transmission of a frame fails - this is done based on the threshold programmed in the AR_GTXTO register. Currently, even though the interrupt is enabled for all chips, it is not handled in the driver. This patch handles GTT events for AR9003 and above chips, checking if the MAC/BB has hung after successive GTT interrupts crosses a threshold (5). This can be enabled for the older chips in the AR9002 family once appropriate HW hang checks are implemented for them. 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/ath9k/main.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index ca8aff1aec94..73a36551a5ed 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -258,6 +258,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
}
}
+ sc->gtt_cnt = 0;
ieee80211_wake_queues(sc->hw);
return true;
@@ -476,6 +477,19 @@ void ath9k_tasklet(unsigned long data)
}
}
+ if (status & ATH9K_INT_GTT) {
+ sc->gtt_cnt++;
+
+ if ((sc->gtt_cnt >= MAX_GTT_CNT) && !ath9k_hw_check_alive(ah)) {
+ type = RESET_TYPE_TX_GTT;
+ ath9k_queue_reset(sc, type);
+ atomic_inc(&ah->intr_ref_cnt);
+ ath_dbg(common, ANY,
+ "GTT: Skipping interrupts\n");
+ goto out;
+ }
+ }
+
spin_lock_irqsave(&sc->sc_pm_lock, flags);
if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
/*
@@ -503,10 +517,19 @@ void ath9k_tasklet(unsigned long data)
}
if (status & ATH9K_INT_TX) {
- if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+ /*
+ * For EDMA chips, TX completion is enabled for the
+ * beacon queue, so if a beacon has been transmitted
+ * successfully after a GTT interrupt, the GTT counter
+ * gets reset to zero here.
+ */
+ /* sc->gtt_cnt = 0; */
+
ath_tx_edma_tasklet(sc);
- else
+ } else {
ath_tx_tasklet(sc);
+ }
wake_up(&sc->tx_wait);
}
@@ -536,6 +559,7 @@ irqreturn_t ath_isr(int irq, void *dev)
ATH9K_INT_TX | \
ATH9K_INT_BMISS | \
ATH9K_INT_CST | \
+ ATH9K_INT_GTT | \
ATH9K_INT_TSFOOR | \
ATH9K_INT_GENTIMER | \
ATH9K_INT_MCI)
@@ -608,7 +632,6 @@ irqreturn_t ath_isr(int irq, void *dev)
}
#endif
-
if (status & ATH9K_INT_SWBA)
tasklet_schedule(&sc->bcon_tasklet);
@@ -733,7 +756,12 @@ static int ath9k_start(struct ieee80211_hw *hw)
if (ah->config.hw_hang_checks & HW_BB_WATCHDOG)
ah->imask |= ATH9K_INT_BB_WATCHDOG;
- ah->imask |= ATH9K_INT_GTT;
+ /*
+ * Enable GTT interrupts only for AR9003/AR9004 chips
+ * for now.
+ */
+ if (AR_SREV_9300_20_OR_LATER(ah))
+ ah->imask |= ATH9K_INT_GTT;
if (ah->caps.hw_caps & ATH9K_HW_CAP_HT)
ah->imask |= ATH9K_INT_CST;