ath11k: refactor debugfs code into debugfs.c
[linux-2.6-microblaze.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 "debugfs.h"
7
8 #include "core.h"
9 #include "debug.h"
10 #include "wmi.h"
11 #include "hal_rx.h"
12 #include "dp_tx.h"
13 #include "debug_htt_stats.h"
14 #include "peer.h"
15
16 static const char *htt_bp_umac_ring[HTT_SW_UMAC_RING_IDX_MAX] = {
17         "REO2SW1_RING",
18         "REO2SW2_RING",
19         "REO2SW3_RING",
20         "REO2SW4_RING",
21         "WBM2REO_LINK_RING",
22         "REO2TCL_RING",
23         "REO2FW_RING",
24         "RELEASE_RING",
25         "PPE_RELEASE_RING",
26         "TCL2TQM_RING",
27         "TQM_RELEASE_RING",
28         "REO_RELEASE_RING",
29         "WBM2SW0_RELEASE_RING",
30         "WBM2SW1_RELEASE_RING",
31         "WBM2SW2_RELEASE_RING",
32         "WBM2SW3_RELEASE_RING",
33         "REO_CMD_RING",
34         "REO_STATUS_RING",
35 };
36
37 static const char *htt_bp_lmac_ring[HTT_SW_LMAC_RING_IDX_MAX] = {
38         "FW2RXDMA_BUF_RING",
39         "FW2RXDMA_STATUS_RING",
40         "FW2RXDMA_LINK_RING",
41         "SW2RXDMA_BUF_RING",
42         "WBM2RXDMA_LINK_RING",
43         "RXDMA2FW_RING",
44         "RXDMA2SW_RING",
45         "RXDMA2RELEASE_RING",
46         "RXDMA2REO_RING",
47         "MONITOR_STATUS_RING",
48         "MONITOR_BUF_RING",
49         "MONITOR_DESC_RING",
50         "MONITOR_DEST_RING",
51 };
52
53 static void ath11k_fw_stats_pdevs_free(struct list_head *head)
54 {
55         struct ath11k_fw_stats_pdev *i, *tmp;
56
57         list_for_each_entry_safe(i, tmp, head, list) {
58                 list_del(&i->list);
59                 kfree(i);
60         }
61 }
62
63 static void ath11k_fw_stats_vdevs_free(struct list_head *head)
64 {
65         struct ath11k_fw_stats_vdev *i, *tmp;
66
67         list_for_each_entry_safe(i, tmp, head, list) {
68                 list_del(&i->list);
69                 kfree(i);
70         }
71 }
72
73 static void ath11k_fw_stats_bcn_free(struct list_head *head)
74 {
75         struct ath11k_fw_stats_bcn *i, *tmp;
76
77         list_for_each_entry_safe(i, tmp, head, list) {
78                 list_del(&i->list);
79                 kfree(i);
80         }
81 }
82
83 static void ath11k_debug_fw_stats_reset(struct ath11k *ar)
84 {
85         spin_lock_bh(&ar->data_lock);
86         ar->debug.fw_stats_done = false;
87         ath11k_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs);
88         ath11k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
89         spin_unlock_bh(&ar->data_lock);
90 }
91
92 void ath11k_debug_fw_stats_process(struct ath11k_base *ab, struct sk_buff *skb)
93 {
94         struct ath11k_fw_stats stats = {};
95         struct ath11k *ar;
96         struct ath11k_pdev *pdev;
97         bool is_end;
98         static unsigned int num_vdev, num_bcn;
99         size_t total_vdevs_started = 0;
100         int i, ret;
101
102         INIT_LIST_HEAD(&stats.pdevs);
103         INIT_LIST_HEAD(&stats.vdevs);
104         INIT_LIST_HEAD(&stats.bcn);
105
106         ret = ath11k_wmi_pull_fw_stats(ab, skb, &stats);
107         if (ret) {
108                 ath11k_warn(ab, "failed to pull fw stats: %d\n", ret);
109                 goto free;
110         }
111
112         rcu_read_lock();
113         ar = ath11k_mac_get_ar_by_pdev_id(ab, stats.pdev_id);
114         if (!ar) {
115                 rcu_read_unlock();
116                 ath11k_warn(ab, "failed to get ar for pdev_id %d: %d\n",
117                             stats.pdev_id, ret);
118                 goto free;
119         }
120
121         spin_lock_bh(&ar->data_lock);
122
123         if (stats.stats_id == WMI_REQUEST_PDEV_STAT) {
124                 list_splice_tail_init(&stats.pdevs, &ar->debug.fw_stats.pdevs);
125                 ar->debug.fw_stats_done = true;
126                 goto complete;
127         }
128
129         if (stats.stats_id == WMI_REQUEST_VDEV_STAT) {
130                 if (list_empty(&stats.vdevs)) {
131                         ath11k_warn(ab, "empty vdev stats");
132                         goto complete;
133                 }
134                 /* FW sends all the active VDEV stats irrespective of PDEV,
135                  * hence limit until the count of all VDEVs started
136                  */
137                 for (i = 0; i < ab->num_radios; i++) {
138                         pdev = rcu_dereference(ab->pdevs_active[i]);
139                         if (pdev && pdev->ar)
140                                 total_vdevs_started += ar->num_started_vdevs;
141                 }
142
143                 is_end = ((++num_vdev) == total_vdevs_started);
144
145                 list_splice_tail_init(&stats.vdevs,
146                                       &ar->debug.fw_stats.vdevs);
147
148                 if (is_end) {
149                         ar->debug.fw_stats_done = true;
150                         num_vdev = 0;
151                 }
152                 goto complete;
153         }
154
155         if (stats.stats_id == WMI_REQUEST_BCN_STAT) {
156                 if (list_empty(&stats.bcn)) {
157                         ath11k_warn(ab, "empty bcn stats");
158                         goto complete;
159                 }
160                 /* Mark end until we reached the count of all started VDEVs
161                  * within the PDEV
162                  */
163                 is_end = ((++num_bcn) == ar->num_started_vdevs);
164
165                 list_splice_tail_init(&stats.bcn,
166                                       &ar->debug.fw_stats.bcn);
167
168                 if (is_end) {
169                         ar->debug.fw_stats_done = true;
170                         num_bcn = 0;
171                 }
172         }
173 complete:
174         complete(&ar->debug.fw_stats_complete);
175         rcu_read_unlock();
176         spin_unlock_bh(&ar->data_lock);
177
178 free:
179         ath11k_fw_stats_pdevs_free(&stats.pdevs);
180         ath11k_fw_stats_vdevs_free(&stats.vdevs);
181         ath11k_fw_stats_bcn_free(&stats.bcn);
182 }
183
184 static int ath11k_debug_fw_stats_request(struct ath11k *ar,
185                                          struct stats_request_params *req_param)
186 {
187         struct ath11k_base *ab = ar->ab;
188         unsigned long timeout, time_left;
189         int ret;
190
191         lockdep_assert_held(&ar->conf_mutex);
192
193         /* FW stats can get split when exceeding the stats data buffer limit.
194          * In that case, since there is no end marking for the back-to-back
195          * received 'update stats' event, we keep a 3 seconds timeout in case,
196          * fw_stats_done is not marked yet
197          */
198         timeout = jiffies + msecs_to_jiffies(3 * HZ);
199
200         ath11k_debug_fw_stats_reset(ar);
201
202         reinit_completion(&ar->debug.fw_stats_complete);
203
204         ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);
205
206         if (ret) {
207                 ath11k_warn(ab, "could not request fw stats (%d)\n",
208                             ret);
209                 return ret;
210         }
211
212         time_left =
213         wait_for_completion_timeout(&ar->debug.fw_stats_complete,
214                                     1 * HZ);
215         if (!time_left)
216                 return -ETIMEDOUT;
217
218         for (;;) {
219                 if (time_after(jiffies, timeout))
220                         break;
221
222                 spin_lock_bh(&ar->data_lock);
223                 if (ar->debug.fw_stats_done) {
224                         spin_unlock_bh(&ar->data_lock);
225                         break;
226                 }
227                 spin_unlock_bh(&ar->data_lock);
228         }
229         return 0;
230 }
231
232 static int ath11k_open_pdev_stats(struct inode *inode, struct file *file)
233 {
234         struct ath11k *ar = inode->i_private;
235         struct ath11k_base *ab = ar->ab;
236         struct stats_request_params req_param;
237         void *buf = NULL;
238         int ret;
239
240         mutex_lock(&ar->conf_mutex);
241
242         if (ar->state != ATH11K_STATE_ON) {
243                 ret = -ENETDOWN;
244                 goto err_unlock;
245         }
246
247         buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
248         if (!buf) {
249                 ret = -ENOMEM;
250                 goto err_unlock;
251         }
252
253         req_param.pdev_id = ar->pdev->pdev_id;
254         req_param.vdev_id = 0;
255         req_param.stats_id = WMI_REQUEST_PDEV_STAT;
256
257         ret = ath11k_debug_fw_stats_request(ar, &req_param);
258         if (ret) {
259                 ath11k_warn(ab, "failed to request fw pdev stats: %d\n", ret);
260                 goto err_free;
261         }
262
263         ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id,
264                                  buf);
265
266         file->private_data = buf;
267
268         mutex_unlock(&ar->conf_mutex);
269         return 0;
270
271 err_free:
272         vfree(buf);
273
274 err_unlock:
275         mutex_unlock(&ar->conf_mutex);
276         return ret;
277 }
278
279 static int ath11k_release_pdev_stats(struct inode *inode, struct file *file)
280 {
281         vfree(file->private_data);
282
283         return 0;
284 }
285
286 static ssize_t ath11k_read_pdev_stats(struct file *file,
287                                       char __user *user_buf,
288                                       size_t count, loff_t *ppos)
289 {
290         const char *buf = file->private_data;
291         size_t len = strlen(buf);
292
293         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
294 }
295
296 static const struct file_operations fops_pdev_stats = {
297         .open = ath11k_open_pdev_stats,
298         .release = ath11k_release_pdev_stats,
299         .read = ath11k_read_pdev_stats,
300         .owner = THIS_MODULE,
301         .llseek = default_llseek,
302 };
303
304 static int ath11k_open_vdev_stats(struct inode *inode, struct file *file)
305 {
306         struct ath11k *ar = inode->i_private;
307         struct stats_request_params req_param;
308         void *buf = NULL;
309         int ret;
310
311         mutex_lock(&ar->conf_mutex);
312
313         if (ar->state != ATH11K_STATE_ON) {
314                 ret = -ENETDOWN;
315                 goto err_unlock;
316         }
317
318         buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
319         if (!buf) {
320                 ret = -ENOMEM;
321                 goto err_unlock;
322         }
323
324         req_param.pdev_id = ar->pdev->pdev_id;
325         /* VDEV stats is always sent for all active VDEVs from FW */
326         req_param.vdev_id = 0;
327         req_param.stats_id = WMI_REQUEST_VDEV_STAT;
328
329         ret = ath11k_debug_fw_stats_request(ar, &req_param);
330         if (ret) {
331                 ath11k_warn(ar->ab, "failed to request fw vdev stats: %d\n", ret);
332                 goto err_free;
333         }
334
335         ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id,
336                                  buf);
337
338         file->private_data = buf;
339
340         mutex_unlock(&ar->conf_mutex);
341         return 0;
342
343 err_free:
344         vfree(buf);
345
346 err_unlock:
347         mutex_unlock(&ar->conf_mutex);
348         return ret;
349 }
350
351 static int ath11k_release_vdev_stats(struct inode *inode, struct file *file)
352 {
353         vfree(file->private_data);
354
355         return 0;
356 }
357
358 static ssize_t ath11k_read_vdev_stats(struct file *file,
359                                       char __user *user_buf,
360                                       size_t count, loff_t *ppos)
361 {
362         const char *buf = file->private_data;
363         size_t len = strlen(buf);
364
365         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
366 }
367
368 static const struct file_operations fops_vdev_stats = {
369         .open = ath11k_open_vdev_stats,
370         .release = ath11k_release_vdev_stats,
371         .read = ath11k_read_vdev_stats,
372         .owner = THIS_MODULE,
373         .llseek = default_llseek,
374 };
375
376 static int ath11k_open_bcn_stats(struct inode *inode, struct file *file)
377 {
378         struct ath11k *ar = inode->i_private;
379         struct ath11k_vif *arvif;
380         struct stats_request_params req_param;
381         void *buf = NULL;
382         int ret;
383
384         mutex_lock(&ar->conf_mutex);
385
386         if (ar->state != ATH11K_STATE_ON) {
387                 ret = -ENETDOWN;
388                 goto err_unlock;
389         }
390
391         buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
392         if (!buf) {
393                 ret = -ENOMEM;
394                 goto err_unlock;
395         }
396
397         req_param.stats_id = WMI_REQUEST_BCN_STAT;
398         req_param.pdev_id = ar->pdev->pdev_id;
399
400         /* loop all active VDEVs for bcn stats */
401         list_for_each_entry(arvif, &ar->arvifs, list) {
402                 if (!arvif->is_up)
403                         continue;
404
405                 req_param.vdev_id = arvif->vdev_id;
406                 ret = ath11k_debug_fw_stats_request(ar, &req_param);
407                 if (ret) {
408                         ath11k_warn(ar->ab, "failed to request fw bcn stats: %d\n", ret);
409                         goto err_free;
410                 }
411         }
412
413         ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id,
414                                  buf);
415
416         /* since beacon stats request is looped for all active VDEVs, saved fw
417          * stats is not freed for each request until done for all active VDEVs
418          */
419         spin_lock_bh(&ar->data_lock);
420         ath11k_fw_stats_bcn_free(&ar->debug.fw_stats.bcn);
421         spin_unlock_bh(&ar->data_lock);
422
423         file->private_data = buf;
424
425         mutex_unlock(&ar->conf_mutex);
426         return 0;
427
428 err_free:
429         vfree(buf);
430
431 err_unlock:
432         mutex_unlock(&ar->conf_mutex);
433         return ret;
434 }
435
436 static int ath11k_release_bcn_stats(struct inode *inode, struct file *file)
437 {
438         vfree(file->private_data);
439
440         return 0;
441 }
442
443 static ssize_t ath11k_read_bcn_stats(struct file *file,
444                                      char __user *user_buf,
445                                      size_t count, loff_t *ppos)
446 {
447         const char *buf = file->private_data;
448         size_t len = strlen(buf);
449
450         return simple_read_from_buffer(user_buf, count, ppos, buf, len);
451 }
452
453 static const struct file_operations fops_bcn_stats = {
454         .open = ath11k_open_bcn_stats,
455         .release = ath11k_release_bcn_stats,
456         .read = ath11k_read_bcn_stats,
457         .owner = THIS_MODULE,
458         .llseek = default_llseek,
459 };
460
461 static ssize_t ath11k_read_simulate_fw_crash(struct file *file,
462                                              char __user *user_buf,
463                                              size_t count, loff_t *ppos)
464 {
465         const char buf[] =
466                 "To simulate firmware crash write one of the keywords to this file:\n"
467                 "`assert` - this will send WMI_FORCE_FW_HANG_CMDID to firmware to cause assert.\n"
468                 "`hw-restart` - this will simply queue hw restart without fw/hw actually crashing.\n";
469
470         return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
471 }
472
473 /* Simulate firmware crash:
474  * 'soft': Call wmi command causing firmware hang. This firmware hang is
475  * recoverable by warm firmware reset.
476  * 'hard': Force firmware crash by setting any vdev parameter for not allowed
477  * vdev id. This is hard firmware crash because it is recoverable only by cold
478  * firmware reset.
479  */
480 static ssize_t ath11k_write_simulate_fw_crash(struct file *file,
481                                               const char __user *user_buf,
482                                               size_t count, loff_t *ppos)
483 {
484         struct ath11k_base *ab = file->private_data;
485         struct ath11k_pdev *pdev;
486         struct ath11k *ar = ab->pdevs[0].ar;
487         char buf[32] = {0};
488         ssize_t rc;
489         int i, ret, radioup = 0;
490
491         for (i = 0; i < ab->num_radios; i++) {
492                 pdev = &ab->pdevs[i];
493                 ar = pdev->ar;
494                 if (ar && ar->state == ATH11K_STATE_ON) {
495                         radioup = 1;
496                         break;
497                 }
498         }
499         /* filter partial writes and invalid commands */
500         if (*ppos != 0 || count >= sizeof(buf) || count == 0)
501                 return -EINVAL;
502
503         rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
504         if (rc < 0)
505                 return rc;
506
507         /* drop the possible '\n' from the end */
508         if (buf[*ppos - 1] == '\n')
509                 buf[*ppos - 1] = '\0';
510
511         if (radioup == 0) {
512                 ret = -ENETDOWN;
513                 goto exit;
514         }
515
516         if (!strcmp(buf, "assert")) {
517                 ath11k_info(ab, "simulating firmware assert crash\n");
518                 ret = ath11k_wmi_force_fw_hang_cmd(ar,
519                                                    ATH11K_WMI_FW_HANG_ASSERT_TYPE,
520                                                    ATH11K_WMI_FW_HANG_DELAY);
521         } else {
522                 ret = -EINVAL;
523                 goto exit;
524         }
525
526         if (ret) {
527                 ath11k_warn(ab, "failed to simulate firmware crash: %d\n", ret);
528                 goto exit;
529         }
530
531         ret = count;
532
533 exit:
534         return ret;
535 }
536
537 static const struct file_operations fops_simulate_fw_crash = {
538         .read = ath11k_read_simulate_fw_crash,
539         .write = ath11k_write_simulate_fw_crash,
540         .open = simple_open,
541         .owner = THIS_MODULE,
542         .llseek = default_llseek,
543 };
544
545 static ssize_t ath11k_write_enable_extd_tx_stats(struct file *file,
546                                                  const char __user *ubuf,
547                                                  size_t count, loff_t *ppos)
548 {
549         struct ath11k *ar = file->private_data;
550         u32 filter;
551         int ret;
552
553         if (kstrtouint_from_user(ubuf, count, 0, &filter))
554                 return -EINVAL;
555
556         mutex_lock(&ar->conf_mutex);
557
558         if (ar->state != ATH11K_STATE_ON) {
559                 ret = -ENETDOWN;
560                 goto out;
561         }
562
563         if (filter == ar->debug.extd_tx_stats) {
564                 ret = count;
565                 goto out;
566         }
567
568         ar->debug.extd_tx_stats = filter;
569         ret = count;
570
571 out:
572         mutex_unlock(&ar->conf_mutex);
573         return ret;
574 }
575
576 static ssize_t ath11k_read_enable_extd_tx_stats(struct file *file,
577                                                 char __user *ubuf,
578                                                 size_t count, loff_t *ppos)
579
580 {
581         char buf[32] = {0};
582         struct ath11k *ar = file->private_data;
583         int len = 0;
584
585         mutex_lock(&ar->conf_mutex);
586         len = scnprintf(buf, sizeof(buf) - len, "%08x\n",
587                         ar->debug.extd_tx_stats);
588         mutex_unlock(&ar->conf_mutex);
589
590         return simple_read_from_buffer(ubuf, count, ppos, buf, len);
591 }
592
593 static const struct file_operations fops_extd_tx_stats = {
594         .read = ath11k_read_enable_extd_tx_stats,
595         .write = ath11k_write_enable_extd_tx_stats,
596         .open = simple_open
597 };
598
599 static ssize_t ath11k_write_extd_rx_stats(struct file *file,
600                                           const char __user *ubuf,
601                                           size_t count, loff_t *ppos)
602 {
603         struct ath11k *ar = file->private_data;
604         struct ath11k_base *ab = ar->ab;
605         struct htt_rx_ring_tlv_filter tlv_filter = {0};
606         u32 enable, rx_filter = 0, ring_id;
607         int i;
608         int ret;
609
610         if (kstrtouint_from_user(ubuf, count, 0, &enable))
611                 return -EINVAL;
612
613         mutex_lock(&ar->conf_mutex);
614
615         if (ar->state != ATH11K_STATE_ON) {
616                 ret = -ENETDOWN;
617                 goto exit;
618         }
619
620         if (enable > 1) {
621                 ret = -EINVAL;
622                 goto exit;
623         }
624
625         if (enable == ar->debug.extd_rx_stats) {
626                 ret = count;
627                 goto exit;
628         }
629
630         if (enable) {
631                 rx_filter =  HTT_RX_FILTER_TLV_FLAGS_MPDU_START;
632                 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_START;
633                 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END;
634                 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS;
635                 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT;
636                 rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE;
637
638                 tlv_filter.rx_filter = rx_filter;
639                 tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
640                 tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
641                 tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
642                 tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
643                         HTT_RX_FP_DATA_FILTER_FLASG3;
644         } else {
645                 tlv_filter = ath11k_mac_mon_status_filter_default;
646         }
647
648         ar->debug.rx_filter = tlv_filter.rx_filter;
649
650         for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
651                 ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
652                 ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
653                                                        HAL_RXDMA_MONITOR_STATUS,
654                                                        DP_RX_BUFFER_SIZE, &tlv_filter);
655
656                 if (ret) {
657                         ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
658                         goto exit;
659                 }
660         }
661
662         ar->debug.extd_rx_stats = enable;
663         ret = count;
664 exit:
665         mutex_unlock(&ar->conf_mutex);
666         return ret;
667 }
668
669 static ssize_t ath11k_read_extd_rx_stats(struct file *file,
670                                          char __user *ubuf,
671                                          size_t count, loff_t *ppos)
672 {
673         struct ath11k *ar = file->private_data;
674         char buf[32];
675         int len = 0;
676
677         mutex_lock(&ar->conf_mutex);
678         len = scnprintf(buf, sizeof(buf) - len, "%d\n",
679                         ar->debug.extd_rx_stats);
680         mutex_unlock(&ar->conf_mutex);
681
682         return simple_read_from_buffer(ubuf, count, ppos, buf, len);
683 }
684
685 static const struct file_operations fops_extd_rx_stats = {
686         .read = ath11k_read_extd_rx_stats,
687         .write = ath11k_write_extd_rx_stats,
688         .open = simple_open,
689 };
690
691 static int ath11k_fill_bp_stats(struct ath11k_base *ab,
692                                 struct ath11k_bp_stats *bp_stats,
693                                 char *buf, int len, int size)
694 {
695         lockdep_assert_held(&ab->base_lock);
696
697         len += scnprintf(buf + len, size - len, "count: %u\n",
698                          bp_stats->count);
699         len += scnprintf(buf + len, size - len, "hp: %u\n",
700                          bp_stats->hp);
701         len += scnprintf(buf + len, size - len, "tp: %u\n",
702                          bp_stats->tp);
703         len += scnprintf(buf + len, size - len, "seen before: %ums\n\n",
704                          jiffies_to_msecs(jiffies - bp_stats->jiffies));
705         return len;
706 }
707
708 static ssize_t ath11k_debug_dump_soc_ring_bp_stats(struct ath11k_base *ab,
709                                                    char *buf, int size)
710 {
711         struct ath11k_bp_stats *bp_stats;
712         bool stats_rxd = false;
713         u8 i, pdev_idx;
714         int len = 0;
715
716         len += scnprintf(buf + len, size - len, "\nBackpressure Stats\n");
717         len += scnprintf(buf + len, size - len, "==================\n");
718
719         spin_lock_bh(&ab->base_lock);
720         for (i = 0; i < HTT_SW_UMAC_RING_IDX_MAX; i++) {
721                 bp_stats = &ab->soc_stats.bp_stats.umac_ring_bp_stats[i];
722
723                 if (!bp_stats->count)
724                         continue;
725
726                 len += scnprintf(buf + len, size - len, "Ring: %s\n",
727                                  htt_bp_umac_ring[i]);
728                 len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
729                 stats_rxd = true;
730         }
731
732         for (i = 0; i < HTT_SW_LMAC_RING_IDX_MAX; i++) {
733                 for (pdev_idx = 0; pdev_idx < MAX_RADIOS; pdev_idx++) {
734                         bp_stats =
735                                 &ab->soc_stats.bp_stats.lmac_ring_bp_stats[i][pdev_idx];
736
737                         if (!bp_stats->count)
738                                 continue;
739
740                         len += scnprintf(buf + len, size - len, "Ring: %s\n",
741                                          htt_bp_lmac_ring[i]);
742                         len += scnprintf(buf + len, size - len, "pdev: %d\n",
743                                          pdev_idx);
744                         len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
745                         stats_rxd = true;
746                 }
747         }
748         spin_unlock_bh(&ab->base_lock);
749
750         if (!stats_rxd)
751                 len += scnprintf(buf + len, size - len,
752                                  "No Ring Backpressure stats received\n\n");
753
754         return len;
755 }
756
757 static ssize_t ath11k_debug_dump_soc_dp_stats(struct file *file,
758                                               char __user *user_buf,
759                                               size_t count, loff_t *ppos)
760 {
761         struct ath11k_base *ab = file->private_data;
762         struct ath11k_soc_dp_stats *soc_stats = &ab->soc_stats;
763         int len = 0, i, retval;
764         const int size = 4096;
765         static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = {
766                         "Overflow", "MPDU len", "FCS", "Decrypt", "TKIP MIC",
767                         "Unencrypt", "MSDU len", "MSDU limit", "WiFi parse",
768                         "AMSDU parse", "SA timeout", "DA timeout",
769                         "Flow timeout", "Flush req"};
770         static const char *reo_err[HAL_REO_DEST_RING_ERROR_CODE_MAX] = {
771                         "Desc addr zero", "Desc inval", "AMPDU in non BA",
772                         "Non BA dup", "BA dup", "Frame 2k jump", "BAR 2k jump",
773                         "Frame OOR", "BAR OOR", "No BA session",
774                         "Frame SN equal SSN", "PN check fail", "2k err",
775                         "PN err", "Desc blocked"};
776
777         char *buf;
778
779         buf = kzalloc(size, GFP_KERNEL);
780         if (!buf)
781                 return -ENOMEM;
782
783         len += scnprintf(buf + len, size - len, "SOC RX STATS:\n\n");
784         len += scnprintf(buf + len, size - len, "err ring pkts: %u\n",
785                          soc_stats->err_ring_pkts);
786         len += scnprintf(buf + len, size - len, "Invalid RBM: %u\n\n",
787                          soc_stats->invalid_rbm);
788         len += scnprintf(buf + len, size - len, "RXDMA errors:\n");
789         for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++)
790                 len += scnprintf(buf + len, size - len, "%s: %u\n",
791                                  rxdma_err[i], soc_stats->rxdma_error[i]);
792
793         len += scnprintf(buf + len, size - len, "\nREO errors:\n");
794         for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++)
795                 len += scnprintf(buf + len, size - len, "%s: %u\n",
796                                  reo_err[i], soc_stats->reo_error[i]);
797
798         len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n");
799         len += scnprintf(buf + len, size - len,
800                          "ring0: %u\nring1: %u\nring2: %u\nring3: %u\n",
801                          soc_stats->hal_reo_error[0],
802                          soc_stats->hal_reo_error[1],
803                          soc_stats->hal_reo_error[2],
804                          soc_stats->hal_reo_error[3]);
805
806         len += scnprintf(buf + len, size - len, "\nSOC TX STATS:\n");
807         len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n");
808
809         for (i = 0; i < DP_TCL_NUM_RING_MAX; i++)
810                 len += scnprintf(buf + len, size - len, "ring%d: %u\n",
811                                  i, soc_stats->tx_err.desc_na[i]);
812
813         len += scnprintf(buf + len, size - len,
814                          "\nMisc Transmit Failures: %d\n",
815                          atomic_read(&soc_stats->tx_err.misc_fail));
816
817         len += ath11k_debug_dump_soc_ring_bp_stats(ab, buf + len, size - len);
818
819         if (len > size)
820                 len = size;
821         retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
822         kfree(buf);
823
824         return retval;
825 }
826
827 static const struct file_operations fops_soc_dp_stats = {
828         .read = ath11k_debug_dump_soc_dp_stats,
829         .open = simple_open,
830         .owner = THIS_MODULE,
831         .llseek = default_llseek,
832 };
833
834 int ath11k_debug_pdev_create(struct ath11k_base *ab)
835 {
836         if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
837                 return 0;
838
839         ab->debugfs_soc = debugfs_create_dir(ab->hw_params.name, ab->debugfs_ath11k);
840
841         if (IS_ERR_OR_NULL(ab->debugfs_soc)) {
842                 if (IS_ERR(ab->debugfs_soc))
843                         return PTR_ERR(ab->debugfs_soc);
844                 return -ENOMEM;
845         }
846
847         debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
848                             &fops_simulate_fw_crash);
849
850         debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab,
851                             &fops_soc_dp_stats);
852
853         return 0;
854 }
855
856 void ath11k_debug_pdev_destroy(struct ath11k_base *ab)
857 {
858         debugfs_remove_recursive(ab->debugfs_ath11k);
859         ab->debugfs_ath11k = NULL;
860 }
861
862 int ath11k_debug_soc_create(struct ath11k_base *ab)
863 {
864         ab->debugfs_ath11k = debugfs_create_dir("ath11k", NULL);
865
866         if (IS_ERR_OR_NULL(ab->debugfs_ath11k)) {
867                 if (IS_ERR(ab->debugfs_ath11k))
868                         return PTR_ERR(ab->debugfs_ath11k);
869                 return -ENOMEM;
870         }
871
872         return 0;
873 }
874
875 void ath11k_debug_soc_destroy(struct ath11k_base *ab)
876 {
877         debugfs_remove_recursive(ab->debugfs_soc);
878         ab->debugfs_soc = NULL;
879 }
880
881 void ath11k_debug_fw_stats_init(struct ath11k *ar)
882 {
883         struct dentry *fwstats_dir = debugfs_create_dir("fw_stats",
884                                                         ar->debug.debugfs_pdev);
885
886         ar->debug.fw_stats.debugfs_fwstats = fwstats_dir;
887
888         /* all stats debugfs files created are under "fw_stats" directory
889          * created per PDEV
890          */
891         debugfs_create_file("pdev_stats", 0600, fwstats_dir, ar,
892                             &fops_pdev_stats);
893         debugfs_create_file("vdev_stats", 0600, fwstats_dir, ar,
894                             &fops_vdev_stats);
895         debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar,
896                             &fops_bcn_stats);
897
898         INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs);
899         INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs);
900         INIT_LIST_HEAD(&ar->debug.fw_stats.bcn);
901
902         init_completion(&ar->debug.fw_stats_complete);
903 }
904
905 static ssize_t ath11k_write_pktlog_filter(struct file *file,
906                                           const char __user *ubuf,
907                                           size_t count, loff_t *ppos)
908 {
909         struct ath11k *ar = file->private_data;
910         struct ath11k_base *ab = ar->ab;
911         struct htt_rx_ring_tlv_filter tlv_filter = {0};
912         u32 rx_filter = 0, ring_id, filter, mode;
913         u8 buf[128] = {0};
914         int i, ret;
915         ssize_t rc;
916
917         mutex_lock(&ar->conf_mutex);
918         if (ar->state != ATH11K_STATE_ON) {
919                 ret = -ENETDOWN;
920                 goto out;
921         }
922
923         rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
924         if (rc < 0) {
925                 ret = rc;
926                 goto out;
927         }
928         buf[rc] = '\0';
929
930         ret = sscanf(buf, "0x%x %u", &filter, &mode);
931         if (ret != 2) {
932                 ret = -EINVAL;
933                 goto out;
934         }
935
936         if (filter) {
937                 ret = ath11k_wmi_pdev_pktlog_enable(ar, filter);
938                 if (ret) {
939                         ath11k_warn(ar->ab,
940                                     "failed to enable pktlog filter %x: %d\n",
941                                     ar->debug.pktlog_filter, ret);
942                         goto out;
943                 }
944         } else {
945                 ret = ath11k_wmi_pdev_pktlog_disable(ar);
946                 if (ret) {
947                         ath11k_warn(ar->ab, "failed to disable pktlog: %d\n", ret);
948                         goto out;
949                 }
950         }
951
952 #define HTT_RX_FILTER_TLV_LITE_MODE \
953                         (HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
954                         HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
955                         HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \
956                         HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \
957                         HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \
958                         HTT_RX_FILTER_TLV_FLAGS_MPDU_START)
959
960         if (mode == ATH11K_PKTLOG_MODE_FULL) {
961                 rx_filter = HTT_RX_FILTER_TLV_LITE_MODE |
962                             HTT_RX_FILTER_TLV_FLAGS_MSDU_START |
963                             HTT_RX_FILTER_TLV_FLAGS_MSDU_END |
964                             HTT_RX_FILTER_TLV_FLAGS_MPDU_END |
965                             HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER |
966                             HTT_RX_FILTER_TLV_FLAGS_ATTENTION;
967         } else if (mode == ATH11K_PKTLOG_MODE_LITE) {
968                 ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
969                                                           HTT_PPDU_STATS_TAG_PKTLOG);
970                 if (ret) {
971                         ath11k_err(ar->ab, "failed to enable pktlog lite: %d\n", ret);
972                         goto out;
973                 }
974
975                 rx_filter = HTT_RX_FILTER_TLV_LITE_MODE;
976         } else {
977                 ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
978                                                           HTT_PPDU_STATS_TAG_DEFAULT);
979                 if (ret) {
980                         ath11k_err(ar->ab, "failed to send htt ppdu stats req: %d\n",
981                                    ret);
982                         goto out;
983                 }
984         }
985
986         tlv_filter.rx_filter = rx_filter;
987         if (rx_filter) {
988                 tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
989                 tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
990                 tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
991                 tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
992                                                HTT_RX_FP_DATA_FILTER_FLASG3;
993         }
994
995         for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
996                 ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
997                 ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id,
998                                                        ar->dp.mac_id + i,
999                                                        HAL_RXDMA_MONITOR_STATUS,
1000                                                        DP_RX_BUFFER_SIZE, &tlv_filter);
1001
1002                 if (ret) {
1003                         ath11k_warn(ab, "failed to set rx filter for monitor status ring\n");
1004                         goto out;
1005                 }
1006         }
1007
1008         ath11k_dbg(ab, ATH11K_DBG_WMI, "pktlog filter %d mode %s\n",
1009                    filter, ((mode == ATH11K_PKTLOG_MODE_FULL) ? "full" : "lite"));
1010
1011         ar->debug.pktlog_filter = filter;
1012         ar->debug.pktlog_mode = mode;
1013         ret = count;
1014
1015 out:
1016         mutex_unlock(&ar->conf_mutex);
1017         return ret;
1018 }
1019
1020 static ssize_t ath11k_read_pktlog_filter(struct file *file,
1021                                          char __user *ubuf,
1022                                          size_t count, loff_t *ppos)
1023
1024 {
1025         char buf[32] = {0};
1026         struct ath11k *ar = file->private_data;
1027         int len = 0;
1028
1029         mutex_lock(&ar->conf_mutex);
1030         len = scnprintf(buf, sizeof(buf) - len, "%08x %08x\n",
1031                         ar->debug.pktlog_filter,
1032                         ar->debug.pktlog_mode);
1033         mutex_unlock(&ar->conf_mutex);
1034
1035         return simple_read_from_buffer(ubuf, count, ppos, buf, len);
1036 }
1037
1038 static const struct file_operations fops_pktlog_filter = {
1039         .read = ath11k_read_pktlog_filter,
1040         .write = ath11k_write_pktlog_filter,
1041         .open = simple_open
1042 };
1043
1044 static ssize_t ath11k_write_simulate_radar(struct file *file,
1045                                            const char __user *user_buf,
1046                                            size_t count, loff_t *ppos)
1047 {
1048         struct ath11k *ar = file->private_data;
1049         int ret;
1050
1051         ret = ath11k_wmi_simulate_radar(ar);
1052         if (ret)
1053                 return ret;
1054
1055         return count;
1056 }
1057
1058 static const struct file_operations fops_simulate_radar = {
1059         .write = ath11k_write_simulate_radar,
1060         .open = simple_open
1061 };
1062
1063 int ath11k_debug_register(struct ath11k *ar)
1064 {
1065         struct ath11k_base *ab = ar->ab;
1066         char pdev_name[5];
1067         char buf[100] = {0};
1068
1069         snprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx);
1070
1071         ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc);
1072
1073         if (IS_ERR_OR_NULL(ar->debug.debugfs_pdev)) {
1074                 if (IS_ERR(ar->debug.debugfs_pdev))
1075                         return PTR_ERR(ar->debug.debugfs_pdev);
1076
1077                 return -ENOMEM;
1078         }
1079
1080         /* Create a symlink under ieee80211/phy* */
1081         snprintf(buf, 100, "../../ath11k/%pd2", ar->debug.debugfs_pdev);
1082         debugfs_create_symlink("ath11k", ar->hw->wiphy->debugfsdir, buf);
1083
1084         ath11k_debug_htt_stats_init(ar);
1085
1086         ath11k_debug_fw_stats_init(ar);
1087
1088         debugfs_create_file("ext_tx_stats", 0644,
1089                             ar->debug.debugfs_pdev, ar,
1090                             &fops_extd_tx_stats);
1091         debugfs_create_file("ext_rx_stats", 0644,
1092                             ar->debug.debugfs_pdev, ar,
1093                             &fops_extd_rx_stats);
1094         debugfs_create_file("pktlog_filter", 0644,
1095                             ar->debug.debugfs_pdev, ar,
1096                             &fops_pktlog_filter);
1097
1098         if (ar->hw->wiphy->bands[NL80211_BAND_5GHZ]) {
1099                 debugfs_create_file("dfs_simulate_radar", 0200,
1100                                     ar->debug.debugfs_pdev, ar,
1101                                     &fops_simulate_radar);
1102                 debugfs_create_bool("dfs_block_radar_events", 0200,
1103                                     ar->debug.debugfs_pdev,
1104                                     &ar->dfs_block_radar_events);
1105         }
1106
1107         return 0;
1108 }
1109
1110 void ath11k_debug_unregister(struct ath11k *ar)
1111 {
1112 }