Skip to content

Commit

Permalink
ath9k: Process GTT interrupts
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Sujith Manoharan authored and John W. Linville committed Jan 13, 2014
1 parent 9d89cad commit 071aa9a
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 4 deletions.
2 changes: 2 additions & 0 deletions drivers/net/wireless/ath/ath9k/ath9k.h
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,7 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs);
#define DEFAULT_CACHELINE 32
#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */
#define ATH_TXPOWER_MAX 100 /* .5 dBm units */
#define MAX_GTT_CNT 5

enum sc_op_flags {
SC_OP_INVALID,
Expand Down Expand Up @@ -733,6 +734,7 @@ struct ath_softc {
unsigned long sc_flags;
unsigned long driver_data;

u8 gtt_cnt;
u32 intrstatus;
u16 ps_flags; /* PS_* */
u16 curtxpow;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/ath9k/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ enum ath_reset_type {
RESET_TYPE_BB_WATCHDOG,
RESET_TYPE_FATAL_INT,
RESET_TYPE_TX_ERROR,
RESET_TYPE_TX_GTT,
RESET_TYPE_TX_HANG,
RESET_TYPE_PLL_HANG,
RESET_TYPE_MAC_HANG,
Expand Down
36 changes: 32 additions & 4 deletions drivers/net/wireless/ath/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
/*
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -608,7 +632,6 @@ irqreturn_t ath_isr(int irq, void *dev)
}
#endif


if (status & ATH9K_INT_SWBA)
tasklet_schedule(&sc->bcon_tasklet);

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 071aa9a

Please sign in to comment.