]> Git Repo - linux.git/blob - drivers/net/wireless/ath/ath11k/debugfs.c
Merge tag 'net-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
[linux.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 "debugfs_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_debugfs_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_debugfs_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_debugfs_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_debugfs_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_debugfs_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_debugfs_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_debugfs_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_debugfs_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_debugfs_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 < ab->hw_params.max_tx_ring; 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_debugfs_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_debugfs_dump_soc_dp_stats,
829         .open = simple_open,
830         .owner = THIS_MODULE,
831         .llseek = default_llseek,
832 };
833
834 int ath11k_debugfs_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         if (IS_ERR(ab->debugfs_soc))
841                 return PTR_ERR(ab->debugfs_soc);
842
843         debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
844                             &fops_simulate_fw_crash);
845
846         debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab,
847                             &fops_soc_dp_stats);
848
849         return 0;
850 }
851
852 void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab)
853 {
854         debugfs_remove_recursive(ab->debugfs_soc);
855         ab->debugfs_soc = NULL;
856 }
857
858 int ath11k_debugfs_soc_create(struct ath11k_base *ab)
859 {
860         ab->debugfs_ath11k = debugfs_create_dir("ath11k", NULL);
861
862         return PTR_ERR_OR_ZERO(ab->debugfs_ath11k);
863 }
864
865 void ath11k_debugfs_soc_destroy(struct ath11k_base *ab)
866 {
867         debugfs_remove_recursive(ab->debugfs_ath11k);
868         ab->debugfs_ath11k = NULL;
869 }
870 EXPORT_SYMBOL(ath11k_debugfs_soc_destroy);
871
872 void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
873 {
874         struct dentry *fwstats_dir = debugfs_create_dir("fw_stats",
875                                                         ar->debug.debugfs_pdev);
876
877         ar->debug.fw_stats.debugfs_fwstats = fwstats_dir;
878
879         /* all stats debugfs files created are under "fw_stats" directory
880          * created per PDEV
881          */
882         debugfs_create_file("pdev_stats", 0600, fwstats_dir, ar,
883                             &fops_pdev_stats);
884         debugfs_create_file("vdev_stats", 0600, fwstats_dir, ar,
885                             &fops_vdev_stats);
886         debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar,
887                             &fops_bcn_stats);
888
889         INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs);
890         INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs);
891         INIT_LIST_HEAD(&ar->debug.fw_stats.bcn);
892
893         init_completion(&ar->debug.fw_stats_complete);
894 }
895
896 static ssize_t ath11k_write_pktlog_filter(struct file *file,
897                                           const char __user *ubuf,
898                                           size_t count, loff_t *ppos)
899 {
900         struct ath11k *ar = file->private_data;
901         struct ath11k_base *ab = ar->ab;
902         struct htt_rx_ring_tlv_filter tlv_filter = {0};
903         u32 rx_filter = 0, ring_id, filter, mode;
904         u8 buf[128] = {0};
905         int i, ret, rx_buf_sz = 0;
906         ssize_t rc;
907
908         mutex_lock(&ar->conf_mutex);
909         if (ar->state != ATH11K_STATE_ON) {
910                 ret = -ENETDOWN;
911                 goto out;
912         }
913
914         rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
915         if (rc < 0) {
916                 ret = rc;
917                 goto out;
918         }
919         buf[rc] = '\0';
920
921         ret = sscanf(buf, "0x%x %u", &filter, &mode);
922         if (ret != 2) {
923                 ret = -EINVAL;
924                 goto out;
925         }
926
927         if (filter) {
928                 ret = ath11k_wmi_pdev_pktlog_enable(ar, filter);
929                 if (ret) {
930                         ath11k_warn(ar->ab,
931                                     "failed to enable pktlog filter %x: %d\n",
932                                     ar->debug.pktlog_filter, ret);
933                         goto out;
934                 }
935         } else {
936                 ret = ath11k_wmi_pdev_pktlog_disable(ar);
937                 if (ret) {
938                         ath11k_warn(ar->ab, "failed to disable pktlog: %d\n", ret);
939                         goto out;
940                 }
941         }
942
943         /* Clear rx filter set for monitor mode and rx status */
944         for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
945                 ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
946                 ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
947                                                        HAL_RXDMA_MONITOR_STATUS,
948                                                        rx_buf_sz, &tlv_filter);
949                 if (ret) {
950                         ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
951                         goto out;
952                 }
953         }
954 #define HTT_RX_FILTER_TLV_LITE_MODE \
955                         (HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
956                         HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
957                         HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \
958                         HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \
959                         HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \
960                         HTT_RX_FILTER_TLV_FLAGS_MPDU_START)
961
962         if (mode == ATH11K_PKTLOG_MODE_FULL) {
963                 rx_filter = HTT_RX_FILTER_TLV_LITE_MODE |
964                             HTT_RX_FILTER_TLV_FLAGS_MSDU_START |
965                             HTT_RX_FILTER_TLV_FLAGS_MSDU_END |
966                             HTT_RX_FILTER_TLV_FLAGS_MPDU_END |
967                             HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER |
968                             HTT_RX_FILTER_TLV_FLAGS_ATTENTION;
969                 rx_buf_sz = DP_RX_BUFFER_SIZE;
970         } else if (mode == ATH11K_PKTLOG_MODE_LITE) {
971                 ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
972                                                           HTT_PPDU_STATS_TAG_PKTLOG);
973                 if (ret) {
974                         ath11k_err(ar->ab, "failed to enable pktlog lite: %d\n", ret);
975                         goto out;
976                 }
977
978                 rx_filter = HTT_RX_FILTER_TLV_LITE_MODE;
979                 rx_buf_sz = DP_RX_BUFFER_SIZE_LITE;
980         } else {
981                 rx_buf_sz = DP_RX_BUFFER_SIZE;
982                 tlv_filter = ath11k_mac_mon_status_filter_default;
983                 rx_filter = tlv_filter.rx_filter;
984
985                 ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
986                                                           HTT_PPDU_STATS_TAG_DEFAULT);
987                 if (ret) {
988                         ath11k_err(ar->ab, "failed to send htt ppdu stats req: %d\n",
989                                    ret);
990                         goto out;
991                 }
992         }
993
994         tlv_filter.rx_filter = rx_filter;
995         if (rx_filter) {
996                 tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
997                 tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
998                 tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
999                 tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
1000                                                HTT_RX_FP_DATA_FILTER_FLASG3;
1001         }
1002
1003         for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
1004                 ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
1005                 ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id,
1006                                                        ar->dp.mac_id + i,
1007                                                        HAL_RXDMA_MONITOR_STATUS,
1008                                                        rx_buf_sz, &tlv_filter);
1009
1010                 if (ret) {
1011                         ath11k_warn(ab, "failed to set rx filter for monitor status ring\n");
1012                         goto out;
1013                 }
1014         }
1015
1016         ath11k_info(ab, "pktlog mode %s\n",
1017                     ((mode == ATH11K_PKTLOG_MODE_FULL) ? "full" : "lite"));
1018
1019         ar->debug.pktlog_filter = filter;
1020         ar->debug.pktlog_mode = mode;
1021         ret = count;
1022
1023 out:
1024         mutex_unlock(&ar->conf_mutex);
1025         return ret;
1026 }
1027
1028 static ssize_t ath11k_read_pktlog_filter(struct file *file,
1029                                          char __user *ubuf,
1030                                          size_t count, loff_t *ppos)
1031
1032 {
1033         char buf[32] = {0};
1034         struct ath11k *ar = file->private_data;
1035         int len = 0;
1036
1037         mutex_lock(&ar->conf_mutex);
1038         len = scnprintf(buf, sizeof(buf) - len, "%08x %08x\n",
1039                         ar->debug.pktlog_filter,
1040                         ar->debug.pktlog_mode);
1041         mutex_unlock(&ar->conf_mutex);
1042
1043         return simple_read_from_buffer(ubuf, count, ppos, buf, len);
1044 }
1045
1046 static const struct file_operations fops_pktlog_filter = {
1047         .read = ath11k_read_pktlog_filter,
1048         .write = ath11k_write_pktlog_filter,
1049         .open = simple_open
1050 };
1051
1052 static ssize_t ath11k_write_simulate_radar(struct file *file,
1053                                            const char __user *user_buf,
1054                                            size_t count, loff_t *ppos)
1055 {
1056         struct ath11k *ar = file->private_data;
1057         int ret;
1058
1059         ret = ath11k_wmi_simulate_radar(ar);
1060         if (ret)
1061                 return ret;
1062
1063         return count;
1064 }
1065
1066 static const struct file_operations fops_simulate_radar = {
1067         .write = ath11k_write_simulate_radar,
1068         .open = simple_open
1069 };
1070
1071 int ath11k_debugfs_register(struct ath11k *ar)
1072 {
1073         struct ath11k_base *ab = ar->ab;
1074         char pdev_name[5];
1075         char buf[100] = {0};
1076
1077         snprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx);
1078
1079         ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc);
1080         if (IS_ERR(ar->debug.debugfs_pdev))
1081                 return PTR_ERR(ar->debug.debugfs_pdev);
1082
1083         /* Create a symlink under ieee80211/phy* */
1084         snprintf(buf, 100, "../../ath11k/%pd2", ar->debug.debugfs_pdev);
1085         debugfs_create_symlink("ath11k", ar->hw->wiphy->debugfsdir, buf);
1086
1087         ath11k_debugfs_htt_stats_init(ar);
1088
1089         ath11k_debugfs_fw_stats_init(ar);
1090
1091         debugfs_create_file("ext_tx_stats", 0644,
1092                             ar->debug.debugfs_pdev, ar,
1093                             &fops_extd_tx_stats);
1094         debugfs_create_file("ext_rx_stats", 0644,
1095                             ar->debug.debugfs_pdev, ar,
1096                             &fops_extd_rx_stats);
1097         debugfs_create_file("pktlog_filter", 0644,
1098                             ar->debug.debugfs_pdev, ar,
1099                             &fops_pktlog_filter);
1100
1101         if (ar->hw->wiphy->bands[NL80211_BAND_5GHZ]) {
1102                 debugfs_create_file("dfs_simulate_radar", 0200,
1103                                     ar->debug.debugfs_pdev, ar,
1104                                     &fops_simulate_radar);
1105                 debugfs_create_bool("dfs_block_radar_events", 0200,
1106                                     ar->debug.debugfs_pdev,
1107                                     &ar->dfs_block_radar_events);
1108         }
1109
1110         return 0;
1111 }
1112
1113 void ath11k_debugfs_unregister(struct ath11k *ar)
1114 {
1115 }
This page took 0.110768 seconds and 4 git commands to generate.