ath9k: fix ready time of the multicast buffer queue
[linux-2.6-block.git] / drivers / net / wireless / ath / ath9k / debug.c
CommitLineData
88b126af 1/*
5b68138e 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
88b126af
S
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
5a0e3ad6 17#include <linux/slab.h>
582d0064 18#include <linux/vmalloc.h>
ee40fa06 19#include <linux/export.h>
52103115
GJ
20#include <asm/unaligned.h>
21
394cf0a1 22#include "ath9k.h"
88b126af 23
475a6e4d
LR
24#define REG_WRITE_D(_ah, _reg, _val) \
25 ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg))
26#define REG_READ_D(_ah, _reg) \
27 ath9k_hw_common(_ah)->ops->read((_ah), (_reg))
28
6a4d05dc
FF
29void ath9k_debug_sync_cause(struct ath_softc *sc, u32 sync_cause)
30{
31 if (sync_cause)
32 sc->debug.stats.istats.sync_cause_all++;
33 if (sync_cause & AR_INTR_SYNC_RTC_IRQ)
34 sc->debug.stats.istats.sync_rtc_irq++;
35 if (sync_cause & AR_INTR_SYNC_MAC_IRQ)
36 sc->debug.stats.istats.sync_mac_irq++;
37 if (sync_cause & AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS)
38 sc->debug.stats.istats.eeprom_illegal_access++;
39 if (sync_cause & AR_INTR_SYNC_APB_TIMEOUT)
40 sc->debug.stats.istats.apb_timeout++;
41 if (sync_cause & AR_INTR_SYNC_PCI_MODE_CONFLICT)
42 sc->debug.stats.istats.pci_mode_conflict++;
43 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL)
44 sc->debug.stats.istats.host1_fatal++;
45 if (sync_cause & AR_INTR_SYNC_HOST1_PERR)
46 sc->debug.stats.istats.host1_perr++;
47 if (sync_cause & AR_INTR_SYNC_TRCV_FIFO_PERR)
48 sc->debug.stats.istats.trcv_fifo_perr++;
49 if (sync_cause & AR_INTR_SYNC_RADM_CPL_EP)
50 sc->debug.stats.istats.radm_cpl_ep++;
51 if (sync_cause & AR_INTR_SYNC_RADM_CPL_DLLP_ABORT)
52 sc->debug.stats.istats.radm_cpl_dllp_abort++;
53 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TLP_ABORT)
54 sc->debug.stats.istats.radm_cpl_tlp_abort++;
55 if (sync_cause & AR_INTR_SYNC_RADM_CPL_ECRC_ERR)
56 sc->debug.stats.istats.radm_cpl_ecrc_err++;
57 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT)
58 sc->debug.stats.istats.radm_cpl_timeout++;
59 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT)
60 sc->debug.stats.istats.local_timeout++;
61 if (sync_cause & AR_INTR_SYNC_PM_ACCESS)
62 sc->debug.stats.istats.pm_access++;
63 if (sync_cause & AR_INTR_SYNC_MAC_AWAKE)
64 sc->debug.stats.istats.mac_awake++;
65 if (sync_cause & AR_INTR_SYNC_MAC_ASLEEP)
66 sc->debug.stats.istats.mac_asleep++;
67 if (sync_cause & AR_INTR_SYNC_MAC_SLEEP_ACCESS)
68 sc->debug.stats.istats.mac_sleep_access++;
69}
2a163c6d 70
582d0064
VT
71static ssize_t ath9k_debugfs_read_buf(struct file *file, char __user *user_buf,
72 size_t count, loff_t *ppos)
73{
74 u8 *buf = file->private_data;
75 return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
76}
77
78static int ath9k_debugfs_release_buf(struct inode *inode, struct file *file)
79{
80 vfree(file->private_data);
81 return 0;
82}
83
a830df07
FF
84#ifdef CONFIG_ATH_DEBUG
85
2493928e
JH
86static ssize_t read_file_debug(struct file *file, char __user *user_buf,
87 size_t count, loff_t *ppos)
88{
89 struct ath_softc *sc = file->private_data;
c46917bb 90 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2493928e 91 char buf[32];
581f725c
VT
92 unsigned int len;
93
2b87f3aa 94 len = sprintf(buf, "0x%08x\n", common->debug_mask);
2493928e
JH
95 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
96}
97
98static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
99 size_t count, loff_t *ppos)
100{
101 struct ath_softc *sc = file->private_data;
c46917bb 102 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2493928e
JH
103 unsigned long mask;
104 char buf[32];
581f725c
VT
105 ssize_t len;
106
107 len = min(count, sizeof(buf) - 1);
108 if (copy_from_user(buf, user_buf, len))
04236066 109 return -EFAULT;
581f725c
VT
110
111 buf[len] = '\0';
27d7f477 112 if (kstrtoul(buf, 0, &mask))
581f725c
VT
113 return -EINVAL;
114
c46917bb 115 common->debug_mask = mask;
2493928e
JH
116 return count;
117}
118
119static const struct file_operations fops_debug = {
120 .read = read_file_debug,
121 .write = write_file_debug,
234e3405 122 .open = simple_open,
6038f373
AB
123 .owner = THIS_MODULE,
124 .llseek = default_llseek,
2493928e
JH
125};
126
a830df07
FF
127#endif
128
991a0987
PR
129#define DMA_BUF_LEN 1024
130
15340694 131
6e4d291e 132static ssize_t read_file_ani(struct file *file, char __user *user_buf,
05c0be2f
MSS
133 size_t count, loff_t *ppos)
134{
135 struct ath_softc *sc = file->private_data;
136 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
6e4d291e 137 struct ath_hw *ah = sc->sc_ah;
2120ac96
JP
138 unsigned int len = 0;
139 const unsigned int size = 1024;
6e4d291e
SM
140 ssize_t retval = 0;
141 char *buf;
05c0be2f 142
6e4d291e
SM
143 buf = kzalloc(size, GFP_KERNEL);
144 if (buf == NULL)
145 return -ENOMEM;
146
147 if (common->disable_ani) {
5e88ba62
ZK
148 len += scnprintf(buf + len, size - len, "%s: %s\n",
149 "ANI", "DISABLED");
6e4d291e
SM
150 goto exit;
151 }
152
5e88ba62
ZK
153 len += scnprintf(buf + len, size - len, "%15s: %s\n",
154 "ANI", "ENABLED");
155 len += scnprintf(buf + len, size - len, "%15s: %u\n",
156 "ANI RESET", ah->stats.ast_ani_reset);
157 len += scnprintf(buf + len, size - len, "%15s: %u\n",
158 "SPUR UP", ah->stats.ast_ani_spurup);
159 len += scnprintf(buf + len, size - len, "%15s: %u\n",
160 "SPUR DOWN", ah->stats.ast_ani_spurup);
161 len += scnprintf(buf + len, size - len, "%15s: %u\n",
162 "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon);
163 len += scnprintf(buf + len, size - len, "%15s: %u\n",
164 "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff);
165 len += scnprintf(buf + len, size - len, "%15s: %u\n",
166 "MRC-CCK ON", ah->stats.ast_ani_ccklow);
167 len += scnprintf(buf + len, size - len, "%15s: %u\n",
168 "MRC-CCK OFF", ah->stats.ast_ani_cckhigh);
169 len += scnprintf(buf + len, size - len, "%15s: %u\n",
170 "FIR-STEP UP", ah->stats.ast_ani_stepup);
171 len += scnprintf(buf + len, size - len, "%15s: %u\n",
172 "FIR-STEP DOWN", ah->stats.ast_ani_stepdown);
173 len += scnprintf(buf + len, size - len, "%15s: %u\n",
174 "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero);
175 len += scnprintf(buf + len, size - len, "%15s: %u\n",
176 "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs);
177 len += scnprintf(buf + len, size - len, "%15s: %u\n",
178 "CCK ERRORS", ah->stats.ast_ani_cckerrs);
6e4d291e
SM
179exit:
180 if (len > size)
181 len = size;
182
183 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
184 kfree(buf);
185
186 return retval;
05c0be2f
MSS
187}
188
6e4d291e
SM
189static ssize_t write_file_ani(struct file *file,
190 const char __user *user_buf,
191 size_t count, loff_t *ppos)
05c0be2f
MSS
192{
193 struct ath_softc *sc = file->private_data;
194 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
6e4d291e 195 unsigned long ani;
05c0be2f
MSS
196 char buf[32];
197 ssize_t len;
198
199 len = min(count, sizeof(buf) - 1);
200 if (copy_from_user(buf, user_buf, len))
201 return -EFAULT;
202
203 buf[len] = '\0';
3899ba90 204 if (kstrtoul(buf, 0, &ani))
05c0be2f
MSS
205 return -EINVAL;
206
6e4d291e 207 if (ani < 0 || ani > 1)
05c0be2f
MSS
208 return -EINVAL;
209
6e4d291e 210 common->disable_ani = !ani;
05c0be2f 211
6e4d291e 212 if (common->disable_ani) {
781b14a3 213 clear_bit(SC_OP_ANI_RUN, &sc->sc_flags);
da0d45f7 214 ath_stop_ani(sc);
05c0be2f 215 } else {
da0d45f7 216 ath_check_ani(sc);
05c0be2f
MSS
217 }
218
219 return count;
220}
221
6e4d291e
SM
222static const struct file_operations fops_ani = {
223 .read = read_file_ani,
224 .write = write_file_ani,
234e3405 225 .open = simple_open,
05c0be2f
MSS
226 .owner = THIS_MODULE,
227 .llseek = default_llseek,
228};
15340694 229
36e8825e
SM
230#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
231
63081305
SM
232static ssize_t read_file_bt_ant_diversity(struct file *file,
233 char __user *user_buf,
234 size_t count, loff_t *ppos)
302a3c3a
SM
235{
236 struct ath_softc *sc = file->private_data;
237 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
238 char buf[32];
239 unsigned int len;
240
63081305 241 len = sprintf(buf, "%d\n", common->bt_ant_diversity);
302a3c3a
SM
242 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
243}
244
63081305
SM
245static ssize_t write_file_bt_ant_diversity(struct file *file,
246 const char __user *user_buf,
247 size_t count, loff_t *ppos)
302a3c3a
SM
248{
249 struct ath_softc *sc = file->private_data;
250 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
3f2da955 251 struct ath9k_hw_capabilities *pCap = &sc->sc_ah->caps;
63081305 252 unsigned long bt_ant_diversity;
302a3c3a
SM
253 char buf[32];
254 ssize_t len;
255
256 len = min(count, sizeof(buf) - 1);
257 if (copy_from_user(buf, user_buf, len))
258 return -EFAULT;
259
3f2da955
SM
260 if (!(pCap->hw_caps & ATH9K_HW_CAP_BT_ANT_DIV))
261 goto exit;
262
302a3c3a 263 buf[len] = '\0';
63081305 264 if (kstrtoul(buf, 0, &bt_ant_diversity))
302a3c3a
SM
265 return -EINVAL;
266
63081305 267 common->bt_ant_diversity = !!bt_ant_diversity;
302a3c3a 268 ath9k_ps_wakeup(sc);
047dc3ac 269 ath9k_hw_set_bt_ant_diversity(sc->sc_ah, common->bt_ant_diversity);
63081305
SM
270 ath_dbg(common, CONFIG, "Enable WLAN/BT RX Antenna diversity: %d\n",
271 common->bt_ant_diversity);
302a3c3a 272 ath9k_ps_restore(sc);
3f2da955 273exit:
302a3c3a
SM
274 return count;
275}
276
63081305
SM
277static const struct file_operations fops_bt_ant_diversity = {
278 .read = read_file_bt_ant_diversity,
279 .write = write_file_bt_ant_diversity,
302a3c3a
SM
280 .open = simple_open,
281 .owner = THIS_MODULE,
282 .llseek = default_llseek,
283};
284
36e8825e
SM
285#endif
286
e3d52914
SM
287void ath9k_debug_stat_ant(struct ath_softc *sc,
288 struct ath_hw_antcomb_conf *div_ant_conf,
289 int main_rssi_avg, int alt_rssi_avg)
290{
291 struct ath_antenna_stats *as_main = &sc->debug.stats.ant_stats[ANT_MAIN];
292 struct ath_antenna_stats *as_alt = &sc->debug.stats.ant_stats[ANT_ALT];
293
294 as_main->lna_attempt_cnt[div_ant_conf->main_lna_conf]++;
295 as_alt->lna_attempt_cnt[div_ant_conf->alt_lna_conf]++;
296
297 as_main->rssi_avg = main_rssi_avg;
298 as_alt->rssi_avg = alt_rssi_avg;
299}
300
4eba10cc
SM
301static ssize_t read_file_antenna_diversity(struct file *file,
302 char __user *user_buf,
303 size_t count, loff_t *ppos)
304{
305 struct ath_softc *sc = file->private_data;
306 struct ath_hw *ah = sc->sc_ah;
307 struct ath9k_hw_capabilities *pCap = &ah->caps;
308 struct ath_antenna_stats *as_main = &sc->debug.stats.ant_stats[ANT_MAIN];
309 struct ath_antenna_stats *as_alt = &sc->debug.stats.ant_stats[ANT_ALT];
e3d52914 310 struct ath_hw_antcomb_conf div_ant_conf;
2120ac96
JP
311 unsigned int len = 0;
312 const unsigned int size = 1024;
4eba10cc
SM
313 ssize_t retval = 0;
314 char *buf;
2120ac96
JP
315 static const char *lna_conf_str[4] = {
316 "LNA1_MINUS_LNA2", "LNA2", "LNA1", "LNA1_PLUS_LNA2"
317 };
4eba10cc
SM
318
319 buf = kzalloc(size, GFP_KERNEL);
320 if (buf == NULL)
321 return -ENOMEM;
322
323 if (!(pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)) {
5e88ba62
ZK
324 len += scnprintf(buf + len, size - len, "%s\n",
325 "Antenna Diversity Combining is disabled");
4eba10cc
SM
326 goto exit;
327 }
328
e3d52914
SM
329 ath9k_ps_wakeup(sc);
330 ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf);
5e88ba62
ZK
331 len += scnprintf(buf + len, size - len, "Current MAIN config : %s\n",
332 lna_conf_str[div_ant_conf.main_lna_conf]);
333 len += scnprintf(buf + len, size - len, "Current ALT config : %s\n",
334 lna_conf_str[div_ant_conf.alt_lna_conf]);
335 len += scnprintf(buf + len, size - len, "Average MAIN RSSI : %d\n",
336 as_main->rssi_avg);
337 len += scnprintf(buf + len, size - len, "Average ALT RSSI : %d\n\n",
338 as_alt->rssi_avg);
e3d52914
SM
339 ath9k_ps_restore(sc);
340
5e88ba62
ZK
341 len += scnprintf(buf + len, size - len, "Packet Receive Cnt:\n");
342 len += scnprintf(buf + len, size - len, "-------------------\n");
343
344 len += scnprintf(buf + len, size - len, "%30s%15s\n",
345 "MAIN", "ALT");
346 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n",
347 "TOTAL COUNT",
348 as_main->recv_cnt,
349 as_alt->recv_cnt);
350 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n",
351 "LNA1",
352 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1],
353 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1]);
354 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n",
355 "LNA2",
356 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2],
357 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2]);
358 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n",
359 "LNA1 + LNA2",
360 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2],
361 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]);
362 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n",
363 "LNA1 - LNA2",
364 as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2],
365 as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]);
366
367 len += scnprintf(buf + len, size - len, "\nLNA Config Attempts:\n");
368 len += scnprintf(buf + len, size - len, "--------------------\n");
369
370 len += scnprintf(buf + len, size - len, "%30s%15s\n",
371 "MAIN", "ALT");
372 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n",
373 "LNA1",
374 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1],
375 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1]);
376 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n",
377 "LNA2",
378 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2],
379 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2]);
380 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n",
381 "LNA1 + LNA2",
382 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2],
383 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]);
384 len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n",
385 "LNA1 - LNA2",
386 as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2],
387 as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]);
e3d52914 388
4eba10cc
SM
389exit:
390 if (len > size)
391 len = size;
392
393 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
394 kfree(buf);
395
396 return retval;
397}
398
399static const struct file_operations fops_antenna_diversity = {
400 .read = read_file_antenna_diversity,
401 .open = simple_open,
402 .owner = THIS_MODULE,
403 .llseek = default_llseek,
404};
405
2a163c6d
S
406static ssize_t read_file_dma(struct file *file, char __user *user_buf,
407 size_t count, loff_t *ppos)
408{
409 struct ath_softc *sc = file->private_data;
cbe61d8a 410 struct ath_hw *ah = sc->sc_ah;
991a0987
PR
411 char *buf;
412 int retval;
2a163c6d
S
413 unsigned int len = 0;
414 u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
415 int i, qcuOffset = 0, dcuOffset = 0;
416 u32 *qcuBase = &val[0], *dcuBase = &val[4];
417
991a0987
PR
418 buf = kmalloc(DMA_BUF_LEN, GFP_KERNEL);
419 if (!buf)
04236066 420 return -ENOMEM;
991a0987 421
7cf4a2e7
S
422 ath9k_ps_wakeup(sc);
423
475a6e4d 424 REG_WRITE_D(ah, AR_MACMISC,
2a163c6d
S
425 ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
426 (AR_MACMISC_MISC_OBS_BUS_1 <<
427 AR_MACMISC_MISC_OBS_BUS_MSB_S)));
428
5e88ba62
ZK
429 len += scnprintf(buf + len, DMA_BUF_LEN - len,
430 "Raw DMA Debug values:\n");
2a163c6d
S
431
432 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
433 if (i % 4 == 0)
5e88ba62 434 len += scnprintf(buf + len, DMA_BUF_LEN - len, "\n");
2a163c6d 435
475a6e4d 436 val[i] = REG_READ_D(ah, AR_DMADBG_0 + (i * sizeof(u32)));
5e88ba62
ZK
437 len += scnprintf(buf + len, DMA_BUF_LEN - len, "%d: %08x ",
438 i, val[i]);
2a163c6d
S
439 }
440
5e88ba62
ZK
441 len += scnprintf(buf + len, DMA_BUF_LEN - len, "\n\n");
442 len += scnprintf(buf + len, DMA_BUF_LEN - len,
443 "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
2a163c6d
S
444
445 for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) {
446 if (i == 8) {
447 qcuOffset = 0;
448 qcuBase++;
449 }
450
451 if (i == 6) {
452 dcuOffset = 0;
453 dcuBase++;
454 }
455
5e88ba62
ZK
456 len += scnprintf(buf + len, DMA_BUF_LEN - len,
457 "%2d %2x %1x %2x %2x\n",
458 i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
459 (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3),
460 val[2] & (0x7 << (i * 3)) >> (i * 3),
461 (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
2a163c6d
S
462 }
463
5e88ba62 464 len += scnprintf(buf + len, DMA_BUF_LEN - len, "\n");
2a163c6d 465
5e88ba62 466 len += scnprintf(buf + len, DMA_BUF_LEN - len,
2a163c6d
S
467 "qcu_stitch state: %2x qcu_fetch state: %2x\n",
468 (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
5e88ba62 469 len += scnprintf(buf + len, DMA_BUF_LEN - len,
2a163c6d
S
470 "qcu_complete state: %2x dcu_complete state: %2x\n",
471 (val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
5e88ba62 472 len += scnprintf(buf + len, DMA_BUF_LEN - len,
2a163c6d
S
473 "dcu_arb state: %2x dcu_fp state: %2x\n",
474 (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
5e88ba62 475 len += scnprintf(buf + len, DMA_BUF_LEN - len,
2a163c6d
S
476 "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n",
477 (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
5e88ba62 478 len += scnprintf(buf + len, DMA_BUF_LEN - len,
2a163c6d
S
479 "txfifo_valid_0: %1d txfifo_valid_1: %1d\n",
480 (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
5e88ba62 481 len += scnprintf(buf + len, DMA_BUF_LEN - len,
2a163c6d
S
482 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n",
483 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
484
5e88ba62
ZK
485 len += scnprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x\n",
486 REG_READ_D(ah, AR_OBS_BUS_1));
487 len += scnprintf(buf + len, DMA_BUF_LEN - len,
488 "AR_CR: 0x%x\n", REG_READ_D(ah, AR_CR));
2a163c6d 489
7cf4a2e7
S
490 ath9k_ps_restore(sc);
491
2b87f3aa
DC
492 if (len > DMA_BUF_LEN)
493 len = DMA_BUF_LEN;
494
991a0987
PR
495 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
496 kfree(buf);
497 return retval;
2a163c6d
S
498}
499
500static const struct file_operations fops_dma = {
501 .read = read_file_dma,
234e3405 502 .open = simple_open,
6038f373
AB
503 .owner = THIS_MODULE,
504 .llseek = default_llseek,
2a163c6d
S
505};
506
817e11de
S
507
508void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
509{
510 if (status)
17d7904d 511 sc->debug.stats.istats.total++;
a9616f41
LR
512 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
513 if (status & ATH9K_INT_RXLP)
514 sc->debug.stats.istats.rxlp++;
515 if (status & ATH9K_INT_RXHP)
516 sc->debug.stats.istats.rxhp++;
08578b8f
LR
517 if (status & ATH9K_INT_BB_WATCHDOG)
518 sc->debug.stats.istats.bb_watchdog++;
a9616f41
LR
519 } else {
520 if (status & ATH9K_INT_RX)
521 sc->debug.stats.istats.rxok++;
522 }
817e11de 523 if (status & ATH9K_INT_RXEOL)
17d7904d 524 sc->debug.stats.istats.rxeol++;
817e11de 525 if (status & ATH9K_INT_RXORN)
17d7904d 526 sc->debug.stats.istats.rxorn++;
817e11de 527 if (status & ATH9K_INT_TX)
17d7904d 528 sc->debug.stats.istats.txok++;
817e11de 529 if (status & ATH9K_INT_TXURN)
17d7904d 530 sc->debug.stats.istats.txurn++;
817e11de 531 if (status & ATH9K_INT_RXPHY)
17d7904d 532 sc->debug.stats.istats.rxphyerr++;
817e11de 533 if (status & ATH9K_INT_RXKCM)
17d7904d 534 sc->debug.stats.istats.rx_keycache_miss++;
817e11de 535 if (status & ATH9K_INT_SWBA)
17d7904d 536 sc->debug.stats.istats.swba++;
817e11de 537 if (status & ATH9K_INT_BMISS)
17d7904d 538 sc->debug.stats.istats.bmiss++;
817e11de 539 if (status & ATH9K_INT_BNR)
17d7904d 540 sc->debug.stats.istats.bnr++;
817e11de 541 if (status & ATH9K_INT_CST)
17d7904d 542 sc->debug.stats.istats.cst++;
817e11de 543 if (status & ATH9K_INT_GTT)
17d7904d 544 sc->debug.stats.istats.gtt++;
817e11de 545 if (status & ATH9K_INT_TIM)
17d7904d 546 sc->debug.stats.istats.tim++;
817e11de 547 if (status & ATH9K_INT_CABEND)
17d7904d 548 sc->debug.stats.istats.cabend++;
817e11de 549 if (status & ATH9K_INT_DTIMSYNC)
17d7904d 550 sc->debug.stats.istats.dtimsync++;
817e11de 551 if (status & ATH9K_INT_DTIM)
17d7904d 552 sc->debug.stats.istats.dtim++;
6dde1aab
MSS
553 if (status & ATH9K_INT_TSFOOR)
554 sc->debug.stats.istats.tsfoor++;
97ba515a
SM
555 if (status & ATH9K_INT_MCI)
556 sc->debug.stats.istats.mci++;
c9e6e980
MSS
557 if (status & ATH9K_INT_GENTIMER)
558 sc->debug.stats.istats.gen_timer++;
817e11de
S
559}
560
561static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
562 size_t count, loff_t *ppos)
563{
564 struct ath_softc *sc = file->private_data;
817e11de 565 unsigned int len = 0;
462e58f2
BG
566 int rv;
567 int mxlen = 4000;
568 char *buf = kmalloc(mxlen, GFP_KERNEL);
569 if (!buf)
570 return -ENOMEM;
571
572#define PR_IS(a, s) \
573 do { \
5e88ba62
ZK
574 len += scnprintf(buf + len, mxlen - len, \
575 "%21s: %10u\n", a, \
576 sc->debug.stats.istats.s); \
462e58f2 577 } while (0)
817e11de 578
a9616f41 579 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
462e58f2
BG
580 PR_IS("RXLP", rxlp);
581 PR_IS("RXHP", rxhp);
582 PR_IS("WATHDOG", bb_watchdog);
a9616f41 583 } else {
462e58f2 584 PR_IS("RX", rxok);
a9616f41 585 }
462e58f2
BG
586 PR_IS("RXEOL", rxeol);
587 PR_IS("RXORN", rxorn);
588 PR_IS("TX", txok);
589 PR_IS("TXURN", txurn);
590 PR_IS("MIB", mib);
591 PR_IS("RXPHY", rxphyerr);
592 PR_IS("RXKCM", rx_keycache_miss);
593 PR_IS("SWBA", swba);
594 PR_IS("BMISS", bmiss);
595 PR_IS("BNR", bnr);
596 PR_IS("CST", cst);
597 PR_IS("GTT", gtt);
598 PR_IS("TIM", tim);
599 PR_IS("CABEND", cabend);
600 PR_IS("DTIMSYNC", dtimsync);
601 PR_IS("DTIM", dtim);
602 PR_IS("TSFOOR", tsfoor);
97ba515a 603 PR_IS("MCI", mci);
c9e6e980 604 PR_IS("GENTIMER", gen_timer);
462e58f2
BG
605 PR_IS("TOTAL", total);
606
5e88ba62
ZK
607 len += scnprintf(buf + len, mxlen - len,
608 "SYNC_CAUSE stats:\n");
462e58f2
BG
609
610 PR_IS("Sync-All", sync_cause_all);
611 PR_IS("RTC-IRQ", sync_rtc_irq);
612 PR_IS("MAC-IRQ", sync_mac_irq);
613 PR_IS("EEPROM-Illegal-Access", eeprom_illegal_access);
614 PR_IS("APB-Timeout", apb_timeout);
615 PR_IS("PCI-Mode-Conflict", pci_mode_conflict);
616 PR_IS("HOST1-Fatal", host1_fatal);
617 PR_IS("HOST1-Perr", host1_perr);
618 PR_IS("TRCV-FIFO-Perr", trcv_fifo_perr);
619 PR_IS("RADM-CPL-EP", radm_cpl_ep);
620 PR_IS("RADM-CPL-DLLP-Abort", radm_cpl_dllp_abort);
621 PR_IS("RADM-CPL-TLP-Abort", radm_cpl_tlp_abort);
622 PR_IS("RADM-CPL-ECRC-Err", radm_cpl_ecrc_err);
623 PR_IS("RADM-CPL-Timeout", radm_cpl_timeout);
624 PR_IS("Local-Bus-Timeout", local_timeout);
625 PR_IS("PM-Access", pm_access);
626 PR_IS("MAC-Awake", mac_awake);
627 PR_IS("MAC-Asleep", mac_asleep);
628 PR_IS("MAC-Sleep-Access", mac_sleep_access);
629
630 if (len > mxlen)
631 len = mxlen;
632
633 rv = simple_read_from_buffer(user_buf, count, ppos, buf, len);
634 kfree(buf);
635 return rv;
817e11de
S
636}
637
638static const struct file_operations fops_interrupt = {
639 .read = read_file_interrupt,
234e3405 640 .open = simple_open,
6038f373
AB
641 .owner = THIS_MODULE,
642 .llseek = default_llseek,
817e11de
S
643};
644
fec247c0
S
645static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
646 size_t count, loff_t *ppos)
647{
648 struct ath_softc *sc = file->private_data;
649 char *buf;
78ef731c 650 unsigned int len = 0, size = 2048;
fec247c0
S
651 ssize_t retval = 0;
652
653 buf = kzalloc(size, GFP_KERNEL);
654 if (buf == NULL)
04236066 655 return -ENOMEM;
fec247c0 656
78ef731c 657 len += sprintf(buf, "%30s %10s%10s%10s\n\n",
7f010c93 658 "BE", "BK", "VI", "VO");
fec247c0
S
659
660 PR("MPDUs Queued: ", queued);
661 PR("MPDUs Completed: ", completed);
5a6f78af 662 PR("MPDUs XRetried: ", xretries);
fec247c0 663 PR("Aggregates: ", a_aggr);
bda8adda
BG
664 PR("AMPDUs Queued HW:", a_queued_hw);
665 PR("AMPDUs Queued SW:", a_queued_sw);
fec247c0
S
666 PR("AMPDUs Completed:", a_completed);
667 PR("AMPDUs Retried: ", a_retries);
668 PR("AMPDUs XRetried: ", a_xretries);
4d900389 669 PR("TXERR Filtered: ", txerr_filtered);
fec247c0
S
670 PR("FIFO Underrun: ", fifo_underrun);
671 PR("TXOP Exceeded: ", xtxop);
672 PR("TXTIMER Expiry: ", timer_exp);
673 PR("DESC CFG Error: ", desc_cfg_err);
674 PR("DATA Underrun: ", data_underrun);
675 PR("DELIM Underrun: ", delim_underrun);
99c15bf5
BG
676 PR("TX-Pkts-All: ", tx_pkts_all);
677 PR("TX-Bytes-All: ", tx_bytes_all);
78ef731c
SM
678 PR("HW-put-tx-buf: ", puttxbuf);
679 PR("HW-tx-start: ", txstart);
680 PR("HW-tx-proc-desc: ", txprocdesc);
a5a0bca1 681 PR("TX-Failed: ", txfailed);
71e025a5 682
7f010c93
BG
683 if (len > size)
684 len = size;
685
686 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
687 kfree(buf);
688
689 return retval;
690}
691
18fcf1c6
FF
692static ssize_t print_queue(struct ath_softc *sc, struct ath_txq *txq,
693 char *buf, ssize_t size)
694{
695 ssize_t len = 0;
696
697 ath_txq_lock(sc, txq);
698
5e88ba62
ZK
699 len += scnprintf(buf + len, size - len, "%s: %d ",
700 "qnum", txq->axq_qnum);
701 len += scnprintf(buf + len, size - len, "%s: %2d ",
702 "qdepth", txq->axq_depth);
703 len += scnprintf(buf + len, size - len, "%s: %2d ",
704 "ampdu-depth", txq->axq_ampdu_depth);
705 len += scnprintf(buf + len, size - len, "%s: %3d ",
706 "pending", txq->pending_frames);
707 len += scnprintf(buf + len, size - len, "%s: %d\n",
708 "stopped", txq->stopped);
18fcf1c6
FF
709
710 ath_txq_unlock(sc, txq);
711 return len;
712}
713
c0b74876
SM
714static ssize_t read_file_queues(struct file *file, char __user *user_buf,
715 size_t count, loff_t *ppos)
716{
717 struct ath_softc *sc = file->private_data;
718 struct ath_txq *txq;
719 char *buf;
2120ac96
JP
720 unsigned int len = 0;
721 const unsigned int size = 1024;
c0b74876
SM
722 ssize_t retval = 0;
723 int i;
2120ac96
JP
724 static const char *qname[4] = {
725 "VO", "VI", "BE", "BK"
726 };
c0b74876
SM
727
728 buf = kzalloc(size, GFP_KERNEL);
729 if (buf == NULL)
730 return -ENOMEM;
731
732 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
733 txq = sc->tx.txq_map[i];
5e88ba62 734 len += scnprintf(buf + len, size - len, "(%s): ", qname[i]);
18fcf1c6 735 len += print_queue(sc, txq, buf + len, size - len);
c0b74876
SM
736 }
737
5e88ba62 738 len += scnprintf(buf + len, size - len, "(CAB): ");
18fcf1c6
FF
739 len += print_queue(sc, sc->beacon.cabq, buf + len, size - len);
740
c0b74876
SM
741 if (len > size)
742 len = size;
743
744 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
745 kfree(buf);
746
747 return retval;
748}
749
55f6d0ff
BG
750static ssize_t read_file_misc(struct file *file, char __user *user_buf,
751 size_t count, loff_t *ppos)
752{
753 struct ath_softc *sc = file->private_data;
754 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
55f6d0ff 755 struct ieee80211_hw *hw = sc->hw;
6bcf6f64
SM
756 struct ath9k_vif_iter_data iter_data;
757 char buf[512];
758 unsigned int len = 0;
55f6d0ff 759 ssize_t retval = 0;
55f6d0ff 760 unsigned int reg;
6bcf6f64 761 u32 rxfilter;
55f6d0ff 762
5e88ba62
ZK
763 len += scnprintf(buf + len, sizeof(buf) - len,
764 "BSSID: %pM\n", common->curbssid);
765 len += scnprintf(buf + len, sizeof(buf) - len,
766 "BSSID-MASK: %pM\n", common->bssidmask);
767 len += scnprintf(buf + len, sizeof(buf) - len,
768 "OPMODE: %s\n",
769 ath_opmode_to_string(sc->sc_ah->opmode));
55f6d0ff 770
79d2b157 771 ath9k_ps_wakeup(sc);
6bcf6f64 772 rxfilter = ath9k_hw_getrxfilter(sc->sc_ah);
79d2b157 773 ath9k_ps_restore(sc);
6bcf6f64 774
5e88ba62
ZK
775 len += scnprintf(buf + len, sizeof(buf) - len,
776 "RXFILTER: 0x%x", rxfilter);
6bcf6f64
SM
777
778 if (rxfilter & ATH9K_RX_FILTER_UCAST)
5e88ba62 779 len += scnprintf(buf + len, sizeof(buf) - len, " UCAST");
6bcf6f64 780 if (rxfilter & ATH9K_RX_FILTER_MCAST)
5e88ba62 781 len += scnprintf(buf + len, sizeof(buf) - len, " MCAST");
6bcf6f64 782 if (rxfilter & ATH9K_RX_FILTER_BCAST)
5e88ba62 783 len += scnprintf(buf + len, sizeof(buf) - len, " BCAST");
6bcf6f64 784 if (rxfilter & ATH9K_RX_FILTER_CONTROL)
5e88ba62 785 len += scnprintf(buf + len, sizeof(buf) - len, " CONTROL");
6bcf6f64 786 if (rxfilter & ATH9K_RX_FILTER_BEACON)
5e88ba62 787 len += scnprintf(buf + len, sizeof(buf) - len, " BEACON");
6bcf6f64 788 if (rxfilter & ATH9K_RX_FILTER_PROM)
5e88ba62 789 len += scnprintf(buf + len, sizeof(buf) - len, " PROM");
6bcf6f64 790 if (rxfilter & ATH9K_RX_FILTER_PROBEREQ)
5e88ba62 791 len += scnprintf(buf + len, sizeof(buf) - len, " PROBEREQ");
6bcf6f64 792 if (rxfilter & ATH9K_RX_FILTER_PHYERR)
5e88ba62 793 len += scnprintf(buf + len, sizeof(buf) - len, " PHYERR");
6bcf6f64 794 if (rxfilter & ATH9K_RX_FILTER_MYBEACON)
5e88ba62 795 len += scnprintf(buf + len, sizeof(buf) - len, " MYBEACON");
6bcf6f64 796 if (rxfilter & ATH9K_RX_FILTER_COMP_BAR)
5e88ba62 797 len += scnprintf(buf + len, sizeof(buf) - len, " COMP_BAR");
6bcf6f64 798 if (rxfilter & ATH9K_RX_FILTER_PSPOLL)
5e88ba62 799 len += scnprintf(buf + len, sizeof(buf) - len, " PSPOLL");
6bcf6f64 800 if (rxfilter & ATH9K_RX_FILTER_PHYRADAR)
5e88ba62 801 len += scnprintf(buf + len, sizeof(buf) - len, " PHYRADAR");
6bcf6f64 802 if (rxfilter & ATH9K_RX_FILTER_MCAST_BCAST_ALL)
5e88ba62 803 len += scnprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL");
6bcf6f64 804 if (rxfilter & ATH9K_RX_FILTER_CONTROL_WRAPPER)
5e88ba62 805 len += scnprintf(buf + len, sizeof(buf) - len, " CONTROL_WRAPPER");
6bcf6f64 806
5e88ba62 807 len += scnprintf(buf + len, sizeof(buf) - len, "\n");
55f6d0ff
BG
808
809 reg = sc->sc_ah->imask;
6bcf6f64 810
5e88ba62
ZK
811 len += scnprintf(buf + len, sizeof(buf) - len,
812 "INTERRUPT-MASK: 0x%x", reg);
6bcf6f64 813
55f6d0ff 814 if (reg & ATH9K_INT_SWBA)
5e88ba62 815 len += scnprintf(buf + len, sizeof(buf) - len, " SWBA");
55f6d0ff 816 if (reg & ATH9K_INT_BMISS)
5e88ba62 817 len += scnprintf(buf + len, sizeof(buf) - len, " BMISS");
55f6d0ff 818 if (reg & ATH9K_INT_CST)
5e88ba62 819 len += scnprintf(buf + len, sizeof(buf) - len, " CST");
55f6d0ff 820 if (reg & ATH9K_INT_RX)
5e88ba62 821 len += scnprintf(buf + len, sizeof(buf) - len, " RX");
55f6d0ff 822 if (reg & ATH9K_INT_RXHP)
5e88ba62 823 len += scnprintf(buf + len, sizeof(buf) - len, " RXHP");
55f6d0ff 824 if (reg & ATH9K_INT_RXLP)
5e88ba62 825 len += scnprintf(buf + len, sizeof(buf) - len, " RXLP");
55f6d0ff 826 if (reg & ATH9K_INT_BB_WATCHDOG)
5e88ba62 827 len += scnprintf(buf + len, sizeof(buf) - len, " BB_WATCHDOG");
55f6d0ff 828
5e88ba62 829 len += scnprintf(buf + len, sizeof(buf) - len, "\n");
6bcf6f64
SM
830
831 ath9k_calculate_iter_data(hw, NULL, &iter_data);
832
5e88ba62
ZK
833 len += scnprintf(buf + len, sizeof(buf) - len,
834 "VIF-COUNTS: AP: %i STA: %i MESH: %i WDS: %i"
835 " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n",
836 iter_data.naps, iter_data.nstations, iter_data.nmeshes,
837 iter_data.nwds, iter_data.nadhocs,
838 sc->nvifs, sc->nbcnvifs);
55f6d0ff 839
6bcf6f64
SM
840 if (len > sizeof(buf))
841 len = sizeof(buf);
55f6d0ff
BG
842
843 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
55f6d0ff
BG
844 return retval;
845}
846
f8b815dc
SM
847static ssize_t read_file_reset(struct file *file, char __user *user_buf,
848 size_t count, loff_t *ppos)
849{
850 struct ath_softc *sc = file->private_data;
851 char buf[512];
852 unsigned int len = 0;
853
5e88ba62
ZK
854 len += scnprintf(buf + len, sizeof(buf) - len,
855 "%17s: %2d\n", "Baseband Hang",
856 sc->debug.stats.reset[RESET_TYPE_BB_HANG]);
857 len += scnprintf(buf + len, sizeof(buf) - len,
858 "%17s: %2d\n", "Baseband Watchdog",
859 sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG]);
860 len += scnprintf(buf + len, sizeof(buf) - len,
861 "%17s: %2d\n", "Fatal HW Error",
862 sc->debug.stats.reset[RESET_TYPE_FATAL_INT]);
863 len += scnprintf(buf + len, sizeof(buf) - len,
864 "%17s: %2d\n", "TX HW error",
865 sc->debug.stats.reset[RESET_TYPE_TX_ERROR]);
866 len += scnprintf(buf + len, sizeof(buf) - len,
867 "%17s: %2d\n", "TX Path Hang",
868 sc->debug.stats.reset[RESET_TYPE_TX_HANG]);
869 len += scnprintf(buf + len, sizeof(buf) - len,
870 "%17s: %2d\n", "PLL RX Hang",
871 sc->debug.stats.reset[RESET_TYPE_PLL_HANG]);
443626e5
FF
872 len += scnprintf(buf + len, sizeof(buf) - len,
873 "%17s: %2d\n", "MAC Hang",
874 sc->debug.stats.reset[RESET_TYPE_MAC_HANG]);
875 len += scnprintf(buf + len, sizeof(buf) - len,
876 "%17s: %2d\n", "Stuck Beacon",
877 sc->debug.stats.reset[RESET_TYPE_BEACON_STUCK]);
5e88ba62
ZK
878 len += scnprintf(buf + len, sizeof(buf) - len,
879 "%17s: %2d\n", "MCI Reset",
880 sc->debug.stats.reset[RESET_TYPE_MCI]);
f8b815dc
SM
881
882 if (len > sizeof(buf))
883 len = sizeof(buf);
884
885 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
886}
887
066dae93 888void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
55797b1a
FF
889 struct ath_tx_status *ts, struct ath_txq *txq,
890 unsigned int flags)
fec247c0 891{
5bec3e5a 892 int qnum = txq->axq_qnum;
066dae93
FF
893
894 TX_STAT_INC(qnum, tx_pkts_all);
895 sc->debug.stats.txstats[qnum].tx_bytes_all += bf->bf_mpdu->len;
99c15bf5 896
fec247c0 897 if (bf_isampdu(bf)) {
156369fa 898 if (flags & ATH_TX_ERROR)
066dae93 899 TX_STAT_INC(qnum, a_xretries);
fec247c0 900 else
066dae93 901 TX_STAT_INC(qnum, a_completed);
fec247c0 902 } else {
55797b1a 903 if (ts->ts_status & ATH9K_TXERR_XRETRY)
5a6f78af
FF
904 TX_STAT_INC(qnum, xretries);
905 else
906 TX_STAT_INC(qnum, completed);
fec247c0
S
907 }
908
4d900389
BG
909 if (ts->ts_status & ATH9K_TXERR_FILT)
910 TX_STAT_INC(qnum, txerr_filtered);
db1a052b 911 if (ts->ts_status & ATH9K_TXERR_FIFO)
066dae93 912 TX_STAT_INC(qnum, fifo_underrun);
db1a052b 913 if (ts->ts_status & ATH9K_TXERR_XTXOP)
066dae93 914 TX_STAT_INC(qnum, xtxop);
db1a052b 915 if (ts->ts_status & ATH9K_TXERR_TIMER_EXPIRED)
066dae93 916 TX_STAT_INC(qnum, timer_exp);
db1a052b 917 if (ts->ts_flags & ATH9K_TX_DESC_CFG_ERR)
066dae93 918 TX_STAT_INC(qnum, desc_cfg_err);
db1a052b 919 if (ts->ts_flags & ATH9K_TX_DATA_UNDERRUN)
066dae93 920 TX_STAT_INC(qnum, data_underrun);
db1a052b 921 if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN)
066dae93 922 TX_STAT_INC(qnum, delim_underrun);
fec247c0
S
923}
924
925static const struct file_operations fops_xmit = {
926 .read = read_file_xmit,
234e3405 927 .open = simple_open,
6038f373
AB
928 .owner = THIS_MODULE,
929 .llseek = default_llseek,
fec247c0 930};
39d89cd3 931
c0b74876
SM
932static const struct file_operations fops_queues = {
933 .read = read_file_queues,
934 .open = simple_open,
935 .owner = THIS_MODULE,
936 .llseek = default_llseek,
937};
938
55f6d0ff
BG
939static const struct file_operations fops_misc = {
940 .read = read_file_misc,
234e3405 941 .open = simple_open,
55f6d0ff
BG
942 .owner = THIS_MODULE,
943 .llseek = default_llseek,
944};
945
f8b815dc
SM
946static const struct file_operations fops_reset = {
947 .read = read_file_reset,
234e3405 948 .open = simple_open,
f8b815dc
SM
949 .owner = THIS_MODULE,
950 .llseek = default_llseek,
951};
952
1395d3f0
S
953static ssize_t read_file_recv(struct file *file, char __user *user_buf,
954 size_t count, loff_t *ppos)
955{
24a0731e
BG
956#define RXS_ERR(s, e) \
957 do { \
5e88ba62 958 len += scnprintf(buf + len, size - len, \
c3b9f9e8 959 "%18s : %10u\n", s, \
5e88ba62 960 sc->debug.stats.rxstats.e);\
24a0731e
BG
961 } while (0)
962
1395d3f0
S
963 struct ath_softc *sc = file->private_data;
964 char *buf;
4203214e 965 unsigned int len = 0, size = 1600;
1395d3f0
S
966 ssize_t retval = 0;
967
968 buf = kzalloc(size, GFP_KERNEL);
969 if (buf == NULL)
04236066 970 return -ENOMEM;
1395d3f0 971
c3b9f9e8
SM
972 RXS_ERR("PKTS-ALL", rx_pkts_all);
973 RXS_ERR("BYTES-ALL", rx_bytes_all);
974 RXS_ERR("BEACONS", rx_beacons);
975 RXS_ERR("FRAGS", rx_frags);
976 RXS_ERR("SPECTRAL", rx_spectral);
977
24a0731e
BG
978 RXS_ERR("CRC ERR", crc_err);
979 RXS_ERR("DECRYPT CRC ERR", decrypt_crc_err);
980 RXS_ERR("PHY ERR", phy_err);
981 RXS_ERR("MIC ERR", mic_err);
982 RXS_ERR("PRE-DELIM CRC ERR", pre_delim_crc_err);
983 RXS_ERR("POST-DELIM CRC ERR", post_delim_crc_err);
984 RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err);
c3b9f9e8
SM
985 RXS_ERR("LENGTH-ERR", rx_len_err);
986 RXS_ERR("OOM-ERR", rx_oom_err);
987 RXS_ERR("RATE-ERR", rx_rate_err);
988 RXS_ERR("TOO-MANY-FRAGS", rx_too_many_frags_err);
99c15bf5 989
2b87f3aa
DC
990 if (len > size)
991 len = size;
992
1395d3f0
S
993 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
994 kfree(buf);
995
996 return retval;
997
24a0731e 998#undef RXS_ERR
1395d3f0
S
999}
1000
8e6f5aa2 1001void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
1395d3f0 1002{
1395d3f0
S
1003#define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++
1004
99c15bf5
BG
1005 RX_STAT_INC(rx_pkts_all);
1006 sc->debug.stats.rxstats.rx_bytes_all += rs->rs_datalen;
1007
8e6f5aa2 1008 if (rs->rs_status & ATH9K_RXERR_CRC)
1395d3f0 1009 RX_STAT_INC(crc_err);
8e6f5aa2 1010 if (rs->rs_status & ATH9K_RXERR_DECRYPT)
1395d3f0 1011 RX_STAT_INC(decrypt_crc_err);
8e6f5aa2 1012 if (rs->rs_status & ATH9K_RXERR_MIC)
1395d3f0 1013 RX_STAT_INC(mic_err);
8e6f5aa2 1014 if (rs->rs_status & ATH9K_RX_DELIM_CRC_PRE)
1395d3f0 1015 RX_STAT_INC(pre_delim_crc_err);
8e6f5aa2 1016 if (rs->rs_status & ATH9K_RX_DELIM_CRC_POST)
1395d3f0 1017 RX_STAT_INC(post_delim_crc_err);
8e6f5aa2 1018 if (rs->rs_status & ATH9K_RX_DECRYPT_BUSY)
1395d3f0
S
1019 RX_STAT_INC(decrypt_busy_err);
1020
8e6f5aa2 1021 if (rs->rs_status & ATH9K_RXERR_PHY) {
1395d3f0 1022 RX_STAT_INC(phy_err);
dbb07f00
SM
1023 if (rs->rs_phyerr < ATH9K_PHYERR_MAX)
1024 RX_PHY_ERR_INC(rs->rs_phyerr);
1395d3f0
S
1025 }
1026
1395d3f0
S
1027#undef RX_PHY_ERR_INC
1028}
1029
1030static const struct file_operations fops_recv = {
1031 .read = read_file_recv,
234e3405 1032 .open = simple_open,
6038f373
AB
1033 .owner = THIS_MODULE,
1034 .llseek = default_llseek,
1395d3f0
S
1035};
1036
c3b9f9e8
SM
1037static ssize_t read_file_phy_err(struct file *file, char __user *user_buf,
1038 size_t count, loff_t *ppos)
1039{
1040#define PHY_ERR(s, p) \
1041 len += scnprintf(buf + len, size - len, "%22s : %10u\n", s, \
1042 sc->debug.stats.rxstats.phy_err_stats[p]);
1043
1044 struct ath_softc *sc = file->private_data;
1045 char *buf;
1046 unsigned int len = 0, size = 1600;
1047 ssize_t retval = 0;
1048
1049 buf = kzalloc(size, GFP_KERNEL);
1050 if (buf == NULL)
1051 return -ENOMEM;
1052
1053 PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
1054 PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING);
1055 PHY_ERR("PARITY ERR", ATH9K_PHYERR_PARITY);
1056 PHY_ERR("RATE ERR", ATH9K_PHYERR_RATE);
1057 PHY_ERR("LENGTH ERR", ATH9K_PHYERR_LENGTH);
1058 PHY_ERR("RADAR ERR", ATH9K_PHYERR_RADAR);
1059 PHY_ERR("SERVICE ERR", ATH9K_PHYERR_SERVICE);
1060 PHY_ERR("TOR ERR", ATH9K_PHYERR_TOR);
1061 PHY_ERR("OFDM-TIMING ERR", ATH9K_PHYERR_OFDM_TIMING);
1062 PHY_ERR("OFDM-SIGNAL-PARITY ERR", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
1063 PHY_ERR("OFDM-RATE ERR", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
1064 PHY_ERR("OFDM-LENGTH ERR", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
1065 PHY_ERR("OFDM-POWER-DROP ERR", ATH9K_PHYERR_OFDM_POWER_DROP);
1066 PHY_ERR("OFDM-SERVICE ERR", ATH9K_PHYERR_OFDM_SERVICE);
1067 PHY_ERR("OFDM-RESTART ERR", ATH9K_PHYERR_OFDM_RESTART);
1068 PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT);
1069 PHY_ERR("CCK-TIMING ERR", ATH9K_PHYERR_CCK_TIMING);
1070 PHY_ERR("CCK-HEADER-CRC ERR", ATH9K_PHYERR_CCK_HEADER_CRC);
1071 PHY_ERR("CCK-RATE ERR", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
1072 PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE);
1073 PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART);
1074 PHY_ERR("CCK-LENGTH ERR", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
1075 PHY_ERR("CCK-POWER-DROP ERR", ATH9K_PHYERR_CCK_POWER_DROP);
1076 PHY_ERR("HT-CRC ERR", ATH9K_PHYERR_HT_CRC_ERROR);
1077 PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
1078 PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL);
1079
1080 if (len > size)
1081 len = size;
1082
1083 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1084 kfree(buf);
1085
1086 return retval;
1087
1088#undef PHY_ERR
1089}
1090
1091static const struct file_operations fops_phy_err = {
1092 .read = read_file_phy_err,
1093 .open = simple_open,
1094 .owner = THIS_MODULE,
1095 .llseek = default_llseek,
1096};
1097
9bff0bc4
FF
1098static ssize_t read_file_regidx(struct file *file, char __user *user_buf,
1099 size_t count, loff_t *ppos)
1100{
1101 struct ath_softc *sc = file->private_data;
1102 char buf[32];
1103 unsigned int len;
1104
2b87f3aa 1105 len = sprintf(buf, "0x%08x\n", sc->debug.regidx);
9bff0bc4
FF
1106 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1107}
1108
1109static ssize_t write_file_regidx(struct file *file, const char __user *user_buf,
1110 size_t count, loff_t *ppos)
1111{
1112 struct ath_softc *sc = file->private_data;
1113 unsigned long regidx;
1114 char buf[32];
1115 ssize_t len;
1116
1117 len = min(count, sizeof(buf) - 1);
1118 if (copy_from_user(buf, user_buf, len))
04236066 1119 return -EFAULT;
9bff0bc4
FF
1120
1121 buf[len] = '\0';
27d7f477 1122 if (kstrtoul(buf, 0, &regidx))
9bff0bc4
FF
1123 return -EINVAL;
1124
1125 sc->debug.regidx = regidx;
1126 return count;
1127}
1128
1129static const struct file_operations fops_regidx = {
1130 .read = read_file_regidx,
1131 .write = write_file_regidx,
234e3405 1132 .open = simple_open,
6038f373
AB
1133 .owner = THIS_MODULE,
1134 .llseek = default_llseek,
9bff0bc4
FF
1135};
1136
1137static ssize_t read_file_regval(struct file *file, char __user *user_buf,
1138 size_t count, loff_t *ppos)
1139{
1140 struct ath_softc *sc = file->private_data;
1141 struct ath_hw *ah = sc->sc_ah;
1142 char buf[32];
1143 unsigned int len;
1144 u32 regval;
1145
79d2b157 1146 ath9k_ps_wakeup(sc);
9bff0bc4 1147 regval = REG_READ_D(ah, sc->debug.regidx);
79d2b157 1148 ath9k_ps_restore(sc);
2b87f3aa 1149 len = sprintf(buf, "0x%08x\n", regval);
9bff0bc4
FF
1150 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1151}
1152
1153static ssize_t write_file_regval(struct file *file, const char __user *user_buf,
1154 size_t count, loff_t *ppos)
1155{
1156 struct ath_softc *sc = file->private_data;
1157 struct ath_hw *ah = sc->sc_ah;
1158 unsigned long regval;
1159 char buf[32];
1160 ssize_t len;
1161
1162 len = min(count, sizeof(buf) - 1);
1163 if (copy_from_user(buf, user_buf, len))
04236066 1164 return -EFAULT;
9bff0bc4
FF
1165
1166 buf[len] = '\0';
27d7f477 1167 if (kstrtoul(buf, 0, &regval))
9bff0bc4
FF
1168 return -EINVAL;
1169
79d2b157 1170 ath9k_ps_wakeup(sc);
9bff0bc4 1171 REG_WRITE_D(ah, sc->debug.regidx, regval);
79d2b157 1172 ath9k_ps_restore(sc);
9bff0bc4
FF
1173 return count;
1174}
1175
1176static const struct file_operations fops_regval = {
1177 .read = read_file_regval,
1178 .write = write_file_regval,
234e3405 1179 .open = simple_open,
6038f373
AB
1180 .owner = THIS_MODULE,
1181 .llseek = default_llseek,
9bff0bc4
FF
1182};
1183
582d0064
VT
1184#define REGDUMP_LINE_SIZE 20
1185
1186static int open_file_regdump(struct inode *inode, struct file *file)
1187{
1188 struct ath_softc *sc = inode->i_private;
1189 unsigned int len = 0;
1190 u8 *buf;
1191 int i;
1192 unsigned long num_regs, regdump_len, max_reg_offset;
1193
1194 max_reg_offset = AR_SREV_9300_20_OR_LATER(sc->sc_ah) ? 0x16bd4 : 0xb500;
1195 num_regs = max_reg_offset / 4 + 1;
1196 regdump_len = num_regs * REGDUMP_LINE_SIZE + 1;
1197 buf = vmalloc(regdump_len);
1198 if (!buf)
1199 return -ENOMEM;
1200
1201 ath9k_ps_wakeup(sc);
1202 for (i = 0; i < num_regs; i++)
1203 len += scnprintf(buf + len, regdump_len - len,
1204 "0x%06x 0x%08x\n", i << 2, REG_READ(sc->sc_ah, i << 2));
1205 ath9k_ps_restore(sc);
1206
1207 file->private_data = buf;
1208
1209 return 0;
1210}
1211
1212static const struct file_operations fops_regdump = {
1213 .open = open_file_regdump,
1214 .read = ath9k_debugfs_read_buf,
1215 .release = ath9k_debugfs_release_buf,
1216 .owner = THIS_MODULE,
1217 .llseek = default_llseek,/* read accesses f_pos */
1218};
1219
d069a46b
RM
1220static ssize_t read_file_dump_nfcal(struct file *file, char __user *user_buf,
1221 size_t count, loff_t *ppos)
1222{
1223 struct ath_softc *sc = file->private_data;
1224 struct ath_hw *ah = sc->sc_ah;
1225 struct ath9k_nfcal_hist *h = sc->caldata.nfCalHist;
1226 struct ath_common *common = ath9k_hw_common(ah);
1227 struct ieee80211_conf *conf = &common->hw->conf;
1228 u32 len = 0, size = 1500;
1229 u32 i, j;
1230 ssize_t retval = 0;
1231 char *buf;
1232 u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
1233 u8 nread;
1234
1235 buf = kzalloc(size, GFP_KERNEL);
1236 if (!buf)
1237 return -ENOMEM;
1238
5e88ba62
ZK
1239 len += scnprintf(buf + len, size - len,
1240 "Channel Noise Floor : %d\n", ah->noise);
1241 len += scnprintf(buf + len, size - len,
1242 "Chain | privNF | # Readings | NF Readings\n");
d069a46b
RM
1243 for (i = 0; i < NUM_NF_READINGS; i++) {
1244 if (!(chainmask & (1 << i)) ||
1245 ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)))
1246 continue;
1247
1248 nread = AR_PHY_CCA_FILTERWINDOW_LENGTH - h[i].invalidNFcount;
5e88ba62
ZK
1249 len += scnprintf(buf + len, size - len, " %d\t %d\t %d\t\t",
1250 i, h[i].privNF, nread);
d069a46b 1251 for (j = 0; j < nread; j++)
5e88ba62
ZK
1252 len += scnprintf(buf + len, size - len,
1253 " %d", h[i].nfCalBuffer[j]);
1254 len += scnprintf(buf + len, size - len, "\n");
d069a46b
RM
1255 }
1256
1257 if (len > size)
1258 len = size;
1259
1260 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1261 kfree(buf);
1262
1263 return retval;
1264}
1265
1266static const struct file_operations fops_dump_nfcal = {
1267 .read = read_file_dump_nfcal,
234e3405 1268 .open = simple_open,
d069a46b
RM
1269 .owner = THIS_MODULE,
1270 .llseek = default_llseek,
1271};
1272
580f010f
RM
1273static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
1274 size_t count, loff_t *ppos)
1275{
1276 struct ath_softc *sc = file->private_data;
1277 struct ath_hw *ah = sc->sc_ah;
1278 u32 len = 0, size = 1500;
1279 ssize_t retval = 0;
1280 char *buf;
1281
1282 buf = kzalloc(size, GFP_KERNEL);
1283 if (!buf)
1284 return -ENOMEM;
1285
1286 len = ah->eep_ops->dump_eeprom(ah, true, buf, len, size);
1287
1288 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1289 kfree(buf);
1290
1291 return retval;
1292}
1293
1294static const struct file_operations fops_base_eeprom = {
1295 .read = read_file_base_eeprom,
234e3405 1296 .open = simple_open,
580f010f
RM
1297 .owner = THIS_MODULE,
1298 .llseek = default_llseek,
1299};
1300
3f4c4bdd
RM
1301static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf,
1302 size_t count, loff_t *ppos)
1303{
1304 struct ath_softc *sc = file->private_data;
1305 struct ath_hw *ah = sc->sc_ah;
1306 u32 len = 0, size = 6000;
1307 char *buf;
1308 size_t retval;
1309
1310 buf = kzalloc(size, GFP_KERNEL);
1311 if (buf == NULL)
1312 return -ENOMEM;
1313
1314 len = ah->eep_ops->dump_eeprom(ah, false, buf, len, size);
1315
1316 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1317 kfree(buf);
1318
1319 return retval;
1320}
1321
1322static const struct file_operations fops_modal_eeprom = {
1323 .read = read_file_modal_eeprom,
234e3405 1324 .open = simple_open,
3f4c4bdd
RM
1325 .owner = THIS_MODULE,
1326 .llseek = default_llseek,
1327};
1328
4df50ca8
RM
1329#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
1330static ssize_t read_file_btcoex(struct file *file, char __user *user_buf,
1331 size_t count, loff_t *ppos)
1332{
1333 struct ath_softc *sc = file->private_data;
1334 u32 len = 0, size = 1500;
1335 char *buf;
1336 size_t retval;
1337
1338 buf = kzalloc(size, GFP_KERNEL);
1339 if (buf == NULL)
1340 return -ENOMEM;
1341
ac46ba43 1342 if (!sc->sc_ah->common.btcoex_enabled) {
5e88ba62
ZK
1343 len = scnprintf(buf, size, "%s\n",
1344 "BTCOEX is disabled");
ac46ba43
SM
1345 goto exit;
1346 }
4df50ca8 1347
ac46ba43
SM
1348 len = ath9k_dump_btcoex(sc, buf, size);
1349exit:
4df50ca8
RM
1350 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1351 kfree(buf);
1352
1353 return retval;
1354}
1355
1356static const struct file_operations fops_btcoex = {
1357 .read = read_file_btcoex,
1358 .open = simple_open,
1359 .owner = THIS_MODULE,
1360 .llseek = default_llseek,
1361};
1362#endif
1363
c175db87
SM
1364/* Ethtool support for get-stats */
1365
1366#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
1367static const char ath9k_gstrings_stats[][ETH_GSTRING_LEN] = {
1368 "tx_pkts_nic",
1369 "tx_bytes_nic",
1370 "rx_pkts_nic",
1371 "rx_bytes_nic",
1372 AMKSTR(d_tx_pkts),
1373 AMKSTR(d_tx_bytes),
1374 AMKSTR(d_tx_mpdus_queued),
1375 AMKSTR(d_tx_mpdus_completed),
1376 AMKSTR(d_tx_mpdu_xretries),
1377 AMKSTR(d_tx_aggregates),
1378 AMKSTR(d_tx_ampdus_queued_hw),
1379 AMKSTR(d_tx_ampdus_queued_sw),
1380 AMKSTR(d_tx_ampdus_completed),
1381 AMKSTR(d_tx_ampdu_retries),
1382 AMKSTR(d_tx_ampdu_xretries),
1383 AMKSTR(d_tx_fifo_underrun),
1384 AMKSTR(d_tx_op_exceeded),
1385 AMKSTR(d_tx_timer_expiry),
1386 AMKSTR(d_tx_desc_cfg_err),
1387 AMKSTR(d_tx_data_underrun),
1388 AMKSTR(d_tx_delim_underrun),
18c45b10 1389 "d_rx_crc_err",
c175db87
SM
1390 "d_rx_decrypt_crc_err",
1391 "d_rx_phy_err",
1392 "d_rx_mic_err",
1393 "d_rx_pre_delim_crc_err",
1394 "d_rx_post_delim_crc_err",
1395 "d_rx_decrypt_busy_err",
1396
1397 "d_rx_phyerr_radar",
1398 "d_rx_phyerr_ofdm_timing",
1399 "d_rx_phyerr_cck_timing",
1400
1401};
1402#define ATH9K_SSTATS_LEN ARRAY_SIZE(ath9k_gstrings_stats)
1403
1404void ath9k_get_et_strings(struct ieee80211_hw *hw,
1405 struct ieee80211_vif *vif,
1406 u32 sset, u8 *data)
1407{
1408 if (sset == ETH_SS_STATS)
1409 memcpy(data, *ath9k_gstrings_stats,
1410 sizeof(ath9k_gstrings_stats));
1411}
1412
1413int ath9k_get_et_sset_count(struct ieee80211_hw *hw,
1414 struct ieee80211_vif *vif, int sset)
1415{
1416 if (sset == ETH_SS_STATS)
1417 return ATH9K_SSTATS_LEN;
1418 return 0;
1419}
1420
1421#define AWDATA(elem) \
1422 do { \
1423 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].elem; \
1424 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].elem; \
1425 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].elem; \
1426 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].elem; \
1427 } while (0)
1428
1429#define AWDATA_RX(elem) \
1430 do { \
1431 data[i++] = sc->debug.stats.rxstats.elem; \
1432 } while (0)
1433
1434void ath9k_get_et_stats(struct ieee80211_hw *hw,
1435 struct ieee80211_vif *vif,
1436 struct ethtool_stats *stats, u64 *data)
1437{
1438 struct ath_softc *sc = hw->priv;
1439 int i = 0;
1440
1441 data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_pkts_all +
1442 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_pkts_all +
1443 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_pkts_all +
1444 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_pkts_all);
1445 data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_bytes_all +
1446 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_bytes_all +
1447 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_bytes_all +
1448 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_bytes_all);
1449 AWDATA_RX(rx_pkts_all);
1450 AWDATA_RX(rx_bytes_all);
1451
1452 AWDATA(tx_pkts_all);
1453 AWDATA(tx_bytes_all);
1454 AWDATA(queued);
1455 AWDATA(completed);
1456 AWDATA(xretries);
1457 AWDATA(a_aggr);
1458 AWDATA(a_queued_hw);
1459 AWDATA(a_queued_sw);
1460 AWDATA(a_completed);
1461 AWDATA(a_retries);
1462 AWDATA(a_xretries);
1463 AWDATA(fifo_underrun);
1464 AWDATA(xtxop);
1465 AWDATA(timer_exp);
1466 AWDATA(desc_cfg_err);
1467 AWDATA(data_underrun);
1468 AWDATA(delim_underrun);
1469
18c45b10 1470 AWDATA_RX(crc_err);
c175db87
SM
1471 AWDATA_RX(decrypt_crc_err);
1472 AWDATA_RX(phy_err);
1473 AWDATA_RX(mic_err);
1474 AWDATA_RX(pre_delim_crc_err);
1475 AWDATA_RX(post_delim_crc_err);
1476 AWDATA_RX(decrypt_busy_err);
1477
1478 AWDATA_RX(phy_err_stats[ATH9K_PHYERR_RADAR]);
1479 AWDATA_RX(phy_err_stats[ATH9K_PHYERR_OFDM_TIMING]);
1480 AWDATA_RX(phy_err_stats[ATH9K_PHYERR_CCK_TIMING]);
1481
1482 WARN_ON(i != ATH9K_SSTATS_LEN);
1483}
1484
af690092
SM
1485void ath9k_deinit_debug(struct ath_softc *sc)
1486{
f65c0825 1487 ath9k_spectral_deinit_debug(sc);
af690092
SM
1488}
1489
4d6b228d 1490int ath9k_init_debug(struct ath_hw *ah)
88b126af 1491{
bc974f4a
LR
1492 struct ath_common *common = ath9k_hw_common(ah);
1493 struct ath_softc *sc = (struct ath_softc *) common->priv;
4d6b228d 1494
eb272441
BG
1495 sc->debug.debugfs_phy = debugfs_create_dir("ath9k",
1496 sc->hw->wiphy->debugfsdir);
17d7904d 1497 if (!sc->debug.debugfs_phy)
c8a72c00 1498 return -ENOMEM;
826d2680 1499
a830df07 1500#ifdef CONFIG_ATH_DEBUG
c70cab1a
FF
1501 debugfs_create_file("debug", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
1502 sc, &fops_debug);
a830df07 1503#endif
29942bc1
ZK
1504
1505 ath9k_dfs_init_debug(sc);
ef6b19e4 1506 ath9k_tx99_init_debug(sc);
f65c0825 1507 ath9k_spectral_init_debug(sc);
29942bc1 1508
c70cab1a
FF
1509 debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
1510 &fops_dma);
1511 debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
1512 &fops_interrupt);
c70cab1a
FF
1513 debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc,
1514 &fops_xmit);
c0b74876
SM
1515 debugfs_create_file("queues", S_IRUSR, sc->debug.debugfs_phy, sc,
1516 &fops_queues);
7702e788 1517 debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
bea843c7 1518 &sc->tx.txq_max_pending[IEEE80211_AC_BK]);
7702e788 1519 debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
bea843c7 1520 &sc->tx.txq_max_pending[IEEE80211_AC_BE]);
7702e788 1521 debugfs_create_u32("qlen_vi", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
bea843c7 1522 &sc->tx.txq_max_pending[IEEE80211_AC_VI]);
7702e788 1523 debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
bea843c7 1524 &sc->tx.txq_max_pending[IEEE80211_AC_VO]);
c70cab1a
FF
1525 debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc,
1526 &fops_misc);
f8b815dc
SM
1527 debugfs_create_file("reset", S_IRUSR, sc->debug.debugfs_phy, sc,
1528 &fops_reset);
c70cab1a
FF
1529 debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc,
1530 &fops_recv);
c3b9f9e8
SM
1531 debugfs_create_file("phy_err", S_IRUSR, sc->debug.debugfs_phy, sc,
1532 &fops_phy_err);
ca6d4a74
FF
1533 debugfs_create_u8("rx_chainmask", S_IRUSR, sc->debug.debugfs_phy,
1534 &ah->rxchainmask);
1535 debugfs_create_u8("tx_chainmask", S_IRUSR, sc->debug.debugfs_phy,
1536 &ah->txchainmask);
6e4d291e
SM
1537 debugfs_create_file("ani", S_IRUSR | S_IWUSR,
1538 sc->debug.debugfs_phy, sc, &fops_ani);
74673db9
FF
1539 debugfs_create_bool("paprd", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
1540 &sc->sc_ah->config.enable_paprd);
c70cab1a
FF
1541 debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
1542 sc, &fops_regidx);
1543 debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
1544 sc, &fops_regval);
1545 debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR,
1546 sc->debug.debugfs_phy,
1547 &ah->config.cwm_ignore_extcca);
1548 debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc,
1549 &fops_regdump);
d069a46b
RM
1550 debugfs_create_file("dump_nfcal", S_IRUSR, sc->debug.debugfs_phy, sc,
1551 &fops_dump_nfcal);
580f010f
RM
1552 debugfs_create_file("base_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
1553 &fops_base_eeprom);
3f4c4bdd
RM
1554 debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
1555 &fops_modal_eeprom);
691680b8
FF
1556 debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
1557 sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
691680b8
FF
1558 debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
1559 sc->debug.debugfs_phy, &sc->sc_ah->gpio_val);
4eba10cc
SM
1560 debugfs_create_file("antenna_diversity", S_IRUSR,
1561 sc->debug.debugfs_phy, sc, &fops_antenna_diversity);
4df50ca8 1562#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
36e8825e
SM
1563 debugfs_create_file("bt_ant_diversity", S_IRUSR | S_IWUSR,
1564 sc->debug.debugfs_phy, sc, &fops_bt_ant_diversity);
4df50ca8
RM
1565 debugfs_create_file("btcoex", S_IRUSR, sc->debug.debugfs_phy, sc,
1566 &fops_btcoex);
1567#endif
89f927af 1568
826d2680 1569 return 0;
88b126af 1570}