aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBen Greear <greearb@candelatech.com>2012-04-12 13:04:00 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-04-16 14:16:58 -0400
commit462e58f2b6f2f3ca113b44794f2c35ee8e792b93 (patch)
treef4c4bfb31bb82ff192caeb870b46ff10e8decc11 /drivers
parent24a0731e70fb007c989ae81dd72bc4fe99e27818 (diff)
ath9k: Gather and report IRQ sync_cause errors.
Report all defined sync_cause errors in debugfs to aid with debugging. Use a macro to print out the interrupts file contents to decrease code duplication. Signed-off-by: Ben Greear <greearb@candelatech.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c116
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h23
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c49
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h6
6 files changed, 145 insertions, 52 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index aa2abaf31cba..8d78253c26ce 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -136,6 +136,7 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
136 } 136 }
137 137
138 if (sync_cause) { 138 if (sync_cause) {
139 ath9k_debug_sync_cause(common, sync_cause);
139 fatal_int = 140 fatal_int =
140 (sync_cause & 141 (sync_cause &
141 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR)) 142 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index a66a13b76848..d9e0824af093 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -306,6 +306,8 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
306 ar9003_mci_get_isr(ah, masked); 306 ar9003_mci_get_isr(ah, masked);
307 307
308 if (sync_cause) { 308 if (sync_cause) {
309 ath9k_debug_sync_cause(common, sync_cause);
310
309 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { 311 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
310 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); 312 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
311 REG_WRITE(ah, AR_RC, 0); 313 REG_WRITE(ah, AR_RC, 0);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 78f2962f9bee..fde700c4e490 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -380,63 +380,75 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
380 size_t count, loff_t *ppos) 380 size_t count, loff_t *ppos)
381{ 381{
382 struct ath_softc *sc = file->private_data; 382 struct ath_softc *sc = file->private_data;
383 char buf[512];
384 unsigned int len = 0; 383 unsigned int len = 0;
384 int rv;
385 int mxlen = 4000;
386 char *buf = kmalloc(mxlen, GFP_KERNEL);
387 if (!buf)
388 return -ENOMEM;
389
390#define PR_IS(a, s) \
391 do { \
392 len += snprintf(buf + len, mxlen - len, \
393 "%21s: %10u\n", a, \
394 sc->debug.stats.istats.s); \
395 } while (0)
385 396
386 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { 397 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
387 len += snprintf(buf + len, sizeof(buf) - len, 398 PR_IS("RXLP", rxlp);
388 "%8s: %10u\n", "RXLP", sc->debug.stats.istats.rxlp); 399 PR_IS("RXHP", rxhp);
389 len += snprintf(buf + len, sizeof(buf) - len, 400 PR_IS("WATHDOG", bb_watchdog);
390 "%8s: %10u\n", "RXHP", sc->debug.stats.istats.rxhp);
391 len += snprintf(buf + len, sizeof(buf) - len,
392 "%8s: %10u\n", "WATCHDOG",
393 sc->debug.stats.istats.bb_watchdog);
394 } else { 401 } else {
395 len += snprintf(buf + len, sizeof(buf) - len, 402 PR_IS("RX", rxok);
396 "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
397 } 403 }
398 len += snprintf(buf + len, sizeof(buf) - len, 404 PR_IS("RXEOL", rxeol);
399 "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol); 405 PR_IS("RXORN", rxorn);
400 len += snprintf(buf + len, sizeof(buf) - len, 406 PR_IS("TX", txok);
401 "%8s: %10u\n", "RXORN", sc->debug.stats.istats.rxorn); 407 PR_IS("TXURN", txurn);
402 len += snprintf(buf + len, sizeof(buf) - len, 408 PR_IS("MIB", mib);
403 "%8s: %10u\n", "TX", sc->debug.stats.istats.txok); 409 PR_IS("RXPHY", rxphyerr);
404 len += snprintf(buf + len, sizeof(buf) - len, 410 PR_IS("RXKCM", rx_keycache_miss);
405 "%8s: %10u\n", "TXURN", sc->debug.stats.istats.txurn); 411 PR_IS("SWBA", swba);
406 len += snprintf(buf + len, sizeof(buf) - len, 412 PR_IS("BMISS", bmiss);
407 "%8s: %10u\n", "MIB", sc->debug.stats.istats.mib); 413 PR_IS("BNR", bnr);
408 len += snprintf(buf + len, sizeof(buf) - len, 414 PR_IS("CST", cst);
409 "%8s: %10u\n", "RXPHY", sc->debug.stats.istats.rxphyerr); 415 PR_IS("GTT", gtt);
410 len += snprintf(buf + len, sizeof(buf) - len, 416 PR_IS("TIM", tim);
411 "%8s: %10u\n", "RXKCM", sc->debug.stats.istats.rx_keycache_miss); 417 PR_IS("CABEND", cabend);
412 len += snprintf(buf + len, sizeof(buf) - len, 418 PR_IS("DTIMSYNC", dtimsync);
413 "%8s: %10u\n", "SWBA", sc->debug.stats.istats.swba); 419 PR_IS("DTIM", dtim);
414 len += snprintf(buf + len, sizeof(buf) - len, 420 PR_IS("TSFOOR", tsfoor);
415 "%8s: %10u\n", "BMISS", sc->debug.stats.istats.bmiss); 421 PR_IS("TOTAL", total);
416 len += snprintf(buf + len, sizeof(buf) - len, 422
417 "%8s: %10u\n", "BNR", sc->debug.stats.istats.bnr); 423 len += snprintf(buf + len, mxlen - len,
418 len += snprintf(buf + len, sizeof(buf) - len, 424 "SYNC_CAUSE stats:\n");
419 "%8s: %10u\n", "CST", sc->debug.stats.istats.cst); 425
420 len += snprintf(buf + len, sizeof(buf) - len, 426 PR_IS("Sync-All", sync_cause_all);
421 "%8s: %10u\n", "GTT", sc->debug.stats.istats.gtt); 427 PR_IS("RTC-IRQ", sync_rtc_irq);
422 len += snprintf(buf + len, sizeof(buf) - len, 428 PR_IS("MAC-IRQ", sync_mac_irq);
423 "%8s: %10u\n", "TIM", sc->debug.stats.istats.tim); 429 PR_IS("EEPROM-Illegal-Access", eeprom_illegal_access);
424 len += snprintf(buf + len, sizeof(buf) - len, 430 PR_IS("APB-Timeout", apb_timeout);
425 "%8s: %10u\n", "CABEND", sc->debug.stats.istats.cabend); 431 PR_IS("PCI-Mode-Conflict", pci_mode_conflict);
426 len += snprintf(buf + len, sizeof(buf) - len, 432 PR_IS("HOST1-Fatal", host1_fatal);
427 "%8s: %10u\n", "DTIMSYNC", sc->debug.stats.istats.dtimsync); 433 PR_IS("HOST1-Perr", host1_perr);
428 len += snprintf(buf + len, sizeof(buf) - len, 434 PR_IS("TRCV-FIFO-Perr", trcv_fifo_perr);
429 "%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim); 435 PR_IS("RADM-CPL-EP", radm_cpl_ep);
430 len += snprintf(buf + len, sizeof(buf) - len, 436 PR_IS("RADM-CPL-DLLP-Abort", radm_cpl_dllp_abort);
431 "%8s: %10u\n", "TSFOOR", sc->debug.stats.istats.tsfoor); 437 PR_IS("RADM-CPL-TLP-Abort", radm_cpl_tlp_abort);
432 len += snprintf(buf + len, sizeof(buf) - len, 438 PR_IS("RADM-CPL-ECRC-Err", radm_cpl_ecrc_err);
433 "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total); 439 PR_IS("RADM-CPL-Timeout", radm_cpl_timeout);
434 440 PR_IS("Local-Bus-Timeout", local_timeout);
435 441 PR_IS("PM-Access", pm_access);
436 if (len > sizeof(buf)) 442 PR_IS("MAC-Awake", mac_awake);
437 len = sizeof(buf); 443 PR_IS("MAC-Asleep", mac_asleep);
438 444 PR_IS("MAC-Sleep-Access", mac_sleep_access);
439 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 445
446 if (len > mxlen)
447 len = mxlen;
448
449 rv = simple_read_from_buffer(user_buf, count, ppos, buf, len);
450 kfree(buf);
451 return rv;
440} 452}
441 453
442static const struct file_operations fops_interrupt = { 454static const struct file_operations fops_interrupt = {
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 17f6cc27af32..c34da09d9103 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -60,6 +60,7 @@ struct ath_buf;
60 * @tsfoor: TSF out of range, indicates that the corrected TSF received 60 * @tsfoor: TSF out of range, indicates that the corrected TSF received
61 * from a beacon differs from the PCU's internal TSF by more than a 61 * from a beacon differs from the PCU's internal TSF by more than a
62 * (programmable) threshold 62 * (programmable) threshold
63 * @local_timeout: Internal bus timeout.
63 */ 64 */
64struct ath_interrupt_stats { 65struct ath_interrupt_stats {
65 u32 total; 66 u32 total;
@@ -85,8 +86,30 @@ struct ath_interrupt_stats {
85 u32 dtim; 86 u32 dtim;
86 u32 bb_watchdog; 87 u32 bb_watchdog;
87 u32 tsfoor; 88 u32 tsfoor;
89
90 /* Sync-cause stats */
91 u32 sync_cause_all;
92 u32 sync_rtc_irq;
93 u32 sync_mac_irq;
94 u32 eeprom_illegal_access;
95 u32 apb_timeout;
96 u32 pci_mode_conflict;
97 u32 host1_fatal;
98 u32 host1_perr;
99 u32 trcv_fifo_perr;
100 u32 radm_cpl_ep;
101 u32 radm_cpl_dllp_abort;
102 u32 radm_cpl_tlp_abort;
103 u32 radm_cpl_ecrc_err;
104 u32 radm_cpl_timeout;
105 u32 local_timeout;
106 u32 pm_access;
107 u32 mac_awake;
108 u32 mac_asleep;
109 u32 mac_sleep_access;
88}; 110};
89 111
112
90/** 113/**
91 * struct ath_tx_stats - Statistics about TX 114 * struct ath_tx_stats - Statistics about TX
92 * @tx_pkts_all: No. of total frames transmitted, including ones that 115 * @tx_pkts_all: No. of total frames transmitted, including ones that
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 6fa8128db19f..2aaa1fd4df2f 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -24,6 +24,8 @@
24#include "rc.h" 24#include "rc.h"
25#include "ar9003_mac.h" 25#include "ar9003_mac.h"
26#include "ar9003_mci.h" 26#include "ar9003_mci.h"
27#include "debug.h"
28#include "ath9k.h"
27 29
28static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); 30static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
29 31
@@ -83,6 +85,53 @@ static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah)
83/* Helper Functions */ 85/* Helper Functions */
84/********************/ 86/********************/
85 87
88#ifdef CONFIG_ATH9K_DEBUGFS
89
90void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause)
91{
92 struct ath_softc *sc = common->priv;
93 if (sync_cause)
94 sc->debug.stats.istats.sync_cause_all++;
95 if (sync_cause & AR_INTR_SYNC_RTC_IRQ)
96 sc->debug.stats.istats.sync_rtc_irq++;
97 if (sync_cause & AR_INTR_SYNC_MAC_IRQ)
98 sc->debug.stats.istats.sync_mac_irq++;
99 if (sync_cause & AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS)
100 sc->debug.stats.istats.eeprom_illegal_access++;
101 if (sync_cause & AR_INTR_SYNC_APB_TIMEOUT)
102 sc->debug.stats.istats.apb_timeout++;
103 if (sync_cause & AR_INTR_SYNC_PCI_MODE_CONFLICT)
104 sc->debug.stats.istats.pci_mode_conflict++;
105 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL)
106 sc->debug.stats.istats.host1_fatal++;
107 if (sync_cause & AR_INTR_SYNC_HOST1_PERR)
108 sc->debug.stats.istats.host1_perr++;
109 if (sync_cause & AR_INTR_SYNC_TRCV_FIFO_PERR)
110 sc->debug.stats.istats.trcv_fifo_perr++;
111 if (sync_cause & AR_INTR_SYNC_RADM_CPL_EP)
112 sc->debug.stats.istats.radm_cpl_ep++;
113 if (sync_cause & AR_INTR_SYNC_RADM_CPL_DLLP_ABORT)
114 sc->debug.stats.istats.radm_cpl_dllp_abort++;
115 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TLP_ABORT)
116 sc->debug.stats.istats.radm_cpl_tlp_abort++;
117 if (sync_cause & AR_INTR_SYNC_RADM_CPL_ECRC_ERR)
118 sc->debug.stats.istats.radm_cpl_ecrc_err++;
119 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT)
120 sc->debug.stats.istats.radm_cpl_timeout++;
121 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT)
122 sc->debug.stats.istats.local_timeout++;
123 if (sync_cause & AR_INTR_SYNC_PM_ACCESS)
124 sc->debug.stats.istats.pm_access++;
125 if (sync_cause & AR_INTR_SYNC_MAC_AWAKE)
126 sc->debug.stats.istats.mac_awake++;
127 if (sync_cause & AR_INTR_SYNC_MAC_ASLEEP)
128 sc->debug.stats.istats.mac_asleep++;
129 if (sync_cause & AR_INTR_SYNC_MAC_SLEEP_ACCESS)
130 sc->debug.stats.istats.mac_sleep_access++;
131}
132#endif
133
134
86static void ath9k_hw_set_clockrate(struct ath_hw *ah) 135static void ath9k_hw_set_clockrate(struct ath_hw *ah)
87{ 136{
88 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; 137 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 1d4b98331ce2..dd4b8f4097c8 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -956,6 +956,12 @@ bool ath9k_hw_check_alive(struct ath_hw *ah);
956 956
957bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); 957bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
958 958
959#ifdef CONFIG_ATH9K_DEBUGFS
960void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause);
961#else
962static void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause) {}
963#endif
964
959/* Generic hw timer primitives */ 965/* Generic hw timer primitives */
960struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, 966struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
961 void (*trigger)(void *), 967 void (*trigger)(void *),