1 // SPDX-License-Identifier: BSD-3-Clause-Clear
3 * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
13 #include "debugfs_htt_stats.h"
16 static const char *htt_bp_umac_ring
[HTT_SW_UMAC_RING_IDX_MAX
] = {
29 "WBM2SW0_RELEASE_RING",
30 "WBM2SW1_RELEASE_RING",
31 "WBM2SW2_RELEASE_RING",
32 "WBM2SW3_RELEASE_RING",
37 static const char *htt_bp_lmac_ring
[HTT_SW_LMAC_RING_IDX_MAX
] = {
39 "FW2RXDMA_STATUS_RING",
42 "WBM2RXDMA_LINK_RING",
47 "MONITOR_STATUS_RING",
53 static void ath11k_fw_stats_pdevs_free(struct list_head
*head
)
55 struct ath11k_fw_stats_pdev
*i
, *tmp
;
57 list_for_each_entry_safe(i
, tmp
, head
, list
) {
63 static void ath11k_fw_stats_vdevs_free(struct list_head
*head
)
65 struct ath11k_fw_stats_vdev
*i
, *tmp
;
67 list_for_each_entry_safe(i
, tmp
, head
, list
) {
73 static void ath11k_fw_stats_bcn_free(struct list_head
*head
)
75 struct ath11k_fw_stats_bcn
*i
, *tmp
;
77 list_for_each_entry_safe(i
, tmp
, head
, list
) {
83 static void ath11k_debugfs_fw_stats_reset(struct ath11k
*ar
)
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
);
92 void ath11k_debugfs_fw_stats_process(struct ath11k_base
*ab
, struct sk_buff
*skb
)
94 struct ath11k_fw_stats stats
= {};
96 struct ath11k_pdev
*pdev
;
98 static unsigned int num_vdev
, num_bcn
;
99 size_t total_vdevs_started
= 0;
102 INIT_LIST_HEAD(&stats
.pdevs
);
103 INIT_LIST_HEAD(&stats
.vdevs
);
104 INIT_LIST_HEAD(&stats
.bcn
);
106 ret
= ath11k_wmi_pull_fw_stats(ab
, skb
, &stats
);
108 ath11k_warn(ab
, "failed to pull fw stats: %d\n", ret
);
113 ar
= ath11k_mac_get_ar_by_pdev_id(ab
, stats
.pdev_id
);
116 ath11k_warn(ab
, "failed to get ar for pdev_id %d: %d\n",
121 spin_lock_bh(&ar
->data_lock
);
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;
129 if (stats
.stats_id
== WMI_REQUEST_VDEV_STAT
) {
130 if (list_empty(&stats
.vdevs
)) {
131 ath11k_warn(ab
, "empty vdev stats");
134 /* FW sends all the active VDEV stats irrespective of PDEV,
135 * hence limit until the count of all VDEVs started
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
;
143 is_end
= ((++num_vdev
) == total_vdevs_started
);
145 list_splice_tail_init(&stats
.vdevs
,
146 &ar
->debug
.fw_stats
.vdevs
);
149 ar
->debug
.fw_stats_done
= true;
155 if (stats
.stats_id
== WMI_REQUEST_BCN_STAT
) {
156 if (list_empty(&stats
.bcn
)) {
157 ath11k_warn(ab
, "empty bcn stats");
160 /* Mark end until we reached the count of all started VDEVs
163 is_end
= ((++num_bcn
) == ar
->num_started_vdevs
);
165 list_splice_tail_init(&stats
.bcn
,
166 &ar
->debug
.fw_stats
.bcn
);
169 ar
->debug
.fw_stats_done
= true;
174 complete(&ar
->debug
.fw_stats_complete
);
176 spin_unlock_bh(&ar
->data_lock
);
179 ath11k_fw_stats_pdevs_free(&stats
.pdevs
);
180 ath11k_fw_stats_vdevs_free(&stats
.vdevs
);
181 ath11k_fw_stats_bcn_free(&stats
.bcn
);
184 static int ath11k_debugfs_fw_stats_request(struct ath11k
*ar
,
185 struct stats_request_params
*req_param
)
187 struct ath11k_base
*ab
= ar
->ab
;
188 unsigned long timeout
, time_left
;
191 lockdep_assert_held(&ar
->conf_mutex
);
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
198 timeout
= jiffies
+ msecs_to_jiffies(3 * HZ
);
200 ath11k_debugfs_fw_stats_reset(ar
);
202 reinit_completion(&ar
->debug
.fw_stats_complete
);
204 ret
= ath11k_wmi_send_stats_request_cmd(ar
, req_param
);
207 ath11k_warn(ab
, "could not request fw stats (%d)\n",
213 wait_for_completion_timeout(&ar
->debug
.fw_stats_complete
,
219 if (time_after(jiffies
, timeout
))
222 spin_lock_bh(&ar
->data_lock
);
223 if (ar
->debug
.fw_stats_done
) {
224 spin_unlock_bh(&ar
->data_lock
);
227 spin_unlock_bh(&ar
->data_lock
);
232 static int ath11k_open_pdev_stats(struct inode
*inode
, struct file
*file
)
234 struct ath11k
*ar
= inode
->i_private
;
235 struct ath11k_base
*ab
= ar
->ab
;
236 struct stats_request_params req_param
;
240 mutex_lock(&ar
->conf_mutex
);
242 if (ar
->state
!= ATH11K_STATE_ON
) {
247 buf
= vmalloc(ATH11K_FW_STATS_BUF_SIZE
);
253 req_param
.pdev_id
= ar
->pdev
->pdev_id
;
254 req_param
.vdev_id
= 0;
255 req_param
.stats_id
= WMI_REQUEST_PDEV_STAT
;
257 ret
= ath11k_debugfs_fw_stats_request(ar
, &req_param
);
259 ath11k_warn(ab
, "failed to request fw pdev stats: %d\n", ret
);
263 ath11k_wmi_fw_stats_fill(ar
, &ar
->debug
.fw_stats
, req_param
.stats_id
,
266 file
->private_data
= buf
;
268 mutex_unlock(&ar
->conf_mutex
);
275 mutex_unlock(&ar
->conf_mutex
);
279 static int ath11k_release_pdev_stats(struct inode
*inode
, struct file
*file
)
281 vfree(file
->private_data
);
286 static ssize_t
ath11k_read_pdev_stats(struct file
*file
,
287 char __user
*user_buf
,
288 size_t count
, loff_t
*ppos
)
290 const char *buf
= file
->private_data
;
291 size_t len
= strlen(buf
);
293 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
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
,
304 static int ath11k_open_vdev_stats(struct inode
*inode
, struct file
*file
)
306 struct ath11k
*ar
= inode
->i_private
;
307 struct stats_request_params req_param
;
311 mutex_lock(&ar
->conf_mutex
);
313 if (ar
->state
!= ATH11K_STATE_ON
) {
318 buf
= vmalloc(ATH11K_FW_STATS_BUF_SIZE
);
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
;
329 ret
= ath11k_debugfs_fw_stats_request(ar
, &req_param
);
331 ath11k_warn(ar
->ab
, "failed to request fw vdev stats: %d\n", ret
);
335 ath11k_wmi_fw_stats_fill(ar
, &ar
->debug
.fw_stats
, req_param
.stats_id
,
338 file
->private_data
= buf
;
340 mutex_unlock(&ar
->conf_mutex
);
347 mutex_unlock(&ar
->conf_mutex
);
351 static int ath11k_release_vdev_stats(struct inode
*inode
, struct file
*file
)
353 vfree(file
->private_data
);
358 static ssize_t
ath11k_read_vdev_stats(struct file
*file
,
359 char __user
*user_buf
,
360 size_t count
, loff_t
*ppos
)
362 const char *buf
= file
->private_data
;
363 size_t len
= strlen(buf
);
365 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
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
,
376 static int ath11k_open_bcn_stats(struct inode
*inode
, struct file
*file
)
378 struct ath11k
*ar
= inode
->i_private
;
379 struct ath11k_vif
*arvif
;
380 struct stats_request_params req_param
;
384 mutex_lock(&ar
->conf_mutex
);
386 if (ar
->state
!= ATH11K_STATE_ON
) {
391 buf
= vmalloc(ATH11K_FW_STATS_BUF_SIZE
);
397 req_param
.stats_id
= WMI_REQUEST_BCN_STAT
;
398 req_param
.pdev_id
= ar
->pdev
->pdev_id
;
400 /* loop all active VDEVs for bcn stats */
401 list_for_each_entry(arvif
, &ar
->arvifs
, list
) {
405 req_param
.vdev_id
= arvif
->vdev_id
;
406 ret
= ath11k_debugfs_fw_stats_request(ar
, &req_param
);
408 ath11k_warn(ar
->ab
, "failed to request fw bcn stats: %d\n", ret
);
413 ath11k_wmi_fw_stats_fill(ar
, &ar
->debug
.fw_stats
, req_param
.stats_id
,
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
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
);
423 file
->private_data
= buf
;
425 mutex_unlock(&ar
->conf_mutex
);
432 mutex_unlock(&ar
->conf_mutex
);
436 static int ath11k_release_bcn_stats(struct inode
*inode
, struct file
*file
)
438 vfree(file
->private_data
);
443 static ssize_t
ath11k_read_bcn_stats(struct file
*file
,
444 char __user
*user_buf
,
445 size_t count
, loff_t
*ppos
)
447 const char *buf
= file
->private_data
;
448 size_t len
= strlen(buf
);
450 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
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
,
461 static ssize_t
ath11k_read_simulate_fw_crash(struct file
*file
,
462 char __user
*user_buf
,
463 size_t count
, loff_t
*ppos
)
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";
470 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, strlen(buf
));
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
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
)
484 struct ath11k_base
*ab
= file
->private_data
;
485 struct ath11k_pdev
*pdev
;
486 struct ath11k
*ar
= ab
->pdevs
[0].ar
;
489 int i
, ret
, radioup
= 0;
491 for (i
= 0; i
< ab
->num_radios
; i
++) {
492 pdev
= &ab
->pdevs
[i
];
494 if (ar
&& ar
->state
== ATH11K_STATE_ON
) {
499 /* filter partial writes and invalid commands */
500 if (*ppos
!= 0 || count
>= sizeof(buf
) || count
== 0)
503 rc
= simple_write_to_buffer(buf
, sizeof(buf
) - 1, ppos
, user_buf
, count
);
507 /* drop the possible '\n' from the end */
508 if (buf
[*ppos
- 1] == '\n')
509 buf
[*ppos
- 1] = '\0';
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
);
527 ath11k_warn(ab
, "failed to simulate firmware crash: %d\n", ret
);
537 static const struct file_operations fops_simulate_fw_crash
= {
538 .read
= ath11k_read_simulate_fw_crash
,
539 .write
= ath11k_write_simulate_fw_crash
,
541 .owner
= THIS_MODULE
,
542 .llseek
= default_llseek
,
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
)
549 struct ath11k
*ar
= file
->private_data
;
553 if (kstrtouint_from_user(ubuf
, count
, 0, &filter
))
556 mutex_lock(&ar
->conf_mutex
);
558 if (ar
->state
!= ATH11K_STATE_ON
) {
563 if (filter
== ar
->debug
.extd_tx_stats
) {
568 ar
->debug
.extd_tx_stats
= filter
;
572 mutex_unlock(&ar
->conf_mutex
);
576 static ssize_t
ath11k_read_enable_extd_tx_stats(struct file
*file
,
578 size_t count
, loff_t
*ppos
)
582 struct ath11k
*ar
= file
->private_data
;
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
);
590 return simple_read_from_buffer(ubuf
, count
, ppos
, buf
, len
);
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
,
599 static ssize_t
ath11k_write_extd_rx_stats(struct file
*file
,
600 const char __user
*ubuf
,
601 size_t count
, loff_t
*ppos
)
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
;
610 if (kstrtouint_from_user(ubuf
, count
, 0, &enable
))
613 mutex_lock(&ar
->conf_mutex
);
615 if (ar
->state
!= ATH11K_STATE_ON
) {
625 if (enable
== ar
->debug
.extd_rx_stats
) {
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
;
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
;
645 tlv_filter
= ath11k_mac_mon_status_filter_default
;
648 ar
->debug
.rx_filter
= tlv_filter
.rx_filter
;
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
);
657 ath11k_warn(ar
->ab
, "failed to set rx filter for monitor status ring\n");
662 ar
->debug
.extd_rx_stats
= enable
;
665 mutex_unlock(&ar
->conf_mutex
);
669 static ssize_t
ath11k_read_extd_rx_stats(struct file
*file
,
671 size_t count
, loff_t
*ppos
)
673 struct ath11k
*ar
= file
->private_data
;
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
);
682 return simple_read_from_buffer(ubuf
, count
, ppos
, buf
, len
);
685 static const struct file_operations fops_extd_rx_stats
= {
686 .read
= ath11k_read_extd_rx_stats
,
687 .write
= ath11k_write_extd_rx_stats
,
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
)
695 lockdep_assert_held(&ab
->base_lock
);
697 len
+= scnprintf(buf
+ len
, size
- len
, "count: %u\n",
699 len
+= scnprintf(buf
+ len
, size
- len
, "hp: %u\n",
701 len
+= scnprintf(buf
+ len
, size
- len
, "tp: %u\n",
703 len
+= scnprintf(buf
+ len
, size
- len
, "seen before: %ums\n\n",
704 jiffies_to_msecs(jiffies
- bp_stats
->jiffies
));
708 static ssize_t
ath11k_debugfs_dump_soc_ring_bp_stats(struct ath11k_base
*ab
,
711 struct ath11k_bp_stats
*bp_stats
;
712 bool stats_rxd
= false;
716 len
+= scnprintf(buf
+ len
, size
- len
, "\nBackpressure Stats\n");
717 len
+= scnprintf(buf
+ len
, size
- len
, "==================\n");
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
];
723 if (!bp_stats
->count
)
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
);
732 for (i
= 0; i
< HTT_SW_LMAC_RING_IDX_MAX
; i
++) {
733 for (pdev_idx
= 0; pdev_idx
< MAX_RADIOS
; pdev_idx
++) {
735 &ab
->soc_stats
.bp_stats
.lmac_ring_bp_stats
[i
][pdev_idx
];
737 if (!bp_stats
->count
)
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",
744 len
= ath11k_fill_bp_stats(ab
, bp_stats
, buf
, len
, size
);
748 spin_unlock_bh(&ab
->base_lock
);
751 len
+= scnprintf(buf
+ len
, size
- len
,
752 "No Ring Backpressure stats received\n\n");
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
)
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"};
779 buf
= kzalloc(size
, GFP_KERNEL
);
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
]);
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
]);
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]);
806 len
+= scnprintf(buf
+ len
, size
- len
, "\nSOC TX STATS:\n");
807 len
+= scnprintf(buf
+ len
, size
- len
, "\nTCL Ring Full Failures:\n");
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
]);
813 len
+= scnprintf(buf
+ len
, size
- len
,
814 "\nMisc Transmit Failures: %d\n",
815 atomic_read(&soc_stats
->tx_err
.misc_fail
));
817 len
+= ath11k_debugfs_dump_soc_ring_bp_stats(ab
, buf
+ len
, size
- len
);
821 retval
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
827 static const struct file_operations fops_soc_dp_stats
= {
828 .read
= ath11k_debugfs_dump_soc_dp_stats
,
830 .owner
= THIS_MODULE
,
831 .llseek
= default_llseek
,
834 int ath11k_debugfs_pdev_create(struct ath11k_base
*ab
)
836 if (test_bit(ATH11K_FLAG_REGISTERED
, &ab
->dev_flags
))
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
);
843 debugfs_create_file("simulate_fw_crash", 0600, ab
->debugfs_soc
, ab
,
844 &fops_simulate_fw_crash
);
846 debugfs_create_file("soc_dp_stats", 0600, ab
->debugfs_soc
, ab
,
852 void ath11k_debugfs_pdev_destroy(struct ath11k_base
*ab
)
854 debugfs_remove_recursive(ab
->debugfs_soc
);
855 ab
->debugfs_soc
= NULL
;
858 int ath11k_debugfs_soc_create(struct ath11k_base
*ab
)
860 ab
->debugfs_ath11k
= debugfs_create_dir("ath11k", NULL
);
862 return PTR_ERR_OR_ZERO(ab
->debugfs_ath11k
);
865 void ath11k_debugfs_soc_destroy(struct ath11k_base
*ab
)
867 debugfs_remove_recursive(ab
->debugfs_ath11k
);
868 ab
->debugfs_ath11k
= NULL
;
870 EXPORT_SYMBOL(ath11k_debugfs_soc_destroy
);
872 void ath11k_debugfs_fw_stats_init(struct ath11k
*ar
)
874 struct dentry
*fwstats_dir
= debugfs_create_dir("fw_stats",
875 ar
->debug
.debugfs_pdev
);
877 ar
->debug
.fw_stats
.debugfs_fwstats
= fwstats_dir
;
879 /* all stats debugfs files created are under "fw_stats" directory
882 debugfs_create_file("pdev_stats", 0600, fwstats_dir
, ar
,
884 debugfs_create_file("vdev_stats", 0600, fwstats_dir
, ar
,
886 debugfs_create_file("beacon_stats", 0600, fwstats_dir
, ar
,
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
);
893 init_completion(&ar
->debug
.fw_stats_complete
);
896 static ssize_t
ath11k_write_pktlog_filter(struct file
*file
,
897 const char __user
*ubuf
,
898 size_t count
, loff_t
*ppos
)
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
;
908 mutex_lock(&ar
->conf_mutex
);
909 if (ar
->state
!= ATH11K_STATE_ON
) {
914 rc
= simple_write_to_buffer(buf
, sizeof(buf
) - 1, ppos
, ubuf
, count
);
921 ret
= sscanf(buf
, "0x%x %u", &filter
, &mode
);
928 ret
= ath11k_wmi_pdev_pktlog_enable(ar
, filter
);
931 "failed to enable pktlog filter %x: %d\n",
932 ar
->debug
.pktlog_filter
, ret
);
936 ret
= ath11k_wmi_pdev_pktlog_disable(ar
);
938 ath11k_warn(ar
->ab
, "failed to disable pktlog: %d\n", ret
);
943 #define HTT_RX_FILTER_TLV_LITE_MODE \
944 (HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
945 HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
946 HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \
947 HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \
948 HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \
949 HTT_RX_FILTER_TLV_FLAGS_MPDU_START)
951 if (mode
== ATH11K_PKTLOG_MODE_FULL
) {
952 rx_filter
= HTT_RX_FILTER_TLV_LITE_MODE
|
953 HTT_RX_FILTER_TLV_FLAGS_MSDU_START
|
954 HTT_RX_FILTER_TLV_FLAGS_MSDU_END
|
955 HTT_RX_FILTER_TLV_FLAGS_MPDU_END
|
956 HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER
|
957 HTT_RX_FILTER_TLV_FLAGS_ATTENTION
;
958 } else if (mode
== ATH11K_PKTLOG_MODE_LITE
) {
959 ret
= ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar
,
960 HTT_PPDU_STATS_TAG_PKTLOG
);
962 ath11k_err(ar
->ab
, "failed to enable pktlog lite: %d\n", ret
);
966 rx_filter
= HTT_RX_FILTER_TLV_LITE_MODE
;
968 ret
= ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar
,
969 HTT_PPDU_STATS_TAG_DEFAULT
);
971 ath11k_err(ar
->ab
, "failed to send htt ppdu stats req: %d\n",
977 tlv_filter
.rx_filter
= rx_filter
;
979 tlv_filter
.pkt_filter_flags0
= HTT_RX_FP_MGMT_FILTER_FLAGS0
;
980 tlv_filter
.pkt_filter_flags1
= HTT_RX_FP_MGMT_FILTER_FLAGS1
;
981 tlv_filter
.pkt_filter_flags2
= HTT_RX_FP_CTRL_FILTER_FLASG2
;
982 tlv_filter
.pkt_filter_flags3
= HTT_RX_FP_CTRL_FILTER_FLASG3
|
983 HTT_RX_FP_DATA_FILTER_FLASG3
;
986 for (i
= 0; i
< ab
->hw_params
.num_rxmda_per_pdev
; i
++) {
987 ring_id
= ar
->dp
.rx_mon_status_refill_ring
[i
].refill_buf_ring
.ring_id
;
988 ret
= ath11k_dp_tx_htt_rx_filter_setup(ab
, ring_id
,
990 HAL_RXDMA_MONITOR_STATUS
,
991 DP_RX_BUFFER_SIZE
, &tlv_filter
);
994 ath11k_warn(ab
, "failed to set rx filter for monitor status ring\n");
999 ath11k_dbg(ab
, ATH11K_DBG_WMI
, "pktlog filter %d mode %s\n",
1000 filter
, ((mode
== ATH11K_PKTLOG_MODE_FULL
) ? "full" : "lite"));
1002 ar
->debug
.pktlog_filter
= filter
;
1003 ar
->debug
.pktlog_mode
= mode
;
1007 mutex_unlock(&ar
->conf_mutex
);
1011 static ssize_t
ath11k_read_pktlog_filter(struct file
*file
,
1013 size_t count
, loff_t
*ppos
)
1017 struct ath11k
*ar
= file
->private_data
;
1020 mutex_lock(&ar
->conf_mutex
);
1021 len
= scnprintf(buf
, sizeof(buf
) - len
, "%08x %08x\n",
1022 ar
->debug
.pktlog_filter
,
1023 ar
->debug
.pktlog_mode
);
1024 mutex_unlock(&ar
->conf_mutex
);
1026 return simple_read_from_buffer(ubuf
, count
, ppos
, buf
, len
);
1029 static const struct file_operations fops_pktlog_filter
= {
1030 .read
= ath11k_read_pktlog_filter
,
1031 .write
= ath11k_write_pktlog_filter
,
1035 static ssize_t
ath11k_write_simulate_radar(struct file
*file
,
1036 const char __user
*user_buf
,
1037 size_t count
, loff_t
*ppos
)
1039 struct ath11k
*ar
= file
->private_data
;
1042 ret
= ath11k_wmi_simulate_radar(ar
);
1049 static const struct file_operations fops_simulate_radar
= {
1050 .write
= ath11k_write_simulate_radar
,
1054 int ath11k_debugfs_register(struct ath11k
*ar
)
1056 struct ath11k_base
*ab
= ar
->ab
;
1058 char buf
[100] = {0};
1060 snprintf(pdev_name
, sizeof(pdev_name
), "%s%d", "mac", ar
->pdev_idx
);
1062 ar
->debug
.debugfs_pdev
= debugfs_create_dir(pdev_name
, ab
->debugfs_soc
);
1063 if (IS_ERR(ar
->debug
.debugfs_pdev
))
1064 return PTR_ERR(ar
->debug
.debugfs_pdev
);
1066 /* Create a symlink under ieee80211/phy* */
1067 snprintf(buf
, 100, "../../ath11k/%pd2", ar
->debug
.debugfs_pdev
);
1068 debugfs_create_symlink("ath11k", ar
->hw
->wiphy
->debugfsdir
, buf
);
1070 ath11k_debugfs_htt_stats_init(ar
);
1072 ath11k_debugfs_fw_stats_init(ar
);
1074 debugfs_create_file("ext_tx_stats", 0644,
1075 ar
->debug
.debugfs_pdev
, ar
,
1076 &fops_extd_tx_stats
);
1077 debugfs_create_file("ext_rx_stats", 0644,
1078 ar
->debug
.debugfs_pdev
, ar
,
1079 &fops_extd_rx_stats
);
1080 debugfs_create_file("pktlog_filter", 0644,
1081 ar
->debug
.debugfs_pdev
, ar
,
1082 &fops_pktlog_filter
);
1084 if (ar
->hw
->wiphy
->bands
[NL80211_BAND_5GHZ
]) {
1085 debugfs_create_file("dfs_simulate_radar", 0200,
1086 ar
->debug
.debugfs_pdev
, ar
,
1087 &fops_simulate_radar
);
1088 debugfs_create_bool("dfs_block_radar_events", 0200,
1089 ar
->debug
.debugfs_pdev
,
1090 &ar
->dfs_block_radar_events
);
1096 void ath11k_debugfs_unregister(struct ath11k
*ar
)