Merge ath-next from ath.git
[linux-2.6-block.git] / drivers / net / wireless / ath / ath10k / debug.c
CommitLineData
5e3dd157
KV
1/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <linux/module.h>
19#include <linux/debugfs.h>
384914b2 20#include <linux/vmalloc.h>
12c27156 21#include <linux/utsname.h>
3e58044b
KV
22#include <linux/crc32.h>
23#include <linux/firmware.h>
5e3dd157
KV
24
25#include "core.h"
26#include "debug.h"
7869b4fa 27#include "hif.h"
d7579d12 28#include "wmi-ops.h"
5e3dd157 29
a3d135e5
KV
30/* ms */
31#define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000
32
384914b2
BG
33#define ATH10K_FW_CRASH_DUMP_VERSION 1
34
35/**
36 * enum ath10k_fw_crash_dump_type - types of data in the dump file
37 * @ATH10K_FW_CRASH_DUMP_REGDUMP: Register crash dump in binary format
38 */
39enum ath10k_fw_crash_dump_type {
40 ATH10K_FW_CRASH_DUMP_REGISTERS = 0,
41
42 ATH10K_FW_CRASH_DUMP_MAX,
43};
44
45struct ath10k_tlv_dump_data {
46 /* see ath10k_fw_crash_dump_type above */
47 __le32 type;
48
49 /* in bytes */
50 __le32 tlv_len;
51
52 /* pad to 32-bit boundaries as needed */
53 u8 tlv_data[];
54} __packed;
55
56struct ath10k_dump_file_data {
57 /* dump file information */
58
59 /* "ATH10K-FW-DUMP" */
60 char df_magic[16];
61
62 __le32 len;
63
64 /* file dump version */
65 __le32 version;
66
67 /* some info we can get from ath10k struct that might help */
68
69 u8 uuid[16];
70
71 __le32 chip_id;
72
73 /* 0 for now, in place for later hardware */
74 __le32 bus_type;
75
76 __le32 target_version;
77 __le32 fw_version_major;
78 __le32 fw_version_minor;
79 __le32 fw_version_release;
80 __le32 fw_version_build;
81 __le32 phy_capability;
82 __le32 hw_min_tx_power;
83 __le32 hw_max_tx_power;
84 __le32 ht_cap_info;
85 __le32 vht_cap_info;
86 __le32 num_rf_chains;
87
88 /* firmware version string */
89 char fw_ver[ETHTOOL_FWVERS_LEN];
90
91 /* Kernel related information */
92
93 /* time-of-day stamp */
94 __le64 tv_sec;
95
96 /* time-of-day stamp, nano-seconds */
97 __le64 tv_nsec;
98
99 /* LINUX_VERSION_CODE */
100 __le32 kernel_ver_code;
101
102 /* VERMAGIC_STRING */
103 char kernel_ver[64];
104
105 /* room for growth w/out changing binary format */
106 u8 unused[128];
107
108 /* struct ath10k_tlv_dump_data + more */
109 u8 data[0];
110} __packed;
111
babcb3ed 112void ath10k_info(struct ath10k *ar, const char *fmt, ...)
5e3dd157
KV
113{
114 struct va_format vaf = {
115 .fmt = fmt,
116 };
117 va_list args;
5e3dd157
KV
118
119 va_start(args, fmt);
120 vaf.va = &args;
babcb3ed 121 dev_info(ar->dev, "%pV", &vaf);
d35a6c18 122 trace_ath10k_log_info(ar, &vaf);
5e3dd157 123 va_end(args);
5e3dd157
KV
124}
125EXPORT_SYMBOL(ath10k_info);
126
23f591ea 127void ath10k_debug_print_hwfw_info(struct ath10k *ar)
8a0c797e 128{
84e3df60 129 char fw_features[128] = {};
8866c727 130 u32 crc = 0;
b27bc5a4
MK
131
132 ath10k_core_get_fw_features_str(ar, fw_features, sizeof(fw_features));
133
8605c022 134 ath10k_info(ar, "%s target 0x%08x chip_id 0x%08x sub %04x:%04x",
8a0c797e
KV
135 ar->hw_params.name,
136 ar->target_version,
137 ar->chip_id,
8605c022 138 ar->id.subsystem_vendor, ar->id.subsystem_device);
f0de90bc 139
23f591ea
KV
140 ath10k_info(ar, "kconfig debug %d debugfs %d tracing %d dfs %d testmode %d\n",
141 config_enabled(CONFIG_ATH10K_DEBUG),
142 config_enabled(CONFIG_ATH10K_DEBUGFS),
143 config_enabled(CONFIG_ATH10K_TRACING),
144 config_enabled(CONFIG_ATH10K_DFS_CERTIFIED),
145 config_enabled(CONFIG_NL80211_TESTMODE));
146
8866c727
MK
147 if (ar->firmware)
148 crc = crc32_le(0, ar->firmware->data, ar->firmware->size);
149
3e58044b 150 ath10k_info(ar, "firmware ver %s api %d features %s crc32 %08x\n",
8a0c797e
KV
151 ar->hw->wiphy->fw_version,
152 ar->fw_api,
3e58044b 153 fw_features,
8866c727 154 crc);
23f591ea
KV
155}
156
157void ath10k_debug_print_board_info(struct ath10k *ar)
158{
159 char boardinfo[100];
160
161 if (ar->id.bmi_ids_valid)
162 scnprintf(boardinfo, sizeof(boardinfo), "%d:%d",
163 ar->id.bmi_chip_id, ar->id.bmi_board_id);
164 else
165 scnprintf(boardinfo, sizeof(boardinfo), "N/A");
f0de90bc 166
3e58044b 167 ath10k_info(ar, "board_file api %d bmi_id %s crc32 %08x",
8605c022 168 ar->bd_api,
3e58044b
KV
169 boardinfo,
170 crc32_le(0, ar->board->data, ar->board->size));
23f591ea 171}
f0de90bc 172
23f591ea
KV
173void ath10k_debug_print_boot_info(struct ath10k *ar)
174{
f0de90bc 175 ath10k_info(ar, "htt-ver %d.%d wmi-op %d htt-op %d cal %s max-sta %d raw %d hwcrypto %d\n",
8a0c797e 176 ar->htt.target_version_major,
34b28b6e 177 ar->htt.target_version_minor,
ffdd0757 178 ar->wmi.op_version,
67c81f5a 179 ar->htt.op_version,
cfd1061e 180 ath10k_cal_mode_str(ar->cal_mode),
b27bc5a4 181 ar->max_num_stations,
ccec9038 182 test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags),
f0de90bc 183 !test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags));
8a0c797e 184}
23f591ea
KV
185
186void ath10k_print_driver_info(struct ath10k *ar)
187{
188 ath10k_debug_print_hwfw_info(ar);
189 ath10k_debug_print_board_info(ar);
190 ath10k_debug_print_boot_info(ar);
191}
8a0c797e
KV
192EXPORT_SYMBOL(ath10k_print_driver_info);
193
babcb3ed 194void ath10k_err(struct ath10k *ar, const char *fmt, ...)
5e3dd157
KV
195{
196 struct va_format vaf = {
197 .fmt = fmt,
198 };
199 va_list args;
5e3dd157
KV
200
201 va_start(args, fmt);
202 vaf.va = &args;
babcb3ed 203 dev_err(ar->dev, "%pV", &vaf);
d35a6c18 204 trace_ath10k_log_err(ar, &vaf);
5e3dd157 205 va_end(args);
5e3dd157
KV
206}
207EXPORT_SYMBOL(ath10k_err);
208
babcb3ed 209void ath10k_warn(struct ath10k *ar, const char *fmt, ...)
5e3dd157
KV
210{
211 struct va_format vaf = {
212 .fmt = fmt,
213 };
214 va_list args;
5e3dd157
KV
215
216 va_start(args, fmt);
217 vaf.va = &args;
7aa7a72a 218 dev_warn_ratelimited(ar->dev, "%pV", &vaf);
d35a6c18 219 trace_ath10k_log_warn(ar, &vaf);
5e3dd157
KV
220
221 va_end(args);
5e3dd157
KV
222}
223EXPORT_SYMBOL(ath10k_warn);
224
225#ifdef CONFIG_ATH10K_DEBUGFS
226
5e3dd157
KV
227static ssize_t ath10k_read_wmi_services(struct file *file,
228 char __user *user_buf,
229 size_t count, loff_t *ppos)
230{
231 struct ath10k *ar = file->private_data;
232 char *buf;
cff990ce
MK
233 unsigned int len = 0, buf_len = 4096;
234 const char *name;
5e3dd157 235 ssize_t ret_cnt;
cff990ce 236 bool enabled;
5e3dd157
KV
237 int i;
238
239 buf = kzalloc(buf_len, GFP_KERNEL);
240 if (!buf)
241 return -ENOMEM;
242
243 mutex_lock(&ar->conf_mutex);
244
245 if (len > buf_len)
246 len = buf_len;
247
acfe7ecf 248 spin_lock_bh(&ar->data_lock);
c4f8c836 249 for (i = 0; i < WMI_SERVICE_MAX; i++) {
acfe7ecf 250 enabled = test_bit(i, ar->wmi.svc_map);
cff990ce
MK
251 name = wmi_service_name(i);
252
253 if (!name) {
254 if (enabled)
255 len += scnprintf(buf + len, buf_len - len,
256 "%-40s %s (bit %d)\n",
257 "unknown", "enabled", i);
258
259 continue;
260 }
5e3dd157
KV
261
262 len += scnprintf(buf + len, buf_len - len,
cff990ce
MK
263 "%-40s %s\n",
264 name, enabled ? "enabled" : "-");
5e3dd157 265 }
acfe7ecf 266 spin_unlock_bh(&ar->data_lock);
5e3dd157
KV
267
268 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
269
270 mutex_unlock(&ar->conf_mutex);
271
272 kfree(buf);
273 return ret_cnt;
274}
275
276static const struct file_operations fops_wmi_services = {
277 .read = ath10k_read_wmi_services,
278 .open = simple_open,
279 .owner = THIS_MODULE,
280 .llseek = default_llseek,
281};
282
b4619ea2 283static void ath10k_fw_stats_pdevs_free(struct list_head *head)
5326849a
MK
284{
285 struct ath10k_fw_stats_pdev *i, *tmp;
286
287 list_for_each_entry_safe(i, tmp, head, list) {
288 list_del(&i->list);
289 kfree(i);
290 }
291}
292
b4619ea2 293static void ath10k_fw_stats_vdevs_free(struct list_head *head)
7b6b153a
MK
294{
295 struct ath10k_fw_stats_vdev *i, *tmp;
296
297 list_for_each_entry_safe(i, tmp, head, list) {
298 list_del(&i->list);
299 kfree(i);
300 }
301}
302
b4619ea2 303static void ath10k_fw_stats_peers_free(struct list_head *head)
5326849a
MK
304{
305 struct ath10k_fw_stats_peer *i, *tmp;
306
307 list_for_each_entry_safe(i, tmp, head, list) {
308 list_del(&i->list);
309 kfree(i);
310 }
311}
312
313static void ath10k_debug_fw_stats_reset(struct ath10k *ar)
314{
315 spin_lock_bh(&ar->data_lock);
316 ar->debug.fw_stats_done = false;
b4619ea2
MSS
317 ath10k_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs);
318 ath10k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
319 ath10k_fw_stats_peers_free(&ar->debug.fw_stats.peers);
5326849a
MK
320 spin_unlock_bh(&ar->data_lock);
321}
322
60ef401a 323void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
5e3dd157 324{
5326849a 325 struct ath10k_fw_stats stats = {};
cc61a1bb 326 bool is_start, is_started, is_end;
5326849a 327 size_t num_peers;
7b6b153a 328 size_t num_vdevs;
d15fb520 329 int ret;
5e3dd157 330
5326849a 331 INIT_LIST_HEAD(&stats.pdevs);
7b6b153a 332 INIT_LIST_HEAD(&stats.vdevs);
5326849a 333 INIT_LIST_HEAD(&stats.peers);
5e3dd157 334
5326849a
MK
335 spin_lock_bh(&ar->data_lock);
336 ret = ath10k_wmi_pull_fw_stats(ar, skb, &stats);
d15fb520
MK
337 if (ret) {
338 ath10k_warn(ar, "failed to pull fw stats: %d\n", ret);
5db879ae 339 goto free;
5e3dd157
KV
340 }
341
5326849a
MK
342 /* Stat data may exceed htc-wmi buffer limit. In such case firmware
343 * splits the stats data and delivers it in a ping-pong fashion of
344 * request cmd-update event.
345 *
346 * However there is no explicit end-of-data. Instead start-of-data is
347 * used as an implicit one. This works as follows:
348 * a) discard stat update events until one with pdev stats is
349 * delivered - this skips session started at end of (b)
350 * b) consume stat update events until another one with pdev stats is
351 * delivered which is treated as end-of-data and is itself discarded
352 */
cc61a1bb 353 if (ath10k_peer_stats_enabled(ar))
74135f59
MSS
354 ath10k_sta_update_rx_duration(ar, &stats.peers);
355
e0b6ce00 356 if (ar->debug.fw_stats_done) {
cc61a1bb 357 if (!ath10k_peer_stats_enabled(ar))
e0b6ce00
MSS
358 ath10k_warn(ar, "received unsolicited stats update event\n");
359
5326849a
MK
360 goto free;
361 }
362
bc6f9ae6
MP
363 num_peers = ath10k_wmi_fw_stats_num_peers(&ar->debug.fw_stats.peers);
364 num_vdevs = ath10k_wmi_fw_stats_num_vdevs(&ar->debug.fw_stats.vdevs);
5326849a
MK
365 is_start = (list_empty(&ar->debug.fw_stats.pdevs) &&
366 !list_empty(&stats.pdevs));
367 is_end = (!list_empty(&ar->debug.fw_stats.pdevs) &&
368 !list_empty(&stats.pdevs));
369
370 if (is_start)
371 list_splice_tail_init(&stats.pdevs, &ar->debug.fw_stats.pdevs);
372
373 if (is_end)
374 ar->debug.fw_stats_done = true;
375
376 is_started = !list_empty(&ar->debug.fw_stats.pdevs);
377
378 if (is_started && !is_end) {
379 if (num_peers >= ATH10K_MAX_NUM_PEER_IDS) {
380 /* Although this is unlikely impose a sane limit to
381 * prevent firmware from DoS-ing the host.
382 */
d57e7f2e 383 ath10k_fw_stats_peers_free(&ar->debug.fw_stats.peers);
5326849a
MK
384 ath10k_warn(ar, "dropping fw peer stats\n");
385 goto free;
386 }
387
7b6b153a 388 if (num_vdevs >= BITS_PER_LONG) {
d57e7f2e 389 ath10k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
7b6b153a
MK
390 ath10k_warn(ar, "dropping fw vdev stats\n");
391 goto free;
392 }
393
5326849a 394 list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers);
7b6b153a 395 list_splice_tail_init(&stats.vdevs, &ar->debug.fw_stats.vdevs);
5326849a
MK
396 }
397
60ef401a 398 complete(&ar->debug.fw_stats_complete);
5e3dd157 399
5326849a
MK
400free:
401 /* In some cases lists have been spliced and cleared. Free up
402 * resources if that is not the case.
403 */
b4619ea2
MSS
404 ath10k_fw_stats_pdevs_free(&stats.pdevs);
405 ath10k_fw_stats_vdevs_free(&stats.vdevs);
406 ath10k_fw_stats_peers_free(&stats.peers);
5326849a 407
87571bf0 408 spin_unlock_bh(&ar->data_lock);
5e3dd157
KV
409}
410
5326849a 411static int ath10k_debug_fw_stats_request(struct ath10k *ar)
5e3dd157 412{
6e8d5438 413 unsigned long timeout, time_left;
5e3dd157
KV
414 int ret;
415
fb2e9c0c 416 lockdep_assert_held(&ar->conf_mutex);
5e3dd157 417
6e8d5438 418 timeout = jiffies + msecs_to_jiffies(1 * HZ);
5326849a
MK
419
420 ath10k_debug_fw_stats_reset(ar);
421
422 for (;;) {
423 if (time_after(jiffies, timeout))
424 return -ETIMEDOUT;
425
426 reinit_completion(&ar->debug.fw_stats_complete);
427
6274cd41 428 ret = ath10k_wmi_request_stats(ar, ar->fw_stats_req_mask);
5326849a
MK
429 if (ret) {
430 ath10k_warn(ar, "could not request stats (%d)\n", ret);
431 return ret;
432 }
5e3dd157 433
6e8d5438
NMG
434 time_left =
435 wait_for_completion_timeout(&ar->debug.fw_stats_complete,
436 1 * HZ);
437 if (!time_left)
5326849a
MK
438 return -ETIMEDOUT;
439
440 spin_lock_bh(&ar->data_lock);
441 if (ar->debug.fw_stats_done) {
442 spin_unlock_bh(&ar->data_lock);
443 break;
444 }
445 spin_unlock_bh(&ar->data_lock);
446 }
fb2e9c0c
MK
447
448 return 0;
449}
450
fb2e9c0c
MK
451static int ath10k_fw_stats_open(struct inode *inode, struct file *file)
452{
453 struct ath10k *ar = inode->i_private;
454 void *buf = NULL;
455 int ret;
456
457 mutex_lock(&ar->conf_mutex);
458
459 if (ar->state != ATH10K_STATE_ON) {
460 ret = -ENETDOWN;
461 goto err_unlock;
462 }
463
464 buf = vmalloc(ATH10K_FW_STATS_BUF_SIZE);
465 if (!buf) {
466 ret = -ENOMEM;
467 goto err_unlock;
468 }
469
5326849a 470 ret = ath10k_debug_fw_stats_request(ar);
fb2e9c0c
MK
471 if (ret) {
472 ath10k_warn(ar, "failed to request fw stats: %d\n", ret);
473 goto err_free;
474 }
475
bc6f9ae6
MP
476 ret = ath10k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, buf);
477 if (ret) {
478 ath10k_warn(ar, "failed to fill fw stats: %d\n", ret);
479 goto err_free;
480 }
481
fb2e9c0c 482 file->private_data = buf;
5e3dd157
KV
483
484 mutex_unlock(&ar->conf_mutex);
fb2e9c0c
MK
485 return 0;
486
487err_free:
488 vfree(buf);
489
490err_unlock:
491 mutex_unlock(&ar->conf_mutex);
492 return ret;
493}
494
495static int ath10k_fw_stats_release(struct inode *inode, struct file *file)
496{
497 vfree(file->private_data);
498
499 return 0;
500}
501
502static ssize_t ath10k_fw_stats_read(struct file *file, char __user *user_buf,
503 size_t count, loff_t *ppos)
504{
505 const char *buf = file->private_data;
506 unsigned int len = strlen(buf);
507
508 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
5e3dd157
KV
509}
510
511static const struct file_operations fops_fw_stats = {
fb2e9c0c
MK
512 .open = ath10k_fw_stats_open,
513 .release = ath10k_fw_stats_release,
60ef401a 514 .read = ath10k_fw_stats_read,
5e3dd157
KV
515 .owner = THIS_MODULE,
516 .llseek = default_llseek,
517};
518
f51dbe73
BG
519static ssize_t ath10k_debug_fw_reset_stats_read(struct file *file,
520 char __user *user_buf,
521 size_t count, loff_t *ppos)
522{
523 struct ath10k *ar = file->private_data;
524 int ret, len, buf_len;
525 char *buf;
526
527 buf_len = 500;
528 buf = kmalloc(buf_len, GFP_KERNEL);
529 if (!buf)
530 return -ENOMEM;
531
532 spin_lock_bh(&ar->data_lock);
533
534 len = 0;
535 len += scnprintf(buf + len, buf_len - len,
536 "fw_crash_counter\t\t%d\n", ar->stats.fw_crash_counter);
537 len += scnprintf(buf + len, buf_len - len,
538 "fw_warm_reset_counter\t\t%d\n",
539 ar->stats.fw_warm_reset_counter);
540 len += scnprintf(buf + len, buf_len - len,
541 "fw_cold_reset_counter\t\t%d\n",
542 ar->stats.fw_cold_reset_counter);
543
544 spin_unlock_bh(&ar->data_lock);
545
546 ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
547
548 kfree(buf);
549
550 return ret;
551}
552
553static const struct file_operations fops_fw_reset_stats = {
554 .open = simple_open,
555 .read = ath10k_debug_fw_reset_stats_read,
556 .owner = THIS_MODULE,
557 .llseek = default_llseek,
558};
559
d5aebc77
BG
560/* This is a clean assert crash in firmware. */
561static int ath10k_debug_fw_assert(struct ath10k *ar)
562{
563 struct wmi_vdev_install_key_cmd *cmd;
564 struct sk_buff *skb;
565
566 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd) + 16);
567 if (!skb)
568 return -ENOMEM;
569
570 cmd = (struct wmi_vdev_install_key_cmd *)skb->data;
571 memset(cmd, 0, sizeof(*cmd));
572
573 /* big enough number so that firmware asserts */
574 cmd->vdev_id = __cpu_to_le32(0x7ffe);
575
576 return ath10k_wmi_cmd_send(ar, skb,
577 ar->wmi.cmd->vdev_install_key_cmdid);
578}
579
278c4a85
MK
580static ssize_t ath10k_read_simulate_fw_crash(struct file *file,
581 char __user *user_buf,
582 size_t count, loff_t *ppos)
583{
75cb96d3
KV
584 const char buf[] =
585 "To simulate firmware crash write one of the keywords to this file:\n"
586 "`soft` - this will send WMI_FORCE_FW_HANG_ASSERT to firmware if FW supports that command.\n"
587 "`hard` - this will send to firmware command with illegal parameters causing firmware crash.\n"
605cdba1
MK
588 "`assert` - this will send special illegal parameter to firmware to cause assert failure and crash.\n"
589 "`hw-restart` - this will simply queue hw restart without fw/hw actually crashing.\n";
8c656992 590
278c4a85
MK
591 return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
592}
593
8c656992
MP
594/* Simulate firmware crash:
595 * 'soft': Call wmi command causing firmware hang. This firmware hang is
596 * recoverable by warm firmware reset.
597 * 'hard': Force firmware crash by setting any vdev parameter for not allowed
598 * vdev id. This is hard firmware crash because it is recoverable only by cold
599 * firmware reset.
600 */
278c4a85
MK
601static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
602 const char __user *user_buf,
603 size_t count, loff_t *ppos)
604{
605 struct ath10k *ar = file->private_data;
8c656992 606 char buf[32];
278c4a85
MK
607 int ret;
608
609 mutex_lock(&ar->conf_mutex);
610
611 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
8c656992
MP
612
613 /* make sure that buf is null terminated */
614 buf[sizeof(buf) - 1] = 0;
278c4a85
MK
615
616 if (ar->state != ATH10K_STATE_ON &&
617 ar->state != ATH10K_STATE_RESTARTED) {
618 ret = -ENETDOWN;
619 goto exit;
620 }
621
8c656992
MP
622 /* drop the possible '\n' from the end */
623 if (buf[count - 1] == '\n') {
624 buf[count - 1] = 0;
625 count--;
626 }
627
628 if (!strcmp(buf, "soft")) {
7aa7a72a 629 ath10k_info(ar, "simulating soft firmware crash\n");
8c656992
MP
630 ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0);
631 } else if (!strcmp(buf, "hard")) {
7aa7a72a 632 ath10k_info(ar, "simulating hard firmware crash\n");
611b3682
BG
633 /* 0x7fff is vdev id, and it is always out of range for all
634 * firmware variants in order to force a firmware crash.
635 */
636 ret = ath10k_wmi_vdev_set_param(ar, 0x7fff,
5b07e07f
KV
637 ar->wmi.vdev_param->rts_threshold,
638 0);
d5aebc77
BG
639 } else if (!strcmp(buf, "assert")) {
640 ath10k_info(ar, "simulating firmware assert crash\n");
641 ret = ath10k_debug_fw_assert(ar);
605cdba1
MK
642 } else if (!strcmp(buf, "hw-restart")) {
643 ath10k_info(ar, "user requested hw restart\n");
644 queue_work(ar->workqueue, &ar->restart_work);
645 ret = 0;
8c656992
MP
646 } else {
647 ret = -EINVAL;
648 goto exit;
649 }
278c4a85 650
8c656992 651 if (ret) {
7aa7a72a 652 ath10k_warn(ar, "failed to simulate firmware crash: %d\n", ret);
8c656992
MP
653 goto exit;
654 }
278c4a85 655
8c656992 656 ret = count;
278c4a85
MK
657
658exit:
659 mutex_unlock(&ar->conf_mutex);
660 return ret;
661}
662
663static const struct file_operations fops_simulate_fw_crash = {
664 .read = ath10k_read_simulate_fw_crash,
665 .write = ath10k_write_simulate_fw_crash,
666 .open = simple_open,
667 .owner = THIS_MODULE,
668 .llseek = default_llseek,
669};
670
763b8cd3
KV
671static ssize_t ath10k_read_chip_id(struct file *file, char __user *user_buf,
672 size_t count, loff_t *ppos)
673{
674 struct ath10k *ar = file->private_data;
675 unsigned int len;
676 char buf[50];
677
678 len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->chip_id);
679
680 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
681}
682
683static const struct file_operations fops_chip_id = {
684 .read = ath10k_read_chip_id,
685 .open = simple_open,
686 .owner = THIS_MODULE,
687 .llseek = default_llseek,
688};
689
384914b2
BG
690struct ath10k_fw_crash_data *
691ath10k_debug_get_new_fw_crash_data(struct ath10k *ar)
692{
693 struct ath10k_fw_crash_data *crash_data = ar->debug.fw_crash_data;
694
695 lockdep_assert_held(&ar->data_lock);
696
697 crash_data->crashed_since_read = true;
698 uuid_le_gen(&crash_data->uuid);
699 getnstimeofday(&crash_data->timestamp);
700
701 return crash_data;
702}
703EXPORT_SYMBOL(ath10k_debug_get_new_fw_crash_data);
704
705static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar)
706{
707 struct ath10k_fw_crash_data *crash_data = ar->debug.fw_crash_data;
708 struct ath10k_dump_file_data *dump_data;
709 struct ath10k_tlv_dump_data *dump_tlv;
710 int hdr_len = sizeof(*dump_data);
711 unsigned int len, sofar = 0;
712 unsigned char *buf;
713
714 len = hdr_len;
715 len += sizeof(*dump_tlv) + sizeof(crash_data->registers);
716
717 sofar += hdr_len;
718
719 /* This is going to get big when we start dumping FW RAM and such,
720 * so go ahead and use vmalloc.
721 */
722 buf = vzalloc(len);
723 if (!buf)
724 return NULL;
725
726 spin_lock_bh(&ar->data_lock);
727
728 if (!crash_data->crashed_since_read) {
729 spin_unlock_bh(&ar->data_lock);
730 vfree(buf);
731 return NULL;
732 }
733
734 dump_data = (struct ath10k_dump_file_data *)(buf);
735 strlcpy(dump_data->df_magic, "ATH10K-FW-DUMP",
736 sizeof(dump_data->df_magic));
737 dump_data->len = cpu_to_le32(len);
738
739 dump_data->version = cpu_to_le32(ATH10K_FW_CRASH_DUMP_VERSION);
740
741 memcpy(dump_data->uuid, &crash_data->uuid, sizeof(dump_data->uuid));
742 dump_data->chip_id = cpu_to_le32(ar->chip_id);
743 dump_data->bus_type = cpu_to_le32(0);
744 dump_data->target_version = cpu_to_le32(ar->target_version);
745 dump_data->fw_version_major = cpu_to_le32(ar->fw_version_major);
746 dump_data->fw_version_minor = cpu_to_le32(ar->fw_version_minor);
747 dump_data->fw_version_release = cpu_to_le32(ar->fw_version_release);
748 dump_data->fw_version_build = cpu_to_le32(ar->fw_version_build);
749 dump_data->phy_capability = cpu_to_le32(ar->phy_capability);
750 dump_data->hw_min_tx_power = cpu_to_le32(ar->hw_min_tx_power);
751 dump_data->hw_max_tx_power = cpu_to_le32(ar->hw_max_tx_power);
752 dump_data->ht_cap_info = cpu_to_le32(ar->ht_cap_info);
753 dump_data->vht_cap_info = cpu_to_le32(ar->vht_cap_info);
754 dump_data->num_rf_chains = cpu_to_le32(ar->num_rf_chains);
755
756 strlcpy(dump_data->fw_ver, ar->hw->wiphy->fw_version,
757 sizeof(dump_data->fw_ver));
758
12c27156
JB
759 dump_data->kernel_ver_code = 0;
760 strlcpy(dump_data->kernel_ver, init_utsname()->release,
384914b2
BG
761 sizeof(dump_data->kernel_ver));
762
763 dump_data->tv_sec = cpu_to_le64(crash_data->timestamp.tv_sec);
764 dump_data->tv_nsec = cpu_to_le64(crash_data->timestamp.tv_nsec);
765
766 /* Gather crash-dump */
767 dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar);
768 dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_REGISTERS);
769 dump_tlv->tlv_len = cpu_to_le32(sizeof(crash_data->registers));
770 memcpy(dump_tlv->tlv_data, &crash_data->registers,
771 sizeof(crash_data->registers));
772 sofar += sizeof(*dump_tlv) + sizeof(crash_data->registers);
773
774 ar->debug.fw_crash_data->crashed_since_read = false;
775
776 spin_unlock_bh(&ar->data_lock);
777
778 return dump_data;
779}
780
781static int ath10k_fw_crash_dump_open(struct inode *inode, struct file *file)
782{
783 struct ath10k *ar = inode->i_private;
784 struct ath10k_dump_file_data *dump;
785
786 dump = ath10k_build_dump_file(ar);
787 if (!dump)
788 return -ENODATA;
789
790 file->private_data = dump;
791
792 return 0;
793}
794
795static ssize_t ath10k_fw_crash_dump_read(struct file *file,
796 char __user *user_buf,
797 size_t count, loff_t *ppos)
798{
799 struct ath10k_dump_file_data *dump_file = file->private_data;
800
801 return simple_read_from_buffer(user_buf, count, ppos,
802 dump_file,
803 le32_to_cpu(dump_file->len));
804}
805
806static int ath10k_fw_crash_dump_release(struct inode *inode,
807 struct file *file)
808{
809 vfree(file->private_data);
810
811 return 0;
812}
813
814static const struct file_operations fops_fw_crash_dump = {
815 .open = ath10k_fw_crash_dump_open,
816 .read = ath10k_fw_crash_dump_read,
817 .release = ath10k_fw_crash_dump_release,
818 .owner = THIS_MODULE,
819 .llseek = default_llseek,
820};
821
077a3804
YL
822static ssize_t ath10k_reg_addr_read(struct file *file,
823 char __user *user_buf,
824 size_t count, loff_t *ppos)
825{
826 struct ath10k *ar = file->private_data;
827 u8 buf[32];
828 unsigned int len = 0;
829 u32 reg_addr;
830
831 mutex_lock(&ar->conf_mutex);
832 reg_addr = ar->debug.reg_addr;
833 mutex_unlock(&ar->conf_mutex);
834
835 len += scnprintf(buf + len, sizeof(buf) - len, "0x%x\n", reg_addr);
836
837 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
838}
839
840static ssize_t ath10k_reg_addr_write(struct file *file,
841 const char __user *user_buf,
842 size_t count, loff_t *ppos)
843{
844 struct ath10k *ar = file->private_data;
845 u32 reg_addr;
846 int ret;
847
848 ret = kstrtou32_from_user(user_buf, count, 0, &reg_addr);
849 if (ret)
850 return ret;
851
852 if (!IS_ALIGNED(reg_addr, 4))
853 return -EFAULT;
854
855 mutex_lock(&ar->conf_mutex);
856 ar->debug.reg_addr = reg_addr;
857 mutex_unlock(&ar->conf_mutex);
858
859 return count;
860}
861
862static const struct file_operations fops_reg_addr = {
863 .read = ath10k_reg_addr_read,
864 .write = ath10k_reg_addr_write,
865 .open = simple_open,
866 .owner = THIS_MODULE,
867 .llseek = default_llseek,
868};
869
870static ssize_t ath10k_reg_value_read(struct file *file,
871 char __user *user_buf,
872 size_t count, loff_t *ppos)
873{
874 struct ath10k *ar = file->private_data;
875 u8 buf[48];
876 unsigned int len;
877 u32 reg_addr, reg_val;
878 int ret;
879
880 mutex_lock(&ar->conf_mutex);
881
882 if (ar->state != ATH10K_STATE_ON &&
883 ar->state != ATH10K_STATE_UTF) {
884 ret = -ENETDOWN;
885 goto exit;
886 }
887
888 reg_addr = ar->debug.reg_addr;
889
890 reg_val = ath10k_hif_read32(ar, reg_addr);
891 len = scnprintf(buf, sizeof(buf), "0x%08x:0x%08x\n", reg_addr, reg_val);
892
893 ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
894
895exit:
896 mutex_unlock(&ar->conf_mutex);
897
898 return ret;
899}
900
901static ssize_t ath10k_reg_value_write(struct file *file,
902 const char __user *user_buf,
903 size_t count, loff_t *ppos)
904{
905 struct ath10k *ar = file->private_data;
906 u32 reg_addr, reg_val;
907 int ret;
908
909 mutex_lock(&ar->conf_mutex);
910
911 if (ar->state != ATH10K_STATE_ON &&
912 ar->state != ATH10K_STATE_UTF) {
913 ret = -ENETDOWN;
914 goto exit;
915 }
916
917 reg_addr = ar->debug.reg_addr;
918
919 ret = kstrtou32_from_user(user_buf, count, 0, &reg_val);
920 if (ret)
921 goto exit;
922
923 ath10k_hif_write32(ar, reg_addr, reg_val);
924
925 ret = count;
926
927exit:
928 mutex_unlock(&ar->conf_mutex);
929
930 return ret;
931}
932
933static const struct file_operations fops_reg_value = {
934 .read = ath10k_reg_value_read,
935 .write = ath10k_reg_value_write,
936 .open = simple_open,
937 .owner = THIS_MODULE,
938 .llseek = default_llseek,
939};
940
9f65ad25
YL
941static ssize_t ath10k_mem_value_read(struct file *file,
942 char __user *user_buf,
943 size_t count, loff_t *ppos)
944{
945 struct ath10k *ar = file->private_data;
946 u8 *buf;
947 int ret;
948
949 if (*ppos < 0)
950 return -EINVAL;
951
952 if (!count)
953 return 0;
954
955 mutex_lock(&ar->conf_mutex);
956
957 buf = vmalloc(count);
958 if (!buf) {
959 ret = -ENOMEM;
960 goto exit;
961 }
962
963 if (ar->state != ATH10K_STATE_ON &&
964 ar->state != ATH10K_STATE_UTF) {
965 ret = -ENETDOWN;
966 goto exit;
967 }
968
969 ret = ath10k_hif_diag_read(ar, *ppos, buf, count);
970 if (ret) {
971 ath10k_warn(ar, "failed to read address 0x%08x via diagnose window fnrom debugfs: %d\n",
972 (u32)(*ppos), ret);
973 goto exit;
974 }
975
976 ret = copy_to_user(user_buf, buf, count);
977 if (ret) {
978 ret = -EFAULT;
979 goto exit;
980 }
981
982 count -= ret;
983 *ppos += count;
984 ret = count;
985
986exit:
987 vfree(buf);
988 mutex_unlock(&ar->conf_mutex);
989
990 return ret;
991}
992
993static ssize_t ath10k_mem_value_write(struct file *file,
994 const char __user *user_buf,
995 size_t count, loff_t *ppos)
996{
997 struct ath10k *ar = file->private_data;
998 u8 *buf;
999 int ret;
1000
1001 if (*ppos < 0)
1002 return -EINVAL;
1003
1004 if (!count)
1005 return 0;
1006
1007 mutex_lock(&ar->conf_mutex);
1008
1009 buf = vmalloc(count);
1010 if (!buf) {
1011 ret = -ENOMEM;
1012 goto exit;
1013 }
1014
1015 if (ar->state != ATH10K_STATE_ON &&
1016 ar->state != ATH10K_STATE_UTF) {
1017 ret = -ENETDOWN;
1018 goto exit;
1019 }
1020
1021 ret = copy_from_user(buf, user_buf, count);
1022 if (ret) {
1023 ret = -EFAULT;
1024 goto exit;
1025 }
1026
1027 ret = ath10k_hif_diag_write(ar, *ppos, buf, count);
1028 if (ret) {
1029 ath10k_warn(ar, "failed to write address 0x%08x via diagnose window from debugfs: %d\n",
1030 (u32)(*ppos), ret);
1031 goto exit;
1032 }
1033
1034 *ppos += count;
1035 ret = count;
1036
1037exit:
1038 vfree(buf);
1039 mutex_unlock(&ar->conf_mutex);
1040
1041 return ret;
1042}
1043
1044static const struct file_operations fops_mem_value = {
1045 .read = ath10k_mem_value_read,
1046 .write = ath10k_mem_value_write,
1047 .open = simple_open,
1048 .owner = THIS_MODULE,
1049 .llseek = default_llseek,
1050};
1051
a3d135e5
KV
1052static int ath10k_debug_htt_stats_req(struct ath10k *ar)
1053{
1054 u64 cookie;
1055 int ret;
1056
1057 lockdep_assert_held(&ar->conf_mutex);
1058
1059 if (ar->debug.htt_stats_mask == 0)
1060 /* htt stats are disabled */
1061 return 0;
1062
1063 if (ar->state != ATH10K_STATE_ON)
1064 return 0;
1065
1066 cookie = get_jiffies_64();
1067
1068 ret = ath10k_htt_h2t_stats_req(&ar->htt, ar->debug.htt_stats_mask,
1069 cookie);
1070 if (ret) {
7aa7a72a 1071 ath10k_warn(ar, "failed to send htt stats request: %d\n", ret);
a3d135e5
KV
1072 return ret;
1073 }
1074
1075 queue_delayed_work(ar->workqueue, &ar->debug.htt_stats_dwork,
1076 msecs_to_jiffies(ATH10K_DEBUG_HTT_STATS_INTERVAL));
1077
1078 return 0;
1079}
1080
1081static void ath10k_debug_htt_stats_dwork(struct work_struct *work)
1082{
1083 struct ath10k *ar = container_of(work, struct ath10k,
1084 debug.htt_stats_dwork.work);
1085
1086 mutex_lock(&ar->conf_mutex);
1087
1088 ath10k_debug_htt_stats_req(ar);
1089
1090 mutex_unlock(&ar->conf_mutex);
1091}
1092
1093static ssize_t ath10k_read_htt_stats_mask(struct file *file,
5b07e07f
KV
1094 char __user *user_buf,
1095 size_t count, loff_t *ppos)
a3d135e5
KV
1096{
1097 struct ath10k *ar = file->private_data;
1098 char buf[32];
1099 unsigned int len;
1100
1101 len = scnprintf(buf, sizeof(buf), "%lu\n", ar->debug.htt_stats_mask);
1102
1103 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1104}
1105
1106static ssize_t ath10k_write_htt_stats_mask(struct file *file,
5b07e07f
KV
1107 const char __user *user_buf,
1108 size_t count, loff_t *ppos)
a3d135e5
KV
1109{
1110 struct ath10k *ar = file->private_data;
1111 unsigned long mask;
1112 int ret;
1113
1114 ret = kstrtoul_from_user(user_buf, count, 0, &mask);
1115 if (ret)
1116 return ret;
1117
1118 /* max 8 bit masks (for now) */
1119 if (mask > 0xff)
1120 return -E2BIG;
1121
1122 mutex_lock(&ar->conf_mutex);
1123
1124 ar->debug.htt_stats_mask = mask;
1125
1126 ret = ath10k_debug_htt_stats_req(ar);
1127 if (ret)
1128 goto out;
1129
1130 ret = count;
1131
1132out:
1133 mutex_unlock(&ar->conf_mutex);
1134
1135 return ret;
1136}
1137
1138static const struct file_operations fops_htt_stats_mask = {
1139 .read = ath10k_read_htt_stats_mask,
1140 .write = ath10k_write_htt_stats_mask,
1141 .open = simple_open,
1142 .owner = THIS_MODULE,
1143 .llseek = default_llseek,
1144};
1145
d385623a
JD
1146static ssize_t ath10k_read_htt_max_amsdu_ampdu(struct file *file,
1147 char __user *user_buf,
1148 size_t count, loff_t *ppos)
1149{
1150 struct ath10k *ar = file->private_data;
1151 char buf[64];
81ec3c09 1152 u8 amsdu, ampdu;
d385623a
JD
1153 unsigned int len;
1154
1155 mutex_lock(&ar->conf_mutex);
1156
ccec9038
DL
1157 amsdu = ar->htt.max_num_amsdu;
1158 ampdu = ar->htt.max_num_ampdu;
d385623a
JD
1159 mutex_unlock(&ar->conf_mutex);
1160
1161 len = scnprintf(buf, sizeof(buf), "%u %u\n", amsdu, ampdu);
1162
1163 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1164}
1165
1166static ssize_t ath10k_write_htt_max_amsdu_ampdu(struct file *file,
1167 const char __user *user_buf,
1168 size_t count, loff_t *ppos)
1169{
1170 struct ath10k *ar = file->private_data;
1171 int res;
1172 char buf[64];
1173 unsigned int amsdu, ampdu;
1174
1175 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
1176
1177 /* make sure that buf is null terminated */
1178 buf[sizeof(buf) - 1] = 0;
1179
1180 res = sscanf(buf, "%u %u", &amsdu, &ampdu);
1181
1182 if (res != 2)
1183 return -EINVAL;
1184
1185 mutex_lock(&ar->conf_mutex);
1186
1187 res = ath10k_htt_h2t_aggr_cfg_msg(&ar->htt, ampdu, amsdu);
1188 if (res)
1189 goto out;
1190
1191 res = count;
ccec9038
DL
1192 ar->htt.max_num_amsdu = amsdu;
1193 ar->htt.max_num_ampdu = ampdu;
d385623a
JD
1194
1195out:
1196 mutex_unlock(&ar->conf_mutex);
1197 return res;
1198}
1199
1200static const struct file_operations fops_htt_max_amsdu_ampdu = {
1201 .read = ath10k_read_htt_max_amsdu_ampdu,
1202 .write = ath10k_write_htt_max_amsdu_ampdu,
1203 .open = simple_open,
1204 .owner = THIS_MODULE,
1205 .llseek = default_llseek,
1206};
1207
f118a3e5 1208static ssize_t ath10k_read_fw_dbglog(struct file *file,
5b07e07f
KV
1209 char __user *user_buf,
1210 size_t count, loff_t *ppos)
f118a3e5
KV
1211{
1212 struct ath10k *ar = file->private_data;
1213 unsigned int len;
467210a6 1214 char buf[64];
f118a3e5 1215
467210a6
SJ
1216 len = scnprintf(buf, sizeof(buf), "0x%08x %u\n",
1217 ar->debug.fw_dbglog_mask, ar->debug.fw_dbglog_level);
f118a3e5
KV
1218
1219 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1220}
1221
1222static ssize_t ath10k_write_fw_dbglog(struct file *file,
1223 const char __user *user_buf,
1224 size_t count, loff_t *ppos)
1225{
1226 struct ath10k *ar = file->private_data;
f118a3e5 1227 int ret;
467210a6
SJ
1228 char buf[64];
1229 unsigned int log_level, mask;
f118a3e5 1230
467210a6
SJ
1231 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
1232
1233 /* make sure that buf is null terminated */
1234 buf[sizeof(buf) - 1] = 0;
1235
1236 ret = sscanf(buf, "%x %u", &mask, &log_level);
1237
1238 if (!ret)
1239 return -EINVAL;
1240
1241 if (ret == 1)
1242 /* default if user did not specify */
1243 log_level = ATH10K_DBGLOG_LEVEL_WARN;
f118a3e5
KV
1244
1245 mutex_lock(&ar->conf_mutex);
1246
1247 ar->debug.fw_dbglog_mask = mask;
467210a6 1248 ar->debug.fw_dbglog_level = log_level;
f118a3e5
KV
1249
1250 if (ar->state == ATH10K_STATE_ON) {
467210a6
SJ
1251 ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask,
1252 ar->debug.fw_dbglog_level);
f118a3e5 1253 if (ret) {
7aa7a72a 1254 ath10k_warn(ar, "dbglog cfg failed from debugfs: %d\n",
f118a3e5
KV
1255 ret);
1256 goto exit;
1257 }
1258 }
1259
1260 ret = count;
1261
1262exit:
1263 mutex_unlock(&ar->conf_mutex);
1264
1265 return ret;
1266}
1267
6cddcc7a
BG
1268/* TODO: Would be nice to always support ethtool stats, would need to
1269 * move the stats storage out of ath10k_debug, or always have ath10k_debug
1270 * struct available..
1271 */
1272
1273/* This generally cooresponds to the debugfs fw_stats file */
1274static const char ath10k_gstrings_stats[][ETH_GSTRING_LEN] = {
1275 "tx_pkts_nic",
1276 "tx_bytes_nic",
1277 "rx_pkts_nic",
1278 "rx_bytes_nic",
1279 "d_noise_floor",
1280 "d_cycle_count",
1281 "d_phy_error",
1282 "d_rts_bad",
1283 "d_rts_good",
1284 "d_tx_power", /* in .5 dbM I think */
1285 "d_rx_crc_err", /* fcs_bad */
1286 "d_no_beacon",
1287 "d_tx_mpdus_queued",
1288 "d_tx_msdu_queued",
1289 "d_tx_msdu_dropped",
1290 "d_local_enqued",
1291 "d_local_freed",
1292 "d_tx_ppdu_hw_queued",
1293 "d_tx_ppdu_reaped",
1294 "d_tx_fifo_underrun",
1295 "d_tx_ppdu_abort",
1296 "d_tx_mpdu_requed",
1297 "d_tx_excessive_retries",
1298 "d_tx_hw_rate",
1299 "d_tx_dropped_sw_retries",
1300 "d_tx_illegal_rate",
1301 "d_tx_continuous_xretries",
1302 "d_tx_timeout",
1303 "d_tx_mpdu_txop_limit",
1304 "d_pdev_resets",
1305 "d_rx_mid_ppdu_route_change",
1306 "d_rx_status",
1307 "d_rx_extra_frags_ring0",
1308 "d_rx_extra_frags_ring1",
1309 "d_rx_extra_frags_ring2",
1310 "d_rx_extra_frags_ring3",
1311 "d_rx_msdu_htt",
1312 "d_rx_mpdu_htt",
1313 "d_rx_msdu_stack",
1314 "d_rx_mpdu_stack",
1315 "d_rx_phy_err",
1316 "d_rx_phy_err_drops",
1317 "d_rx_mpdu_errors", /* FCS, MIC, ENC */
1318 "d_fw_crash_count",
1319 "d_fw_warm_reset_count",
1320 "d_fw_cold_reset_count",
1321};
1322
1323#define ATH10K_SSTATS_LEN ARRAY_SIZE(ath10k_gstrings_stats)
1324
1325void ath10k_debug_get_et_strings(struct ieee80211_hw *hw,
1326 struct ieee80211_vif *vif,
1327 u32 sset, u8 *data)
1328{
1329 if (sset == ETH_SS_STATS)
1330 memcpy(data, *ath10k_gstrings_stats,
1331 sizeof(ath10k_gstrings_stats));
1332}
1333
1334int ath10k_debug_get_et_sset_count(struct ieee80211_hw *hw,
1335 struct ieee80211_vif *vif, int sset)
1336{
1337 if (sset == ETH_SS_STATS)
1338 return ATH10K_SSTATS_LEN;
1339
1340 return 0;
1341}
1342
1343void ath10k_debug_get_et_stats(struct ieee80211_hw *hw,
1344 struct ieee80211_vif *vif,
1345 struct ethtool_stats *stats, u64 *data)
1346{
1347 struct ath10k *ar = hw->priv;
1348 static const struct ath10k_fw_stats_pdev zero_stats = {};
1349 const struct ath10k_fw_stats_pdev *pdev_stats;
1350 int i = 0, ret;
1351
1352 mutex_lock(&ar->conf_mutex);
1353
1354 if (ar->state == ATH10K_STATE_ON) {
1355 ret = ath10k_debug_fw_stats_request(ar);
1356 if (ret) {
1357 /* just print a warning and try to use older results */
1358 ath10k_warn(ar,
1359 "failed to get fw stats for ethtool: %d\n",
1360 ret);
1361 }
1362 }
1363
1364 pdev_stats = list_first_entry_or_null(&ar->debug.fw_stats.pdevs,
1365 struct ath10k_fw_stats_pdev,
1366 list);
1367 if (!pdev_stats) {
1368 /* no results available so just return zeroes */
1369 pdev_stats = &zero_stats;
1370 }
1371
1372 spin_lock_bh(&ar->data_lock);
1373
1374 data[i++] = pdev_stats->hw_reaped; /* ppdu reaped */
1375 data[i++] = 0; /* tx bytes */
1376 data[i++] = pdev_stats->htt_mpdus;
1377 data[i++] = 0; /* rx bytes */
1378 data[i++] = pdev_stats->ch_noise_floor;
1379 data[i++] = pdev_stats->cycle_count;
1380 data[i++] = pdev_stats->phy_err_count;
1381 data[i++] = pdev_stats->rts_bad;
1382 data[i++] = pdev_stats->rts_good;
1383 data[i++] = pdev_stats->chan_tx_power;
1384 data[i++] = pdev_stats->fcs_bad;
1385 data[i++] = pdev_stats->no_beacons;
1386 data[i++] = pdev_stats->mpdu_enqued;
1387 data[i++] = pdev_stats->msdu_enqued;
1388 data[i++] = pdev_stats->wmm_drop;
1389 data[i++] = pdev_stats->local_enqued;
1390 data[i++] = pdev_stats->local_freed;
1391 data[i++] = pdev_stats->hw_queued;
1392 data[i++] = pdev_stats->hw_reaped;
1393 data[i++] = pdev_stats->underrun;
1394 data[i++] = pdev_stats->tx_abort;
1395 data[i++] = pdev_stats->mpdus_requed;
1396 data[i++] = pdev_stats->tx_ko;
1397 data[i++] = pdev_stats->data_rc;
1398 data[i++] = pdev_stats->sw_retry_failure;
1399 data[i++] = pdev_stats->illgl_rate_phy_err;
1400 data[i++] = pdev_stats->pdev_cont_xretry;
1401 data[i++] = pdev_stats->pdev_tx_timeout;
1402 data[i++] = pdev_stats->txop_ovf;
1403 data[i++] = pdev_stats->pdev_resets;
1404 data[i++] = pdev_stats->mid_ppdu_route_change;
1405 data[i++] = pdev_stats->status_rcvd;
1406 data[i++] = pdev_stats->r0_frags;
1407 data[i++] = pdev_stats->r1_frags;
1408 data[i++] = pdev_stats->r2_frags;
1409 data[i++] = pdev_stats->r3_frags;
1410 data[i++] = pdev_stats->htt_msdus;
1411 data[i++] = pdev_stats->htt_mpdus;
1412 data[i++] = pdev_stats->loc_msdus;
1413 data[i++] = pdev_stats->loc_mpdus;
1414 data[i++] = pdev_stats->phy_errs;
1415 data[i++] = pdev_stats->phy_err_drop;
1416 data[i++] = pdev_stats->mpdu_errs;
1417 data[i++] = ar->stats.fw_crash_counter;
1418 data[i++] = ar->stats.fw_warm_reset_counter;
1419 data[i++] = ar->stats.fw_cold_reset_counter;
1420
1421 spin_unlock_bh(&ar->data_lock);
1422
1423 mutex_unlock(&ar->conf_mutex);
1424
1425 WARN_ON(i != ATH10K_SSTATS_LEN);
1426}
1427
f118a3e5
KV
1428static const struct file_operations fops_fw_dbglog = {
1429 .read = ath10k_read_fw_dbglog,
1430 .write = ath10k_write_fw_dbglog,
1431 .open = simple_open,
1432 .owner = THIS_MODULE,
1433 .llseek = default_llseek,
1434};
1435
7869b4fa
KV
1436static int ath10k_debug_cal_data_open(struct inode *inode, struct file *file)
1437{
1438 struct ath10k *ar = inode->i_private;
1439 void *buf;
1440 u32 hi_addr;
1441 __le32 addr;
1442 int ret;
1443
1444 mutex_lock(&ar->conf_mutex);
1445
1446 if (ar->state != ATH10K_STATE_ON &&
1447 ar->state != ATH10K_STATE_UTF) {
1448 ret = -ENETDOWN;
1449 goto err;
1450 }
1451
0b8e3c4c 1452 buf = vmalloc(ar->hw_params.cal_data_len);
7869b4fa
KV
1453 if (!buf) {
1454 ret = -ENOMEM;
1455 goto err;
1456 }
1457
1458 hi_addr = host_interest_item_address(HI_ITEM(hi_board_data));
1459
1460 ret = ath10k_hif_diag_read(ar, hi_addr, &addr, sizeof(addr));
1461 if (ret) {
1462 ath10k_warn(ar, "failed to read hi_board_data address: %d\n", ret);
1463 goto err_vfree;
1464 }
1465
1466 ret = ath10k_hif_diag_read(ar, le32_to_cpu(addr), buf,
0b8e3c4c 1467 ar->hw_params.cal_data_len);
7869b4fa
KV
1468 if (ret) {
1469 ath10k_warn(ar, "failed to read calibration data: %d\n", ret);
1470 goto err_vfree;
1471 }
1472
1473 file->private_data = buf;
1474
1475 mutex_unlock(&ar->conf_mutex);
1476
1477 return 0;
1478
1479err_vfree:
1480 vfree(buf);
1481
1482err:
1483 mutex_unlock(&ar->conf_mutex);
1484
1485 return ret;
1486}
1487
1488static ssize_t ath10k_debug_cal_data_read(struct file *file,
1489 char __user *user_buf,
1490 size_t count, loff_t *ppos)
1491{
0b8e3c4c 1492 struct ath10k *ar = file->private_data;
7869b4fa
KV
1493 void *buf = file->private_data;
1494
1495 return simple_read_from_buffer(user_buf, count, ppos,
0b8e3c4c 1496 buf, ar->hw_params.cal_data_len);
7869b4fa
KV
1497}
1498
1499static int ath10k_debug_cal_data_release(struct inode *inode,
1500 struct file *file)
1501{
1502 vfree(file->private_data);
1503
1504 return 0;
1505}
1506
b3e71d7a
ARN
1507static ssize_t ath10k_write_ani_enable(struct file *file,
1508 const char __user *user_buf,
1509 size_t count, loff_t *ppos)
1510{
1511 struct ath10k *ar = file->private_data;
1512 int ret;
1513 u8 enable;
1514
1515 if (kstrtou8_from_user(user_buf, count, 0, &enable))
1516 return -EINVAL;
1517
1518 mutex_lock(&ar->conf_mutex);
1519
1520 if (ar->ani_enabled == enable) {
1521 ret = count;
1522 goto exit;
1523 }
1524
1525 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->ani_enable,
1526 enable);
1527 if (ret) {
1528 ath10k_warn(ar, "ani_enable failed from debugfs: %d\n", ret);
1529 goto exit;
1530 }
1531 ar->ani_enabled = enable;
1532
1533 ret = count;
1534
1535exit:
1536 mutex_unlock(&ar->conf_mutex);
1537
1538 return ret;
1539}
1540
1541static ssize_t ath10k_read_ani_enable(struct file *file, char __user *user_buf,
1542 size_t count, loff_t *ppos)
1543{
1544 struct ath10k *ar = file->private_data;
1545 int len = 0;
1546 char buf[32];
1547
1548 len = scnprintf(buf, sizeof(buf) - len, "%d\n",
1549 ar->ani_enabled);
1550
1551 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1552}
1553
1554static const struct file_operations fops_ani_enable = {
1555 .read = ath10k_read_ani_enable,
1556 .write = ath10k_write_ani_enable,
1557 .open = simple_open,
1558 .owner = THIS_MODULE,
1559 .llseek = default_llseek,
1560};
1561
7869b4fa
KV
1562static const struct file_operations fops_cal_data = {
1563 .open = ath10k_debug_cal_data_open,
1564 .read = ath10k_debug_cal_data_read,
1565 .release = ath10k_debug_cal_data_release,
1566 .owner = THIS_MODULE,
1567 .llseek = default_llseek,
1568};
1569
a7bd3e99
PO
1570static ssize_t ath10k_read_nf_cal_period(struct file *file,
1571 char __user *user_buf,
1572 size_t count, loff_t *ppos)
1573{
1574 struct ath10k *ar = file->private_data;
1575 unsigned int len;
1576 char buf[32];
1577
1578 len = scnprintf(buf, sizeof(buf), "%d\n",
1579 ar->debug.nf_cal_period);
1580
1581 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1582}
1583
1584static ssize_t ath10k_write_nf_cal_period(struct file *file,
1585 const char __user *user_buf,
1586 size_t count, loff_t *ppos)
1587{
1588 struct ath10k *ar = file->private_data;
1589 unsigned long period;
1590 int ret;
1591
1592 ret = kstrtoul_from_user(user_buf, count, 0, &period);
1593 if (ret)
1594 return ret;
1595
1596 if (period > WMI_PDEV_PARAM_CAL_PERIOD_MAX)
1597 return -EINVAL;
1598
1599 /* there's no way to switch back to the firmware default */
1600 if (period == 0)
1601 return -EINVAL;
1602
1603 mutex_lock(&ar->conf_mutex);
1604
1605 ar->debug.nf_cal_period = period;
1606
1607 if (ar->state != ATH10K_STATE_ON) {
1608 /* firmware is not running, nothing else to do */
1609 ret = count;
1610 goto exit;
1611 }
1612
1613 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->cal_period,
1614 ar->debug.nf_cal_period);
1615 if (ret) {
1616 ath10k_warn(ar, "cal period cfg failed from debugfs: %d\n",
1617 ret);
1618 goto exit;
1619 }
1620
1621 ret = count;
1622
1623exit:
1624 mutex_unlock(&ar->conf_mutex);
1625
1626 return ret;
1627}
1628
1629static const struct file_operations fops_nf_cal_period = {
1630 .read = ath10k_read_nf_cal_period,
1631 .write = ath10k_write_nf_cal_period,
1632 .open = simple_open,
1633 .owner = THIS_MODULE,
1634 .llseek = default_llseek,
1635};
1636
29542666
MK
1637#define ATH10K_TPC_CONFIG_BUF_SIZE (1024 * 1024)
1638
1639static int ath10k_debug_tpc_stats_request(struct ath10k *ar)
1640{
1641 int ret;
1642 unsigned long time_left;
1643
1644 lockdep_assert_held(&ar->conf_mutex);
1645
1646 reinit_completion(&ar->debug.tpc_complete);
1647
1648 ret = ath10k_wmi_pdev_get_tpc_config(ar, WMI_TPC_CONFIG_PARAM);
1649 if (ret) {
1650 ath10k_warn(ar, "failed to request tpc config: %d\n", ret);
1651 return ret;
1652 }
1653
1654 time_left = wait_for_completion_timeout(&ar->debug.tpc_complete,
1655 1 * HZ);
1656 if (time_left == 0)
1657 return -ETIMEDOUT;
1658
1659 return 0;
1660}
1661
1662void ath10k_debug_tpc_stats_process(struct ath10k *ar,
1663 struct ath10k_tpc_stats *tpc_stats)
1664{
1665 spin_lock_bh(&ar->data_lock);
1666
1667 kfree(ar->debug.tpc_stats);
1668 ar->debug.tpc_stats = tpc_stats;
1669 complete(&ar->debug.tpc_complete);
1670
1671 spin_unlock_bh(&ar->data_lock);
1672}
1673
1674static void ath10k_tpc_stats_print(struct ath10k_tpc_stats *tpc_stats,
1675 unsigned int j, char *buf, unsigned int *len)
1676{
1677 unsigned int i, buf_len;
1678 static const char table_str[][5] = { "CDD",
1679 "STBC",
1680 "TXBF" };
1681 static const char pream_str[][6] = { "CCK",
1682 "OFDM",
1683 "HT20",
1684 "HT40",
1685 "VHT20",
1686 "VHT40",
1687 "VHT80",
1688 "HTCUP" };
1689
1690 buf_len = ATH10K_TPC_CONFIG_BUF_SIZE;
1691 *len += scnprintf(buf + *len, buf_len - *len,
1692 "********************************\n");
1693 *len += scnprintf(buf + *len, buf_len - *len,
1694 "******************* %s POWER TABLE ****************\n",
1695 table_str[j]);
1696 *len += scnprintf(buf + *len, buf_len - *len,
1697 "********************************\n");
1698 *len += scnprintf(buf + *len, buf_len - *len,
1699 "No. Preamble Rate_code tpc_value1 tpc_value2 tpc_value3\n");
1700
1701 for (i = 0; i < tpc_stats->rate_max; i++) {
1702 *len += scnprintf(buf + *len, buf_len - *len,
1703 "%8d %s 0x%2x %s\n", i,
1704 pream_str[tpc_stats->tpc_table[j].pream_idx[i]],
1705 tpc_stats->tpc_table[j].rate_code[i],
1706 tpc_stats->tpc_table[j].tpc_value[i]);
1707 }
1708
1709 *len += scnprintf(buf + *len, buf_len - *len,
1710 "***********************************\n");
1711}
1712
1713static void ath10k_tpc_stats_fill(struct ath10k *ar,
1714 struct ath10k_tpc_stats *tpc_stats,
1715 char *buf)
1716{
1717 unsigned int len, j, buf_len;
1718
1719 len = 0;
1720 buf_len = ATH10K_TPC_CONFIG_BUF_SIZE;
1721
1722 spin_lock_bh(&ar->data_lock);
1723
1724 if (!tpc_stats) {
1725 ath10k_warn(ar, "failed to get tpc stats\n");
1726 goto unlock;
1727 }
1728
1729 len += scnprintf(buf + len, buf_len - len, "\n");
1730 len += scnprintf(buf + len, buf_len - len,
1731 "*************************************\n");
1732 len += scnprintf(buf + len, buf_len - len,
1733 "TPC config for channel %4d mode %d\n",
1734 tpc_stats->chan_freq,
1735 tpc_stats->phy_mode);
1736 len += scnprintf(buf + len, buf_len - len,
1737 "*************************************\n");
1738 len += scnprintf(buf + len, buf_len - len,
1739 "CTL = 0x%2x Reg. Domain = %2d\n",
1740 tpc_stats->ctl,
1741 tpc_stats->reg_domain);
1742 len += scnprintf(buf + len, buf_len - len,
1743 "Antenna Gain = %2d Reg. Max Antenna Gain = %2d\n",
1744 tpc_stats->twice_antenna_gain,
1745 tpc_stats->twice_antenna_reduction);
1746 len += scnprintf(buf + len, buf_len - len,
1747 "Power Limit = %2d Reg. Max Power = %2d\n",
1748 tpc_stats->power_limit,
1749 tpc_stats->twice_max_rd_power / 2);
1750 len += scnprintf(buf + len, buf_len - len,
1751 "Num tx chains = %2d Num supported rates = %2d\n",
1752 tpc_stats->num_tx_chain,
1753 tpc_stats->rate_max);
1754
1755 for (j = 0; j < tpc_stats->num_tx_chain ; j++) {
1756 switch (j) {
1757 case WMI_TPC_TABLE_TYPE_CDD:
1758 if (tpc_stats->flag[j] == ATH10K_TPC_TABLE_TYPE_FLAG) {
1759 len += scnprintf(buf + len, buf_len - len,
1760 "CDD not supported\n");
1761 break;
1762 }
1763
1764 ath10k_tpc_stats_print(tpc_stats, j, buf, &len);
1765 break;
1766 case WMI_TPC_TABLE_TYPE_STBC:
1767 if (tpc_stats->flag[j] == ATH10K_TPC_TABLE_TYPE_FLAG) {
1768 len += scnprintf(buf + len, buf_len - len,
1769 "STBC not supported\n");
1770 break;
1771 }
1772
1773 ath10k_tpc_stats_print(tpc_stats, j, buf, &len);
1774 break;
1775 case WMI_TPC_TABLE_TYPE_TXBF:
1776 if (tpc_stats->flag[j] == ATH10K_TPC_TABLE_TYPE_FLAG) {
1777 len += scnprintf(buf + len, buf_len - len,
1778 "TXBF not supported\n***************************\n");
1779 break;
1780 }
1781
1782 ath10k_tpc_stats_print(tpc_stats, j, buf, &len);
1783 break;
1784 default:
1785 len += scnprintf(buf + len, buf_len - len,
1786 "Invalid Type\n");
1787 break;
1788 }
1789 }
1790
1791unlock:
1792 spin_unlock_bh(&ar->data_lock);
1793
1794 if (len >= buf_len)
1795 buf[len - 1] = 0;
1796 else
1797 buf[len] = 0;
1798}
1799
1800static int ath10k_tpc_stats_open(struct inode *inode, struct file *file)
1801{
1802 struct ath10k *ar = inode->i_private;
1803 void *buf = NULL;
1804 int ret;
1805
1806 mutex_lock(&ar->conf_mutex);
1807
1808 if (ar->state != ATH10K_STATE_ON) {
1809 ret = -ENETDOWN;
1810 goto err_unlock;
1811 }
1812
1813 buf = vmalloc(ATH10K_TPC_CONFIG_BUF_SIZE);
1814 if (!buf) {
1815 ret = -ENOMEM;
1816 goto err_unlock;
1817 }
1818
1819 ret = ath10k_debug_tpc_stats_request(ar);
1820 if (ret) {
1821 ath10k_warn(ar, "failed to request tpc config stats: %d\n",
1822 ret);
1823 goto err_free;
1824 }
1825
1826 ath10k_tpc_stats_fill(ar, ar->debug.tpc_stats, buf);
1827 file->private_data = buf;
1828
1829 mutex_unlock(&ar->conf_mutex);
1830 return 0;
1831
1832err_free:
1833 vfree(buf);
1834
1835err_unlock:
1836 mutex_unlock(&ar->conf_mutex);
1837 return ret;
1838}
1839
1840static int ath10k_tpc_stats_release(struct inode *inode, struct file *file)
1841{
1842 vfree(file->private_data);
1843
1844 return 0;
1845}
1846
1847static ssize_t ath10k_tpc_stats_read(struct file *file, char __user *user_buf,
1848 size_t count, loff_t *ppos)
1849{
1850 const char *buf = file->private_data;
1851 unsigned int len = strlen(buf);
1852
1853 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1854}
1855
1856static const struct file_operations fops_tpc_stats = {
1857 .open = ath10k_tpc_stats_open,
1858 .release = ath10k_tpc_stats_release,
1859 .read = ath10k_tpc_stats_read,
1860 .owner = THIS_MODULE,
1861 .llseek = default_llseek,
1862};
1863
db66ea04
KV
1864int ath10k_debug_start(struct ath10k *ar)
1865{
a3d135e5
KV
1866 int ret;
1867
60631c5c
KV
1868 lockdep_assert_held(&ar->conf_mutex);
1869
a3d135e5
KV
1870 ret = ath10k_debug_htt_stats_req(ar);
1871 if (ret)
1872 /* continue normally anyway, this isn't serious */
7aa7a72a
MK
1873 ath10k_warn(ar, "failed to start htt stats workqueue: %d\n",
1874 ret);
a3d135e5 1875
f118a3e5 1876 if (ar->debug.fw_dbglog_mask) {
467210a6
SJ
1877 ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask,
1878 ATH10K_DBGLOG_LEVEL_WARN);
f118a3e5
KV
1879 if (ret)
1880 /* not serious */
7aa7a72a 1881 ath10k_warn(ar, "failed to enable dbglog during start: %d",
f118a3e5
KV
1882 ret);
1883 }
1884
90174455
RM
1885 if (ar->debug.pktlog_filter) {
1886 ret = ath10k_wmi_pdev_pktlog_enable(ar,
1887 ar->debug.pktlog_filter);
1888 if (ret)
1889 /* not serious */
1890 ath10k_warn(ar,
1891 "failed to enable pktlog filter %x: %d\n",
1892 ar->debug.pktlog_filter, ret);
1893 } else {
1894 ret = ath10k_wmi_pdev_pktlog_disable(ar);
1895 if (ret)
1896 /* not serious */
1897 ath10k_warn(ar, "failed to disable pktlog: %d\n", ret);
1898 }
1899
a7bd3e99
PO
1900 if (ar->debug.nf_cal_period) {
1901 ret = ath10k_wmi_pdev_set_param(ar,
1902 ar->wmi.pdev_param->cal_period,
1903 ar->debug.nf_cal_period);
1904 if (ret)
1905 /* not serious */
1906 ath10k_warn(ar, "cal period cfg failed from debug start: %d\n",
1907 ret);
1908 }
1909
90174455 1910 return ret;
db66ea04
KV
1911}
1912
1913void ath10k_debug_stop(struct ath10k *ar)
1914{
60631c5c
KV
1915 lockdep_assert_held(&ar->conf_mutex);
1916
1917 /* Must not use _sync to avoid deadlock, we do that in
1918 * ath10k_debug_destroy(). The check for htt_stats_mask is to avoid
1919 * warning from del_timer(). */
1920 if (ar->debug.htt_stats_mask != 0)
1921 cancel_delayed_work(&ar->debug.htt_stats_dwork);
d385623a 1922
90174455 1923 ath10k_wmi_pdev_pktlog_disable(ar);
db66ea04
KV
1924}
1925
9702c686
JD
1926static ssize_t ath10k_write_simulate_radar(struct file *file,
1927 const char __user *user_buf,
1928 size_t count, loff_t *ppos)
1929{
1930 struct ath10k *ar = file->private_data;
1931
1932 ieee80211_radar_detected(ar->hw);
1933
1934 return count;
1935}
1936
1937static const struct file_operations fops_simulate_radar = {
1938 .write = ath10k_write_simulate_radar,
1939 .open = simple_open,
1940 .owner = THIS_MODULE,
1941 .llseek = default_llseek,
1942};
1943
1944#define ATH10K_DFS_STAT(s, p) (\
1945 len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \
1946 ar->debug.dfs_stats.p))
1947
1948#define ATH10K_DFS_POOL_STAT(s, p) (\
1949 len += scnprintf(buf + len, size - len, "%-28s : %10u\n", s, \
1950 ar->debug.dfs_pool_stats.p))
1951
1952static ssize_t ath10k_read_dfs_stats(struct file *file, char __user *user_buf,
1953 size_t count, loff_t *ppos)
1954{
1955 int retval = 0, len = 0;
1956 const int size = 8000;
1957 struct ath10k *ar = file->private_data;
1958 char *buf;
1959
1960 buf = kzalloc(size, GFP_KERNEL);
1961 if (buf == NULL)
1962 return -ENOMEM;
1963
1964 if (!ar->dfs_detector) {
1965 len += scnprintf(buf + len, size - len, "DFS not enabled\n");
1966 goto exit;
1967 }
1968
1969 ar->debug.dfs_pool_stats =
1970 ar->dfs_detector->get_stats(ar->dfs_detector);
1971
1972 len += scnprintf(buf + len, size - len, "Pulse detector statistics:\n");
1973
1974 ATH10K_DFS_STAT("reported phy errors", phy_errors);
1975 ATH10K_DFS_STAT("pulse events reported", pulses_total);
1976 ATH10K_DFS_STAT("DFS pulses detected", pulses_detected);
1977 ATH10K_DFS_STAT("DFS pulses discarded", pulses_discarded);
1978 ATH10K_DFS_STAT("Radars detected", radar_detected);
1979
1980 len += scnprintf(buf + len, size - len, "Global Pool statistics:\n");
1981 ATH10K_DFS_POOL_STAT("Pool references", pool_reference);
1982 ATH10K_DFS_POOL_STAT("Pulses allocated", pulse_allocated);
1983 ATH10K_DFS_POOL_STAT("Pulses alloc error", pulse_alloc_error);
1984 ATH10K_DFS_POOL_STAT("Pulses in use", pulse_used);
1985 ATH10K_DFS_POOL_STAT("Seqs. allocated", pseq_allocated);
1986 ATH10K_DFS_POOL_STAT("Seqs. alloc error", pseq_alloc_error);
1987 ATH10K_DFS_POOL_STAT("Seqs. in use", pseq_used);
1988
1989exit:
1990 if (len > size)
1991 len = size;
1992
1993 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1994 kfree(buf);
1995
1996 return retval;
1997}
1998
1999static const struct file_operations fops_dfs_stats = {
2000 .read = ath10k_read_dfs_stats,
2001 .open = simple_open,
2002 .owner = THIS_MODULE,
2003 .llseek = default_llseek,
2004};
2005
90174455
RM
2006static ssize_t ath10k_write_pktlog_filter(struct file *file,
2007 const char __user *ubuf,
2008 size_t count, loff_t *ppos)
2009{
2010 struct ath10k *ar = file->private_data;
2011 u32 filter;
2012 int ret;
2013
2014 if (kstrtouint_from_user(ubuf, count, 0, &filter))
2015 return -EINVAL;
2016
2017 mutex_lock(&ar->conf_mutex);
2018
2019 if (ar->state != ATH10K_STATE_ON) {
2020 ar->debug.pktlog_filter = filter;
2021 ret = count;
2022 goto out;
2023 }
2024
9ddc486a
AK
2025 if (filter == ar->debug.pktlog_filter) {
2026 ret = count;
2027 goto out;
2028 }
2029
2030 if (filter) {
90174455
RM
2031 ret = ath10k_wmi_pdev_pktlog_enable(ar, filter);
2032 if (ret) {
2033 ath10k_warn(ar, "failed to enable pktlog filter %x: %d\n",
2034 ar->debug.pktlog_filter, ret);
2035 goto out;
2036 }
2037 } else {
2038 ret = ath10k_wmi_pdev_pktlog_disable(ar);
2039 if (ret) {
2040 ath10k_warn(ar, "failed to disable pktlog: %d\n", ret);
2041 goto out;
2042 }
2043 }
2044
2045 ar->debug.pktlog_filter = filter;
2046 ret = count;
2047
2048out:
2049 mutex_unlock(&ar->conf_mutex);
2050 return ret;
2051}
2052
2053static ssize_t ath10k_read_pktlog_filter(struct file *file, char __user *ubuf,
2054 size_t count, loff_t *ppos)
2055{
2056 char buf[32];
2057 struct ath10k *ar = file->private_data;
2058 int len = 0;
2059
2060 mutex_lock(&ar->conf_mutex);
2061 len = scnprintf(buf, sizeof(buf) - len, "%08x\n",
2062 ar->debug.pktlog_filter);
2063 mutex_unlock(&ar->conf_mutex);
2064
2065 return simple_read_from_buffer(ubuf, count, ppos, buf, len);
2066}
2067
2068static const struct file_operations fops_pktlog_filter = {
2069 .read = ath10k_read_pktlog_filter,
2070 .write = ath10k_write_pktlog_filter,
2071 .open = simple_open
2072};
2073
63fb32df
RM
2074static ssize_t ath10k_write_quiet_period(struct file *file,
2075 const char __user *ubuf,
2076 size_t count, loff_t *ppos)
2077{
2078 struct ath10k *ar = file->private_data;
2079 u32 period;
2080
2081 if (kstrtouint_from_user(ubuf, count, 0, &period))
2082 return -EINVAL;
2083
2084 if (period < ATH10K_QUIET_PERIOD_MIN) {
2085 ath10k_warn(ar, "Quiet period %u can not be lesser than 25ms\n",
2086 period);
2087 return -EINVAL;
2088 }
2089 mutex_lock(&ar->conf_mutex);
2090 ar->thermal.quiet_period = period;
8515b5c7 2091 ath10k_thermal_set_throttling(ar);
63fb32df
RM
2092 mutex_unlock(&ar->conf_mutex);
2093
2094 return count;
2095}
2096
2097static ssize_t ath10k_read_quiet_period(struct file *file, char __user *ubuf,
2098 size_t count, loff_t *ppos)
2099{
2100 char buf[32];
2101 struct ath10k *ar = file->private_data;
2102 int len = 0;
2103
2104 mutex_lock(&ar->conf_mutex);
2105 len = scnprintf(buf, sizeof(buf) - len, "%d\n",
2106 ar->thermal.quiet_period);
2107 mutex_unlock(&ar->conf_mutex);
2108
2109 return simple_read_from_buffer(ubuf, count, ppos, buf, len);
2110}
2111
2112static const struct file_operations fops_quiet_period = {
2113 .read = ath10k_read_quiet_period,
2114 .write = ath10k_write_quiet_period,
2115 .open = simple_open
2116};
2117
844fa572
YL
2118static ssize_t ath10k_write_btcoex(struct file *file,
2119 const char __user *ubuf,
2120 size_t count, loff_t *ppos)
2121{
2122 struct ath10k *ar = file->private_data;
2123 char buf[32];
2124 size_t buf_size;
c28e6f06 2125 int ret = 0;
844fa572
YL
2126 bool val;
2127
2128 buf_size = min(count, (sizeof(buf) - 1));
2129 if (copy_from_user(buf, ubuf, buf_size))
2130 return -EFAULT;
2131
2132 buf[buf_size] = '\0';
2133
2134 if (strtobool(buf, &val) != 0)
2135 return -EINVAL;
2136
2137 mutex_lock(&ar->conf_mutex);
2138
c28e6f06
MSS
2139 if (ar->state != ATH10K_STATE_ON &&
2140 ar->state != ATH10K_STATE_RESTARTED) {
2141 ret = -ENETDOWN;
2142 goto exit;
2143 }
2144
844fa572
YL
2145 if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags) ^ val))
2146 goto exit;
2147
2148 if (val)
2149 set_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
2150 else
2151 clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
2152
844fa572
YL
2153 ath10k_info(ar, "restarting firmware due to btcoex change");
2154
2155 queue_work(ar->workqueue, &ar->restart_work);
c28e6f06 2156 ret = count;
844fa572
YL
2157
2158exit:
2159 mutex_unlock(&ar->conf_mutex);
2160
c28e6f06 2161 return ret;
844fa572
YL
2162}
2163
2164static ssize_t ath10k_read_btcoex(struct file *file, char __user *ubuf,
2165 size_t count, loff_t *ppos)
2166{
2167 char buf[32];
2168 struct ath10k *ar = file->private_data;
2169 int len = 0;
2170
2171 mutex_lock(&ar->conf_mutex);
2172 len = scnprintf(buf, sizeof(buf) - len, "%d\n",
2173 test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags));
2174 mutex_unlock(&ar->conf_mutex);
2175
2176 return simple_read_from_buffer(ubuf, count, ppos, buf, len);
2177}
2178
2179static const struct file_operations fops_btcoex = {
2180 .read = ath10k_read_btcoex,
2181 .write = ath10k_write_btcoex,
2182 .open = simple_open
2183};
2184
cc61a1bb
MSS
2185static ssize_t ath10k_write_peer_stats(struct file *file,
2186 const char __user *ubuf,
2187 size_t count, loff_t *ppos)
2188{
2189 struct ath10k *ar = file->private_data;
2190 char buf[32];
2191 size_t buf_size;
2192 int ret = 0;
2193 bool val;
2194
2195 buf_size = min(count, (sizeof(buf) - 1));
2196 if (copy_from_user(buf, ubuf, buf_size))
2197 return -EFAULT;
2198
2199 buf[buf_size] = '\0';
2200
2201 if (strtobool(buf, &val) != 0)
2202 return -EINVAL;
2203
2204 mutex_lock(&ar->conf_mutex);
2205
2206 if (ar->state != ATH10K_STATE_ON &&
2207 ar->state != ATH10K_STATE_RESTARTED) {
2208 ret = -ENETDOWN;
2209 goto exit;
2210 }
2211
2212 if (!(test_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags) ^ val))
2213 goto exit;
2214
2215 if (val)
2216 set_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags);
2217 else
2218 clear_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags);
2219
2220 ath10k_info(ar, "restarting firmware due to Peer stats change");
2221
2222 queue_work(ar->workqueue, &ar->restart_work);
2223 ret = count;
2224
2225exit:
2226 mutex_unlock(&ar->conf_mutex);
2227 return ret;
2228}
2229
2230static ssize_t ath10k_read_peer_stats(struct file *file, char __user *ubuf,
2231 size_t count, loff_t *ppos)
2232
2233{
2234 char buf[32];
2235 struct ath10k *ar = file->private_data;
2236 int len = 0;
2237
2238 mutex_lock(&ar->conf_mutex);
2239 len = scnprintf(buf, sizeof(buf) - len, "%d\n",
2240 test_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags));
2241 mutex_unlock(&ar->conf_mutex);
2242
2243 return simple_read_from_buffer(ubuf, count, ppos, buf, len);
2244}
2245
2246static const struct file_operations fops_peer_stats = {
2247 .read = ath10k_read_peer_stats,
2248 .write = ath10k_write_peer_stats,
2249 .open = simple_open
2250};
2251
9e100c4d
KV
2252static ssize_t ath10k_debug_fw_checksums_read(struct file *file,
2253 char __user *user_buf,
2254 size_t count, loff_t *ppos)
2255{
2256 struct ath10k *ar = file->private_data;
2257 unsigned int len = 0, buf_len = 4096;
2258 ssize_t ret_cnt;
2259 char *buf;
2260
2261 buf = kzalloc(buf_len, GFP_KERNEL);
2262 if (!buf)
2263 return -ENOMEM;
2264
2265 mutex_lock(&ar->conf_mutex);
2266
9e100c4d
KV
2267 len += scnprintf(buf + len, buf_len - len,
2268 "firmware-N.bin\t\t%08x\n",
2269 crc32_le(0, ar->firmware->data, ar->firmware->size));
2270 len += scnprintf(buf + len, buf_len - len,
2271 "athwlan\t\t\t%08x\n",
2272 crc32_le(0, ar->firmware_data, ar->firmware_len));
2273 len += scnprintf(buf + len, buf_len - len,
2274 "otp\t\t\t%08x\n",
2275 crc32_le(0, ar->otp_data, ar->otp_len));
2276 len += scnprintf(buf + len, buf_len - len,
2277 "codeswap\t\t%08x\n",
2278 crc32_le(0, ar->swap.firmware_codeswap_data,
2279 ar->swap.firmware_codeswap_len));
2280 len += scnprintf(buf + len, buf_len - len,
2281 "board-N.bin\t\t%08x\n",
2282 crc32_le(0, ar->board->data, ar->board->size));
2283 len += scnprintf(buf + len, buf_len - len,
2284 "board\t\t\t%08x\n",
2285 crc32_le(0, ar->board_data, ar->board_len));
2286
2287 ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
2288
2289 mutex_unlock(&ar->conf_mutex);
2290
2291 kfree(buf);
2292 return ret_cnt;
2293}
2294
2295static const struct file_operations fops_fw_checksums = {
2296 .read = ath10k_debug_fw_checksums_read,
2297 .open = simple_open,
2298 .owner = THIS_MODULE,
2299 .llseek = default_llseek,
2300};
2301
5e3dd157
KV
2302int ath10k_debug_create(struct ath10k *ar)
2303{
384914b2 2304 ar->debug.fw_crash_data = vzalloc(sizeof(*ar->debug.fw_crash_data));
e13cf7a3
MK
2305 if (!ar->debug.fw_crash_data)
2306 return -ENOMEM;
384914b2 2307
5326849a 2308 INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs);
7b6b153a 2309 INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs);
5326849a
MK
2310 INIT_LIST_HEAD(&ar->debug.fw_stats.peers);
2311
e13cf7a3
MK
2312 return 0;
2313}
2314
2315void ath10k_debug_destroy(struct ath10k *ar)
2316{
2317 vfree(ar->debug.fw_crash_data);
2318 ar->debug.fw_crash_data = NULL;
5326849a
MK
2319
2320 ath10k_debug_fw_stats_reset(ar);
29542666
MK
2321
2322 kfree(ar->debug.tpc_stats);
e13cf7a3
MK
2323}
2324
2325int ath10k_debug_register(struct ath10k *ar)
2326{
5e3dd157
KV
2327 ar->debug.debugfs_phy = debugfs_create_dir("ath10k",
2328 ar->hw->wiphy->debugfsdir);
adb43b24
MK
2329 if (IS_ERR_OR_NULL(ar->debug.debugfs_phy)) {
2330 if (IS_ERR(ar->debug.debugfs_phy))
2331 return PTR_ERR(ar->debug.debugfs_phy);
d8bb26b9
KV
2332
2333 return -ENOMEM;
adb43b24 2334 }
5e3dd157 2335
a3d135e5
KV
2336 INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork,
2337 ath10k_debug_htt_stats_dwork);
2338
29542666 2339 init_completion(&ar->debug.tpc_complete);
60ef401a 2340 init_completion(&ar->debug.fw_stats_complete);
5e3dd157
KV
2341
2342 debugfs_create_file("fw_stats", S_IRUSR, ar->debug.debugfs_phy, ar,
2343 &fops_fw_stats);
2344
f51dbe73
BG
2345 debugfs_create_file("fw_reset_stats", S_IRUSR, ar->debug.debugfs_phy,
2346 ar, &fops_fw_reset_stats);
2347
5e3dd157
KV
2348 debugfs_create_file("wmi_services", S_IRUSR, ar->debug.debugfs_phy, ar,
2349 &fops_wmi_services);
2350
8bf1ba1c
MSS
2351 debugfs_create_file("simulate_fw_crash", S_IRUSR | S_IWUSR,
2352 ar->debug.debugfs_phy, ar, &fops_simulate_fw_crash);
278c4a85 2353
384914b2
BG
2354 debugfs_create_file("fw_crash_dump", S_IRUSR, ar->debug.debugfs_phy,
2355 ar, &fops_fw_crash_dump);
2356
077a3804
YL
2357 debugfs_create_file("reg_addr", S_IRUSR | S_IWUSR,
2358 ar->debug.debugfs_phy, ar, &fops_reg_addr);
2359
2360 debugfs_create_file("reg_value", S_IRUSR | S_IWUSR,
2361 ar->debug.debugfs_phy, ar, &fops_reg_value);
2362
9f65ad25
YL
2363 debugfs_create_file("mem_value", S_IRUSR | S_IWUSR,
2364 ar->debug.debugfs_phy, ar, &fops_mem_value);
2365
763b8cd3
KV
2366 debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy,
2367 ar, &fops_chip_id);
2368
8bf1ba1c
MSS
2369 debugfs_create_file("htt_stats_mask", S_IRUSR | S_IWUSR,
2370 ar->debug.debugfs_phy, ar, &fops_htt_stats_mask);
a3d135e5 2371
d385623a
JD
2372 debugfs_create_file("htt_max_amsdu_ampdu", S_IRUSR | S_IWUSR,
2373 ar->debug.debugfs_phy, ar,
2374 &fops_htt_max_amsdu_ampdu);
2375
8bf1ba1c
MSS
2376 debugfs_create_file("fw_dbglog", S_IRUSR | S_IWUSR,
2377 ar->debug.debugfs_phy, ar, &fops_fw_dbglog);
f118a3e5 2378
7869b4fa
KV
2379 debugfs_create_file("cal_data", S_IRUSR, ar->debug.debugfs_phy,
2380 ar, &fops_cal_data);
2381
b3e71d7a
ARN
2382 debugfs_create_file("ani_enable", S_IRUSR | S_IWUSR,
2383 ar->debug.debugfs_phy, ar, &fops_ani_enable);
2384
a7bd3e99
PO
2385 debugfs_create_file("nf_cal_period", S_IRUSR | S_IWUSR,
2386 ar->debug.debugfs_phy, ar, &fops_nf_cal_period);
2387
9702c686
JD
2388 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) {
2389 debugfs_create_file("dfs_simulate_radar", S_IWUSR,
2390 ar->debug.debugfs_phy, ar,
2391 &fops_simulate_radar);
2392
7d9b40b4
MP
2393 debugfs_create_bool("dfs_block_radar_events", S_IWUSR,
2394 ar->debug.debugfs_phy,
2395 &ar->dfs_block_radar_events);
2396
9702c686
JD
2397 debugfs_create_file("dfs_stats", S_IRUSR,
2398 ar->debug.debugfs_phy, ar,
2399 &fops_dfs_stats);
2400 }
2401
90174455
RM
2402 debugfs_create_file("pktlog_filter", S_IRUGO | S_IWUSR,
2403 ar->debug.debugfs_phy, ar, &fops_pktlog_filter);
2404
63fb32df
RM
2405 debugfs_create_file("quiet_period", S_IRUGO | S_IWUSR,
2406 ar->debug.debugfs_phy, ar, &fops_quiet_period);
2407
29542666
MK
2408 debugfs_create_file("tpc_stats", S_IRUSR,
2409 ar->debug.debugfs_phy, ar, &fops_tpc_stats);
2410
844fa572
YL
2411 if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map))
2412 debugfs_create_file("btcoex", S_IRUGO | S_IWUSR,
2413 ar->debug.debugfs_phy, ar, &fops_btcoex);
2414
cc61a1bb
MSS
2415 if (test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map))
2416 debugfs_create_file("peer_stats", S_IRUGO | S_IWUSR,
2417 ar->debug.debugfs_phy, ar,
2418 &fops_peer_stats);
2419
9e100c4d
KV
2420 debugfs_create_file("fw_checksums", S_IRUSR,
2421 ar->debug.debugfs_phy, ar, &fops_fw_checksums);
2422
5e3dd157
KV
2423 return 0;
2424}
db66ea04 2425
e13cf7a3 2426void ath10k_debug_unregister(struct ath10k *ar)
60631c5c
KV
2427{
2428 cancel_delayed_work_sync(&ar->debug.htt_stats_dwork);
2429}
2430
5e3dd157
KV
2431#endif /* CONFIG_ATH10K_DEBUGFS */
2432
2433#ifdef CONFIG_ATH10K_DEBUG
7aa7a72a
MK
2434void ath10k_dbg(struct ath10k *ar, enum ath10k_debug_mask mask,
2435 const char *fmt, ...)
5e3dd157
KV
2436{
2437 struct va_format vaf;
2438 va_list args;
2439
2440 va_start(args, fmt);
2441
2442 vaf.fmt = fmt;
2443 vaf.va = &args;
2444
2445 if (ath10k_debug_mask & mask)
7aa7a72a 2446 dev_printk(KERN_DEBUG, ar->dev, "%pV", &vaf);
5e3dd157 2447
d35a6c18 2448 trace_ath10k_log_dbg(ar, mask, &vaf);
5e3dd157
KV
2449
2450 va_end(args);
2451}
2452EXPORT_SYMBOL(ath10k_dbg);
2453
7aa7a72a
MK
2454void ath10k_dbg_dump(struct ath10k *ar,
2455 enum ath10k_debug_mask mask,
5e3dd157
KV
2456 const char *msg, const char *prefix,
2457 const void *buf, size_t len)
2458{
45724a8a
MK
2459 char linebuf[256];
2460 unsigned int linebuflen;
2461 const void *ptr;
2462
5e3dd157
KV
2463 if (ath10k_debug_mask & mask) {
2464 if (msg)
7aa7a72a 2465 ath10k_dbg(ar, mask, "%s\n", msg);
5e3dd157 2466
45724a8a
MK
2467 for (ptr = buf; (ptr - buf) < len; ptr += 16) {
2468 linebuflen = 0;
2469 linebuflen += scnprintf(linebuf + linebuflen,
2470 sizeof(linebuf) - linebuflen,
2471 "%s%08x: ",
2472 (prefix ? prefix : ""),
2473 (unsigned int)(ptr - buf));
2474 hex_dump_to_buffer(ptr, len - (ptr - buf), 16, 1,
2475 linebuf + linebuflen,
2476 sizeof(linebuf) - linebuflen, true);
2477 dev_printk(KERN_DEBUG, ar->dev, "%s\n", linebuf);
2478 }
5e3dd157
KV
2479 }
2480
2481 /* tracing code doesn't like null strings :/ */
d35a6c18 2482 trace_ath10k_log_dbg_dump(ar, msg ? msg : "", prefix ? prefix : "",
5e3dd157
KV
2483 buf, len);
2484}
2485EXPORT_SYMBOL(ath10k_dbg_dump);
2486
2487#endif /* CONFIG_ATH10K_DEBUG */