aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/htc_drv_debug.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_debug.c505
1 files changed, 505 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
new file mode 100644
index 00000000000..eca777497fe
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
@@ -0,0 +1,505 @@
1/*
2 * Copyright (c) 2010-2011 Atheros Communications Inc.
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
17#include "htc.h"
18
19static int ath9k_debugfs_open(struct inode *inode, struct file *file)
20{
21 file->private_data = inode->i_private;
22 return 0;
23}
24
25static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf,
26 size_t count, loff_t *ppos)
27{
28 struct ath9k_htc_priv *priv = file->private_data;
29 struct ath9k_htc_target_int_stats cmd_rsp;
30 char buf[512];
31 unsigned int len = 0;
32 int ret = 0;
33
34 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
35
36 WMI_CMD(WMI_INT_STATS_CMDID);
37 if (ret)
38 return -EINVAL;
39
40 len += snprintf(buf + len, sizeof(buf) - len,
41 "%20s : %10u\n", "RX",
42 be32_to_cpu(cmd_rsp.rx));
43
44 len += snprintf(buf + len, sizeof(buf) - len,
45 "%20s : %10u\n", "RXORN",
46 be32_to_cpu(cmd_rsp.rxorn));
47
48 len += snprintf(buf + len, sizeof(buf) - len,
49 "%20s : %10u\n", "RXEOL",
50 be32_to_cpu(cmd_rsp.rxeol));
51
52 len += snprintf(buf + len, sizeof(buf) - len,
53 "%20s : %10u\n", "TXURN",
54 be32_to_cpu(cmd_rsp.txurn));
55
56 len += snprintf(buf + len, sizeof(buf) - len,
57 "%20s : %10u\n", "TXTO",
58 be32_to_cpu(cmd_rsp.txto));
59
60 len += snprintf(buf + len, sizeof(buf) - len,
61 "%20s : %10u\n", "CST",
62 be32_to_cpu(cmd_rsp.cst));
63
64 if (len > sizeof(buf))
65 len = sizeof(buf);
66
67 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
68}
69
70static const struct file_operations fops_tgt_int_stats = {
71 .read = read_file_tgt_int_stats,
72 .open = ath9k_debugfs_open,
73 .owner = THIS_MODULE,
74 .llseek = default_llseek,
75};
76
77static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf,
78 size_t count, loff_t *ppos)
79{
80 struct ath9k_htc_priv *priv = file->private_data;
81 struct ath9k_htc_target_tx_stats cmd_rsp;
82 char buf[512];
83 unsigned int len = 0;
84 int ret = 0;
85
86 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
87
88 WMI_CMD(WMI_TX_STATS_CMDID);
89 if (ret)
90 return -EINVAL;
91
92 len += snprintf(buf + len, sizeof(buf) - len,
93 "%20s : %10u\n", "Xretries",
94 be32_to_cpu(cmd_rsp.xretries));
95
96 len += snprintf(buf + len, sizeof(buf) - len,
97 "%20s : %10u\n", "FifoErr",
98 be32_to_cpu(cmd_rsp.fifoerr));
99
100 len += snprintf(buf + len, sizeof(buf) - len,
101 "%20s : %10u\n", "Filtered",
102 be32_to_cpu(cmd_rsp.filtered));
103
104 len += snprintf(buf + len, sizeof(buf) - len,
105 "%20s : %10u\n", "TimerExp",
106 be32_to_cpu(cmd_rsp.timer_exp));
107
108 len += snprintf(buf + len, sizeof(buf) - len,
109 "%20s : %10u\n", "ShortRetries",
110 be32_to_cpu(cmd_rsp.shortretries));
111
112 len += snprintf(buf + len, sizeof(buf) - len,
113 "%20s : %10u\n", "LongRetries",
114 be32_to_cpu(cmd_rsp.longretries));
115
116 len += snprintf(buf + len, sizeof(buf) - len,
117 "%20s : %10u\n", "QueueNull",
118 be32_to_cpu(cmd_rsp.qnull));
119
120 len += snprintf(buf + len, sizeof(buf) - len,
121 "%20s : %10u\n", "EncapFail",
122 be32_to_cpu(cmd_rsp.encap_fail));
123
124 len += snprintf(buf + len, sizeof(buf) - len,
125 "%20s : %10u\n", "NoBuf",
126 be32_to_cpu(cmd_rsp.nobuf));
127
128 if (len > sizeof(buf))
129 len = sizeof(buf);
130
131 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
132}
133
134static const struct file_operations fops_tgt_tx_stats = {
135 .read = read_file_tgt_tx_stats,
136 .open = ath9k_debugfs_open,
137 .owner = THIS_MODULE,
138 .llseek = default_llseek,
139};
140
141static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf,
142 size_t count, loff_t *ppos)
143{
144 struct ath9k_htc_priv *priv = file->private_data;
145 struct ath9k_htc_target_rx_stats cmd_rsp;
146 char buf[512];
147 unsigned int len = 0;
148 int ret = 0;
149
150 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
151
152 WMI_CMD(WMI_RX_STATS_CMDID);
153 if (ret)
154 return -EINVAL;
155
156 len += snprintf(buf + len, sizeof(buf) - len,
157 "%20s : %10u\n", "NoBuf",
158 be32_to_cpu(cmd_rsp.nobuf));
159
160 len += snprintf(buf + len, sizeof(buf) - len,
161 "%20s : %10u\n", "HostSend",
162 be32_to_cpu(cmd_rsp.host_send));
163
164 len += snprintf(buf + len, sizeof(buf) - len,
165 "%20s : %10u\n", "HostDone",
166 be32_to_cpu(cmd_rsp.host_done));
167
168 if (len > sizeof(buf))
169 len = sizeof(buf);
170
171 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
172}
173
174static const struct file_operations fops_tgt_rx_stats = {
175 .read = read_file_tgt_rx_stats,
176 .open = ath9k_debugfs_open,
177 .owner = THIS_MODULE,
178 .llseek = default_llseek,
179};
180
181static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
182 size_t count, loff_t *ppos)
183{
184 struct ath9k_htc_priv *priv = file->private_data;
185 char buf[512];
186 unsigned int len = 0;
187
188 len += snprintf(buf + len, sizeof(buf) - len,
189 "%20s : %10u\n", "Buffers queued",
190 priv->debug.tx_stats.buf_queued);
191 len += snprintf(buf + len, sizeof(buf) - len,
192 "%20s : %10u\n", "Buffers completed",
193 priv->debug.tx_stats.buf_completed);
194 len += snprintf(buf + len, sizeof(buf) - len,
195 "%20s : %10u\n", "SKBs queued",
196 priv->debug.tx_stats.skb_queued);
197 len += snprintf(buf + len, sizeof(buf) - len,
198 "%20s : %10u\n", "SKBs success",
199 priv->debug.tx_stats.skb_success);
200 len += snprintf(buf + len, sizeof(buf) - len,
201 "%20s : %10u\n", "SKBs failed",
202 priv->debug.tx_stats.skb_failed);
203 len += snprintf(buf + len, sizeof(buf) - len,
204 "%20s : %10u\n", "CAB queued",
205 priv->debug.tx_stats.cab_queued);
206
207 len += snprintf(buf + len, sizeof(buf) - len,
208 "%20s : %10u\n", "BE queued",
209 priv->debug.tx_stats.queue_stats[WME_AC_BE]);
210 len += snprintf(buf + len, sizeof(buf) - len,
211 "%20s : %10u\n", "BK queued",
212 priv->debug.tx_stats.queue_stats[WME_AC_BK]);
213 len += snprintf(buf + len, sizeof(buf) - len,
214 "%20s : %10u\n", "VI queued",
215 priv->debug.tx_stats.queue_stats[WME_AC_VI]);
216 len += snprintf(buf + len, sizeof(buf) - len,
217 "%20s : %10u\n", "VO queued",
218 priv->debug.tx_stats.queue_stats[WME_AC_VO]);
219
220 if (len > sizeof(buf))
221 len = sizeof(buf);
222
223 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
224}
225
226static const struct file_operations fops_xmit = {
227 .read = read_file_xmit,
228 .open = ath9k_debugfs_open,
229 .owner = THIS_MODULE,
230 .llseek = default_llseek,
231};
232
233void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
234 struct ath_htc_rx_status *rxs)
235{
236#define RX_PHY_ERR_INC(c) priv->debug.rx_stats.err_phy_stats[c]++
237
238 if (rxs->rs_status & ATH9K_RXERR_CRC)
239 priv->debug.rx_stats.err_crc++;
240 if (rxs->rs_status & ATH9K_RXERR_DECRYPT)
241 priv->debug.rx_stats.err_decrypt_crc++;
242 if (rxs->rs_status & ATH9K_RXERR_MIC)
243 priv->debug.rx_stats.err_mic++;
244 if (rxs->rs_status & ATH9K_RX_DELIM_CRC_PRE)
245 priv->debug.rx_stats.err_pre_delim++;
246 if (rxs->rs_status & ATH9K_RX_DELIM_CRC_POST)
247 priv->debug.rx_stats.err_post_delim++;
248 if (rxs->rs_status & ATH9K_RX_DECRYPT_BUSY)
249 priv->debug.rx_stats.err_decrypt_busy++;
250
251 if (rxs->rs_status & ATH9K_RXERR_PHY) {
252 priv->debug.rx_stats.err_phy++;
253 if (rxs->rs_phyerr < ATH9K_PHYERR_MAX)
254 RX_PHY_ERR_INC(rxs->rs_phyerr);
255 }
256
257#undef RX_PHY_ERR_INC
258}
259
260static ssize_t read_file_recv(struct file *file, char __user *user_buf,
261 size_t count, loff_t *ppos)
262{
263#define PHY_ERR(s, p) \
264 len += snprintf(buf + len, size - len, "%20s : %10u\n", s, \
265 priv->debug.rx_stats.err_phy_stats[p]);
266
267 struct ath9k_htc_priv *priv = file->private_data;
268 char *buf;
269 unsigned int len = 0, size = 1500;
270 ssize_t retval = 0;
271
272 buf = kzalloc(size, GFP_KERNEL);
273 if (buf == NULL)
274 return -ENOMEM;
275
276 len += snprintf(buf + len, size - len,
277 "%20s : %10u\n", "SKBs allocated",
278 priv->debug.rx_stats.skb_allocated);
279 len += snprintf(buf + len, size - len,
280 "%20s : %10u\n", "SKBs completed",
281 priv->debug.rx_stats.skb_completed);
282 len += snprintf(buf + len, size - len,
283 "%20s : %10u\n", "SKBs Dropped",
284 priv->debug.rx_stats.skb_dropped);
285
286 len += snprintf(buf + len, size - len,
287 "%20s : %10u\n", "CRC ERR",
288 priv->debug.rx_stats.err_crc);
289 len += snprintf(buf + len, size - len,
290 "%20s : %10u\n", "DECRYPT CRC ERR",
291 priv->debug.rx_stats.err_decrypt_crc);
292 len += snprintf(buf + len, size - len,
293 "%20s : %10u\n", "MIC ERR",
294 priv->debug.rx_stats.err_mic);
295 len += snprintf(buf + len, size - len,
296 "%20s : %10u\n", "PRE-DELIM CRC ERR",
297 priv->debug.rx_stats.err_pre_delim);
298 len += snprintf(buf + len, size - len,
299 "%20s : %10u\n", "POST-DELIM CRC ERR",
300 priv->debug.rx_stats.err_post_delim);
301 len += snprintf(buf + len, size - len,
302 "%20s : %10u\n", "DECRYPT BUSY ERR",
303 priv->debug.rx_stats.err_decrypt_busy);
304 len += snprintf(buf + len, size - len,
305 "%20s : %10u\n", "TOTAL PHY ERR",
306 priv->debug.rx_stats.err_phy);
307
308
309 PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN);
310 PHY_ERR("TIMING", ATH9K_PHYERR_TIMING);
311 PHY_ERR("PARITY", ATH9K_PHYERR_PARITY);
312 PHY_ERR("RATE", ATH9K_PHYERR_RATE);
313 PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH);
314 PHY_ERR("RADAR", ATH9K_PHYERR_RADAR);
315 PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE);
316 PHY_ERR("TOR", ATH9K_PHYERR_TOR);
317 PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING);
318 PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
319 PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
320 PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
321 PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP);
322 PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE);
323 PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART);
324 PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT);
325 PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING);
326 PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC);
327 PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
328 PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE);
329 PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART);
330 PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
331 PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP);
332 PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR);
333 PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
334 PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL);
335
336 if (len > size)
337 len = size;
338
339 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
340 kfree(buf);
341
342 return retval;
343
344#undef PHY_ERR
345}
346
347static const struct file_operations fops_recv = {
348 .read = read_file_recv,
349 .open = ath9k_debugfs_open,
350 .owner = THIS_MODULE,
351 .llseek = default_llseek,
352};
353
354static ssize_t read_file_slot(struct file *file, char __user *user_buf,
355 size_t count, loff_t *ppos)
356{
357 struct ath9k_htc_priv *priv = file->private_data;
358 char buf[512];
359 unsigned int len = 0;
360
361 spin_lock_bh(&priv->tx.tx_lock);
362
363 len += snprintf(buf + len, sizeof(buf) - len, "TX slot bitmap : ");
364
365 len += bitmap_scnprintf(buf + len, sizeof(buf) - len,
366 priv->tx.tx_slot, MAX_TX_BUF_NUM);
367
368 len += snprintf(buf + len, sizeof(buf) - len, "\n");
369
370 len += snprintf(buf + len, sizeof(buf) - len,
371 "Used slots : %d\n",
372 bitmap_weight(priv->tx.tx_slot, MAX_TX_BUF_NUM));
373
374 spin_unlock_bh(&priv->tx.tx_lock);
375
376 if (len > sizeof(buf))
377 len = sizeof(buf);
378
379 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
380}
381
382static const struct file_operations fops_slot = {
383 .read = read_file_slot,
384 .open = ath9k_debugfs_open,
385 .owner = THIS_MODULE,
386 .llseek = default_llseek,
387};
388
389static ssize_t read_file_queue(struct file *file, char __user *user_buf,
390 size_t count, loff_t *ppos)
391{
392 struct ath9k_htc_priv *priv = file->private_data;
393 char buf[512];
394 unsigned int len = 0;
395
396 len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
397 "Mgmt endpoint", skb_queue_len(&priv->tx.mgmt_ep_queue));
398
399 len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
400 "Cab endpoint", skb_queue_len(&priv->tx.cab_ep_queue));
401
402 len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
403 "Data BE endpoint", skb_queue_len(&priv->tx.data_be_queue));
404
405 len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
406 "Data BK endpoint", skb_queue_len(&priv->tx.data_bk_queue));
407
408 len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
409 "Data VI endpoint", skb_queue_len(&priv->tx.data_vi_queue));
410
411 len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
412 "Data VO endpoint", skb_queue_len(&priv->tx.data_vo_queue));
413
414 len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
415 "Failed queue", skb_queue_len(&priv->tx.tx_failed));
416
417 spin_lock_bh(&priv->tx.tx_lock);
418 len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
419 "Queued count", priv->tx.queued_cnt);
420 spin_unlock_bh(&priv->tx.tx_lock);
421
422 if (len > sizeof(buf))
423 len = sizeof(buf);
424
425 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
426
427}
428
429static const struct file_operations fops_queue = {
430 .read = read_file_queue,
431 .open = ath9k_debugfs_open,
432 .owner = THIS_MODULE,
433 .llseek = default_llseek,
434};
435
436static ssize_t read_file_debug(struct file *file, char __user *user_buf,
437 size_t count, loff_t *ppos)
438{
439 struct ath9k_htc_priv *priv = file->private_data;
440 struct ath_common *common = ath9k_hw_common(priv->ah);
441 char buf[32];
442 unsigned int len;
443
444 len = sprintf(buf, "0x%08x\n", common->debug_mask);
445 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
446}
447
448static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
449 size_t count, loff_t *ppos)
450{
451 struct ath9k_htc_priv *priv = file->private_data;
452 struct ath_common *common = ath9k_hw_common(priv->ah);
453 unsigned long mask;
454 char buf[32];
455 ssize_t len;
456
457 len = min(count, sizeof(buf) - 1);
458 if (copy_from_user(buf, user_buf, len))
459 return -EFAULT;
460
461 buf[len] = '\0';
462 if (strict_strtoul(buf, 0, &mask))
463 return -EINVAL;
464
465 common->debug_mask = mask;
466 return count;
467}
468
469static const struct file_operations fops_debug = {
470 .read = read_file_debug,
471 .write = write_file_debug,
472 .open = ath9k_debugfs_open,
473 .owner = THIS_MODULE,
474 .llseek = default_llseek,
475};
476
477int ath9k_htc_init_debug(struct ath_hw *ah)
478{
479 struct ath_common *common = ath9k_hw_common(ah);
480 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
481
482 priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME,
483 priv->hw->wiphy->debugfsdir);
484 if (!priv->debug.debugfs_phy)
485 return -ENOMEM;
486
487 debugfs_create_file("tgt_int_stats", S_IRUSR, priv->debug.debugfs_phy,
488 priv, &fops_tgt_int_stats);
489 debugfs_create_file("tgt_tx_stats", S_IRUSR, priv->debug.debugfs_phy,
490 priv, &fops_tgt_tx_stats);
491 debugfs_create_file("tgt_rx_stats", S_IRUSR, priv->debug.debugfs_phy,
492 priv, &fops_tgt_rx_stats);
493 debugfs_create_file("xmit", S_IRUSR, priv->debug.debugfs_phy,
494 priv, &fops_xmit);
495 debugfs_create_file("recv", S_IRUSR, priv->debug.debugfs_phy,
496 priv, &fops_recv);
497 debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy,
498 priv, &fops_slot);
499 debugfs_create_file("queue", S_IRUSR, priv->debug.debugfs_phy,
500 priv, &fops_queue);
501 debugfs_create_file("debug", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy,
502 priv, &fops_debug);
503
504 return 0;
505}