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