diff options
author | Ben Greear <greearb@candelatech.com> | 2012-04-12 13:04:00 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-04-16 14:16:58 -0400 |
commit | 462e58f2b6f2f3ca113b44794f2c35ee8e792b93 (patch) | |
tree | f4c4bfb31bb82ff192caeb870b46ff10e8decc11 /drivers | |
parent | 24a0731e70fb007c989ae81dd72bc4fe99e27818 (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.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_mac.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.c | 116 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.h | 23 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 49 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.h | 6 |
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 | ||
442 | static const struct file_operations fops_interrupt = { | 454 | static 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 | */ |
64 | struct ath_interrupt_stats { | 65 | struct 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 | ||
28 | static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); | 30 | static 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 | |||
90 | void 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 | |||
86 | static void ath9k_hw_set_clockrate(struct ath_hw *ah) | 135 | static 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 | ||
957 | bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); | 957 | bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); |
958 | 958 | ||
959 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
960 | void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause); | ||
961 | #else | ||
962 | static 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 */ |
960 | struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, | 966 | struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, |
961 | void (*trigger)(void *), | 967 | void (*trigger)(void *), |