ath9k: enable the baseband watchdog events for AR9003
authorLuis R. Rodriguez <lrodriguez@atheros.com>
Thu, 13 May 2010 17:33:44 +0000 (13:33 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 2 Jun 2010 20:13:00 +0000 (16:13 -0400)
This enables the baseband watchdog events for the AR9003
family on ath9k. Upon an a baseband watchdog interrupt we reset
the hardware, this should address corner case conditions where
normal operation can stall. Enable ATH_DBG_RESET to be able
to review details of the bb watchdog interrupt once it happens.
If you're curious how often this happens just grep the debugfs
interrupt file.

Cc: Sam Ng <sam.ng@atheros.com>
Cc: Paul Shaw <paul.shaw@atheros.com>
Cc: Don Breslin <don.breslin@atheros.com>
Cc: Cliff Holden <cliff.holden@atheros.com
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/debug.h
drivers/net/wireless/ath/ath9k/main.c

index 29898f8d1893606627abdeb601966dc213cc61b8..ee8387740ebe1a2571b71f66f652dc4bc330ac88 100644 (file)
@@ -269,6 +269,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
                        sc->debug.stats.istats.rxlp++;
                if (status & ATH9K_INT_RXHP)
                        sc->debug.stats.istats.rxhp++;
+               if (status & ATH9K_INT_BB_WATCHDOG)
+                       sc->debug.stats.istats.bb_watchdog++;
        } else {
                if (status & ATH9K_INT_RX)
                        sc->debug.stats.istats.rxok++;
@@ -319,6 +321,9 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
                        "%8s: %10u\n", "RXLP", sc->debug.stats.istats.rxlp);
                len += snprintf(buf + len, sizeof(buf) - len,
                        "%8s: %10u\n", "RXHP", sc->debug.stats.istats.rxhp);
+               len += snprintf(buf + len, sizeof(buf) - len,
+                       "%8s: %10u\n", "WATCHDOG",
+                       sc->debug.stats.istats.bb_watchdog);
        } else {
                len += snprintf(buf + len, sizeof(buf) - len,
                        "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
index 5147b8709e103bf0811390b9c0989f8485b9c361..5d21704e87fff40c078382e1010f4b1fc529efcf 100644 (file)
@@ -53,6 +53,7 @@ struct ath_buf;
  * @cabend: RX End of CAB traffic
  * @dtimsync: DTIM sync lossage
  * @dtim: RX Beacon with DTIM
+ * @bb_watchdog: Baseband watchdog
  */
 struct ath_interrupt_stats {
        u32 total;
@@ -76,6 +77,7 @@ struct ath_interrupt_stats {
        u32 cabend;
        u32 dtimsync;
        u32 dtim;
+       u32 bb_watchdog;
 };
 
 struct ath_rc_stats {
index abfa0493236f5a8c5f785d0126a26c9c0cba45bc..b98b2f2ed07df89c0fa9a6a0628975c114407734 100644 (file)
@@ -520,6 +520,12 @@ irqreturn_t ath_isr(int irq, void *dev)
            !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)))
                goto chip_reset;
 
+       if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
+           (status & ATH9K_INT_BB_WATCHDOG)) {
+               ar9003_hw_bb_watchdog_dbg_info(ah);
+               goto chip_reset;
+       }
+
        if (status & ATH9K_INT_SWBA)
                tasklet_schedule(&sc->bcon_tasklet);
 
@@ -1195,7 +1201,9 @@ static int ath9k_start(struct ieee80211_hw *hw)
                    ATH9K_INT_GLOBAL;
 
        if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
-               ah->imask |= ATH9K_INT_RXHP | ATH9K_INT_RXLP;
+               ah->imask |= ATH9K_INT_RXHP |
+                            ATH9K_INT_RXLP |
+                            ATH9K_INT_BB_WATCHDOG;
        else
                ah->imask |= ATH9K_INT_RX;