2011-09-15 20:55:16 +03:00
|
|
|
--- a/drivers/net/wireless/ath/ath9k/debug.h
|
|
|
|
+++ b/drivers/net/wireless/ath/ath9k/debug.h
|
|
|
|
@@ -25,8 +25,10 @@ struct ath_buf;
|
|
|
|
|
|
|
|
#ifdef CONFIG_ATH9K_DEBUGFS
|
|
|
|
#define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++
|
|
|
|
+#define RESET_STAT_INC(sc, type) sc->debug.stats.reset[type]++
|
|
|
|
#else
|
|
|
|
#define TX_STAT_INC(q, c) do { } while (0)
|
|
|
|
+#define RESET_STAT_INC(sc, type) do { } while (0)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_ATH9K_DEBUGFS
|
|
|
|
@@ -171,10 +173,21 @@ struct ath_rx_stats {
|
|
|
|
u8 rs_antenna;
|
|
|
|
};
|
|
|
|
|
|
|
|
+enum ath_reset_type {
|
|
|
|
+ RESET_TYPE_BB_HANG,
|
|
|
|
+ RESET_TYPE_BB_WATCHDOG,
|
|
|
|
+ RESET_TYPE_FATAL_INT,
|
|
|
|
+ RESET_TYPE_TX_ERROR,
|
|
|
|
+ RESET_TYPE_TX_HANG,
|
|
|
|
+ RESET_TYPE_PLL_HANG,
|
|
|
|
+ __RESET_TYPE_MAX
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
struct ath_stats {
|
|
|
|
struct ath_interrupt_stats istats;
|
|
|
|
struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
|
|
|
|
struct ath_rx_stats rxstats;
|
|
|
|
+ u32 reset[__RESET_TYPE_MAX];
|
|
|
|
};
|
|
|
|
|
|
|
|
#define ATH_DBG_MAX_SAMPLES 10
|
|
|
|
--- a/drivers/net/wireless/ath/ath9k/main.c
|
|
|
|
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
2011-09-17 10:03:20 +03:00
|
|
|
@@ -679,6 +679,16 @@ void ath9k_tasklet(unsigned long data)
|
2011-09-15 20:55:16 +03:00
|
|
|
|
|
|
|
if ((status & ATH9K_INT_FATAL) ||
|
|
|
|
(status & ATH9K_INT_BB_WATCHDOG)) {
|
2011-09-17 10:03:20 +03:00
|
|
|
+#ifdef CONFIG_ATH9K_DEBUGFS
|
2011-09-15 20:55:16 +03:00
|
|
|
+ enum ath_reset_type type;
|
|
|
|
+
|
|
|
|
+ if (status & ATH9K_INT_FATAL)
|
|
|
|
+ type = RESET_TYPE_FATAL_INT;
|
|
|
|
+ else
|
|
|
|
+ type = RESET_TYPE_BB_WATCHDOG;
|
|
|
|
+
|
|
|
|
+ RESET_STAT_INC(sc, type);
|
2011-09-17 10:03:20 +03:00
|
|
|
+#endif
|
2011-09-15 20:55:16 +03:00
|
|
|
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
|
|
|
|
goto out;
|
|
|
|
}
|
2011-09-17 10:03:20 +03:00
|
|
|
@@ -995,8 +1005,10 @@ void ath_hw_check(struct work_struct *wo
|
2011-09-15 20:55:16 +03:00
|
|
|
ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, "
|
|
|
|
"busy=%d (try %d)\n", busy, sc->hw_busy_count + 1);
|
|
|
|
if (busy >= 99) {
|
|
|
|
- if (++sc->hw_busy_count >= 3)
|
|
|
|
+ if (++sc->hw_busy_count >= 3) {
|
|
|
|
+ RESET_STAT_INC(sc, RESET_TYPE_BB_HANG);
|
|
|
|
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
|
|
|
|
+ }
|
|
|
|
|
|
|
|
} else if (busy >= 0)
|
|
|
|
sc->hw_busy_count = 0;
|
2011-09-17 10:03:20 +03:00
|
|
|
@@ -1016,6 +1028,7 @@ static void ath_hw_pll_rx_hang_check(str
|
2011-09-15 20:55:16 +03:00
|
|
|
/* Rx is hung for more than 500ms. Reset it */
|
|
|
|
ath_dbg(common, ATH_DBG_RESET,
|
|
|
|
"Possible RX hang, resetting");
|
|
|
|
+ RESET_STAT_INC(sc, RESET_TYPE_PLL_HANG);
|
|
|
|
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
|
|
|
|
count = 0;
|
|
|
|
}
|
|
|
|
--- a/drivers/net/wireless/ath/ath9k/xmit.c
|
|
|
|
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
|
|
|
|
@@ -587,8 +587,10 @@ static void ath_tx_complete_aggr(struct
|
|
|
|
|
|
|
|
rcu_read_unlock();
|
|
|
|
|
|
|
|
- if (needreset)
|
|
|
|
+ if (needreset) {
|
|
|
|
+ RESET_STAT_INC(sc, RESET_TYPE_TX_ERROR);
|
|
|
|
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
|
|
|
|
+ }
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool ath_lookup_legacy(struct ath_buf *bf)
|
|
|
|
@@ -2270,6 +2272,7 @@ static void ath_tx_complete_poll_work(st
|
|
|
|
if (needreset) {
|
|
|
|
ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
|
|
|
|
"tx hung, resetting the chip\n");
|
|
|
|
+ RESET_STAT_INC(sc, RESET_TYPE_TX_HANG);
|
|
|
|
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
|
|
|
|
}
|
|
|
|
|
|
|
|
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
|
|
|
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
|
|
|
@@ -523,9 +523,22 @@ static ssize_t read_file_wiphy(struct fi
|
|
|
|
if (tmp & ATH9K_RX_FILTER_PHYRADAR)
|
|
|
|
len += snprintf(buf + len, sizeof(buf) - len, " PHYRADAR");
|
|
|
|
if (tmp & ATH9K_RX_FILTER_MCAST_BCAST_ALL)
|
|
|
|
- len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL\n");
|
|
|
|
- else
|
|
|
|
- len += snprintf(buf + len, sizeof(buf) - len, "\n");
|
|
|
|
+ len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL");
|
|
|
|
+
|
|
|
|
+ len += snprintf(buf + len, sizeof(buf) - len,
|
|
|
|
+ "\n\nReset causes:\n"
|
|
|
|
+ " baseband hang: %d\n"
|
|
|
|
+ " baseband watchdog: %d\n"
|
|
|
|
+ " fatal hardware error interrupt: %d\n"
|
|
|
|
+ " tx hardware error: %d\n"
|
|
|
|
+ " tx path hang: %d\n"
|
|
|
|
+ " pll rx hang: %d\n",
|
|
|
|
+ sc->debug.stats.reset[RESET_TYPE_BB_HANG],
|
|
|
|
+ sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG],
|
|
|
|
+ sc->debug.stats.reset[RESET_TYPE_FATAL_INT],
|
|
|
|
+ sc->debug.stats.reset[RESET_TYPE_TX_ERROR],
|
|
|
|
+ sc->debug.stats.reset[RESET_TYPE_TX_HANG],
|
|
|
|
+ sc->debug.stats.reset[RESET_TYPE_PLL_HANG]);
|
|
|
|
|
|
|
|
if (len > sizeof(buf))
|
|
|
|
len = sizeof(buf);
|