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