Loading...
1// SPDX-License-Identifier: BSD-3-Clause-Clear
2/*
3 * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
4 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
5 */
6
7#include <linux/vmalloc.h>
8
9#include "debugfs.h"
10
11#include "core.h"
12#include "debug.h"
13#include "wmi.h"
14#include "hal_rx.h"
15#include "dp_tx.h"
16#include "debugfs_htt_stats.h"
17#include "peer.h"
18#include "hif.h"
19
20static const char *htt_bp_umac_ring[HTT_SW_UMAC_RING_IDX_MAX] = {
21 "REO2SW1_RING",
22 "REO2SW2_RING",
23 "REO2SW3_RING",
24 "REO2SW4_RING",
25 "WBM2REO_LINK_RING",
26 "REO2TCL_RING",
27 "REO2FW_RING",
28 "RELEASE_RING",
29 "PPE_RELEASE_RING",
30 "TCL2TQM_RING",
31 "TQM_RELEASE_RING",
32 "REO_RELEASE_RING",
33 "WBM2SW0_RELEASE_RING",
34 "WBM2SW1_RELEASE_RING",
35 "WBM2SW2_RELEASE_RING",
36 "WBM2SW3_RELEASE_RING",
37 "REO_CMD_RING",
38 "REO_STATUS_RING",
39};
40
41static const char *htt_bp_lmac_ring[HTT_SW_LMAC_RING_IDX_MAX] = {
42 "FW2RXDMA_BUF_RING",
43 "FW2RXDMA_STATUS_RING",
44 "FW2RXDMA_LINK_RING",
45 "SW2RXDMA_BUF_RING",
46 "WBM2RXDMA_LINK_RING",
47 "RXDMA2FW_RING",
48 "RXDMA2SW_RING",
49 "RXDMA2RELEASE_RING",
50 "RXDMA2REO_RING",
51 "MONITOR_STATUS_RING",
52 "MONITOR_BUF_RING",
53 "MONITOR_DESC_RING",
54 "MONITOR_DEST_RING",
55};
56
57void ath11k_debugfs_add_dbring_entry(struct ath11k *ar,
58 enum wmi_direct_buffer_module id,
59 enum ath11k_dbg_dbr_event event,
60 struct hal_srng *srng)
61{
62 struct ath11k_debug_dbr *dbr_debug;
63 struct ath11k_dbg_dbr_data *dbr_data;
64 struct ath11k_dbg_dbr_entry *entry;
65
66 if (id >= WMI_DIRECT_BUF_MAX || event >= ATH11K_DBG_DBR_EVENT_MAX)
67 return;
68
69 dbr_debug = ar->debug.dbr_debug[id];
70 if (!dbr_debug)
71 return;
72
73 if (!dbr_debug->dbr_debug_enabled)
74 return;
75
76 dbr_data = &dbr_debug->dbr_dbg_data;
77
78 spin_lock_bh(&dbr_data->lock);
79
80 if (dbr_data->entries) {
81 entry = &dbr_data->entries[dbr_data->dbr_debug_idx];
82 entry->hp = srng->u.src_ring.hp;
83 entry->tp = *srng->u.src_ring.tp_addr;
84 entry->timestamp = jiffies;
85 entry->event = event;
86
87 dbr_data->dbr_debug_idx++;
88 if (dbr_data->dbr_debug_idx ==
89 dbr_data->num_ring_debug_entries)
90 dbr_data->dbr_debug_idx = 0;
91 }
92
93 spin_unlock_bh(&dbr_data->lock);
94}
95
96static void ath11k_debugfs_fw_stats_reset(struct ath11k *ar)
97{
98 spin_lock_bh(&ar->data_lock);
99 ar->fw_stats_done = false;
100 ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs);
101 ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs);
102 spin_unlock_bh(&ar->data_lock);
103}
104
105void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *stats)
106{
107 struct ath11k_base *ab = ar->ab;
108 struct ath11k_pdev *pdev;
109 bool is_end;
110 static unsigned int num_vdev, num_bcn;
111 size_t total_vdevs_started = 0;
112 int i;
113
114 /* WMI_REQUEST_PDEV_STAT request has been already processed */
115
116 if (stats->stats_id == WMI_REQUEST_RSSI_PER_CHAIN_STAT) {
117 ar->fw_stats_done = true;
118 return;
119 }
120
121 if (stats->stats_id == WMI_REQUEST_VDEV_STAT) {
122 if (list_empty(&stats->vdevs)) {
123 ath11k_warn(ab, "empty vdev stats");
124 return;
125 }
126 /* FW sends all the active VDEV stats irrespective of PDEV,
127 * hence limit until the count of all VDEVs started
128 */
129 for (i = 0; i < ab->num_radios; i++) {
130 pdev = rcu_dereference(ab->pdevs_active[i]);
131 if (pdev && pdev->ar)
132 total_vdevs_started += ar->num_started_vdevs;
133 }
134
135 is_end = ((++num_vdev) == total_vdevs_started);
136
137 list_splice_tail_init(&stats->vdevs,
138 &ar->fw_stats.vdevs);
139
140 if (is_end) {
141 ar->fw_stats_done = true;
142 num_vdev = 0;
143 }
144 return;
145 }
146
147 if (stats->stats_id == WMI_REQUEST_BCN_STAT) {
148 if (list_empty(&stats->bcn)) {
149 ath11k_warn(ab, "empty bcn stats");
150 return;
151 }
152 /* Mark end until we reached the count of all started VDEVs
153 * within the PDEV
154 */
155 is_end = ((++num_bcn) == ar->num_started_vdevs);
156
157 list_splice_tail_init(&stats->bcn,
158 &ar->fw_stats.bcn);
159
160 if (is_end) {
161 ar->fw_stats_done = true;
162 num_bcn = 0;
163 }
164 }
165}
166
167static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
168 struct stats_request_params *req_param)
169{
170 struct ath11k_base *ab = ar->ab;
171 unsigned long timeout, time_left;
172 int ret;
173
174 lockdep_assert_held(&ar->conf_mutex);
175
176 /* FW stats can get split when exceeding the stats data buffer limit.
177 * In that case, since there is no end marking for the back-to-back
178 * received 'update stats' event, we keep a 3 seconds timeout in case,
179 * fw_stats_done is not marked yet
180 */
181 timeout = jiffies + msecs_to_jiffies(3 * 1000);
182
183 ath11k_debugfs_fw_stats_reset(ar);
184
185 reinit_completion(&ar->fw_stats_complete);
186
187 ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);
188
189 if (ret) {
190 ath11k_warn(ab, "could not request fw stats (%d)\n",
191 ret);
192 return ret;
193 }
194
195 time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ);
196
197 if (!time_left)
198 return -ETIMEDOUT;
199
200 for (;;) {
201 if (time_after(jiffies, timeout))
202 break;
203
204 spin_lock_bh(&ar->data_lock);
205 if (ar->fw_stats_done) {
206 spin_unlock_bh(&ar->data_lock);
207 break;
208 }
209 spin_unlock_bh(&ar->data_lock);
210 }
211 return 0;
212}
213
214int ath11k_debugfs_get_fw_stats(struct ath11k *ar, u32 pdev_id,
215 u32 vdev_id, u32 stats_id)
216{
217 struct ath11k_base *ab = ar->ab;
218 struct stats_request_params req_param;
219 int ret;
220
221 mutex_lock(&ar->conf_mutex);
222
223 if (ar->state != ATH11K_STATE_ON) {
224 ret = -ENETDOWN;
225 goto err_unlock;
226 }
227
228 req_param.pdev_id = pdev_id;
229 req_param.vdev_id = vdev_id;
230 req_param.stats_id = stats_id;
231
232 ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
233 if (ret)
234 ath11k_warn(ab, "failed to request fw stats: %d\n", ret);
235
236 ath11k_dbg(ab, ATH11K_DBG_WMI,
237 "debug get fw stat pdev id %d vdev id %d stats id 0x%x\n",
238 pdev_id, vdev_id, stats_id);
239
240err_unlock:
241 mutex_unlock(&ar->conf_mutex);
242
243 return ret;
244}
245
246static int ath11k_open_pdev_stats(struct inode *inode, struct file *file)
247{
248 struct ath11k *ar = inode->i_private;
249 struct ath11k_base *ab = ar->ab;
250 struct stats_request_params req_param;
251 void *buf = NULL;
252 int ret;
253
254 mutex_lock(&ar->conf_mutex);
255
256 if (ar->state != ATH11K_STATE_ON) {
257 ret = -ENETDOWN;
258 goto err_unlock;
259 }
260
261 buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
262 if (!buf) {
263 ret = -ENOMEM;
264 goto err_unlock;
265 }
266
267 req_param.pdev_id = ar->pdev->pdev_id;
268 req_param.vdev_id = 0;
269 req_param.stats_id = WMI_REQUEST_PDEV_STAT;
270
271 ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
272 if (ret) {
273 ath11k_warn(ab, "failed to request fw pdev stats: %d\n", ret);
274 goto err_free;
275 }
276
277 ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
278
279 file->private_data = buf;
280
281 mutex_unlock(&ar->conf_mutex);
282 return 0;
283
284err_free:
285 vfree(buf);
286
287err_unlock:
288 mutex_unlock(&ar->conf_mutex);
289 return ret;
290}
291
292static int ath11k_release_pdev_stats(struct inode *inode, struct file *file)
293{
294 vfree(file->private_data);
295
296 return 0;
297}
298
299static ssize_t ath11k_read_pdev_stats(struct file *file,
300 char __user *user_buf,
301 size_t count, loff_t *ppos)
302{
303 const char *buf = file->private_data;
304 size_t len = strlen(buf);
305
306 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
307}
308
309static const struct file_operations fops_pdev_stats = {
310 .open = ath11k_open_pdev_stats,
311 .release = ath11k_release_pdev_stats,
312 .read = ath11k_read_pdev_stats,
313 .owner = THIS_MODULE,
314 .llseek = default_llseek,
315};
316
317static int ath11k_open_vdev_stats(struct inode *inode, struct file *file)
318{
319 struct ath11k *ar = inode->i_private;
320 struct stats_request_params req_param;
321 void *buf = NULL;
322 int ret;
323
324 mutex_lock(&ar->conf_mutex);
325
326 if (ar->state != ATH11K_STATE_ON) {
327 ret = -ENETDOWN;
328 goto err_unlock;
329 }
330
331 buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
332 if (!buf) {
333 ret = -ENOMEM;
334 goto err_unlock;
335 }
336
337 req_param.pdev_id = ar->pdev->pdev_id;
338 /* VDEV stats is always sent for all active VDEVs from FW */
339 req_param.vdev_id = 0;
340 req_param.stats_id = WMI_REQUEST_VDEV_STAT;
341
342 ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
343 if (ret) {
344 ath11k_warn(ar->ab, "failed to request fw vdev stats: %d\n", ret);
345 goto err_free;
346 }
347
348 ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
349
350 file->private_data = buf;
351
352 mutex_unlock(&ar->conf_mutex);
353 return 0;
354
355err_free:
356 vfree(buf);
357
358err_unlock:
359 mutex_unlock(&ar->conf_mutex);
360 return ret;
361}
362
363static int ath11k_release_vdev_stats(struct inode *inode, struct file *file)
364{
365 vfree(file->private_data);
366
367 return 0;
368}
369
370static ssize_t ath11k_read_vdev_stats(struct file *file,
371 char __user *user_buf,
372 size_t count, loff_t *ppos)
373{
374 const char *buf = file->private_data;
375 size_t len = strlen(buf);
376
377 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
378}
379
380static const struct file_operations fops_vdev_stats = {
381 .open = ath11k_open_vdev_stats,
382 .release = ath11k_release_vdev_stats,
383 .read = ath11k_read_vdev_stats,
384 .owner = THIS_MODULE,
385 .llseek = default_llseek,
386};
387
388static int ath11k_open_bcn_stats(struct inode *inode, struct file *file)
389{
390 struct ath11k *ar = inode->i_private;
391 struct ath11k_vif *arvif;
392 struct stats_request_params req_param;
393 void *buf = NULL;
394 int ret;
395
396 mutex_lock(&ar->conf_mutex);
397
398 if (ar->state != ATH11K_STATE_ON) {
399 ret = -ENETDOWN;
400 goto err_unlock;
401 }
402
403 buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
404 if (!buf) {
405 ret = -ENOMEM;
406 goto err_unlock;
407 }
408
409 req_param.stats_id = WMI_REQUEST_BCN_STAT;
410 req_param.pdev_id = ar->pdev->pdev_id;
411
412 /* loop all active VDEVs for bcn stats */
413 list_for_each_entry(arvif, &ar->arvifs, list) {
414 if (!arvif->is_up)
415 continue;
416
417 req_param.vdev_id = arvif->vdev_id;
418 ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
419 if (ret) {
420 ath11k_warn(ar->ab, "failed to request fw bcn stats: %d\n", ret);
421 goto err_free;
422 }
423 }
424
425 ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
426
427 /* since beacon stats request is looped for all active VDEVs, saved fw
428 * stats is not freed for each request until done for all active VDEVs
429 */
430 spin_lock_bh(&ar->data_lock);
431 ath11k_fw_stats_bcn_free(&ar->fw_stats.bcn);
432 spin_unlock_bh(&ar->data_lock);
433
434 file->private_data = buf;
435
436 mutex_unlock(&ar->conf_mutex);
437 return 0;
438
439err_free:
440 vfree(buf);
441
442err_unlock:
443 mutex_unlock(&ar->conf_mutex);
444 return ret;
445}
446
447static int ath11k_release_bcn_stats(struct inode *inode, struct file *file)
448{
449 vfree(file->private_data);
450
451 return 0;
452}
453
454static ssize_t ath11k_read_bcn_stats(struct file *file,
455 char __user *user_buf,
456 size_t count, loff_t *ppos)
457{
458 const char *buf = file->private_data;
459 size_t len = strlen(buf);
460
461 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
462}
463
464static const struct file_operations fops_bcn_stats = {
465 .open = ath11k_open_bcn_stats,
466 .release = ath11k_release_bcn_stats,
467 .read = ath11k_read_bcn_stats,
468 .owner = THIS_MODULE,
469 .llseek = default_llseek,
470};
471
472static ssize_t ath11k_read_simulate_fw_crash(struct file *file,
473 char __user *user_buf,
474 size_t count, loff_t *ppos)
475{
476 const char buf[] =
477 "To simulate firmware crash write one of the keywords to this file:\n"
478 "`assert` - this will send WMI_FORCE_FW_HANG_CMDID to firmware to cause assert.\n"
479 "`hw-restart` - this will simply queue hw restart without fw/hw actually crashing.\n";
480
481 return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
482}
483
484/* Simulate firmware crash:
485 * 'soft': Call wmi command causing firmware hang. This firmware hang is
486 * recoverable by warm firmware reset.
487 * 'hard': Force firmware crash by setting any vdev parameter for not allowed
488 * vdev id. This is hard firmware crash because it is recoverable only by cold
489 * firmware reset.
490 */
491static ssize_t ath11k_write_simulate_fw_crash(struct file *file,
492 const char __user *user_buf,
493 size_t count, loff_t *ppos)
494{
495 struct ath11k_base *ab = file->private_data;
496 struct ath11k_pdev *pdev;
497 struct ath11k *ar = ab->pdevs[0].ar;
498 char buf[32] = {0};
499 ssize_t rc;
500 int i, ret, radioup = 0;
501
502 for (i = 0; i < ab->num_radios; i++) {
503 pdev = &ab->pdevs[i];
504 ar = pdev->ar;
505 if (ar && ar->state == ATH11K_STATE_ON) {
506 radioup = 1;
507 break;
508 }
509 }
510 /* filter partial writes and invalid commands */
511 if (*ppos != 0 || count >= sizeof(buf) || count == 0)
512 return -EINVAL;
513
514 rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
515 if (rc < 0)
516 return rc;
517
518 /* drop the possible '\n' from the end */
519 if (buf[*ppos - 1] == '\n')
520 buf[*ppos - 1] = '\0';
521
522 if (radioup == 0) {
523 ret = -ENETDOWN;
524 goto exit;
525 }
526
527 if (!strcmp(buf, "assert")) {
528 ath11k_info(ab, "simulating firmware assert crash\n");
529 ret = ath11k_wmi_force_fw_hang_cmd(ar,
530 ATH11K_WMI_FW_HANG_ASSERT_TYPE,
531 ATH11K_WMI_FW_HANG_DELAY);
532 } else if (!strcmp(buf, "hw-restart")) {
533 ath11k_info(ab, "user requested hw restart\n");
534 queue_work(ab->workqueue_aux, &ab->reset_work);
535 ret = 0;
536 } else {
537 ret = -EINVAL;
538 goto exit;
539 }
540
541 if (ret) {
542 ath11k_warn(ab, "failed to simulate firmware crash: %d\n", ret);
543 goto exit;
544 }
545
546 ret = count;
547
548exit:
549 return ret;
550}
551
552static const struct file_operations fops_simulate_fw_crash = {
553 .read = ath11k_read_simulate_fw_crash,
554 .write = ath11k_write_simulate_fw_crash,
555 .open = simple_open,
556 .owner = THIS_MODULE,
557 .llseek = default_llseek,
558};
559
560static ssize_t ath11k_write_enable_extd_tx_stats(struct file *file,
561 const char __user *ubuf,
562 size_t count, loff_t *ppos)
563{
564 struct ath11k *ar = file->private_data;
565 u32 filter;
566 int ret;
567
568 if (kstrtouint_from_user(ubuf, count, 0, &filter))
569 return -EINVAL;
570
571 mutex_lock(&ar->conf_mutex);
572
573 if (ar->state != ATH11K_STATE_ON) {
574 ret = -ENETDOWN;
575 goto out;
576 }
577
578 if (filter == ar->debug.extd_tx_stats) {
579 ret = count;
580 goto out;
581 }
582
583 ar->debug.extd_tx_stats = filter;
584 ret = count;
585
586out:
587 mutex_unlock(&ar->conf_mutex);
588 return ret;
589}
590
591static ssize_t ath11k_read_enable_extd_tx_stats(struct file *file,
592 char __user *ubuf,
593 size_t count, loff_t *ppos)
594
595{
596 char buf[32] = {0};
597 struct ath11k *ar = file->private_data;
598 int len = 0;
599
600 mutex_lock(&ar->conf_mutex);
601 len = scnprintf(buf, sizeof(buf) - len, "%08x\n",
602 ar->debug.extd_tx_stats);
603 mutex_unlock(&ar->conf_mutex);
604
605 return simple_read_from_buffer(ubuf, count, ppos, buf, len);
606}
607
608static const struct file_operations fops_extd_tx_stats = {
609 .read = ath11k_read_enable_extd_tx_stats,
610 .write = ath11k_write_enable_extd_tx_stats,
611 .open = simple_open
612};
613
614static ssize_t ath11k_write_extd_rx_stats(struct file *file,
615 const char __user *ubuf,
616 size_t count, loff_t *ppos)
617{
618 struct ath11k *ar = file->private_data;
619 struct ath11k_base *ab = ar->ab;
620 struct htt_rx_ring_tlv_filter tlv_filter = {0};
621 u32 enable, rx_filter = 0, ring_id;
622 int i;
623 int ret;
624
625 if (kstrtouint_from_user(ubuf, count, 0, &enable))
626 return -EINVAL;
627
628 mutex_lock(&ar->conf_mutex);
629
630 if (ar->state != ATH11K_STATE_ON) {
631 ret = -ENETDOWN;
632 goto exit;
633 }
634
635 if (enable > 1) {
636 ret = -EINVAL;
637 goto exit;
638 }
639
640 if (enable == ar->debug.extd_rx_stats) {
641 ret = count;
642 goto exit;
643 }
644
645 if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags)) {
646 ar->debug.extd_rx_stats = enable;
647 ret = count;
648 goto exit;
649 }
650
651 if (enable) {
652 rx_filter = HTT_RX_FILTER_TLV_FLAGS_MPDU_START;
653 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_START;
654 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END;
655 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS;
656 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT;
657 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE;
658
659 tlv_filter.rx_filter = rx_filter;
660 tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
661 tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
662 tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
663 tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
664 HTT_RX_FP_DATA_FILTER_FLASG3;
665 } else {
666 tlv_filter = ath11k_mac_mon_status_filter_default;
667 }
668
669 ar->debug.rx_filter = tlv_filter.rx_filter;
670
671 for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
672 ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
673 ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
674 HAL_RXDMA_MONITOR_STATUS,
675 DP_RX_BUFFER_SIZE, &tlv_filter);
676
677 if (ret) {
678 ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
679 goto exit;
680 }
681 }
682
683 ar->debug.extd_rx_stats = enable;
684 ret = count;
685exit:
686 mutex_unlock(&ar->conf_mutex);
687 return ret;
688}
689
690static ssize_t ath11k_read_extd_rx_stats(struct file *file,
691 char __user *ubuf,
692 size_t count, loff_t *ppos)
693{
694 struct ath11k *ar = file->private_data;
695 char buf[32];
696 int len = 0;
697
698 mutex_lock(&ar->conf_mutex);
699 len = scnprintf(buf, sizeof(buf) - len, "%d\n",
700 ar->debug.extd_rx_stats);
701 mutex_unlock(&ar->conf_mutex);
702
703 return simple_read_from_buffer(ubuf, count, ppos, buf, len);
704}
705
706static const struct file_operations fops_extd_rx_stats = {
707 .read = ath11k_read_extd_rx_stats,
708 .write = ath11k_write_extd_rx_stats,
709 .open = simple_open,
710};
711
712static int ath11k_fill_bp_stats(struct ath11k_base *ab,
713 struct ath11k_bp_stats *bp_stats,
714 char *buf, int len, int size)
715{
716 lockdep_assert_held(&ab->base_lock);
717
718 len += scnprintf(buf + len, size - len, "count: %u\n",
719 bp_stats->count);
720 len += scnprintf(buf + len, size - len, "hp: %u\n",
721 bp_stats->hp);
722 len += scnprintf(buf + len, size - len, "tp: %u\n",
723 bp_stats->tp);
724 len += scnprintf(buf + len, size - len, "seen before: %ums\n\n",
725 jiffies_to_msecs(jiffies - bp_stats->jiffies));
726 return len;
727}
728
729static ssize_t ath11k_debugfs_dump_soc_ring_bp_stats(struct ath11k_base *ab,
730 char *buf, int size)
731{
732 struct ath11k_bp_stats *bp_stats;
733 bool stats_rxd = false;
734 u8 i, pdev_idx;
735 int len = 0;
736
737 len += scnprintf(buf + len, size - len, "\nBackpressure Stats\n");
738 len += scnprintf(buf + len, size - len, "==================\n");
739
740 spin_lock_bh(&ab->base_lock);
741 for (i = 0; i < HTT_SW_UMAC_RING_IDX_MAX; i++) {
742 bp_stats = &ab->soc_stats.bp_stats.umac_ring_bp_stats[i];
743
744 if (!bp_stats->count)
745 continue;
746
747 len += scnprintf(buf + len, size - len, "Ring: %s\n",
748 htt_bp_umac_ring[i]);
749 len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
750 stats_rxd = true;
751 }
752
753 for (i = 0; i < HTT_SW_LMAC_RING_IDX_MAX; i++) {
754 for (pdev_idx = 0; pdev_idx < MAX_RADIOS; pdev_idx++) {
755 bp_stats =
756 &ab->soc_stats.bp_stats.lmac_ring_bp_stats[i][pdev_idx];
757
758 if (!bp_stats->count)
759 continue;
760
761 len += scnprintf(buf + len, size - len, "Ring: %s\n",
762 htt_bp_lmac_ring[i]);
763 len += scnprintf(buf + len, size - len, "pdev: %d\n",
764 pdev_idx);
765 len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
766 stats_rxd = true;
767 }
768 }
769 spin_unlock_bh(&ab->base_lock);
770
771 if (!stats_rxd)
772 len += scnprintf(buf + len, size - len,
773 "No Ring Backpressure stats received\n\n");
774
775 return len;
776}
777
778static ssize_t ath11k_debugfs_dump_soc_dp_stats(struct file *file,
779 char __user *user_buf,
780 size_t count, loff_t *ppos)
781{
782 struct ath11k_base *ab = file->private_data;
783 struct ath11k_soc_dp_stats *soc_stats = &ab->soc_stats;
784 int len = 0, i, retval;
785 const int size = 4096;
786 static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = {
787 "Overflow", "MPDU len", "FCS", "Decrypt", "TKIP MIC",
788 "Unencrypt", "MSDU len", "MSDU limit", "WiFi parse",
789 "AMSDU parse", "SA timeout", "DA timeout",
790 "Flow timeout", "Flush req"};
791 static const char *reo_err[HAL_REO_DEST_RING_ERROR_CODE_MAX] = {
792 "Desc addr zero", "Desc inval", "AMPDU in non BA",
793 "Non BA dup", "BA dup", "Frame 2k jump", "BAR 2k jump",
794 "Frame OOR", "BAR OOR", "No BA session",
795 "Frame SN equal SSN", "PN check fail", "2k err",
796 "PN err", "Desc blocked"};
797
798 char *buf;
799
800 buf = kzalloc(size, GFP_KERNEL);
801 if (!buf)
802 return -ENOMEM;
803
804 len += scnprintf(buf + len, size - len, "SOC RX STATS:\n\n");
805 len += scnprintf(buf + len, size - len, "err ring pkts: %u\n",
806 soc_stats->err_ring_pkts);
807 len += scnprintf(buf + len, size - len, "Invalid RBM: %u\n\n",
808 soc_stats->invalid_rbm);
809 len += scnprintf(buf + len, size - len, "RXDMA errors:\n");
810 for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++)
811 len += scnprintf(buf + len, size - len, "%s: %u\n",
812 rxdma_err[i], soc_stats->rxdma_error[i]);
813
814 len += scnprintf(buf + len, size - len, "\nREO errors:\n");
815 for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++)
816 len += scnprintf(buf + len, size - len, "%s: %u\n",
817 reo_err[i], soc_stats->reo_error[i]);
818
819 len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n");
820 len += scnprintf(buf + len, size - len,
821 "ring0: %u\nring1: %u\nring2: %u\nring3: %u\n",
822 soc_stats->hal_reo_error[0],
823 soc_stats->hal_reo_error[1],
824 soc_stats->hal_reo_error[2],
825 soc_stats->hal_reo_error[3]);
826
827 len += scnprintf(buf + len, size - len, "\nSOC TX STATS:\n");
828 len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n");
829
830 for (i = 0; i < ab->hw_params.max_tx_ring; i++)
831 len += scnprintf(buf + len, size - len, "ring%d: %u\n",
832 i, soc_stats->tx_err.desc_na[i]);
833
834 len += scnprintf(buf + len, size - len,
835 "\nMisc Transmit Failures: %d\n",
836 atomic_read(&soc_stats->tx_err.misc_fail));
837
838 len += ath11k_debugfs_dump_soc_ring_bp_stats(ab, buf + len, size - len);
839
840 if (len > size)
841 len = size;
842 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
843 kfree(buf);
844
845 return retval;
846}
847
848static const struct file_operations fops_soc_dp_stats = {
849 .read = ath11k_debugfs_dump_soc_dp_stats,
850 .open = simple_open,
851 .owner = THIS_MODULE,
852 .llseek = default_llseek,
853};
854
855static ssize_t ath11k_write_fw_dbglog(struct file *file,
856 const char __user *user_buf,
857 size_t count, loff_t *ppos)
858{
859 struct ath11k *ar = file->private_data;
860 char buf[128] = {0};
861 struct ath11k_fw_dbglog dbglog;
862 unsigned int param, mod_id_index, is_end;
863 u64 value;
864 int ret, num;
865
866 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
867 user_buf, count);
868 if (ret <= 0)
869 return ret;
870
871 num = sscanf(buf, "%u %llx %u %u", ¶m, &value, &mod_id_index, &is_end);
872
873 if (num < 2)
874 return -EINVAL;
875
876 mutex_lock(&ar->conf_mutex);
877 if (param == WMI_DEBUG_LOG_PARAM_MOD_ENABLE_BITMAP ||
878 param == WMI_DEBUG_LOG_PARAM_WOW_MOD_ENABLE_BITMAP) {
879 if (num != 4 || mod_id_index > (MAX_MODULE_ID_BITMAP_WORDS - 1)) {
880 ret = -EINVAL;
881 goto out;
882 }
883 ar->debug.module_id_bitmap[mod_id_index] = upper_32_bits(value);
884 if (!is_end) {
885 ret = count;
886 goto out;
887 }
888 } else {
889 if (num != 2) {
890 ret = -EINVAL;
891 goto out;
892 }
893 }
894
895 dbglog.param = param;
896 dbglog.value = lower_32_bits(value);
897 ret = ath11k_wmi_fw_dbglog_cfg(ar, ar->debug.module_id_bitmap, &dbglog);
898 if (ret) {
899 ath11k_warn(ar->ab, "fw dbglog config failed from debugfs: %d\n",
900 ret);
901 goto out;
902 }
903
904 ret = count;
905
906out:
907 mutex_unlock(&ar->conf_mutex);
908 return ret;
909}
910
911static const struct file_operations fops_fw_dbglog = {
912 .write = ath11k_write_fw_dbglog,
913 .open = simple_open,
914 .owner = THIS_MODULE,
915 .llseek = default_llseek,
916};
917
918static int ath11k_open_sram_dump(struct inode *inode, struct file *file)
919{
920 struct ath11k_base *ab = inode->i_private;
921 u8 *buf;
922 u32 start, end;
923 int ret;
924
925 start = ab->hw_params.sram_dump.start;
926 end = ab->hw_params.sram_dump.end;
927
928 buf = vmalloc(end - start + 1);
929 if (!buf)
930 return -ENOMEM;
931
932 ret = ath11k_hif_read(ab, buf, start, end);
933 if (ret) {
934 ath11k_warn(ab, "failed to dump sram: %d\n", ret);
935 vfree(buf);
936 return ret;
937 }
938
939 file->private_data = buf;
940 return 0;
941}
942
943static ssize_t ath11k_read_sram_dump(struct file *file,
944 char __user *user_buf,
945 size_t count, loff_t *ppos)
946{
947 struct ath11k_base *ab = file->f_inode->i_private;
948 const char *buf = file->private_data;
949 int len;
950 u32 start, end;
951
952 start = ab->hw_params.sram_dump.start;
953 end = ab->hw_params.sram_dump.end;
954 len = end - start + 1;
955
956 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
957}
958
959static int ath11k_release_sram_dump(struct inode *inode, struct file *file)
960{
961 vfree(file->private_data);
962 file->private_data = NULL;
963
964 return 0;
965}
966
967static const struct file_operations fops_sram_dump = {
968 .open = ath11k_open_sram_dump,
969 .read = ath11k_read_sram_dump,
970 .release = ath11k_release_sram_dump,
971 .owner = THIS_MODULE,
972 .llseek = default_llseek,
973};
974
975int ath11k_debugfs_pdev_create(struct ath11k_base *ab)
976{
977 if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
978 return 0;
979
980 debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
981 &fops_simulate_fw_crash);
982
983 debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab,
984 &fops_soc_dp_stats);
985
986 if (ab->hw_params.sram_dump.start != 0)
987 debugfs_create_file("sram", 0400, ab->debugfs_soc, ab,
988 &fops_sram_dump);
989
990 return 0;
991}
992
993void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab)
994{
995 debugfs_remove_recursive(ab->debugfs_soc);
996 ab->debugfs_soc = NULL;
997}
998
999int ath11k_debugfs_soc_create(struct ath11k_base *ab)
1000{
1001 struct dentry *root;
1002 bool dput_needed;
1003 char name[64];
1004 int ret;
1005
1006 root = debugfs_lookup("ath11k", NULL);
1007 if (!root) {
1008 root = debugfs_create_dir("ath11k", NULL);
1009 if (IS_ERR_OR_NULL(root))
1010 return PTR_ERR(root);
1011
1012 dput_needed = false;
1013 } else {
1014 /* a dentry from lookup() needs dput() after we don't use it */
1015 dput_needed = true;
1016 }
1017
1018 scnprintf(name, sizeof(name), "%s-%s", ath11k_bus_str(ab->hif.bus),
1019 dev_name(ab->dev));
1020
1021 ab->debugfs_soc = debugfs_create_dir(name, root);
1022 if (IS_ERR_OR_NULL(ab->debugfs_soc)) {
1023 ret = PTR_ERR(ab->debugfs_soc);
1024 goto out;
1025 }
1026
1027 ret = 0;
1028
1029out:
1030 if (dput_needed)
1031 dput(root);
1032
1033 return ret;
1034}
1035
1036void ath11k_debugfs_soc_destroy(struct ath11k_base *ab)
1037{
1038 debugfs_remove_recursive(ab->debugfs_soc);
1039 ab->debugfs_soc = NULL;
1040
1041 /* We are not removing ath11k directory on purpose, even if it
1042 * would be empty. This simplifies the directory handling and it's
1043 * a minor cosmetic issue to leave an empty ath11k directory to
1044 * debugfs.
1045 */
1046}
1047EXPORT_SYMBOL(ath11k_debugfs_soc_destroy);
1048
1049void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
1050{
1051 struct dentry *fwstats_dir = debugfs_create_dir("fw_stats",
1052 ar->debug.debugfs_pdev);
1053
1054 ar->fw_stats.debugfs_fwstats = fwstats_dir;
1055
1056 /* all stats debugfs files created are under "fw_stats" directory
1057 * created per PDEV
1058 */
1059 debugfs_create_file("pdev_stats", 0600, fwstats_dir, ar,
1060 &fops_pdev_stats);
1061 debugfs_create_file("vdev_stats", 0600, fwstats_dir, ar,
1062 &fops_vdev_stats);
1063 debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar,
1064 &fops_bcn_stats);
1065}
1066
1067static ssize_t ath11k_write_pktlog_filter(struct file *file,
1068 const char __user *ubuf,
1069 size_t count, loff_t *ppos)
1070{
1071 struct ath11k *ar = file->private_data;
1072 struct ath11k_base *ab = ar->ab;
1073 struct htt_rx_ring_tlv_filter tlv_filter = {0};
1074 u32 rx_filter = 0, ring_id, filter, mode;
1075 u8 buf[128] = {0};
1076 int i, ret, rx_buf_sz = 0;
1077 ssize_t rc;
1078
1079 mutex_lock(&ar->conf_mutex);
1080 if (ar->state != ATH11K_STATE_ON) {
1081 ret = -ENETDOWN;
1082 goto out;
1083 }
1084
1085 rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1086 if (rc < 0) {
1087 ret = rc;
1088 goto out;
1089 }
1090 buf[rc] = '\0';
1091
1092 ret = sscanf(buf, "0x%x %u", &filter, &mode);
1093 if (ret != 2) {
1094 ret = -EINVAL;
1095 goto out;
1096 }
1097
1098 if (filter) {
1099 ret = ath11k_wmi_pdev_pktlog_enable(ar, filter);
1100 if (ret) {
1101 ath11k_warn(ar->ab,
1102 "failed to enable pktlog filter %x: %d\n",
1103 ar->debug.pktlog_filter, ret);
1104 goto out;
1105 }
1106 } else {
1107 ret = ath11k_wmi_pdev_pktlog_disable(ar);
1108 if (ret) {
1109 ath11k_warn(ar->ab, "failed to disable pktlog: %d\n", ret);
1110 goto out;
1111 }
1112 }
1113
1114 /* Clear rx filter set for monitor mode and rx status */
1115 for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
1116 ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
1117 ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
1118 HAL_RXDMA_MONITOR_STATUS,
1119 rx_buf_sz, &tlv_filter);
1120 if (ret) {
1121 ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
1122 goto out;
1123 }
1124 }
1125#define HTT_RX_FILTER_TLV_LITE_MODE \
1126 (HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
1127 HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
1128 HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \
1129 HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \
1130 HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \
1131 HTT_RX_FILTER_TLV_FLAGS_MPDU_START)
1132
1133 if (mode == ATH11K_PKTLOG_MODE_FULL) {
1134 rx_filter = HTT_RX_FILTER_TLV_LITE_MODE |
1135 HTT_RX_FILTER_TLV_FLAGS_MSDU_START |
1136 HTT_RX_FILTER_TLV_FLAGS_MSDU_END |
1137 HTT_RX_FILTER_TLV_FLAGS_MPDU_END |
1138 HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER |
1139 HTT_RX_FILTER_TLV_FLAGS_ATTENTION;
1140 rx_buf_sz = DP_RX_BUFFER_SIZE;
1141 } else if (mode == ATH11K_PKTLOG_MODE_LITE) {
1142 ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
1143 HTT_PPDU_STATS_TAG_PKTLOG);
1144 if (ret) {
1145 ath11k_err(ar->ab, "failed to enable pktlog lite: %d\n", ret);
1146 goto out;
1147 }
1148
1149 rx_filter = HTT_RX_FILTER_TLV_LITE_MODE;
1150 rx_buf_sz = DP_RX_BUFFER_SIZE_LITE;
1151 } else {
1152 rx_buf_sz = DP_RX_BUFFER_SIZE;
1153 tlv_filter = ath11k_mac_mon_status_filter_default;
1154 rx_filter = tlv_filter.rx_filter;
1155
1156 ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
1157 HTT_PPDU_STATS_TAG_DEFAULT);
1158 if (ret) {
1159 ath11k_err(ar->ab, "failed to send htt ppdu stats req: %d\n",
1160 ret);
1161 goto out;
1162 }
1163 }
1164
1165 tlv_filter.rx_filter = rx_filter;
1166 if (rx_filter) {
1167 tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
1168 tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
1169 tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
1170 tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
1171 HTT_RX_FP_DATA_FILTER_FLASG3;
1172 }
1173
1174 for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
1175 ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
1176 ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id,
1177 ar->dp.mac_id + i,
1178 HAL_RXDMA_MONITOR_STATUS,
1179 rx_buf_sz, &tlv_filter);
1180
1181 if (ret) {
1182 ath11k_warn(ab, "failed to set rx filter for monitor status ring\n");
1183 goto out;
1184 }
1185 }
1186
1187 ath11k_info(ab, "pktlog mode %s\n",
1188 ((mode == ATH11K_PKTLOG_MODE_FULL) ? "full" : "lite"));
1189
1190 ar->debug.pktlog_filter = filter;
1191 ar->debug.pktlog_mode = mode;
1192 ret = count;
1193
1194out:
1195 mutex_unlock(&ar->conf_mutex);
1196 return ret;
1197}
1198
1199static ssize_t ath11k_read_pktlog_filter(struct file *file,
1200 char __user *ubuf,
1201 size_t count, loff_t *ppos)
1202
1203{
1204 char buf[32] = {0};
1205 struct ath11k *ar = file->private_data;
1206 int len = 0;
1207
1208 mutex_lock(&ar->conf_mutex);
1209 len = scnprintf(buf, sizeof(buf) - len, "%08x %08x\n",
1210 ar->debug.pktlog_filter,
1211 ar->debug.pktlog_mode);
1212 mutex_unlock(&ar->conf_mutex);
1213
1214 return simple_read_from_buffer(ubuf, count, ppos, buf, len);
1215}
1216
1217static const struct file_operations fops_pktlog_filter = {
1218 .read = ath11k_read_pktlog_filter,
1219 .write = ath11k_write_pktlog_filter,
1220 .open = simple_open
1221};
1222
1223static ssize_t ath11k_write_simulate_radar(struct file *file,
1224 const char __user *user_buf,
1225 size_t count, loff_t *ppos)
1226{
1227 struct ath11k *ar = file->private_data;
1228 int ret;
1229
1230 ret = ath11k_wmi_simulate_radar(ar);
1231 if (ret)
1232 return ret;
1233
1234 return count;
1235}
1236
1237static const struct file_operations fops_simulate_radar = {
1238 .write = ath11k_write_simulate_radar,
1239 .open = simple_open
1240};
1241
1242static ssize_t ath11k_debug_dump_dbr_entries(struct file *file,
1243 char __user *user_buf,
1244 size_t count, loff_t *ppos)
1245{
1246 struct ath11k_dbg_dbr_data *dbr_dbg_data = file->private_data;
1247 static const char * const event_id_to_string[] = {"empty", "Rx", "Replenish"};
1248 int size = ATH11K_DEBUG_DBR_ENTRIES_MAX * 100;
1249 char *buf;
1250 int i, ret;
1251 int len = 0;
1252
1253 buf = kzalloc(size, GFP_KERNEL);
1254 if (!buf)
1255 return -ENOMEM;
1256
1257 len += scnprintf(buf + len, size - len,
1258 "-----------------------------------------\n");
1259 len += scnprintf(buf + len, size - len,
1260 "| idx | hp | tp | timestamp | event |\n");
1261 len += scnprintf(buf + len, size - len,
1262 "-----------------------------------------\n");
1263
1264 spin_lock_bh(&dbr_dbg_data->lock);
1265
1266 for (i = 0; i < dbr_dbg_data->num_ring_debug_entries; i++) {
1267 len += scnprintf(buf + len, size - len,
1268 "|%4u|%8u|%8u|%11llu|%8s|\n", i,
1269 dbr_dbg_data->entries[i].hp,
1270 dbr_dbg_data->entries[i].tp,
1271 dbr_dbg_data->entries[i].timestamp,
1272 event_id_to_string[dbr_dbg_data->entries[i].event]);
1273 }
1274
1275 spin_unlock_bh(&dbr_dbg_data->lock);
1276
1277 ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1278 kfree(buf);
1279
1280 return ret;
1281}
1282
1283static const struct file_operations fops_debug_dump_dbr_entries = {
1284 .read = ath11k_debug_dump_dbr_entries,
1285 .open = simple_open,
1286 .owner = THIS_MODULE,
1287 .llseek = default_llseek,
1288};
1289
1290static void ath11k_debugfs_dbr_dbg_destroy(struct ath11k *ar, int dbr_id)
1291{
1292 struct ath11k_debug_dbr *dbr_debug;
1293 struct ath11k_dbg_dbr_data *dbr_dbg_data;
1294
1295 if (!ar->debug.dbr_debug[dbr_id])
1296 return;
1297
1298 dbr_debug = ar->debug.dbr_debug[dbr_id];
1299 dbr_dbg_data = &dbr_debug->dbr_dbg_data;
1300
1301 debugfs_remove_recursive(dbr_debug->dbr_debugfs);
1302 kfree(dbr_dbg_data->entries);
1303 kfree(dbr_debug);
1304 ar->debug.dbr_debug[dbr_id] = NULL;
1305}
1306
1307static int ath11k_debugfs_dbr_dbg_init(struct ath11k *ar, int dbr_id)
1308{
1309 struct ath11k_debug_dbr *dbr_debug;
1310 struct ath11k_dbg_dbr_data *dbr_dbg_data;
1311 static const char * const dbr_id_to_str[] = {"spectral", "CFR"};
1312
1313 if (ar->debug.dbr_debug[dbr_id])
1314 return 0;
1315
1316 ar->debug.dbr_debug[dbr_id] = kzalloc(sizeof(*dbr_debug),
1317 GFP_KERNEL);
1318
1319 if (!ar->debug.dbr_debug[dbr_id])
1320 return -ENOMEM;
1321
1322 dbr_debug = ar->debug.dbr_debug[dbr_id];
1323 dbr_dbg_data = &dbr_debug->dbr_dbg_data;
1324
1325 if (dbr_debug->dbr_debugfs)
1326 return 0;
1327
1328 dbr_debug->dbr_debugfs = debugfs_create_dir(dbr_id_to_str[dbr_id],
1329 ar->debug.debugfs_pdev);
1330 if (IS_ERR_OR_NULL(dbr_debug->dbr_debugfs)) {
1331 if (IS_ERR(dbr_debug->dbr_debugfs))
1332 return PTR_ERR(dbr_debug->dbr_debugfs);
1333 return -ENOMEM;
1334 }
1335
1336 dbr_debug->dbr_debug_enabled = true;
1337 dbr_dbg_data->num_ring_debug_entries = ATH11K_DEBUG_DBR_ENTRIES_MAX;
1338 dbr_dbg_data->dbr_debug_idx = 0;
1339 dbr_dbg_data->entries = kcalloc(ATH11K_DEBUG_DBR_ENTRIES_MAX,
1340 sizeof(struct ath11k_dbg_dbr_entry),
1341 GFP_KERNEL);
1342 if (!dbr_dbg_data->entries)
1343 return -ENOMEM;
1344
1345 spin_lock_init(&dbr_dbg_data->lock);
1346
1347 debugfs_create_file("dump_dbr_debug", 0444, dbr_debug->dbr_debugfs,
1348 dbr_dbg_data, &fops_debug_dump_dbr_entries);
1349
1350 return 0;
1351}
1352
1353static ssize_t ath11k_debugfs_write_enable_dbr_dbg(struct file *file,
1354 const char __user *ubuf,
1355 size_t count, loff_t *ppos)
1356{
1357 struct ath11k *ar = file->private_data;
1358 char buf[32] = {0};
1359 u32 dbr_id, enable;
1360 int ret;
1361
1362 mutex_lock(&ar->conf_mutex);
1363
1364 if (ar->state != ATH11K_STATE_ON) {
1365 ret = -ENETDOWN;
1366 goto out;
1367 }
1368
1369 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1370 if (ret < 0)
1371 goto out;
1372
1373 buf[ret] = '\0';
1374 ret = sscanf(buf, "%u %u", &dbr_id, &enable);
1375 if (ret != 2 || dbr_id > 1 || enable > 1) {
1376 ret = -EINVAL;
1377 ath11k_warn(ar->ab, "usage: echo <dbr_id> <val> dbr_id:0-Spectral 1-CFR val:0-disable 1-enable\n");
1378 goto out;
1379 }
1380
1381 if (enable) {
1382 ret = ath11k_debugfs_dbr_dbg_init(ar, dbr_id);
1383 if (ret) {
1384 ath11k_warn(ar->ab, "db ring module debugfs init failed: %d\n",
1385 ret);
1386 goto out;
1387 }
1388 } else {
1389 ath11k_debugfs_dbr_dbg_destroy(ar, dbr_id);
1390 }
1391
1392 ret = count;
1393out:
1394 mutex_unlock(&ar->conf_mutex);
1395 return ret;
1396}
1397
1398static const struct file_operations fops_dbr_debug = {
1399 .write = ath11k_debugfs_write_enable_dbr_dbg,
1400 .open = simple_open,
1401 .owner = THIS_MODULE,
1402 .llseek = default_llseek,
1403};
1404
1405static ssize_t ath11k_write_ps_timekeeper_enable(struct file *file,
1406 const char __user *user_buf,
1407 size_t count, loff_t *ppos)
1408{
1409 struct ath11k *ar = file->private_data;
1410 ssize_t ret;
1411 u8 ps_timekeeper_enable;
1412
1413 if (kstrtou8_from_user(user_buf, count, 0, &ps_timekeeper_enable))
1414 return -EINVAL;
1415
1416 mutex_lock(&ar->conf_mutex);
1417
1418 if (ar->state != ATH11K_STATE_ON) {
1419 ret = -ENETDOWN;
1420 goto exit;
1421 }
1422
1423 if (!ar->ps_state_enable) {
1424 ret = -EINVAL;
1425 goto exit;
1426 }
1427
1428 ar->ps_timekeeper_enable = !!ps_timekeeper_enable;
1429 ret = count;
1430exit:
1431 mutex_unlock(&ar->conf_mutex);
1432
1433 return ret;
1434}
1435
1436static ssize_t ath11k_read_ps_timekeeper_enable(struct file *file,
1437 char __user *user_buf,
1438 size_t count, loff_t *ppos)
1439{
1440 struct ath11k *ar = file->private_data;
1441 char buf[32];
1442 int len;
1443
1444 mutex_lock(&ar->conf_mutex);
1445 len = scnprintf(buf, sizeof(buf), "%d\n", ar->ps_timekeeper_enable);
1446 mutex_unlock(&ar->conf_mutex);
1447
1448 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1449}
1450
1451static const struct file_operations fops_ps_timekeeper_enable = {
1452 .read = ath11k_read_ps_timekeeper_enable,
1453 .write = ath11k_write_ps_timekeeper_enable,
1454 .open = simple_open,
1455 .owner = THIS_MODULE,
1456 .llseek = default_llseek,
1457};
1458
1459static void ath11k_reset_peer_ps_duration(void *data,
1460 struct ieee80211_sta *sta)
1461{
1462 struct ath11k *ar = data;
1463 struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
1464
1465 spin_lock_bh(&ar->data_lock);
1466 arsta->ps_total_duration = 0;
1467 spin_unlock_bh(&ar->data_lock);
1468}
1469
1470static ssize_t ath11k_write_reset_ps_duration(struct file *file,
1471 const char __user *user_buf,
1472 size_t count, loff_t *ppos)
1473{
1474 struct ath11k *ar = file->private_data;
1475 int ret;
1476 u8 reset_ps_duration;
1477
1478 if (kstrtou8_from_user(user_buf, count, 0, &reset_ps_duration))
1479 return -EINVAL;
1480
1481 mutex_lock(&ar->conf_mutex);
1482
1483 if (ar->state != ATH11K_STATE_ON) {
1484 ret = -ENETDOWN;
1485 goto exit;
1486 }
1487
1488 if (!ar->ps_state_enable) {
1489 ret = -EINVAL;
1490 goto exit;
1491 }
1492
1493 ieee80211_iterate_stations_atomic(ar->hw,
1494 ath11k_reset_peer_ps_duration,
1495 ar);
1496
1497 ret = count;
1498exit:
1499 mutex_unlock(&ar->conf_mutex);
1500 return ret;
1501}
1502
1503static const struct file_operations fops_reset_ps_duration = {
1504 .write = ath11k_write_reset_ps_duration,
1505 .open = simple_open,
1506 .owner = THIS_MODULE,
1507 .llseek = default_llseek,
1508};
1509
1510static void ath11k_peer_ps_state_disable(void *data,
1511 struct ieee80211_sta *sta)
1512{
1513 struct ath11k *ar = data;
1514 struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
1515
1516 spin_lock_bh(&ar->data_lock);
1517 arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED;
1518 arsta->ps_start_time = 0;
1519 arsta->ps_total_duration = 0;
1520 spin_unlock_bh(&ar->data_lock);
1521}
1522
1523static ssize_t ath11k_write_ps_state_enable(struct file *file,
1524 const char __user *user_buf,
1525 size_t count, loff_t *ppos)
1526{
1527 struct ath11k *ar = file->private_data;
1528 struct ath11k_pdev *pdev = ar->pdev;
1529 int ret;
1530 u32 param;
1531 u8 ps_state_enable;
1532
1533 if (kstrtou8_from_user(user_buf, count, 0, &ps_state_enable))
1534 return -EINVAL;
1535
1536 mutex_lock(&ar->conf_mutex);
1537
1538 ps_state_enable = !!ps_state_enable;
1539
1540 if (ar->ps_state_enable == ps_state_enable) {
1541 ret = count;
1542 goto exit;
1543 }
1544
1545 param = WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE;
1546 ret = ath11k_wmi_pdev_set_param(ar, param, ps_state_enable, pdev->pdev_id);
1547 if (ret) {
1548 ath11k_warn(ar->ab, "failed to enable ps_state_enable: %d\n",
1549 ret);
1550 goto exit;
1551 }
1552 ar->ps_state_enable = ps_state_enable;
1553
1554 if (!ar->ps_state_enable) {
1555 ar->ps_timekeeper_enable = false;
1556 ieee80211_iterate_stations_atomic(ar->hw,
1557 ath11k_peer_ps_state_disable,
1558 ar);
1559 }
1560
1561 ret = count;
1562
1563exit:
1564 mutex_unlock(&ar->conf_mutex);
1565
1566 return ret;
1567}
1568
1569static ssize_t ath11k_read_ps_state_enable(struct file *file,
1570 char __user *user_buf,
1571 size_t count, loff_t *ppos)
1572{
1573 struct ath11k *ar = file->private_data;
1574 char buf[32];
1575 int len;
1576
1577 mutex_lock(&ar->conf_mutex);
1578 len = scnprintf(buf, sizeof(buf), "%d\n", ar->ps_state_enable);
1579 mutex_unlock(&ar->conf_mutex);
1580
1581 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1582}
1583
1584static const struct file_operations fops_ps_state_enable = {
1585 .read = ath11k_read_ps_state_enable,
1586 .write = ath11k_write_ps_state_enable,
1587 .open = simple_open,
1588 .owner = THIS_MODULE,
1589 .llseek = default_llseek,
1590};
1591
1592int ath11k_debugfs_register(struct ath11k *ar)
1593{
1594 struct ath11k_base *ab = ar->ab;
1595 char pdev_name[10];
1596 char buf[100] = {0};
1597
1598 snprintf(pdev_name, sizeof(pdev_name), "%s%u", "mac", ar->pdev_idx);
1599
1600 ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc);
1601 if (IS_ERR(ar->debug.debugfs_pdev))
1602 return PTR_ERR(ar->debug.debugfs_pdev);
1603
1604 /* Create a symlink under ieee80211/phy* */
1605 snprintf(buf, 100, "../../ath11k/%pd2", ar->debug.debugfs_pdev);
1606 debugfs_create_symlink("ath11k", ar->hw->wiphy->debugfsdir, buf);
1607
1608 ath11k_debugfs_htt_stats_init(ar);
1609
1610 ath11k_debugfs_fw_stats_init(ar);
1611
1612 debugfs_create_file("ext_tx_stats", 0644,
1613 ar->debug.debugfs_pdev, ar,
1614 &fops_extd_tx_stats);
1615 debugfs_create_file("ext_rx_stats", 0644,
1616 ar->debug.debugfs_pdev, ar,
1617 &fops_extd_rx_stats);
1618 debugfs_create_file("pktlog_filter", 0644,
1619 ar->debug.debugfs_pdev, ar,
1620 &fops_pktlog_filter);
1621 debugfs_create_file("fw_dbglog_config", 0600,
1622 ar->debug.debugfs_pdev, ar,
1623 &fops_fw_dbglog);
1624
1625 if (ar->hw->wiphy->bands[NL80211_BAND_5GHZ]) {
1626 debugfs_create_file("dfs_simulate_radar", 0200,
1627 ar->debug.debugfs_pdev, ar,
1628 &fops_simulate_radar);
1629 debugfs_create_bool("dfs_block_radar_events", 0200,
1630 ar->debug.debugfs_pdev,
1631 &ar->dfs_block_radar_events);
1632 }
1633
1634 if (ab->hw_params.dbr_debug_support)
1635 debugfs_create_file("enable_dbr_debug", 0200, ar->debug.debugfs_pdev,
1636 ar, &fops_dbr_debug);
1637
1638 debugfs_create_file("ps_state_enable", 0600, ar->debug.debugfs_pdev, ar,
1639 &fops_ps_state_enable);
1640
1641 if (test_bit(WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT,
1642 ar->ab->wmi_ab.svc_map)) {
1643 debugfs_create_file("ps_timekeeper_enable", 0600,
1644 ar->debug.debugfs_pdev, ar,
1645 &fops_ps_timekeeper_enable);
1646
1647 debugfs_create_file("reset_ps_duration", 0200,
1648 ar->debug.debugfs_pdev, ar,
1649 &fops_reset_ps_duration);
1650 }
1651
1652 return 0;
1653}
1654
1655void ath11k_debugfs_unregister(struct ath11k *ar)
1656{
1657 struct ath11k_debug_dbr *dbr_debug;
1658 struct ath11k_dbg_dbr_data *dbr_dbg_data;
1659 int i;
1660
1661 for (i = 0; i < WMI_DIRECT_BUF_MAX; i++) {
1662 dbr_debug = ar->debug.dbr_debug[i];
1663 if (!dbr_debug)
1664 continue;
1665
1666 dbr_dbg_data = &dbr_debug->dbr_dbg_data;
1667 kfree(dbr_dbg_data->entries);
1668 debugfs_remove_recursive(dbr_debug->dbr_debugfs);
1669 kfree(dbr_debug);
1670 ar->debug.dbr_debug[i] = NULL;
1671 }
1672}
1673
1674static ssize_t ath11k_write_twt_add_dialog(struct file *file,
1675 const char __user *ubuf,
1676 size_t count, loff_t *ppos)
1677{
1678 struct ath11k_vif *arvif = file->private_data;
1679 struct wmi_twt_add_dialog_params params = { 0 };
1680 struct wmi_twt_enable_params twt_params = {0};
1681 struct ath11k *ar = arvif->ar;
1682 u8 buf[128] = {0};
1683 int ret;
1684
1685 if (ar->twt_enabled == 0) {
1686 ath11k_err(ar->ab, "twt support is not enabled\n");
1687 return -EOPNOTSUPP;
1688 }
1689
1690 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1691 if (ret < 0)
1692 return ret;
1693
1694 buf[ret] = '\0';
1695 ret = sscanf(buf,
1696 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u %u %u %u %u %hhu %hhu %hhu %hhu %hhu",
1697 ¶ms.peer_macaddr[0],
1698 ¶ms.peer_macaddr[1],
1699 ¶ms.peer_macaddr[2],
1700 ¶ms.peer_macaddr[3],
1701 ¶ms.peer_macaddr[4],
1702 ¶ms.peer_macaddr[5],
1703 ¶ms.dialog_id,
1704 ¶ms.wake_intvl_us,
1705 ¶ms.wake_intvl_mantis,
1706 ¶ms.wake_dura_us,
1707 ¶ms.sp_offset_us,
1708 ¶ms.twt_cmd,
1709 ¶ms.flag_bcast,
1710 ¶ms.flag_trigger,
1711 ¶ms.flag_flow_type,
1712 ¶ms.flag_protection);
1713 if (ret != 16)
1714 return -EINVAL;
1715
1716 /* In the case of station vif, TWT is entirely handled by
1717 * the firmware based on the input parameters in the TWT enable
1718 * WMI command that is sent to the target during assoc.
1719 * For manually testing the TWT feature, we need to first disable
1720 * TWT and send enable command again with TWT input parameter
1721 * sta_cong_timer_ms set to 0.
1722 */
1723 if (arvif->vif->type == NL80211_IFTYPE_STATION) {
1724 ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
1725
1726 ath11k_wmi_fill_default_twt_params(&twt_params);
1727 twt_params.sta_cong_timer_ms = 0;
1728
1729 ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id, &twt_params);
1730 }
1731
1732 params.vdev_id = arvif->vdev_id;
1733
1734 ret = ath11k_wmi_send_twt_add_dialog_cmd(arvif->ar, ¶ms);
1735 if (ret)
1736 goto err_twt_add_dialog;
1737
1738 return count;
1739
1740err_twt_add_dialog:
1741 if (arvif->vif->type == NL80211_IFTYPE_STATION) {
1742 ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
1743 ath11k_wmi_fill_default_twt_params(&twt_params);
1744 ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id, &twt_params);
1745 }
1746
1747 return ret;
1748}
1749
1750static ssize_t ath11k_write_twt_del_dialog(struct file *file,
1751 const char __user *ubuf,
1752 size_t count, loff_t *ppos)
1753{
1754 struct ath11k_vif *arvif = file->private_data;
1755 struct wmi_twt_del_dialog_params params = { 0 };
1756 struct wmi_twt_enable_params twt_params = {0};
1757 struct ath11k *ar = arvif->ar;
1758 u8 buf[64] = {0};
1759 int ret;
1760
1761 if (ar->twt_enabled == 0) {
1762 ath11k_err(ar->ab, "twt support is not enabled\n");
1763 return -EOPNOTSUPP;
1764 }
1765
1766 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1767 if (ret < 0)
1768 return ret;
1769
1770 buf[ret] = '\0';
1771 ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u",
1772 ¶ms.peer_macaddr[0],
1773 ¶ms.peer_macaddr[1],
1774 ¶ms.peer_macaddr[2],
1775 ¶ms.peer_macaddr[3],
1776 ¶ms.peer_macaddr[4],
1777 ¶ms.peer_macaddr[5],
1778 ¶ms.dialog_id);
1779 if (ret != 7)
1780 return -EINVAL;
1781
1782 params.vdev_id = arvif->vdev_id;
1783
1784 ret = ath11k_wmi_send_twt_del_dialog_cmd(arvif->ar, ¶ms);
1785 if (ret)
1786 return ret;
1787
1788 if (arvif->vif->type == NL80211_IFTYPE_STATION) {
1789 ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
1790 ath11k_wmi_fill_default_twt_params(&twt_params);
1791 ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id, &twt_params);
1792 }
1793
1794 return count;
1795}
1796
1797static ssize_t ath11k_write_twt_pause_dialog(struct file *file,
1798 const char __user *ubuf,
1799 size_t count, loff_t *ppos)
1800{
1801 struct ath11k_vif *arvif = file->private_data;
1802 struct wmi_twt_pause_dialog_params params = { 0 };
1803 u8 buf[64] = {0};
1804 int ret;
1805
1806 if (arvif->ar->twt_enabled == 0) {
1807 ath11k_err(arvif->ar->ab, "twt support is not enabled\n");
1808 return -EOPNOTSUPP;
1809 }
1810
1811 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1812 if (ret < 0)
1813 return ret;
1814
1815 buf[ret] = '\0';
1816 ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u",
1817 ¶ms.peer_macaddr[0],
1818 ¶ms.peer_macaddr[1],
1819 ¶ms.peer_macaddr[2],
1820 ¶ms.peer_macaddr[3],
1821 ¶ms.peer_macaddr[4],
1822 ¶ms.peer_macaddr[5],
1823 ¶ms.dialog_id);
1824 if (ret != 7)
1825 return -EINVAL;
1826
1827 params.vdev_id = arvif->vdev_id;
1828
1829 ret = ath11k_wmi_send_twt_pause_dialog_cmd(arvif->ar, ¶ms);
1830 if (ret)
1831 return ret;
1832
1833 return count;
1834}
1835
1836static ssize_t ath11k_write_twt_resume_dialog(struct file *file,
1837 const char __user *ubuf,
1838 size_t count, loff_t *ppos)
1839{
1840 struct ath11k_vif *arvif = file->private_data;
1841 struct wmi_twt_resume_dialog_params params = { 0 };
1842 u8 buf[64] = {0};
1843 int ret;
1844
1845 if (arvif->ar->twt_enabled == 0) {
1846 ath11k_err(arvif->ar->ab, "twt support is not enabled\n");
1847 return -EOPNOTSUPP;
1848 }
1849
1850 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1851 if (ret < 0)
1852 return ret;
1853
1854 buf[ret] = '\0';
1855 ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u %u %u",
1856 ¶ms.peer_macaddr[0],
1857 ¶ms.peer_macaddr[1],
1858 ¶ms.peer_macaddr[2],
1859 ¶ms.peer_macaddr[3],
1860 ¶ms.peer_macaddr[4],
1861 ¶ms.peer_macaddr[5],
1862 ¶ms.dialog_id,
1863 ¶ms.sp_offset_us,
1864 ¶ms.next_twt_size);
1865 if (ret != 9)
1866 return -EINVAL;
1867
1868 params.vdev_id = arvif->vdev_id;
1869
1870 ret = ath11k_wmi_send_twt_resume_dialog_cmd(arvif->ar, ¶ms);
1871 if (ret)
1872 return ret;
1873
1874 return count;
1875}
1876
1877static const struct file_operations ath11k_fops_twt_add_dialog = {
1878 .write = ath11k_write_twt_add_dialog,
1879 .open = simple_open
1880};
1881
1882static const struct file_operations ath11k_fops_twt_del_dialog = {
1883 .write = ath11k_write_twt_del_dialog,
1884 .open = simple_open
1885};
1886
1887static const struct file_operations ath11k_fops_twt_pause_dialog = {
1888 .write = ath11k_write_twt_pause_dialog,
1889 .open = simple_open
1890};
1891
1892static const struct file_operations ath11k_fops_twt_resume_dialog = {
1893 .write = ath11k_write_twt_resume_dialog,
1894 .open = simple_open
1895};
1896
1897void ath11k_debugfs_op_vif_add(struct ieee80211_hw *hw,
1898 struct ieee80211_vif *vif)
1899{
1900 struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
1901 struct ath11k_base *ab = arvif->ar->ab;
1902 struct dentry *debugfs_twt;
1903
1904 if (arvif->vif->type != NL80211_IFTYPE_AP &&
1905 !(arvif->vif->type == NL80211_IFTYPE_STATION &&
1906 test_bit(WMI_TLV_SERVICE_STA_TWT, ab->wmi_ab.svc_map)))
1907 return;
1908
1909 debugfs_twt = debugfs_create_dir("twt",
1910 arvif->vif->debugfs_dir);
1911 debugfs_create_file("add_dialog", 0200, debugfs_twt,
1912 arvif, &ath11k_fops_twt_add_dialog);
1913
1914 debugfs_create_file("del_dialog", 0200, debugfs_twt,
1915 arvif, &ath11k_fops_twt_del_dialog);
1916
1917 debugfs_create_file("pause_dialog", 0200, debugfs_twt,
1918 arvif, &ath11k_fops_twt_pause_dialog);
1919
1920 debugfs_create_file("resume_dialog", 0200, debugfs_twt,
1921 arvif, &ath11k_fops_twt_resume_dialog);
1922}
1923
1// SPDX-License-Identifier: BSD-3-Clause-Clear
2/*
3 * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
4 */
5
6#include <linux/vmalloc.h>
7
8#include "debugfs.h"
9
10#include "core.h"
11#include "debug.h"
12#include "wmi.h"
13#include "hal_rx.h"
14#include "dp_tx.h"
15#include "debugfs_htt_stats.h"
16#include "peer.h"
17#include "hif.h"
18
19static const char *htt_bp_umac_ring[HTT_SW_UMAC_RING_IDX_MAX] = {
20 "REO2SW1_RING",
21 "REO2SW2_RING",
22 "REO2SW3_RING",
23 "REO2SW4_RING",
24 "WBM2REO_LINK_RING",
25 "REO2TCL_RING",
26 "REO2FW_RING",
27 "RELEASE_RING",
28 "PPE_RELEASE_RING",
29 "TCL2TQM_RING",
30 "TQM_RELEASE_RING",
31 "REO_RELEASE_RING",
32 "WBM2SW0_RELEASE_RING",
33 "WBM2SW1_RELEASE_RING",
34 "WBM2SW2_RELEASE_RING",
35 "WBM2SW3_RELEASE_RING",
36 "REO_CMD_RING",
37 "REO_STATUS_RING",
38};
39
40static const char *htt_bp_lmac_ring[HTT_SW_LMAC_RING_IDX_MAX] = {
41 "FW2RXDMA_BUF_RING",
42 "FW2RXDMA_STATUS_RING",
43 "FW2RXDMA_LINK_RING",
44 "SW2RXDMA_BUF_RING",
45 "WBM2RXDMA_LINK_RING",
46 "RXDMA2FW_RING",
47 "RXDMA2SW_RING",
48 "RXDMA2RELEASE_RING",
49 "RXDMA2REO_RING",
50 "MONITOR_STATUS_RING",
51 "MONITOR_BUF_RING",
52 "MONITOR_DESC_RING",
53 "MONITOR_DEST_RING",
54};
55
56void ath11k_debugfs_add_dbring_entry(struct ath11k *ar,
57 enum wmi_direct_buffer_module id,
58 enum ath11k_dbg_dbr_event event,
59 struct hal_srng *srng)
60{
61 struct ath11k_debug_dbr *dbr_debug;
62 struct ath11k_dbg_dbr_data *dbr_data;
63 struct ath11k_dbg_dbr_entry *entry;
64
65 if (id >= WMI_DIRECT_BUF_MAX || event >= ATH11K_DBG_DBR_EVENT_MAX)
66 return;
67
68 dbr_debug = ar->debug.dbr_debug[id];
69 if (!dbr_debug)
70 return;
71
72 if (!dbr_debug->dbr_debug_enabled)
73 return;
74
75 dbr_data = &dbr_debug->dbr_dbg_data;
76
77 spin_lock_bh(&dbr_data->lock);
78
79 if (dbr_data->entries) {
80 entry = &dbr_data->entries[dbr_data->dbr_debug_idx];
81 entry->hp = srng->u.src_ring.hp;
82 entry->tp = *srng->u.src_ring.tp_addr;
83 entry->timestamp = jiffies;
84 entry->event = event;
85
86 dbr_data->dbr_debug_idx++;
87 if (dbr_data->dbr_debug_idx ==
88 dbr_data->num_ring_debug_entries)
89 dbr_data->dbr_debug_idx = 0;
90 }
91
92 spin_unlock_bh(&dbr_data->lock);
93}
94
95static void ath11k_debugfs_fw_stats_reset(struct ath11k *ar)
96{
97 spin_lock_bh(&ar->data_lock);
98 ar->fw_stats_done = false;
99 ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs);
100 ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs);
101 spin_unlock_bh(&ar->data_lock);
102}
103
104void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *stats)
105{
106 struct ath11k_base *ab = ar->ab;
107 struct ath11k_pdev *pdev;
108 bool is_end;
109 static unsigned int num_vdev, num_bcn;
110 size_t total_vdevs_started = 0;
111 int i;
112
113 /* WMI_REQUEST_PDEV_STAT request has been already processed */
114
115 if (stats->stats_id == WMI_REQUEST_RSSI_PER_CHAIN_STAT) {
116 ar->fw_stats_done = true;
117 return;
118 }
119
120 if (stats->stats_id == WMI_REQUEST_VDEV_STAT) {
121 if (list_empty(&stats->vdevs)) {
122 ath11k_warn(ab, "empty vdev stats");
123 return;
124 }
125 /* FW sends all the active VDEV stats irrespective of PDEV,
126 * hence limit until the count of all VDEVs started
127 */
128 for (i = 0; i < ab->num_radios; i++) {
129 pdev = rcu_dereference(ab->pdevs_active[i]);
130 if (pdev && pdev->ar)
131 total_vdevs_started += ar->num_started_vdevs;
132 }
133
134 is_end = ((++num_vdev) == total_vdevs_started);
135
136 list_splice_tail_init(&stats->vdevs,
137 &ar->fw_stats.vdevs);
138
139 if (is_end) {
140 ar->fw_stats_done = true;
141 num_vdev = 0;
142 }
143 return;
144 }
145
146 if (stats->stats_id == WMI_REQUEST_BCN_STAT) {
147 if (list_empty(&stats->bcn)) {
148 ath11k_warn(ab, "empty bcn stats");
149 return;
150 }
151 /* Mark end until we reached the count of all started VDEVs
152 * within the PDEV
153 */
154 is_end = ((++num_bcn) == ar->num_started_vdevs);
155
156 list_splice_tail_init(&stats->bcn,
157 &ar->fw_stats.bcn);
158
159 if (is_end) {
160 ar->fw_stats_done = true;
161 num_bcn = 0;
162 }
163 }
164}
165
166static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
167 struct stats_request_params *req_param)
168{
169 struct ath11k_base *ab = ar->ab;
170 unsigned long timeout, time_left;
171 int ret;
172
173 lockdep_assert_held(&ar->conf_mutex);
174
175 /* FW stats can get split when exceeding the stats data buffer limit.
176 * In that case, since there is no end marking for the back-to-back
177 * received 'update stats' event, we keep a 3 seconds timeout in case,
178 * fw_stats_done is not marked yet
179 */
180 timeout = jiffies + msecs_to_jiffies(3 * 1000);
181
182 ath11k_debugfs_fw_stats_reset(ar);
183
184 reinit_completion(&ar->fw_stats_complete);
185
186 ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);
187
188 if (ret) {
189 ath11k_warn(ab, "could not request fw stats (%d)\n",
190 ret);
191 return ret;
192 }
193
194 time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ);
195
196 if (!time_left)
197 return -ETIMEDOUT;
198
199 for (;;) {
200 if (time_after(jiffies, timeout))
201 break;
202
203 spin_lock_bh(&ar->data_lock);
204 if (ar->fw_stats_done) {
205 spin_unlock_bh(&ar->data_lock);
206 break;
207 }
208 spin_unlock_bh(&ar->data_lock);
209 }
210 return 0;
211}
212
213int ath11k_debugfs_get_fw_stats(struct ath11k *ar, u32 pdev_id,
214 u32 vdev_id, u32 stats_id)
215{
216 struct ath11k_base *ab = ar->ab;
217 struct stats_request_params req_param;
218 int ret;
219
220 mutex_lock(&ar->conf_mutex);
221
222 if (ar->state != ATH11K_STATE_ON) {
223 ret = -ENETDOWN;
224 goto err_unlock;
225 }
226
227 req_param.pdev_id = pdev_id;
228 req_param.vdev_id = vdev_id;
229 req_param.stats_id = stats_id;
230
231 ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
232 if (ret)
233 ath11k_warn(ab, "failed to request fw stats: %d\n", ret);
234
235 ath11k_dbg(ab, ATH11K_DBG_WMI,
236 "debug get fw stat pdev id %d vdev id %d stats id 0x%x\n",
237 pdev_id, vdev_id, stats_id);
238
239err_unlock:
240 mutex_unlock(&ar->conf_mutex);
241
242 return ret;
243}
244
245static int ath11k_open_pdev_stats(struct inode *inode, struct file *file)
246{
247 struct ath11k *ar = inode->i_private;
248 struct ath11k_base *ab = ar->ab;
249 struct stats_request_params req_param;
250 void *buf = NULL;
251 int ret;
252
253 mutex_lock(&ar->conf_mutex);
254
255 if (ar->state != ATH11K_STATE_ON) {
256 ret = -ENETDOWN;
257 goto err_unlock;
258 }
259
260 buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
261 if (!buf) {
262 ret = -ENOMEM;
263 goto err_unlock;
264 }
265
266 req_param.pdev_id = ar->pdev->pdev_id;
267 req_param.vdev_id = 0;
268 req_param.stats_id = WMI_REQUEST_PDEV_STAT;
269
270 ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
271 if (ret) {
272 ath11k_warn(ab, "failed to request fw pdev stats: %d\n", ret);
273 goto err_free;
274 }
275
276 ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
277
278 file->private_data = buf;
279
280 mutex_unlock(&ar->conf_mutex);
281 return 0;
282
283err_free:
284 vfree(buf);
285
286err_unlock:
287 mutex_unlock(&ar->conf_mutex);
288 return ret;
289}
290
291static int ath11k_release_pdev_stats(struct inode *inode, struct file *file)
292{
293 vfree(file->private_data);
294
295 return 0;
296}
297
298static ssize_t ath11k_read_pdev_stats(struct file *file,
299 char __user *user_buf,
300 size_t count, loff_t *ppos)
301{
302 const char *buf = file->private_data;
303 size_t len = strlen(buf);
304
305 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
306}
307
308static const struct file_operations fops_pdev_stats = {
309 .open = ath11k_open_pdev_stats,
310 .release = ath11k_release_pdev_stats,
311 .read = ath11k_read_pdev_stats,
312 .owner = THIS_MODULE,
313 .llseek = default_llseek,
314};
315
316static int ath11k_open_vdev_stats(struct inode *inode, struct file *file)
317{
318 struct ath11k *ar = inode->i_private;
319 struct stats_request_params req_param;
320 void *buf = NULL;
321 int ret;
322
323 mutex_lock(&ar->conf_mutex);
324
325 if (ar->state != ATH11K_STATE_ON) {
326 ret = -ENETDOWN;
327 goto err_unlock;
328 }
329
330 buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
331 if (!buf) {
332 ret = -ENOMEM;
333 goto err_unlock;
334 }
335
336 req_param.pdev_id = ar->pdev->pdev_id;
337 /* VDEV stats is always sent for all active VDEVs from FW */
338 req_param.vdev_id = 0;
339 req_param.stats_id = WMI_REQUEST_VDEV_STAT;
340
341 ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
342 if (ret) {
343 ath11k_warn(ar->ab, "failed to request fw vdev stats: %d\n", ret);
344 goto err_free;
345 }
346
347 ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
348
349 file->private_data = buf;
350
351 mutex_unlock(&ar->conf_mutex);
352 return 0;
353
354err_free:
355 vfree(buf);
356
357err_unlock:
358 mutex_unlock(&ar->conf_mutex);
359 return ret;
360}
361
362static int ath11k_release_vdev_stats(struct inode *inode, struct file *file)
363{
364 vfree(file->private_data);
365
366 return 0;
367}
368
369static ssize_t ath11k_read_vdev_stats(struct file *file,
370 char __user *user_buf,
371 size_t count, loff_t *ppos)
372{
373 const char *buf = file->private_data;
374 size_t len = strlen(buf);
375
376 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
377}
378
379static const struct file_operations fops_vdev_stats = {
380 .open = ath11k_open_vdev_stats,
381 .release = ath11k_release_vdev_stats,
382 .read = ath11k_read_vdev_stats,
383 .owner = THIS_MODULE,
384 .llseek = default_llseek,
385};
386
387static int ath11k_open_bcn_stats(struct inode *inode, struct file *file)
388{
389 struct ath11k *ar = inode->i_private;
390 struct ath11k_vif *arvif;
391 struct stats_request_params req_param;
392 void *buf = NULL;
393 int ret;
394
395 mutex_lock(&ar->conf_mutex);
396
397 if (ar->state != ATH11K_STATE_ON) {
398 ret = -ENETDOWN;
399 goto err_unlock;
400 }
401
402 buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
403 if (!buf) {
404 ret = -ENOMEM;
405 goto err_unlock;
406 }
407
408 req_param.stats_id = WMI_REQUEST_BCN_STAT;
409 req_param.pdev_id = ar->pdev->pdev_id;
410
411 /* loop all active VDEVs for bcn stats */
412 list_for_each_entry(arvif, &ar->arvifs, list) {
413 if (!arvif->is_up)
414 continue;
415
416 req_param.vdev_id = arvif->vdev_id;
417 ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
418 if (ret) {
419 ath11k_warn(ar->ab, "failed to request fw bcn stats: %d\n", ret);
420 goto err_free;
421 }
422 }
423
424 ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
425
426 /* since beacon stats request is looped for all active VDEVs, saved fw
427 * stats is not freed for each request until done for all active VDEVs
428 */
429 spin_lock_bh(&ar->data_lock);
430 ath11k_fw_stats_bcn_free(&ar->fw_stats.bcn);
431 spin_unlock_bh(&ar->data_lock);
432
433 file->private_data = buf;
434
435 mutex_unlock(&ar->conf_mutex);
436 return 0;
437
438err_free:
439 vfree(buf);
440
441err_unlock:
442 mutex_unlock(&ar->conf_mutex);
443 return ret;
444}
445
446static int ath11k_release_bcn_stats(struct inode *inode, struct file *file)
447{
448 vfree(file->private_data);
449
450 return 0;
451}
452
453static ssize_t ath11k_read_bcn_stats(struct file *file,
454 char __user *user_buf,
455 size_t count, loff_t *ppos)
456{
457 const char *buf = file->private_data;
458 size_t len = strlen(buf);
459
460 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
461}
462
463static const struct file_operations fops_bcn_stats = {
464 .open = ath11k_open_bcn_stats,
465 .release = ath11k_release_bcn_stats,
466 .read = ath11k_read_bcn_stats,
467 .owner = THIS_MODULE,
468 .llseek = default_llseek,
469};
470
471static ssize_t ath11k_read_simulate_fw_crash(struct file *file,
472 char __user *user_buf,
473 size_t count, loff_t *ppos)
474{
475 const char buf[] =
476 "To simulate firmware crash write one of the keywords to this file:\n"
477 "`assert` - this will send WMI_FORCE_FW_HANG_CMDID to firmware to cause assert.\n"
478 "`hw-restart` - this will simply queue hw restart without fw/hw actually crashing.\n";
479
480 return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
481}
482
483/* Simulate firmware crash:
484 * 'soft': Call wmi command causing firmware hang. This firmware hang is
485 * recoverable by warm firmware reset.
486 * 'hard': Force firmware crash by setting any vdev parameter for not allowed
487 * vdev id. This is hard firmware crash because it is recoverable only by cold
488 * firmware reset.
489 */
490static ssize_t ath11k_write_simulate_fw_crash(struct file *file,
491 const char __user *user_buf,
492 size_t count, loff_t *ppos)
493{
494 struct ath11k_base *ab = file->private_data;
495 struct ath11k_pdev *pdev;
496 struct ath11k *ar = ab->pdevs[0].ar;
497 char buf[32] = {0};
498 ssize_t rc;
499 int i, ret, radioup = 0;
500
501 for (i = 0; i < ab->num_radios; i++) {
502 pdev = &ab->pdevs[i];
503 ar = pdev->ar;
504 if (ar && ar->state == ATH11K_STATE_ON) {
505 radioup = 1;
506 break;
507 }
508 }
509 /* filter partial writes and invalid commands */
510 if (*ppos != 0 || count >= sizeof(buf) || count == 0)
511 return -EINVAL;
512
513 rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
514 if (rc < 0)
515 return rc;
516
517 /* drop the possible '\n' from the end */
518 if (buf[*ppos - 1] == '\n')
519 buf[*ppos - 1] = '\0';
520
521 if (radioup == 0) {
522 ret = -ENETDOWN;
523 goto exit;
524 }
525
526 if (!strcmp(buf, "assert")) {
527 ath11k_info(ab, "simulating firmware assert crash\n");
528 ret = ath11k_wmi_force_fw_hang_cmd(ar,
529 ATH11K_WMI_FW_HANG_ASSERT_TYPE,
530 ATH11K_WMI_FW_HANG_DELAY);
531 } else if (!strcmp(buf, "hw-restart")) {
532 ath11k_info(ab, "user requested hw restart\n");
533 queue_work(ab->workqueue_aux, &ab->reset_work);
534 ret = 0;
535 } else {
536 ret = -EINVAL;
537 goto exit;
538 }
539
540 if (ret) {
541 ath11k_warn(ab, "failed to simulate firmware crash: %d\n", ret);
542 goto exit;
543 }
544
545 ret = count;
546
547exit:
548 return ret;
549}
550
551static const struct file_operations fops_simulate_fw_crash = {
552 .read = ath11k_read_simulate_fw_crash,
553 .write = ath11k_write_simulate_fw_crash,
554 .open = simple_open,
555 .owner = THIS_MODULE,
556 .llseek = default_llseek,
557};
558
559static ssize_t ath11k_write_enable_extd_tx_stats(struct file *file,
560 const char __user *ubuf,
561 size_t count, loff_t *ppos)
562{
563 struct ath11k *ar = file->private_data;
564 u32 filter;
565 int ret;
566
567 if (kstrtouint_from_user(ubuf, count, 0, &filter))
568 return -EINVAL;
569
570 mutex_lock(&ar->conf_mutex);
571
572 if (ar->state != ATH11K_STATE_ON) {
573 ret = -ENETDOWN;
574 goto out;
575 }
576
577 if (filter == ar->debug.extd_tx_stats) {
578 ret = count;
579 goto out;
580 }
581
582 ar->debug.extd_tx_stats = filter;
583 ret = count;
584
585out:
586 mutex_unlock(&ar->conf_mutex);
587 return ret;
588}
589
590static ssize_t ath11k_read_enable_extd_tx_stats(struct file *file,
591 char __user *ubuf,
592 size_t count, loff_t *ppos)
593
594{
595 char buf[32] = {0};
596 struct ath11k *ar = file->private_data;
597 int len = 0;
598
599 mutex_lock(&ar->conf_mutex);
600 len = scnprintf(buf, sizeof(buf) - len, "%08x\n",
601 ar->debug.extd_tx_stats);
602 mutex_unlock(&ar->conf_mutex);
603
604 return simple_read_from_buffer(ubuf, count, ppos, buf, len);
605}
606
607static const struct file_operations fops_extd_tx_stats = {
608 .read = ath11k_read_enable_extd_tx_stats,
609 .write = ath11k_write_enable_extd_tx_stats,
610 .open = simple_open
611};
612
613static ssize_t ath11k_write_extd_rx_stats(struct file *file,
614 const char __user *ubuf,
615 size_t count, loff_t *ppos)
616{
617 struct ath11k *ar = file->private_data;
618 struct ath11k_base *ab = ar->ab;
619 struct htt_rx_ring_tlv_filter tlv_filter = {0};
620 u32 enable, rx_filter = 0, ring_id;
621 int i;
622 int ret;
623
624 if (kstrtouint_from_user(ubuf, count, 0, &enable))
625 return -EINVAL;
626
627 mutex_lock(&ar->conf_mutex);
628
629 if (ar->state != ATH11K_STATE_ON) {
630 ret = -ENETDOWN;
631 goto exit;
632 }
633
634 if (enable > 1) {
635 ret = -EINVAL;
636 goto exit;
637 }
638
639 if (enable == ar->debug.extd_rx_stats) {
640 ret = count;
641 goto exit;
642 }
643
644 if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags)) {
645 ar->debug.extd_rx_stats = enable;
646 ret = count;
647 goto exit;
648 }
649
650 if (enable) {
651 rx_filter = HTT_RX_FILTER_TLV_FLAGS_MPDU_START;
652 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_START;
653 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END;
654 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS;
655 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT;
656 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE;
657
658 tlv_filter.rx_filter = rx_filter;
659 tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
660 tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
661 tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
662 tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
663 HTT_RX_FP_DATA_FILTER_FLASG3;
664 } else {
665 tlv_filter = ath11k_mac_mon_status_filter_default;
666 }
667
668 ar->debug.rx_filter = tlv_filter.rx_filter;
669
670 for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
671 ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
672 ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
673 HAL_RXDMA_MONITOR_STATUS,
674 DP_RX_BUFFER_SIZE, &tlv_filter);
675
676 if (ret) {
677 ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
678 goto exit;
679 }
680 }
681
682 ar->debug.extd_rx_stats = enable;
683 ret = count;
684exit:
685 mutex_unlock(&ar->conf_mutex);
686 return ret;
687}
688
689static ssize_t ath11k_read_extd_rx_stats(struct file *file,
690 char __user *ubuf,
691 size_t count, loff_t *ppos)
692{
693 struct ath11k *ar = file->private_data;
694 char buf[32];
695 int len = 0;
696
697 mutex_lock(&ar->conf_mutex);
698 len = scnprintf(buf, sizeof(buf) - len, "%d\n",
699 ar->debug.extd_rx_stats);
700 mutex_unlock(&ar->conf_mutex);
701
702 return simple_read_from_buffer(ubuf, count, ppos, buf, len);
703}
704
705static const struct file_operations fops_extd_rx_stats = {
706 .read = ath11k_read_extd_rx_stats,
707 .write = ath11k_write_extd_rx_stats,
708 .open = simple_open,
709};
710
711static int ath11k_fill_bp_stats(struct ath11k_base *ab,
712 struct ath11k_bp_stats *bp_stats,
713 char *buf, int len, int size)
714{
715 lockdep_assert_held(&ab->base_lock);
716
717 len += scnprintf(buf + len, size - len, "count: %u\n",
718 bp_stats->count);
719 len += scnprintf(buf + len, size - len, "hp: %u\n",
720 bp_stats->hp);
721 len += scnprintf(buf + len, size - len, "tp: %u\n",
722 bp_stats->tp);
723 len += scnprintf(buf + len, size - len, "seen before: %ums\n\n",
724 jiffies_to_msecs(jiffies - bp_stats->jiffies));
725 return len;
726}
727
728static ssize_t ath11k_debugfs_dump_soc_ring_bp_stats(struct ath11k_base *ab,
729 char *buf, int size)
730{
731 struct ath11k_bp_stats *bp_stats;
732 bool stats_rxd = false;
733 u8 i, pdev_idx;
734 int len = 0;
735
736 len += scnprintf(buf + len, size - len, "\nBackpressure Stats\n");
737 len += scnprintf(buf + len, size - len, "==================\n");
738
739 spin_lock_bh(&ab->base_lock);
740 for (i = 0; i < HTT_SW_UMAC_RING_IDX_MAX; i++) {
741 bp_stats = &ab->soc_stats.bp_stats.umac_ring_bp_stats[i];
742
743 if (!bp_stats->count)
744 continue;
745
746 len += scnprintf(buf + len, size - len, "Ring: %s\n",
747 htt_bp_umac_ring[i]);
748 len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
749 stats_rxd = true;
750 }
751
752 for (i = 0; i < HTT_SW_LMAC_RING_IDX_MAX; i++) {
753 for (pdev_idx = 0; pdev_idx < MAX_RADIOS; pdev_idx++) {
754 bp_stats =
755 &ab->soc_stats.bp_stats.lmac_ring_bp_stats[i][pdev_idx];
756
757 if (!bp_stats->count)
758 continue;
759
760 len += scnprintf(buf + len, size - len, "Ring: %s\n",
761 htt_bp_lmac_ring[i]);
762 len += scnprintf(buf + len, size - len, "pdev: %d\n",
763 pdev_idx);
764 len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
765 stats_rxd = true;
766 }
767 }
768 spin_unlock_bh(&ab->base_lock);
769
770 if (!stats_rxd)
771 len += scnprintf(buf + len, size - len,
772 "No Ring Backpressure stats received\n\n");
773
774 return len;
775}
776
777static ssize_t ath11k_debugfs_dump_soc_dp_stats(struct file *file,
778 char __user *user_buf,
779 size_t count, loff_t *ppos)
780{
781 struct ath11k_base *ab = file->private_data;
782 struct ath11k_soc_dp_stats *soc_stats = &ab->soc_stats;
783 int len = 0, i, retval;
784 const int size = 4096;
785 static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = {
786 "Overflow", "MPDU len", "FCS", "Decrypt", "TKIP MIC",
787 "Unencrypt", "MSDU len", "MSDU limit", "WiFi parse",
788 "AMSDU parse", "SA timeout", "DA timeout",
789 "Flow timeout", "Flush req"};
790 static const char *reo_err[HAL_REO_DEST_RING_ERROR_CODE_MAX] = {
791 "Desc addr zero", "Desc inval", "AMPDU in non BA",
792 "Non BA dup", "BA dup", "Frame 2k jump", "BAR 2k jump",
793 "Frame OOR", "BAR OOR", "No BA session",
794 "Frame SN equal SSN", "PN check fail", "2k err",
795 "PN err", "Desc blocked"};
796
797 char *buf;
798
799 buf = kzalloc(size, GFP_KERNEL);
800 if (!buf)
801 return -ENOMEM;
802
803 len += scnprintf(buf + len, size - len, "SOC RX STATS:\n\n");
804 len += scnprintf(buf + len, size - len, "err ring pkts: %u\n",
805 soc_stats->err_ring_pkts);
806 len += scnprintf(buf + len, size - len, "Invalid RBM: %u\n\n",
807 soc_stats->invalid_rbm);
808 len += scnprintf(buf + len, size - len, "RXDMA errors:\n");
809 for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++)
810 len += scnprintf(buf + len, size - len, "%s: %u\n",
811 rxdma_err[i], soc_stats->rxdma_error[i]);
812
813 len += scnprintf(buf + len, size - len, "\nREO errors:\n");
814 for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++)
815 len += scnprintf(buf + len, size - len, "%s: %u\n",
816 reo_err[i], soc_stats->reo_error[i]);
817
818 len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n");
819 len += scnprintf(buf + len, size - len,
820 "ring0: %u\nring1: %u\nring2: %u\nring3: %u\n",
821 soc_stats->hal_reo_error[0],
822 soc_stats->hal_reo_error[1],
823 soc_stats->hal_reo_error[2],
824 soc_stats->hal_reo_error[3]);
825
826 len += scnprintf(buf + len, size - len, "\nSOC TX STATS:\n");
827 len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n");
828
829 for (i = 0; i < ab->hw_params.max_tx_ring; i++)
830 len += scnprintf(buf + len, size - len, "ring%d: %u\n",
831 i, soc_stats->tx_err.desc_na[i]);
832
833 len += scnprintf(buf + len, size - len,
834 "\nMisc Transmit Failures: %d\n",
835 atomic_read(&soc_stats->tx_err.misc_fail));
836
837 len += ath11k_debugfs_dump_soc_ring_bp_stats(ab, buf + len, size - len);
838
839 if (len > size)
840 len = size;
841 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
842 kfree(buf);
843
844 return retval;
845}
846
847static const struct file_operations fops_soc_dp_stats = {
848 .read = ath11k_debugfs_dump_soc_dp_stats,
849 .open = simple_open,
850 .owner = THIS_MODULE,
851 .llseek = default_llseek,
852};
853
854static ssize_t ath11k_write_fw_dbglog(struct file *file,
855 const char __user *user_buf,
856 size_t count, loff_t *ppos)
857{
858 struct ath11k *ar = file->private_data;
859 char buf[128] = {0};
860 struct ath11k_fw_dbglog dbglog;
861 unsigned int param, mod_id_index, is_end;
862 u64 value;
863 int ret, num;
864
865 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
866 user_buf, count);
867 if (ret <= 0)
868 return ret;
869
870 num = sscanf(buf, "%u %llx %u %u", ¶m, &value, &mod_id_index, &is_end);
871
872 if (num < 2)
873 return -EINVAL;
874
875 mutex_lock(&ar->conf_mutex);
876 if (param == WMI_DEBUG_LOG_PARAM_MOD_ENABLE_BITMAP ||
877 param == WMI_DEBUG_LOG_PARAM_WOW_MOD_ENABLE_BITMAP) {
878 if (num != 4 || mod_id_index > (MAX_MODULE_ID_BITMAP_WORDS - 1)) {
879 ret = -EINVAL;
880 goto out;
881 }
882 ar->debug.module_id_bitmap[mod_id_index] = upper_32_bits(value);
883 if (!is_end) {
884 ret = count;
885 goto out;
886 }
887 } else {
888 if (num != 2) {
889 ret = -EINVAL;
890 goto out;
891 }
892 }
893
894 dbglog.param = param;
895 dbglog.value = lower_32_bits(value);
896 ret = ath11k_wmi_fw_dbglog_cfg(ar, ar->debug.module_id_bitmap, &dbglog);
897 if (ret) {
898 ath11k_warn(ar->ab, "fw dbglog config failed from debugfs: %d\n",
899 ret);
900 goto out;
901 }
902
903 ret = count;
904
905out:
906 mutex_unlock(&ar->conf_mutex);
907 return ret;
908}
909
910static const struct file_operations fops_fw_dbglog = {
911 .write = ath11k_write_fw_dbglog,
912 .open = simple_open,
913 .owner = THIS_MODULE,
914 .llseek = default_llseek,
915};
916
917static int ath11k_open_sram_dump(struct inode *inode, struct file *file)
918{
919 struct ath11k_base *ab = inode->i_private;
920 u8 *buf;
921 u32 start, end;
922 int ret;
923
924 start = ab->hw_params.sram_dump.start;
925 end = ab->hw_params.sram_dump.end;
926
927 buf = vmalloc(end - start + 1);
928 if (!buf)
929 return -ENOMEM;
930
931 ret = ath11k_hif_read(ab, buf, start, end);
932 if (ret) {
933 ath11k_warn(ab, "failed to dump sram: %d\n", ret);
934 vfree(buf);
935 return ret;
936 }
937
938 file->private_data = buf;
939 return 0;
940}
941
942static ssize_t ath11k_read_sram_dump(struct file *file,
943 char __user *user_buf,
944 size_t count, loff_t *ppos)
945{
946 struct ath11k_base *ab = file->f_inode->i_private;
947 const char *buf = file->private_data;
948 int len;
949 u32 start, end;
950
951 start = ab->hw_params.sram_dump.start;
952 end = ab->hw_params.sram_dump.end;
953 len = end - start + 1;
954
955 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
956}
957
958static int ath11k_release_sram_dump(struct inode *inode, struct file *file)
959{
960 vfree(file->private_data);
961 file->private_data = NULL;
962
963 return 0;
964}
965
966static const struct file_operations fops_sram_dump = {
967 .open = ath11k_open_sram_dump,
968 .read = ath11k_read_sram_dump,
969 .release = ath11k_release_sram_dump,
970 .owner = THIS_MODULE,
971 .llseek = default_llseek,
972};
973
974int ath11k_debugfs_pdev_create(struct ath11k_base *ab)
975{
976 if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
977 return 0;
978
979 ab->debugfs_soc = debugfs_create_dir(ab->hw_params.name, ab->debugfs_ath11k);
980 if (IS_ERR(ab->debugfs_soc))
981 return PTR_ERR(ab->debugfs_soc);
982
983 debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
984 &fops_simulate_fw_crash);
985
986 debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab,
987 &fops_soc_dp_stats);
988
989 if (ab->hw_params.sram_dump.start != 0)
990 debugfs_create_file("sram", 0400, ab->debugfs_soc, ab,
991 &fops_sram_dump);
992
993 return 0;
994}
995
996void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab)
997{
998 debugfs_remove_recursive(ab->debugfs_soc);
999 ab->debugfs_soc = NULL;
1000}
1001
1002int ath11k_debugfs_soc_create(struct ath11k_base *ab)
1003{
1004 ab->debugfs_ath11k = debugfs_create_dir("ath11k", NULL);
1005
1006 return PTR_ERR_OR_ZERO(ab->debugfs_ath11k);
1007}
1008
1009void ath11k_debugfs_soc_destroy(struct ath11k_base *ab)
1010{
1011 debugfs_remove_recursive(ab->debugfs_ath11k);
1012 ab->debugfs_ath11k = NULL;
1013}
1014EXPORT_SYMBOL(ath11k_debugfs_soc_destroy);
1015
1016void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
1017{
1018 struct dentry *fwstats_dir = debugfs_create_dir("fw_stats",
1019 ar->debug.debugfs_pdev);
1020
1021 ar->fw_stats.debugfs_fwstats = fwstats_dir;
1022
1023 /* all stats debugfs files created are under "fw_stats" directory
1024 * created per PDEV
1025 */
1026 debugfs_create_file("pdev_stats", 0600, fwstats_dir, ar,
1027 &fops_pdev_stats);
1028 debugfs_create_file("vdev_stats", 0600, fwstats_dir, ar,
1029 &fops_vdev_stats);
1030 debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar,
1031 &fops_bcn_stats);
1032}
1033
1034static ssize_t ath11k_write_pktlog_filter(struct file *file,
1035 const char __user *ubuf,
1036 size_t count, loff_t *ppos)
1037{
1038 struct ath11k *ar = file->private_data;
1039 struct ath11k_base *ab = ar->ab;
1040 struct htt_rx_ring_tlv_filter tlv_filter = {0};
1041 u32 rx_filter = 0, ring_id, filter, mode;
1042 u8 buf[128] = {0};
1043 int i, ret, rx_buf_sz = 0;
1044 ssize_t rc;
1045
1046 mutex_lock(&ar->conf_mutex);
1047 if (ar->state != ATH11K_STATE_ON) {
1048 ret = -ENETDOWN;
1049 goto out;
1050 }
1051
1052 rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1053 if (rc < 0) {
1054 ret = rc;
1055 goto out;
1056 }
1057 buf[rc] = '\0';
1058
1059 ret = sscanf(buf, "0x%x %u", &filter, &mode);
1060 if (ret != 2) {
1061 ret = -EINVAL;
1062 goto out;
1063 }
1064
1065 if (filter) {
1066 ret = ath11k_wmi_pdev_pktlog_enable(ar, filter);
1067 if (ret) {
1068 ath11k_warn(ar->ab,
1069 "failed to enable pktlog filter %x: %d\n",
1070 ar->debug.pktlog_filter, ret);
1071 goto out;
1072 }
1073 } else {
1074 ret = ath11k_wmi_pdev_pktlog_disable(ar);
1075 if (ret) {
1076 ath11k_warn(ar->ab, "failed to disable pktlog: %d\n", ret);
1077 goto out;
1078 }
1079 }
1080
1081 /* Clear rx filter set for monitor mode and rx status */
1082 for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
1083 ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
1084 ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
1085 HAL_RXDMA_MONITOR_STATUS,
1086 rx_buf_sz, &tlv_filter);
1087 if (ret) {
1088 ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
1089 goto out;
1090 }
1091 }
1092#define HTT_RX_FILTER_TLV_LITE_MODE \
1093 (HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
1094 HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
1095 HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \
1096 HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \
1097 HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \
1098 HTT_RX_FILTER_TLV_FLAGS_MPDU_START)
1099
1100 if (mode == ATH11K_PKTLOG_MODE_FULL) {
1101 rx_filter = HTT_RX_FILTER_TLV_LITE_MODE |
1102 HTT_RX_FILTER_TLV_FLAGS_MSDU_START |
1103 HTT_RX_FILTER_TLV_FLAGS_MSDU_END |
1104 HTT_RX_FILTER_TLV_FLAGS_MPDU_END |
1105 HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER |
1106 HTT_RX_FILTER_TLV_FLAGS_ATTENTION;
1107 rx_buf_sz = DP_RX_BUFFER_SIZE;
1108 } else if (mode == ATH11K_PKTLOG_MODE_LITE) {
1109 ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
1110 HTT_PPDU_STATS_TAG_PKTLOG);
1111 if (ret) {
1112 ath11k_err(ar->ab, "failed to enable pktlog lite: %d\n", ret);
1113 goto out;
1114 }
1115
1116 rx_filter = HTT_RX_FILTER_TLV_LITE_MODE;
1117 rx_buf_sz = DP_RX_BUFFER_SIZE_LITE;
1118 } else {
1119 rx_buf_sz = DP_RX_BUFFER_SIZE;
1120 tlv_filter = ath11k_mac_mon_status_filter_default;
1121 rx_filter = tlv_filter.rx_filter;
1122
1123 ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
1124 HTT_PPDU_STATS_TAG_DEFAULT);
1125 if (ret) {
1126 ath11k_err(ar->ab, "failed to send htt ppdu stats req: %d\n",
1127 ret);
1128 goto out;
1129 }
1130 }
1131
1132 tlv_filter.rx_filter = rx_filter;
1133 if (rx_filter) {
1134 tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
1135 tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
1136 tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
1137 tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
1138 HTT_RX_FP_DATA_FILTER_FLASG3;
1139 }
1140
1141 for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
1142 ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
1143 ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id,
1144 ar->dp.mac_id + i,
1145 HAL_RXDMA_MONITOR_STATUS,
1146 rx_buf_sz, &tlv_filter);
1147
1148 if (ret) {
1149 ath11k_warn(ab, "failed to set rx filter for monitor status ring\n");
1150 goto out;
1151 }
1152 }
1153
1154 ath11k_info(ab, "pktlog mode %s\n",
1155 ((mode == ATH11K_PKTLOG_MODE_FULL) ? "full" : "lite"));
1156
1157 ar->debug.pktlog_filter = filter;
1158 ar->debug.pktlog_mode = mode;
1159 ret = count;
1160
1161out:
1162 mutex_unlock(&ar->conf_mutex);
1163 return ret;
1164}
1165
1166static ssize_t ath11k_read_pktlog_filter(struct file *file,
1167 char __user *ubuf,
1168 size_t count, loff_t *ppos)
1169
1170{
1171 char buf[32] = {0};
1172 struct ath11k *ar = file->private_data;
1173 int len = 0;
1174
1175 mutex_lock(&ar->conf_mutex);
1176 len = scnprintf(buf, sizeof(buf) - len, "%08x %08x\n",
1177 ar->debug.pktlog_filter,
1178 ar->debug.pktlog_mode);
1179 mutex_unlock(&ar->conf_mutex);
1180
1181 return simple_read_from_buffer(ubuf, count, ppos, buf, len);
1182}
1183
1184static const struct file_operations fops_pktlog_filter = {
1185 .read = ath11k_read_pktlog_filter,
1186 .write = ath11k_write_pktlog_filter,
1187 .open = simple_open
1188};
1189
1190static ssize_t ath11k_write_simulate_radar(struct file *file,
1191 const char __user *user_buf,
1192 size_t count, loff_t *ppos)
1193{
1194 struct ath11k *ar = file->private_data;
1195 int ret;
1196
1197 ret = ath11k_wmi_simulate_radar(ar);
1198 if (ret)
1199 return ret;
1200
1201 return count;
1202}
1203
1204static const struct file_operations fops_simulate_radar = {
1205 .write = ath11k_write_simulate_radar,
1206 .open = simple_open
1207};
1208
1209static ssize_t ath11k_debug_dump_dbr_entries(struct file *file,
1210 char __user *user_buf,
1211 size_t count, loff_t *ppos)
1212{
1213 struct ath11k_dbg_dbr_data *dbr_dbg_data = file->private_data;
1214 static const char * const event_id_to_string[] = {"empty", "Rx", "Replenish"};
1215 int size = ATH11K_DEBUG_DBR_ENTRIES_MAX * 100;
1216 char *buf;
1217 int i, ret;
1218 int len = 0;
1219
1220 buf = kzalloc(size, GFP_KERNEL);
1221 if (!buf)
1222 return -ENOMEM;
1223
1224 len += scnprintf(buf + len, size - len,
1225 "-----------------------------------------\n");
1226 len += scnprintf(buf + len, size - len,
1227 "| idx | hp | tp | timestamp | event |\n");
1228 len += scnprintf(buf + len, size - len,
1229 "-----------------------------------------\n");
1230
1231 spin_lock_bh(&dbr_dbg_data->lock);
1232
1233 for (i = 0; i < dbr_dbg_data->num_ring_debug_entries; i++) {
1234 len += scnprintf(buf + len, size - len,
1235 "|%4u|%8u|%8u|%11llu|%8s|\n", i,
1236 dbr_dbg_data->entries[i].hp,
1237 dbr_dbg_data->entries[i].tp,
1238 dbr_dbg_data->entries[i].timestamp,
1239 event_id_to_string[dbr_dbg_data->entries[i].event]);
1240 }
1241
1242 spin_unlock_bh(&dbr_dbg_data->lock);
1243
1244 ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1245 kfree(buf);
1246
1247 return ret;
1248}
1249
1250static const struct file_operations fops_debug_dump_dbr_entries = {
1251 .read = ath11k_debug_dump_dbr_entries,
1252 .open = simple_open,
1253 .owner = THIS_MODULE,
1254 .llseek = default_llseek,
1255};
1256
1257static void ath11k_debugfs_dbr_dbg_destroy(struct ath11k *ar, int dbr_id)
1258{
1259 struct ath11k_debug_dbr *dbr_debug;
1260 struct ath11k_dbg_dbr_data *dbr_dbg_data;
1261
1262 if (!ar->debug.dbr_debug[dbr_id])
1263 return;
1264
1265 dbr_debug = ar->debug.dbr_debug[dbr_id];
1266 dbr_dbg_data = &dbr_debug->dbr_dbg_data;
1267
1268 debugfs_remove_recursive(dbr_debug->dbr_debugfs);
1269 kfree(dbr_dbg_data->entries);
1270 kfree(dbr_debug);
1271 ar->debug.dbr_debug[dbr_id] = NULL;
1272}
1273
1274static int ath11k_debugfs_dbr_dbg_init(struct ath11k *ar, int dbr_id)
1275{
1276 struct ath11k_debug_dbr *dbr_debug;
1277 struct ath11k_dbg_dbr_data *dbr_dbg_data;
1278 static const char * const dbr_id_to_str[] = {"spectral", "CFR"};
1279
1280 if (ar->debug.dbr_debug[dbr_id])
1281 return 0;
1282
1283 ar->debug.dbr_debug[dbr_id] = kzalloc(sizeof(*dbr_debug),
1284 GFP_KERNEL);
1285
1286 if (!ar->debug.dbr_debug[dbr_id])
1287 return -ENOMEM;
1288
1289 dbr_debug = ar->debug.dbr_debug[dbr_id];
1290 dbr_dbg_data = &dbr_debug->dbr_dbg_data;
1291
1292 if (dbr_debug->dbr_debugfs)
1293 return 0;
1294
1295 dbr_debug->dbr_debugfs = debugfs_create_dir(dbr_id_to_str[dbr_id],
1296 ar->debug.debugfs_pdev);
1297 if (IS_ERR_OR_NULL(dbr_debug->dbr_debugfs)) {
1298 if (IS_ERR(dbr_debug->dbr_debugfs))
1299 return PTR_ERR(dbr_debug->dbr_debugfs);
1300 return -ENOMEM;
1301 }
1302
1303 dbr_debug->dbr_debug_enabled = true;
1304 dbr_dbg_data->num_ring_debug_entries = ATH11K_DEBUG_DBR_ENTRIES_MAX;
1305 dbr_dbg_data->dbr_debug_idx = 0;
1306 dbr_dbg_data->entries = kcalloc(ATH11K_DEBUG_DBR_ENTRIES_MAX,
1307 sizeof(struct ath11k_dbg_dbr_entry),
1308 GFP_KERNEL);
1309 if (!dbr_dbg_data->entries)
1310 return -ENOMEM;
1311
1312 spin_lock_init(&dbr_dbg_data->lock);
1313
1314 debugfs_create_file("dump_dbr_debug", 0444, dbr_debug->dbr_debugfs,
1315 dbr_dbg_data, &fops_debug_dump_dbr_entries);
1316
1317 return 0;
1318}
1319
1320static ssize_t ath11k_debugfs_write_enable_dbr_dbg(struct file *file,
1321 const char __user *ubuf,
1322 size_t count, loff_t *ppos)
1323{
1324 struct ath11k *ar = file->private_data;
1325 char buf[32] = {0};
1326 u32 dbr_id, enable;
1327 int ret;
1328
1329 mutex_lock(&ar->conf_mutex);
1330
1331 if (ar->state != ATH11K_STATE_ON) {
1332 ret = -ENETDOWN;
1333 goto out;
1334 }
1335
1336 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1337 if (ret < 0)
1338 goto out;
1339
1340 buf[ret] = '\0';
1341 ret = sscanf(buf, "%u %u", &dbr_id, &enable);
1342 if (ret != 2 || dbr_id > 1 || enable > 1) {
1343 ret = -EINVAL;
1344 ath11k_warn(ar->ab, "usage: echo <dbr_id> <val> dbr_id:0-Spectral 1-CFR val:0-disable 1-enable\n");
1345 goto out;
1346 }
1347
1348 if (enable) {
1349 ret = ath11k_debugfs_dbr_dbg_init(ar, dbr_id);
1350 if (ret) {
1351 ath11k_warn(ar->ab, "db ring module debugfs init failed: %d\n",
1352 ret);
1353 goto out;
1354 }
1355 } else {
1356 ath11k_debugfs_dbr_dbg_destroy(ar, dbr_id);
1357 }
1358
1359 ret = count;
1360out:
1361 mutex_unlock(&ar->conf_mutex);
1362 return ret;
1363}
1364
1365static const struct file_operations fops_dbr_debug = {
1366 .write = ath11k_debugfs_write_enable_dbr_dbg,
1367 .open = simple_open,
1368 .owner = THIS_MODULE,
1369 .llseek = default_llseek,
1370};
1371
1372static ssize_t ath11k_write_ps_timekeeper_enable(struct file *file,
1373 const char __user *user_buf,
1374 size_t count, loff_t *ppos)
1375{
1376 struct ath11k *ar = file->private_data;
1377 ssize_t ret;
1378 u8 ps_timekeeper_enable;
1379
1380 if (kstrtou8_from_user(user_buf, count, 0, &ps_timekeeper_enable))
1381 return -EINVAL;
1382
1383 mutex_lock(&ar->conf_mutex);
1384
1385 if (ar->state != ATH11K_STATE_ON) {
1386 ret = -ENETDOWN;
1387 goto exit;
1388 }
1389
1390 if (!ar->ps_state_enable) {
1391 ret = -EINVAL;
1392 goto exit;
1393 }
1394
1395 ar->ps_timekeeper_enable = !!ps_timekeeper_enable;
1396 ret = count;
1397exit:
1398 mutex_unlock(&ar->conf_mutex);
1399
1400 return ret;
1401}
1402
1403static ssize_t ath11k_read_ps_timekeeper_enable(struct file *file,
1404 char __user *user_buf,
1405 size_t count, loff_t *ppos)
1406{
1407 struct ath11k *ar = file->private_data;
1408 char buf[32];
1409 int len;
1410
1411 mutex_lock(&ar->conf_mutex);
1412 len = scnprintf(buf, sizeof(buf), "%d\n", ar->ps_timekeeper_enable);
1413 mutex_unlock(&ar->conf_mutex);
1414
1415 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1416}
1417
1418static const struct file_operations fops_ps_timekeeper_enable = {
1419 .read = ath11k_read_ps_timekeeper_enable,
1420 .write = ath11k_write_ps_timekeeper_enable,
1421 .open = simple_open,
1422 .owner = THIS_MODULE,
1423 .llseek = default_llseek,
1424};
1425
1426static void ath11k_reset_peer_ps_duration(void *data,
1427 struct ieee80211_sta *sta)
1428{
1429 struct ath11k *ar = data;
1430 struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
1431
1432 spin_lock_bh(&ar->data_lock);
1433 arsta->ps_total_duration = 0;
1434 spin_unlock_bh(&ar->data_lock);
1435}
1436
1437static ssize_t ath11k_write_reset_ps_duration(struct file *file,
1438 const char __user *user_buf,
1439 size_t count, loff_t *ppos)
1440{
1441 struct ath11k *ar = file->private_data;
1442 int ret;
1443 u8 reset_ps_duration;
1444
1445 if (kstrtou8_from_user(user_buf, count, 0, &reset_ps_duration))
1446 return -EINVAL;
1447
1448 mutex_lock(&ar->conf_mutex);
1449
1450 if (ar->state != ATH11K_STATE_ON) {
1451 ret = -ENETDOWN;
1452 goto exit;
1453 }
1454
1455 if (!ar->ps_state_enable) {
1456 ret = -EINVAL;
1457 goto exit;
1458 }
1459
1460 ieee80211_iterate_stations_atomic(ar->hw,
1461 ath11k_reset_peer_ps_duration,
1462 ar);
1463
1464 ret = count;
1465exit:
1466 mutex_unlock(&ar->conf_mutex);
1467 return ret;
1468}
1469
1470static const struct file_operations fops_reset_ps_duration = {
1471 .write = ath11k_write_reset_ps_duration,
1472 .open = simple_open,
1473 .owner = THIS_MODULE,
1474 .llseek = default_llseek,
1475};
1476
1477static void ath11k_peer_ps_state_disable(void *data,
1478 struct ieee80211_sta *sta)
1479{
1480 struct ath11k *ar = data;
1481 struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
1482
1483 spin_lock_bh(&ar->data_lock);
1484 arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED;
1485 arsta->ps_start_time = 0;
1486 arsta->ps_total_duration = 0;
1487 spin_unlock_bh(&ar->data_lock);
1488}
1489
1490static ssize_t ath11k_write_ps_state_enable(struct file *file,
1491 const char __user *user_buf,
1492 size_t count, loff_t *ppos)
1493{
1494 struct ath11k *ar = file->private_data;
1495 struct ath11k_pdev *pdev = ar->pdev;
1496 int ret;
1497 u32 param;
1498 u8 ps_state_enable;
1499
1500 if (kstrtou8_from_user(user_buf, count, 0, &ps_state_enable))
1501 return -EINVAL;
1502
1503 mutex_lock(&ar->conf_mutex);
1504
1505 ps_state_enable = !!ps_state_enable;
1506
1507 if (ar->ps_state_enable == ps_state_enable) {
1508 ret = count;
1509 goto exit;
1510 }
1511
1512 param = WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE;
1513 ret = ath11k_wmi_pdev_set_param(ar, param, ps_state_enable, pdev->pdev_id);
1514 if (ret) {
1515 ath11k_warn(ar->ab, "failed to enable ps_state_enable: %d\n",
1516 ret);
1517 goto exit;
1518 }
1519 ar->ps_state_enable = ps_state_enable;
1520
1521 if (!ar->ps_state_enable) {
1522 ar->ps_timekeeper_enable = false;
1523 ieee80211_iterate_stations_atomic(ar->hw,
1524 ath11k_peer_ps_state_disable,
1525 ar);
1526 }
1527
1528 ret = count;
1529
1530exit:
1531 mutex_unlock(&ar->conf_mutex);
1532
1533 return ret;
1534}
1535
1536static ssize_t ath11k_read_ps_state_enable(struct file *file,
1537 char __user *user_buf,
1538 size_t count, loff_t *ppos)
1539{
1540 struct ath11k *ar = file->private_data;
1541 char buf[32];
1542 int len;
1543
1544 mutex_lock(&ar->conf_mutex);
1545 len = scnprintf(buf, sizeof(buf), "%d\n", ar->ps_state_enable);
1546 mutex_unlock(&ar->conf_mutex);
1547
1548 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1549}
1550
1551static const struct file_operations fops_ps_state_enable = {
1552 .read = ath11k_read_ps_state_enable,
1553 .write = ath11k_write_ps_state_enable,
1554 .open = simple_open,
1555 .owner = THIS_MODULE,
1556 .llseek = default_llseek,
1557};
1558
1559int ath11k_debugfs_register(struct ath11k *ar)
1560{
1561 struct ath11k_base *ab = ar->ab;
1562 char pdev_name[5];
1563 char buf[100] = {0};
1564
1565 snprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx);
1566
1567 ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc);
1568 if (IS_ERR(ar->debug.debugfs_pdev))
1569 return PTR_ERR(ar->debug.debugfs_pdev);
1570
1571 /* Create a symlink under ieee80211/phy* */
1572 snprintf(buf, 100, "../../ath11k/%pd2", ar->debug.debugfs_pdev);
1573 debugfs_create_symlink("ath11k", ar->hw->wiphy->debugfsdir, buf);
1574
1575 ath11k_debugfs_htt_stats_init(ar);
1576
1577 ath11k_debugfs_fw_stats_init(ar);
1578
1579 debugfs_create_file("ext_tx_stats", 0644,
1580 ar->debug.debugfs_pdev, ar,
1581 &fops_extd_tx_stats);
1582 debugfs_create_file("ext_rx_stats", 0644,
1583 ar->debug.debugfs_pdev, ar,
1584 &fops_extd_rx_stats);
1585 debugfs_create_file("pktlog_filter", 0644,
1586 ar->debug.debugfs_pdev, ar,
1587 &fops_pktlog_filter);
1588 debugfs_create_file("fw_dbglog_config", 0600,
1589 ar->debug.debugfs_pdev, ar,
1590 &fops_fw_dbglog);
1591
1592 if (ar->hw->wiphy->bands[NL80211_BAND_5GHZ]) {
1593 debugfs_create_file("dfs_simulate_radar", 0200,
1594 ar->debug.debugfs_pdev, ar,
1595 &fops_simulate_radar);
1596 debugfs_create_bool("dfs_block_radar_events", 0200,
1597 ar->debug.debugfs_pdev,
1598 &ar->dfs_block_radar_events);
1599 }
1600
1601 if (ab->hw_params.dbr_debug_support)
1602 debugfs_create_file("enable_dbr_debug", 0200, ar->debug.debugfs_pdev,
1603 ar, &fops_dbr_debug);
1604
1605 debugfs_create_file("ps_state_enable", 0600, ar->debug.debugfs_pdev, ar,
1606 &fops_ps_state_enable);
1607
1608 if (test_bit(WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT,
1609 ar->ab->wmi_ab.svc_map)) {
1610 debugfs_create_file("ps_timekeeper_enable", 0600,
1611 ar->debug.debugfs_pdev, ar,
1612 &fops_ps_timekeeper_enable);
1613
1614 debugfs_create_file("reset_ps_duration", 0200,
1615 ar->debug.debugfs_pdev, ar,
1616 &fops_reset_ps_duration);
1617 }
1618
1619 return 0;
1620}
1621
1622void ath11k_debugfs_unregister(struct ath11k *ar)
1623{
1624 struct ath11k_debug_dbr *dbr_debug;
1625 struct ath11k_dbg_dbr_data *dbr_dbg_data;
1626 int i;
1627
1628 for (i = 0; i < WMI_DIRECT_BUF_MAX; i++) {
1629 dbr_debug = ar->debug.dbr_debug[i];
1630 if (!dbr_debug)
1631 continue;
1632
1633 dbr_dbg_data = &dbr_debug->dbr_dbg_data;
1634 kfree(dbr_dbg_data->entries);
1635 debugfs_remove_recursive(dbr_debug->dbr_debugfs);
1636 kfree(dbr_debug);
1637 ar->debug.dbr_debug[i] = NULL;
1638 }
1639}
1640
1641static ssize_t ath11k_write_twt_add_dialog(struct file *file,
1642 const char __user *ubuf,
1643 size_t count, loff_t *ppos)
1644{
1645 struct ath11k_vif *arvif = file->private_data;
1646 struct wmi_twt_add_dialog_params params = { 0 };
1647 struct wmi_twt_enable_params twt_params = {0};
1648 struct ath11k *ar = arvif->ar;
1649 u8 buf[128] = {0};
1650 int ret;
1651
1652 if (ar->twt_enabled == 0) {
1653 ath11k_err(ar->ab, "twt support is not enabled\n");
1654 return -EOPNOTSUPP;
1655 }
1656
1657 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1658 if (ret < 0)
1659 return ret;
1660
1661 buf[ret] = '\0';
1662 ret = sscanf(buf,
1663 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u %u %u %u %u %hhu %hhu %hhu %hhu %hhu",
1664 ¶ms.peer_macaddr[0],
1665 ¶ms.peer_macaddr[1],
1666 ¶ms.peer_macaddr[2],
1667 ¶ms.peer_macaddr[3],
1668 ¶ms.peer_macaddr[4],
1669 ¶ms.peer_macaddr[5],
1670 ¶ms.dialog_id,
1671 ¶ms.wake_intvl_us,
1672 ¶ms.wake_intvl_mantis,
1673 ¶ms.wake_dura_us,
1674 ¶ms.sp_offset_us,
1675 ¶ms.twt_cmd,
1676 ¶ms.flag_bcast,
1677 ¶ms.flag_trigger,
1678 ¶ms.flag_flow_type,
1679 ¶ms.flag_protection);
1680 if (ret != 16)
1681 return -EINVAL;
1682
1683 /* In the case of station vif, TWT is entirely handled by
1684 * the firmware based on the input parameters in the TWT enable
1685 * WMI command that is sent to the target during assoc.
1686 * For manually testing the TWT feature, we need to first disable
1687 * TWT and send enable command again with TWT input parameter
1688 * sta_cong_timer_ms set to 0.
1689 */
1690 if (arvif->vif->type == NL80211_IFTYPE_STATION) {
1691 ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
1692
1693 ath11k_wmi_fill_default_twt_params(&twt_params);
1694 twt_params.sta_cong_timer_ms = 0;
1695
1696 ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id, &twt_params);
1697 }
1698
1699 params.vdev_id = arvif->vdev_id;
1700
1701 ret = ath11k_wmi_send_twt_add_dialog_cmd(arvif->ar, ¶ms);
1702 if (ret)
1703 goto err_twt_add_dialog;
1704
1705 return count;
1706
1707err_twt_add_dialog:
1708 if (arvif->vif->type == NL80211_IFTYPE_STATION) {
1709 ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
1710 ath11k_wmi_fill_default_twt_params(&twt_params);
1711 ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id, &twt_params);
1712 }
1713
1714 return ret;
1715}
1716
1717static ssize_t ath11k_write_twt_del_dialog(struct file *file,
1718 const char __user *ubuf,
1719 size_t count, loff_t *ppos)
1720{
1721 struct ath11k_vif *arvif = file->private_data;
1722 struct wmi_twt_del_dialog_params params = { 0 };
1723 struct wmi_twt_enable_params twt_params = {0};
1724 struct ath11k *ar = arvif->ar;
1725 u8 buf[64] = {0};
1726 int ret;
1727
1728 if (ar->twt_enabled == 0) {
1729 ath11k_err(ar->ab, "twt support is not enabled\n");
1730 return -EOPNOTSUPP;
1731 }
1732
1733 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1734 if (ret < 0)
1735 return ret;
1736
1737 buf[ret] = '\0';
1738 ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u",
1739 ¶ms.peer_macaddr[0],
1740 ¶ms.peer_macaddr[1],
1741 ¶ms.peer_macaddr[2],
1742 ¶ms.peer_macaddr[3],
1743 ¶ms.peer_macaddr[4],
1744 ¶ms.peer_macaddr[5],
1745 ¶ms.dialog_id);
1746 if (ret != 7)
1747 return -EINVAL;
1748
1749 params.vdev_id = arvif->vdev_id;
1750
1751 ret = ath11k_wmi_send_twt_del_dialog_cmd(arvif->ar, ¶ms);
1752 if (ret)
1753 return ret;
1754
1755 if (arvif->vif->type == NL80211_IFTYPE_STATION) {
1756 ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
1757 ath11k_wmi_fill_default_twt_params(&twt_params);
1758 ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id, &twt_params);
1759 }
1760
1761 return count;
1762}
1763
1764static ssize_t ath11k_write_twt_pause_dialog(struct file *file,
1765 const char __user *ubuf,
1766 size_t count, loff_t *ppos)
1767{
1768 struct ath11k_vif *arvif = file->private_data;
1769 struct wmi_twt_pause_dialog_params params = { 0 };
1770 u8 buf[64] = {0};
1771 int ret;
1772
1773 if (arvif->ar->twt_enabled == 0) {
1774 ath11k_err(arvif->ar->ab, "twt support is not enabled\n");
1775 return -EOPNOTSUPP;
1776 }
1777
1778 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1779 if (ret < 0)
1780 return ret;
1781
1782 buf[ret] = '\0';
1783 ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u",
1784 ¶ms.peer_macaddr[0],
1785 ¶ms.peer_macaddr[1],
1786 ¶ms.peer_macaddr[2],
1787 ¶ms.peer_macaddr[3],
1788 ¶ms.peer_macaddr[4],
1789 ¶ms.peer_macaddr[5],
1790 ¶ms.dialog_id);
1791 if (ret != 7)
1792 return -EINVAL;
1793
1794 params.vdev_id = arvif->vdev_id;
1795
1796 ret = ath11k_wmi_send_twt_pause_dialog_cmd(arvif->ar, ¶ms);
1797 if (ret)
1798 return ret;
1799
1800 return count;
1801}
1802
1803static ssize_t ath11k_write_twt_resume_dialog(struct file *file,
1804 const char __user *ubuf,
1805 size_t count, loff_t *ppos)
1806{
1807 struct ath11k_vif *arvif = file->private_data;
1808 struct wmi_twt_resume_dialog_params params = { 0 };
1809 u8 buf[64] = {0};
1810 int ret;
1811
1812 if (arvif->ar->twt_enabled == 0) {
1813 ath11k_err(arvif->ar->ab, "twt support is not enabled\n");
1814 return -EOPNOTSUPP;
1815 }
1816
1817 ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1818 if (ret < 0)
1819 return ret;
1820
1821 buf[ret] = '\0';
1822 ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u %u %u",
1823 ¶ms.peer_macaddr[0],
1824 ¶ms.peer_macaddr[1],
1825 ¶ms.peer_macaddr[2],
1826 ¶ms.peer_macaddr[3],
1827 ¶ms.peer_macaddr[4],
1828 ¶ms.peer_macaddr[5],
1829 ¶ms.dialog_id,
1830 ¶ms.sp_offset_us,
1831 ¶ms.next_twt_size);
1832 if (ret != 9)
1833 return -EINVAL;
1834
1835 params.vdev_id = arvif->vdev_id;
1836
1837 ret = ath11k_wmi_send_twt_resume_dialog_cmd(arvif->ar, ¶ms);
1838 if (ret)
1839 return ret;
1840
1841 return count;
1842}
1843
1844static const struct file_operations ath11k_fops_twt_add_dialog = {
1845 .write = ath11k_write_twt_add_dialog,
1846 .open = simple_open
1847};
1848
1849static const struct file_operations ath11k_fops_twt_del_dialog = {
1850 .write = ath11k_write_twt_del_dialog,
1851 .open = simple_open
1852};
1853
1854static const struct file_operations ath11k_fops_twt_pause_dialog = {
1855 .write = ath11k_write_twt_pause_dialog,
1856 .open = simple_open
1857};
1858
1859static const struct file_operations ath11k_fops_twt_resume_dialog = {
1860 .write = ath11k_write_twt_resume_dialog,
1861 .open = simple_open
1862};
1863
1864void ath11k_debugfs_add_interface(struct ath11k_vif *arvif)
1865{
1866 struct ath11k_base *ab = arvif->ar->ab;
1867
1868 if (arvif->vif->type != NL80211_IFTYPE_AP &&
1869 !(arvif->vif->type == NL80211_IFTYPE_STATION &&
1870 test_bit(WMI_TLV_SERVICE_STA_TWT, ab->wmi_ab.svc_map)))
1871 return;
1872
1873 arvif->debugfs_twt = debugfs_create_dir("twt",
1874 arvif->vif->debugfs_dir);
1875 debugfs_create_file("add_dialog", 0200, arvif->debugfs_twt,
1876 arvif, &ath11k_fops_twt_add_dialog);
1877
1878 debugfs_create_file("del_dialog", 0200, arvif->debugfs_twt,
1879 arvif, &ath11k_fops_twt_del_dialog);
1880
1881 debugfs_create_file("pause_dialog", 0200, arvif->debugfs_twt,
1882 arvif, &ath11k_fops_twt_pause_dialog);
1883
1884 debugfs_create_file("resume_dialog", 0200, arvif->debugfs_twt,
1885 arvif, &ath11k_fops_twt_resume_dialog);
1886}
1887
1888void ath11k_debugfs_remove_interface(struct ath11k_vif *arvif)
1889{
1890 if (!arvif->debugfs_twt)
1891 return;
1892
1893 debugfs_remove_recursive(arvif->debugfs_twt);
1894 arvif->debugfs_twt = NULL;
1895}