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