aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/debug.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/wireless/ath/ath9k/debug.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/debug.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c272
1 files changed, 209 insertions, 63 deletions
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 2be4c2252047..081e0085ed4c 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -14,44 +14,35 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include <linux/slab.h>
17#include <asm/unaligned.h> 18#include <asm/unaligned.h>
18 19
19#include "ath9k.h" 20#include "ath9k.h"
20 21
21static unsigned int ath9k_debug = DBG_DEFAULT; 22#define REG_WRITE_D(_ah, _reg, _val) \
22module_param_named(debug, ath9k_debug, uint, 0); 23 ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg))
24#define REG_READ_D(_ah, _reg) \
25 ath9k_hw_common(_ah)->ops->read((_ah), (_reg))
23 26
24static struct dentry *ath9k_debugfs_root; 27static struct dentry *ath9k_debugfs_root;
25 28
26void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...)
27{
28 if (!sc)
29 return;
30
31 if (sc->debug.debug_mask & dbg_mask) {
32 va_list args;
33
34 va_start(args, fmt);
35 printk(KERN_DEBUG "ath9k: ");
36 vprintk(fmt, args);
37 va_end(args);
38 }
39}
40
41static int ath9k_debugfs_open(struct inode *inode, struct file *file) 29static int ath9k_debugfs_open(struct inode *inode, struct file *file)
42{ 30{
43 file->private_data = inode->i_private; 31 file->private_data = inode->i_private;
44 return 0; 32 return 0;
45} 33}
46 34
35#ifdef CONFIG_ATH_DEBUG
36
47static ssize_t read_file_debug(struct file *file, char __user *user_buf, 37static ssize_t read_file_debug(struct file *file, char __user *user_buf,
48 size_t count, loff_t *ppos) 38 size_t count, loff_t *ppos)
49{ 39{
50 struct ath_softc *sc = file->private_data; 40 struct ath_softc *sc = file->private_data;
41 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
51 char buf[32]; 42 char buf[32];
52 unsigned int len; 43 unsigned int len;
53 44
54 len = snprintf(buf, sizeof(buf), "0x%08x\n", sc->debug.debug_mask); 45 len = snprintf(buf, sizeof(buf), "0x%08x\n", common->debug_mask);
55 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 46 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
56} 47}
57 48
@@ -59,6 +50,7 @@ static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
59 size_t count, loff_t *ppos) 50 size_t count, loff_t *ppos)
60{ 51{
61 struct ath_softc *sc = file->private_data; 52 struct ath_softc *sc = file->private_data;
53 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
62 unsigned long mask; 54 unsigned long mask;
63 char buf[32]; 55 char buf[32];
64 ssize_t len; 56 ssize_t len;
@@ -71,7 +63,7 @@ static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
71 if (strict_strtoul(buf, 0, &mask)) 63 if (strict_strtoul(buf, 0, &mask))
72 return -EINVAL; 64 return -EINVAL;
73 65
74 sc->debug.debug_mask = mask; 66 common->debug_mask = mask;
75 return count; 67 return count;
76} 68}
77 69
@@ -82,38 +74,47 @@ static const struct file_operations fops_debug = {
82 .owner = THIS_MODULE 74 .owner = THIS_MODULE
83}; 75};
84 76
77#endif
78
79#define DMA_BUF_LEN 1024
80
85static ssize_t read_file_dma(struct file *file, char __user *user_buf, 81static ssize_t read_file_dma(struct file *file, char __user *user_buf,
86 size_t count, loff_t *ppos) 82 size_t count, loff_t *ppos)
87{ 83{
88 struct ath_softc *sc = file->private_data; 84 struct ath_softc *sc = file->private_data;
89 struct ath_hw *ah = sc->sc_ah; 85 struct ath_hw *ah = sc->sc_ah;
90 char buf[1024]; 86 char *buf;
87 int retval;
91 unsigned int len = 0; 88 unsigned int len = 0;
92 u32 val[ATH9K_NUM_DMA_DEBUG_REGS]; 89 u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
93 int i, qcuOffset = 0, dcuOffset = 0; 90 int i, qcuOffset = 0, dcuOffset = 0;
94 u32 *qcuBase = &val[0], *dcuBase = &val[4]; 91 u32 *qcuBase = &val[0], *dcuBase = &val[4];
95 92
93 buf = kmalloc(DMA_BUF_LEN, GFP_KERNEL);
94 if (!buf)
95 return 0;
96
96 ath9k_ps_wakeup(sc); 97 ath9k_ps_wakeup(sc);
97 98
98 REG_WRITE(ah, AR_MACMISC, 99 REG_WRITE_D(ah, AR_MACMISC,
99 ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) | 100 ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
100 (AR_MACMISC_MISC_OBS_BUS_1 << 101 (AR_MACMISC_MISC_OBS_BUS_1 <<
101 AR_MACMISC_MISC_OBS_BUS_MSB_S))); 102 AR_MACMISC_MISC_OBS_BUS_MSB_S)));
102 103
103 len += snprintf(buf + len, sizeof(buf) - len, 104 len += snprintf(buf + len, DMA_BUF_LEN - len,
104 "Raw DMA Debug values:\n"); 105 "Raw DMA Debug values:\n");
105 106
106 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) { 107 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
107 if (i % 4 == 0) 108 if (i % 4 == 0)
108 len += snprintf(buf + len, sizeof(buf) - len, "\n"); 109 len += snprintf(buf + len, DMA_BUF_LEN - len, "\n");
109 110
110 val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32))); 111 val[i] = REG_READ_D(ah, AR_DMADBG_0 + (i * sizeof(u32)));
111 len += snprintf(buf + len, sizeof(buf) - len, "%d: %08x ", 112 len += snprintf(buf + len, DMA_BUF_LEN - len, "%d: %08x ",
112 i, val[i]); 113 i, val[i]);
113 } 114 }
114 115
115 len += snprintf(buf + len, sizeof(buf) - len, "\n\n"); 116 len += snprintf(buf + len, DMA_BUF_LEN - len, "\n\n");
116 len += snprintf(buf + len, sizeof(buf) - len, 117 len += snprintf(buf + len, DMA_BUF_LEN - len,
117 "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n"); 118 "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
118 119
119 for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) { 120 for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) {
@@ -127,7 +128,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
127 dcuBase++; 128 dcuBase++;
128 } 129 }
129 130
130 len += snprintf(buf + len, sizeof(buf) - len, 131 len += snprintf(buf + len, DMA_BUF_LEN - len,
131 "%2d %2x %1x %2x %2x\n", 132 "%2d %2x %1x %2x %2x\n",
132 i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset, 133 i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
133 (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3), 134 (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3),
@@ -135,35 +136,37 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
135 (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset); 136 (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
136 } 137 }
137 138
138 len += snprintf(buf + len, sizeof(buf) - len, "\n"); 139 len += snprintf(buf + len, DMA_BUF_LEN - len, "\n");
139 140
140 len += snprintf(buf + len, sizeof(buf) - len, 141 len += snprintf(buf + len, DMA_BUF_LEN - len,
141 "qcu_stitch state: %2x qcu_fetch state: %2x\n", 142 "qcu_stitch state: %2x qcu_fetch state: %2x\n",
142 (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22); 143 (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
143 len += snprintf(buf + len, sizeof(buf) - len, 144 len += snprintf(buf + len, DMA_BUF_LEN - len,
144 "qcu_complete state: %2x dcu_complete state: %2x\n", 145 "qcu_complete state: %2x dcu_complete state: %2x\n",
145 (val[3] & 0x1c000000) >> 26, (val[6] & 0x3)); 146 (val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
146 len += snprintf(buf + len, sizeof(buf) - len, 147 len += snprintf(buf + len, DMA_BUF_LEN - len,
147 "dcu_arb state: %2x dcu_fp state: %2x\n", 148 "dcu_arb state: %2x dcu_fp state: %2x\n",
148 (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27); 149 (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
149 len += snprintf(buf + len, sizeof(buf) - len, 150 len += snprintf(buf + len, DMA_BUF_LEN - len,
150 "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n", 151 "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n",
151 (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10); 152 (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
152 len += snprintf(buf + len, sizeof(buf) - len, 153 len += snprintf(buf + len, DMA_BUF_LEN - len,
153 "txfifo_valid_0: %1d txfifo_valid_1: %1d\n", 154 "txfifo_valid_0: %1d txfifo_valid_1: %1d\n",
154 (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12); 155 (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
155 len += snprintf(buf + len, sizeof(buf) - len, 156 len += snprintf(buf + len, DMA_BUF_LEN - len,
156 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n", 157 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n",
157 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17); 158 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
158 159
159 len += snprintf(buf + len, sizeof(buf) - len, "pcu observe: 0x%x \n", 160 len += snprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x \n",
160 REG_READ(ah, AR_OBS_BUS_1)); 161 REG_READ_D(ah, AR_OBS_BUS_1));
161 len += snprintf(buf + len, sizeof(buf) - len, 162 len += snprintf(buf + len, DMA_BUF_LEN - len,
162 "AR_CR: 0x%x \n", REG_READ(ah, AR_CR)); 163 "AR_CR: 0x%x \n", REG_READ_D(ah, AR_CR));
163 164
164 ath9k_ps_restore(sc); 165 ath9k_ps_restore(sc);
165 166
166 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 167 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
168 kfree(buf);
169 return retval;
167} 170}
168 171
169static const struct file_operations fops_dma = { 172static const struct file_operations fops_dma = {
@@ -266,18 +269,11 @@ static const struct file_operations fops_interrupt = {
266 .owner = THIS_MODULE 269 .owner = THIS_MODULE
267}; 270};
268 271
269void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb) 272void ath_debug_stat_rc(struct ath_softc *sc, int final_rate)
270{ 273{
271 struct ath_tx_info_priv *tx_info_priv = NULL;
272 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
273 struct ieee80211_tx_rate *rates = tx_info->status.rates;
274 int final_ts_idx, idx;
275 struct ath_rc_stats *stats; 274 struct ath_rc_stats *stats;
276 275
277 tx_info_priv = ATH_TX_INFO_PRIV(tx_info); 276 stats = &sc->debug.stats.rcstats[final_rate];
278 final_ts_idx = tx_info_priv->tx.ts_rateindex;
279 idx = rates[final_ts_idx].idx;
280 stats = &sc->debug.stats.rcstats[idx];
281 stats->success++; 277 stats->success++;
282} 278}
283 279
@@ -303,23 +299,49 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
303 if (sc->cur_rate_table == NULL) 299 if (sc->cur_rate_table == NULL)
304 return 0; 300 return 0;
305 301
306 max = 80 + sc->cur_rate_table->rate_cnt * 64; 302 max = 80 + sc->cur_rate_table->rate_cnt * 1024;
307 buf = kmalloc(max + 1, GFP_KERNEL); 303 buf = kmalloc(max + 1, GFP_KERNEL);
308 if (buf == NULL) 304 if (buf == NULL)
309 return 0; 305 return 0;
310 buf[max] = 0; 306 buf[max] = 0;
311 307
312 len += sprintf(buf, "%5s %15s %8s %9s %3s\n\n", "Rate", "Success", 308 len += sprintf(buf, "%6s %6s %6s "
313 "Retries", "XRetries", "PER"); 309 "%10s %10s %10s %10s\n",
310 "HT", "MCS", "Rate",
311 "Success", "Retries", "XRetries", "PER");
314 312
315 for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) { 313 for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
316 u32 ratekbps = sc->cur_rate_table->info[i].ratekbps; 314 u32 ratekbps = sc->cur_rate_table->info[i].ratekbps;
317 struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i]; 315 struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i];
316 char mcs[5];
317 char htmode[5];
318 int used_mcs = 0, used_htmode = 0;
319
320 if (WLAN_RC_PHY_HT(sc->cur_rate_table->info[i].phy)) {
321 used_mcs = snprintf(mcs, 5, "%d",
322 sc->cur_rate_table->info[i].ratecode);
323
324 if (WLAN_RC_PHY_40(sc->cur_rate_table->info[i].phy))
325 used_htmode = snprintf(htmode, 5, "HT40");
326 else if (WLAN_RC_PHY_20(sc->cur_rate_table->info[i].phy))
327 used_htmode = snprintf(htmode, 5, "HT20");
328 else
329 used_htmode = snprintf(htmode, 5, "????");
330 }
331
332 mcs[used_mcs] = '\0';
333 htmode[used_htmode] = '\0';
318 334
319 len += snprintf(buf + len, max - len, 335 len += snprintf(buf + len, max - len,
320 "%3u.%d: %8u %8u %8u %8u\n", ratekbps / 1000, 336 "%6s %6s %3u.%d: "
321 (ratekbps % 1000) / 100, stats->success, 337 "%10u %10u %10u %10u\n",
322 stats->retries, stats->xretries, 338 htmode,
339 mcs,
340 ratekbps / 1000,
341 (ratekbps % 1000) / 100,
342 stats->success,
343 stats->retries,
344 stats->xretries,
323 stats->per); 345 stats->per);
324 } 346 }
325 347
@@ -376,12 +398,12 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
376 aphy->chan_idx, aphy->chan_is_ht); 398 aphy->chan_idx, aphy->chan_is_ht);
377 } 399 }
378 400
379 put_unaligned_le32(REG_READ(sc->sc_ah, AR_STA_ID0), addr); 401 put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr);
380 put_unaligned_le16(REG_READ(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4); 402 put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4);
381 len += snprintf(buf + len, sizeof(buf) - len, 403 len += snprintf(buf + len, sizeof(buf) - len,
382 "addr: %pM\n", addr); 404 "addr: %pM\n", addr);
383 put_unaligned_le32(REG_READ(sc->sc_ah, AR_BSSMSKL), addr); 405 put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_BSSMSKL), addr);
384 put_unaligned_le16(REG_READ(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4); 406 put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4);
385 len += snprintf(buf + len, sizeof(buf) - len, 407 len += snprintf(buf + len, sizeof(buf) - len,
386 "addrmask: %pM\n", addr); 408 "addrmask: %pM\n", addr);
387 409
@@ -568,9 +590,120 @@ static const struct file_operations fops_xmit = {
568 .owner = THIS_MODULE 590 .owner = THIS_MODULE
569}; 591};
570 592
571int ath9k_init_debug(struct ath_softc *sc) 593static ssize_t read_file_recv(struct file *file, char __user *user_buf,
594 size_t count, loff_t *ppos)
572{ 595{
573 sc->debug.debug_mask = ath9k_debug; 596#define PHY_ERR(s, p) \
597 len += snprintf(buf + len, size - len, "%18s : %10u\n", s, \
598 sc->debug.stats.rxstats.phy_err_stats[p]);
599
600 struct ath_softc *sc = file->private_data;
601 char *buf;
602 unsigned int len = 0, size = 1152;
603 ssize_t retval = 0;
604
605 buf = kzalloc(size, GFP_KERNEL);
606 if (buf == NULL)
607 return 0;
608
609 len += snprintf(buf + len, size - len,
610 "%18s : %10u\n", "CRC ERR",
611 sc->debug.stats.rxstats.crc_err);
612 len += snprintf(buf + len, size - len,
613 "%18s : %10u\n", "DECRYPT CRC ERR",
614 sc->debug.stats.rxstats.decrypt_crc_err);
615 len += snprintf(buf + len, size - len,
616 "%18s : %10u\n", "PHY ERR",
617 sc->debug.stats.rxstats.phy_err);
618 len += snprintf(buf + len, size - len,
619 "%18s : %10u\n", "MIC ERR",
620 sc->debug.stats.rxstats.mic_err);
621 len += snprintf(buf + len, size - len,
622 "%18s : %10u\n", "PRE-DELIM CRC ERR",
623 sc->debug.stats.rxstats.pre_delim_crc_err);
624 len += snprintf(buf + len, size - len,
625 "%18s : %10u\n", "POST-DELIM CRC ERR",
626 sc->debug.stats.rxstats.post_delim_crc_err);
627 len += snprintf(buf + len, size - len,
628 "%18s : %10u\n", "DECRYPT BUSY ERR",
629 sc->debug.stats.rxstats.decrypt_busy_err);
630
631 PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN);
632 PHY_ERR("TIMING", ATH9K_PHYERR_TIMING);
633 PHY_ERR("PARITY", ATH9K_PHYERR_PARITY);
634 PHY_ERR("RATE", ATH9K_PHYERR_RATE);
635 PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH);
636 PHY_ERR("RADAR", ATH9K_PHYERR_RADAR);
637 PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE);
638 PHY_ERR("TOR", ATH9K_PHYERR_TOR);
639 PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING);
640 PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
641 PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
642 PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
643 PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP);
644 PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE);
645 PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART);
646 PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT);
647 PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING);
648 PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC);
649 PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
650 PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE);
651 PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART);
652 PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
653 PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP);
654 PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR);
655 PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
656 PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL);
657
658 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
659 kfree(buf);
660
661 return retval;
662
663#undef PHY_ERR
664}
665
666void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf)
667{
668#define RX_STAT_INC(c) sc->debug.stats.rxstats.c++
669#define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++
670
671 struct ath_desc *ds = bf->bf_desc;
672 u32 phyerr;
673
674 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
675 RX_STAT_INC(crc_err);
676 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT)
677 RX_STAT_INC(decrypt_crc_err);
678 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC)
679 RX_STAT_INC(mic_err);
680 if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_PRE)
681 RX_STAT_INC(pre_delim_crc_err);
682 if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_POST)
683 RX_STAT_INC(post_delim_crc_err);
684 if (ds->ds_rxstat.rs_status & ATH9K_RX_DECRYPT_BUSY)
685 RX_STAT_INC(decrypt_busy_err);
686
687 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) {
688 RX_STAT_INC(phy_err);
689 phyerr = ds->ds_rxstat.rs_phyerr & 0x24;
690 RX_PHY_ERR_INC(phyerr);
691 }
692
693#undef RX_STAT_INC
694#undef RX_PHY_ERR_INC
695}
696
697static const struct file_operations fops_recv = {
698 .read = read_file_recv,
699 .open = ath9k_debugfs_open,
700 .owner = THIS_MODULE
701};
702
703int ath9k_init_debug(struct ath_hw *ah)
704{
705 struct ath_common *common = ath9k_hw_common(ah);
706 struct ath_softc *sc = (struct ath_softc *) common->priv;
574 707
575 if (!ath9k_debugfs_root) 708 if (!ath9k_debugfs_root)
576 return -ENOENT; 709 return -ENOENT;
@@ -580,10 +713,12 @@ int ath9k_init_debug(struct ath_softc *sc)
580 if (!sc->debug.debugfs_phy) 713 if (!sc->debug.debugfs_phy)
581 goto err; 714 goto err;
582 715
716#ifdef CONFIG_ATH_DEBUG
583 sc->debug.debugfs_debug = debugfs_create_file("debug", 717 sc->debug.debugfs_debug = debugfs_create_file("debug",
584 S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug); 718 S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug);
585 if (!sc->debug.debugfs_debug) 719 if (!sc->debug.debugfs_debug)
586 goto err; 720 goto err;
721#endif
587 722
588 sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUSR, 723 sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUSR,
589 sc->debug.debugfs_phy, sc, &fops_dma); 724 sc->debug.debugfs_phy, sc, &fops_dma);
@@ -617,14 +752,25 @@ int ath9k_init_debug(struct ath_softc *sc)
617 if (!sc->debug.debugfs_xmit) 752 if (!sc->debug.debugfs_xmit)
618 goto err; 753 goto err;
619 754
755 sc->debug.debugfs_recv = debugfs_create_file("recv",
756 S_IRUSR,
757 sc->debug.debugfs_phy,
758 sc, &fops_recv);
759 if (!sc->debug.debugfs_recv)
760 goto err;
761
620 return 0; 762 return 0;
621err: 763err:
622 ath9k_exit_debug(sc); 764 ath9k_exit_debug(ah);
623 return -ENOMEM; 765 return -ENOMEM;
624} 766}
625 767
626void ath9k_exit_debug(struct ath_softc *sc) 768void ath9k_exit_debug(struct ath_hw *ah)
627{ 769{
770 struct ath_common *common = ath9k_hw_common(ah);
771 struct ath_softc *sc = (struct ath_softc *) common->priv;
772
773 debugfs_remove(sc->debug.debugfs_recv);
628 debugfs_remove(sc->debug.debugfs_xmit); 774 debugfs_remove(sc->debug.debugfs_xmit);
629 debugfs_remove(sc->debug.debugfs_wiphy); 775 debugfs_remove(sc->debug.debugfs_wiphy);
630 debugfs_remove(sc->debug.debugfs_rcstat); 776 debugfs_remove(sc->debug.debugfs_rcstat);