1 // SPDX-License-Identifier: BSD-3-Clause-Clear
3 * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
4 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
7 #include <linux/vmalloc.h>
16 #include "debugfs_htt_stats.h"
20 static const char *htt_bp_umac_ring
[HTT_SW_UMAC_RING_IDX_MAX
] = {
33 "WBM2SW0_RELEASE_RING",
34 "WBM2SW1_RELEASE_RING",
35 "WBM2SW2_RELEASE_RING",
36 "WBM2SW3_RELEASE_RING",
41 static const char *htt_bp_lmac_ring
[HTT_SW_LMAC_RING_IDX_MAX
] = {
43 "FW2RXDMA_STATUS_RING",
46 "WBM2RXDMA_LINK_RING",
51 "MONITOR_STATUS_RING",
57 void ath11k_debugfs_add_dbring_entry(struct ath11k
*ar
,
58 enum wmi_direct_buffer_module id
,
59 enum ath11k_dbg_dbr_event event
,
60 struct hal_srng
*srng
)
62 struct ath11k_debug_dbr
*dbr_debug
;
63 struct ath11k_dbg_dbr_data
*dbr_data
;
64 struct ath11k_dbg_dbr_entry
*entry
;
66 if (id
>= WMI_DIRECT_BUF_MAX
|| event
>= ATH11K_DBG_DBR_EVENT_MAX
)
69 dbr_debug
= ar
->debug
.dbr_debug
[id
];
73 if (!dbr_debug
->dbr_debug_enabled
)
76 dbr_data
= &dbr_debug
->dbr_dbg_data
;
78 spin_lock_bh(&dbr_data
->lock
);
80 if (dbr_data
->entries
) {
81 entry
= &dbr_data
->entries
[dbr_data
->dbr_debug_idx
];
82 entry
->hp
= srng
->u
.src_ring
.hp
;
83 entry
->tp
= *srng
->u
.src_ring
.tp_addr
;
84 entry
->timestamp
= jiffies
;
87 dbr_data
->dbr_debug_idx
++;
88 if (dbr_data
->dbr_debug_idx
==
89 dbr_data
->num_ring_debug_entries
)
90 dbr_data
->dbr_debug_idx
= 0;
93 spin_unlock_bh(&dbr_data
->lock
);
96 static void ath11k_debugfs_fw_stats_reset(struct ath11k
*ar
)
98 spin_lock_bh(&ar
->data_lock
);
99 ar
->fw_stats_done
= false;
100 ath11k_fw_stats_pdevs_free(&ar
->fw_stats
.pdevs
);
101 ath11k_fw_stats_vdevs_free(&ar
->fw_stats
.vdevs
);
102 spin_unlock_bh(&ar
->data_lock
);
105 void ath11k_debugfs_fw_stats_process(struct ath11k
*ar
, struct ath11k_fw_stats
*stats
)
107 struct ath11k_base
*ab
= ar
->ab
;
108 struct ath11k_pdev
*pdev
;
110 static unsigned int num_vdev
, num_bcn
;
111 size_t total_vdevs_started
= 0;
114 /* WMI_REQUEST_PDEV_STAT request has been already processed */
116 if (stats
->stats_id
== WMI_REQUEST_RSSI_PER_CHAIN_STAT
) {
117 ar
->fw_stats_done
= true;
121 if (stats
->stats_id
== WMI_REQUEST_VDEV_STAT
) {
122 if (list_empty(&stats
->vdevs
)) {
123 ath11k_warn(ab
, "empty vdev stats");
126 /* FW sends all the active VDEV stats irrespective of PDEV,
127 * hence limit until the count of all VDEVs started
129 for (i
= 0; i
< ab
->num_radios
; i
++) {
130 pdev
= rcu_dereference(ab
->pdevs_active
[i
]);
131 if (pdev
&& pdev
->ar
)
132 total_vdevs_started
+= ar
->num_started_vdevs
;
135 is_end
= ((++num_vdev
) == total_vdevs_started
);
137 list_splice_tail_init(&stats
->vdevs
,
138 &ar
->fw_stats
.vdevs
);
141 ar
->fw_stats_done
= true;
147 if (stats
->stats_id
== WMI_REQUEST_BCN_STAT
) {
148 if (list_empty(&stats
->bcn
)) {
149 ath11k_warn(ab
, "empty bcn stats");
152 /* Mark end until we reached the count of all started VDEVs
155 is_end
= ((++num_bcn
) == ar
->num_started_vdevs
);
157 list_splice_tail_init(&stats
->bcn
,
161 ar
->fw_stats_done
= true;
167 static int ath11k_debugfs_fw_stats_request(struct ath11k
*ar
,
168 struct stats_request_params
*req_param
)
170 struct ath11k_base
*ab
= ar
->ab
;
171 unsigned long timeout
, time_left
;
174 lockdep_assert_held(&ar
->conf_mutex
);
176 /* FW stats can get split when exceeding the stats data buffer limit.
177 * In that case, since there is no end marking for the back-to-back
178 * received 'update stats' event, we keep a 3 seconds timeout in case,
179 * fw_stats_done is not marked yet
181 timeout
= jiffies
+ msecs_to_jiffies(3 * 1000);
183 ath11k_debugfs_fw_stats_reset(ar
);
185 reinit_completion(&ar
->fw_stats_complete
);
187 ret
= ath11k_wmi_send_stats_request_cmd(ar
, req_param
);
190 ath11k_warn(ab
, "could not request fw stats (%d)\n",
195 time_left
= wait_for_completion_timeout(&ar
->fw_stats_complete
, 1 * HZ
);
201 if (time_after(jiffies
, timeout
))
204 spin_lock_bh(&ar
->data_lock
);
205 if (ar
->fw_stats_done
) {
206 spin_unlock_bh(&ar
->data_lock
);
209 spin_unlock_bh(&ar
->data_lock
);
214 int ath11k_debugfs_get_fw_stats(struct ath11k
*ar
, u32 pdev_id
,
215 u32 vdev_id
, u32 stats_id
)
217 struct ath11k_base
*ab
= ar
->ab
;
218 struct stats_request_params req_param
;
221 mutex_lock(&ar
->conf_mutex
);
223 if (ar
->state
!= ATH11K_STATE_ON
) {
228 req_param
.pdev_id
= pdev_id
;
229 req_param
.vdev_id
= vdev_id
;
230 req_param
.stats_id
= stats_id
;
232 ret
= ath11k_debugfs_fw_stats_request(ar
, &req_param
);
234 ath11k_warn(ab
, "failed to request fw stats: %d\n", ret
);
236 ath11k_dbg(ab
, ATH11K_DBG_WMI
,
237 "debug get fw stat pdev id %d vdev id %d stats id 0x%x\n",
238 pdev_id
, vdev_id
, stats_id
);
241 mutex_unlock(&ar
->conf_mutex
);
246 static int ath11k_open_pdev_stats(struct inode
*inode
, struct file
*file
)
248 struct ath11k
*ar
= inode
->i_private
;
249 struct ath11k_base
*ab
= ar
->ab
;
250 struct stats_request_params req_param
;
254 mutex_lock(&ar
->conf_mutex
);
256 if (ar
->state
!= ATH11K_STATE_ON
) {
261 buf
= vmalloc(ATH11K_FW_STATS_BUF_SIZE
);
267 req_param
.pdev_id
= ar
->pdev
->pdev_id
;
268 req_param
.vdev_id
= 0;
269 req_param
.stats_id
= WMI_REQUEST_PDEV_STAT
;
271 ret
= ath11k_debugfs_fw_stats_request(ar
, &req_param
);
273 ath11k_warn(ab
, "failed to request fw pdev stats: %d\n", ret
);
277 ath11k_wmi_fw_stats_fill(ar
, &ar
->fw_stats
, req_param
.stats_id
, buf
);
279 file
->private_data
= buf
;
281 mutex_unlock(&ar
->conf_mutex
);
288 mutex_unlock(&ar
->conf_mutex
);
292 static int ath11k_release_pdev_stats(struct inode
*inode
, struct file
*file
)
294 vfree(file
->private_data
);
299 static ssize_t
ath11k_read_pdev_stats(struct file
*file
,
300 char __user
*user_buf
,
301 size_t count
, loff_t
*ppos
)
303 const char *buf
= file
->private_data
;
304 size_t len
= strlen(buf
);
306 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
309 static const struct file_operations fops_pdev_stats
= {
310 .open
= ath11k_open_pdev_stats
,
311 .release
= ath11k_release_pdev_stats
,
312 .read
= ath11k_read_pdev_stats
,
313 .owner
= THIS_MODULE
,
314 .llseek
= default_llseek
,
317 static int ath11k_open_vdev_stats(struct inode
*inode
, struct file
*file
)
319 struct ath11k
*ar
= inode
->i_private
;
320 struct stats_request_params req_param
;
324 mutex_lock(&ar
->conf_mutex
);
326 if (ar
->state
!= ATH11K_STATE_ON
) {
331 buf
= vmalloc(ATH11K_FW_STATS_BUF_SIZE
);
337 req_param
.pdev_id
= ar
->pdev
->pdev_id
;
338 /* VDEV stats is always sent for all active VDEVs from FW */
339 req_param
.vdev_id
= 0;
340 req_param
.stats_id
= WMI_REQUEST_VDEV_STAT
;
342 ret
= ath11k_debugfs_fw_stats_request(ar
, &req_param
);
344 ath11k_warn(ar
->ab
, "failed to request fw vdev stats: %d\n", ret
);
348 ath11k_wmi_fw_stats_fill(ar
, &ar
->fw_stats
, req_param
.stats_id
, buf
);
350 file
->private_data
= buf
;
352 mutex_unlock(&ar
->conf_mutex
);
359 mutex_unlock(&ar
->conf_mutex
);
363 static int ath11k_release_vdev_stats(struct inode
*inode
, struct file
*file
)
365 vfree(file
->private_data
);
370 static ssize_t
ath11k_read_vdev_stats(struct file
*file
,
371 char __user
*user_buf
,
372 size_t count
, loff_t
*ppos
)
374 const char *buf
= file
->private_data
;
375 size_t len
= strlen(buf
);
377 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
380 static const struct file_operations fops_vdev_stats
= {
381 .open
= ath11k_open_vdev_stats
,
382 .release
= ath11k_release_vdev_stats
,
383 .read
= ath11k_read_vdev_stats
,
384 .owner
= THIS_MODULE
,
385 .llseek
= default_llseek
,
388 static int ath11k_open_bcn_stats(struct inode
*inode
, struct file
*file
)
390 struct ath11k
*ar
= inode
->i_private
;
391 struct ath11k_vif
*arvif
;
392 struct stats_request_params req_param
;
396 mutex_lock(&ar
->conf_mutex
);
398 if (ar
->state
!= ATH11K_STATE_ON
) {
403 buf
= vmalloc(ATH11K_FW_STATS_BUF_SIZE
);
409 req_param
.stats_id
= WMI_REQUEST_BCN_STAT
;
410 req_param
.pdev_id
= ar
->pdev
->pdev_id
;
412 /* loop all active VDEVs for bcn stats */
413 list_for_each_entry(arvif
, &ar
->arvifs
, list
) {
417 req_param
.vdev_id
= arvif
->vdev_id
;
418 ret
= ath11k_debugfs_fw_stats_request(ar
, &req_param
);
420 ath11k_warn(ar
->ab
, "failed to request fw bcn stats: %d\n", ret
);
425 ath11k_wmi_fw_stats_fill(ar
, &ar
->fw_stats
, req_param
.stats_id
, buf
);
427 /* since beacon stats request is looped for all active VDEVs, saved fw
428 * stats is not freed for each request until done for all active VDEVs
430 spin_lock_bh(&ar
->data_lock
);
431 ath11k_fw_stats_bcn_free(&ar
->fw_stats
.bcn
);
432 spin_unlock_bh(&ar
->data_lock
);
434 file
->private_data
= buf
;
436 mutex_unlock(&ar
->conf_mutex
);
443 mutex_unlock(&ar
->conf_mutex
);
447 static int ath11k_release_bcn_stats(struct inode
*inode
, struct file
*file
)
449 vfree(file
->private_data
);
454 static ssize_t
ath11k_read_bcn_stats(struct file
*file
,
455 char __user
*user_buf
,
456 size_t count
, loff_t
*ppos
)
458 const char *buf
= file
->private_data
;
459 size_t len
= strlen(buf
);
461 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
464 static const struct file_operations fops_bcn_stats
= {
465 .open
= ath11k_open_bcn_stats
,
466 .release
= ath11k_release_bcn_stats
,
467 .read
= ath11k_read_bcn_stats
,
468 .owner
= THIS_MODULE
,
469 .llseek
= default_llseek
,
472 static ssize_t
ath11k_read_simulate_fw_crash(struct file
*file
,
473 char __user
*user_buf
,
474 size_t count
, loff_t
*ppos
)
477 "To simulate firmware crash write one of the keywords to this file:\n"
478 "`assert` - this will send WMI_FORCE_FW_HANG_CMDID to firmware to cause assert.\n"
479 "`hw-restart` - this will simply queue hw restart without fw/hw actually crashing.\n";
481 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, strlen(buf
));
484 /* Simulate firmware crash:
485 * 'soft': Call wmi command causing firmware hang. This firmware hang is
486 * recoverable by warm firmware reset.
487 * 'hard': Force firmware crash by setting any vdev parameter for not allowed
488 * vdev id. This is hard firmware crash because it is recoverable only by cold
491 static ssize_t
ath11k_write_simulate_fw_crash(struct file
*file
,
492 const char __user
*user_buf
,
493 size_t count
, loff_t
*ppos
)
495 struct ath11k_base
*ab
= file
->private_data
;
496 struct ath11k_pdev
*pdev
;
497 struct ath11k
*ar
= ab
->pdevs
[0].ar
;
500 int i
, ret
, radioup
= 0;
502 for (i
= 0; i
< ab
->num_radios
; i
++) {
503 pdev
= &ab
->pdevs
[i
];
505 if (ar
&& ar
->state
== ATH11K_STATE_ON
) {
510 /* filter partial writes and invalid commands */
511 if (*ppos
!= 0 || count
>= sizeof(buf
) || count
== 0)
514 rc
= simple_write_to_buffer(buf
, sizeof(buf
) - 1, ppos
, user_buf
, count
);
518 /* drop the possible '\n' from the end */
519 if (buf
[*ppos
- 1] == '\n')
520 buf
[*ppos
- 1] = '\0';
527 if (!strcmp(buf
, "assert")) {
528 ath11k_info(ab
, "simulating firmware assert crash\n");
529 ret
= ath11k_wmi_force_fw_hang_cmd(ar
,
530 ATH11K_WMI_FW_HANG_ASSERT_TYPE
,
531 ATH11K_WMI_FW_HANG_DELAY
);
532 } else if (!strcmp(buf
, "hw-restart")) {
533 ath11k_info(ab
, "user requested hw restart\n");
534 queue_work(ab
->workqueue_aux
, &ab
->reset_work
);
542 ath11k_warn(ab
, "failed to simulate firmware crash: %d\n", ret
);
552 static const struct file_operations fops_simulate_fw_crash
= {
553 .read
= ath11k_read_simulate_fw_crash
,
554 .write
= ath11k_write_simulate_fw_crash
,
556 .owner
= THIS_MODULE
,
557 .llseek
= default_llseek
,
560 static ssize_t
ath11k_write_enable_extd_tx_stats(struct file
*file
,
561 const char __user
*ubuf
,
562 size_t count
, loff_t
*ppos
)
564 struct ath11k
*ar
= file
->private_data
;
568 if (kstrtouint_from_user(ubuf
, count
, 0, &filter
))
571 mutex_lock(&ar
->conf_mutex
);
573 if (ar
->state
!= ATH11K_STATE_ON
) {
578 if (filter
== ar
->debug
.extd_tx_stats
) {
583 ar
->debug
.extd_tx_stats
= filter
;
587 mutex_unlock(&ar
->conf_mutex
);
591 static ssize_t
ath11k_read_enable_extd_tx_stats(struct file
*file
,
593 size_t count
, loff_t
*ppos
)
597 struct ath11k
*ar
= file
->private_data
;
600 mutex_lock(&ar
->conf_mutex
);
601 len
= scnprintf(buf
, sizeof(buf
) - len
, "%08x\n",
602 ar
->debug
.extd_tx_stats
);
603 mutex_unlock(&ar
->conf_mutex
);
605 return simple_read_from_buffer(ubuf
, count
, ppos
, buf
, len
);
608 static const struct file_operations fops_extd_tx_stats
= {
609 .read
= ath11k_read_enable_extd_tx_stats
,
610 .write
= ath11k_write_enable_extd_tx_stats
,
614 static ssize_t
ath11k_write_extd_rx_stats(struct file
*file
,
615 const char __user
*ubuf
,
616 size_t count
, loff_t
*ppos
)
618 struct ath11k
*ar
= file
->private_data
;
619 struct ath11k_base
*ab
= ar
->ab
;
620 struct htt_rx_ring_tlv_filter tlv_filter
= {0};
621 u32 enable
, rx_filter
= 0, ring_id
;
625 if (kstrtouint_from_user(ubuf
, count
, 0, &enable
))
628 mutex_lock(&ar
->conf_mutex
);
630 if (ar
->state
!= ATH11K_STATE_ON
) {
640 if (enable
== ar
->debug
.extd_rx_stats
) {
645 if (test_bit(ATH11K_FLAG_MONITOR_STARTED
, &ar
->monitor_flags
)) {
646 ar
->debug
.extd_rx_stats
= enable
;
652 rx_filter
= HTT_RX_FILTER_TLV_FLAGS_MPDU_START
;
653 rx_filter
|= HTT_RX_FILTER_TLV_FLAGS_PPDU_START
;
654 rx_filter
|= HTT_RX_FILTER_TLV_FLAGS_PPDU_END
;
655 rx_filter
|= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS
;
656 rx_filter
|= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT
;
657 rx_filter
|= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE
;
659 tlv_filter
.rx_filter
= rx_filter
;
660 tlv_filter
.pkt_filter_flags0
= HTT_RX_FP_MGMT_FILTER_FLAGS0
;
661 tlv_filter
.pkt_filter_flags1
= HTT_RX_FP_MGMT_FILTER_FLAGS1
;
662 tlv_filter
.pkt_filter_flags2
= HTT_RX_FP_CTRL_FILTER_FLASG2
;
663 tlv_filter
.pkt_filter_flags3
= HTT_RX_FP_CTRL_FILTER_FLASG3
|
664 HTT_RX_FP_DATA_FILTER_FLASG3
;
666 tlv_filter
= ath11k_mac_mon_status_filter_default
;
669 ar
->debug
.rx_filter
= tlv_filter
.rx_filter
;
671 for (i
= 0; i
< ab
->hw_params
.num_rxdma_per_pdev
; i
++) {
672 ring_id
= ar
->dp
.rx_mon_status_refill_ring
[i
].refill_buf_ring
.ring_id
;
673 ret
= ath11k_dp_tx_htt_rx_filter_setup(ar
->ab
, ring_id
, ar
->dp
.mac_id
,
674 HAL_RXDMA_MONITOR_STATUS
,
675 DP_RX_BUFFER_SIZE
, &tlv_filter
);
678 ath11k_warn(ar
->ab
, "failed to set rx filter for monitor status ring\n");
683 ar
->debug
.extd_rx_stats
= enable
;
686 mutex_unlock(&ar
->conf_mutex
);
690 static ssize_t
ath11k_read_extd_rx_stats(struct file
*file
,
692 size_t count
, loff_t
*ppos
)
694 struct ath11k
*ar
= file
->private_data
;
698 mutex_lock(&ar
->conf_mutex
);
699 len
= scnprintf(buf
, sizeof(buf
) - len
, "%d\n",
700 ar
->debug
.extd_rx_stats
);
701 mutex_unlock(&ar
->conf_mutex
);
703 return simple_read_from_buffer(ubuf
, count
, ppos
, buf
, len
);
706 static const struct file_operations fops_extd_rx_stats
= {
707 .read
= ath11k_read_extd_rx_stats
,
708 .write
= ath11k_write_extd_rx_stats
,
712 static int ath11k_fill_bp_stats(struct ath11k_base
*ab
,
713 struct ath11k_bp_stats
*bp_stats
,
714 char *buf
, int len
, int size
)
716 lockdep_assert_held(&ab
->base_lock
);
718 len
+= scnprintf(buf
+ len
, size
- len
, "count: %u\n",
720 len
+= scnprintf(buf
+ len
, size
- len
, "hp: %u\n",
722 len
+= scnprintf(buf
+ len
, size
- len
, "tp: %u\n",
724 len
+= scnprintf(buf
+ len
, size
- len
, "seen before: %ums\n\n",
725 jiffies_to_msecs(jiffies
- bp_stats
->jiffies
));
729 static ssize_t
ath11k_debugfs_dump_soc_ring_bp_stats(struct ath11k_base
*ab
,
732 struct ath11k_bp_stats
*bp_stats
;
733 bool stats_rxd
= false;
737 len
+= scnprintf(buf
+ len
, size
- len
, "\nBackpressure Stats\n");
738 len
+= scnprintf(buf
+ len
, size
- len
, "==================\n");
740 spin_lock_bh(&ab
->base_lock
);
741 for (i
= 0; i
< HTT_SW_UMAC_RING_IDX_MAX
; i
++) {
742 bp_stats
= &ab
->soc_stats
.bp_stats
.umac_ring_bp_stats
[i
];
744 if (!bp_stats
->count
)
747 len
+= scnprintf(buf
+ len
, size
- len
, "Ring: %s\n",
748 htt_bp_umac_ring
[i
]);
749 len
= ath11k_fill_bp_stats(ab
, bp_stats
, buf
, len
, size
);
753 for (i
= 0; i
< HTT_SW_LMAC_RING_IDX_MAX
; i
++) {
754 for (pdev_idx
= 0; pdev_idx
< MAX_RADIOS
; pdev_idx
++) {
756 &ab
->soc_stats
.bp_stats
.lmac_ring_bp_stats
[i
][pdev_idx
];
758 if (!bp_stats
->count
)
761 len
+= scnprintf(buf
+ len
, size
- len
, "Ring: %s\n",
762 htt_bp_lmac_ring
[i
]);
763 len
+= scnprintf(buf
+ len
, size
- len
, "pdev: %d\n",
765 len
= ath11k_fill_bp_stats(ab
, bp_stats
, buf
, len
, size
);
769 spin_unlock_bh(&ab
->base_lock
);
772 len
+= scnprintf(buf
+ len
, size
- len
,
773 "No Ring Backpressure stats received\n\n");
778 static ssize_t
ath11k_debugfs_dump_soc_dp_stats(struct file
*file
,
779 char __user
*user_buf
,
780 size_t count
, loff_t
*ppos
)
782 struct ath11k_base
*ab
= file
->private_data
;
783 struct ath11k_soc_dp_stats
*soc_stats
= &ab
->soc_stats
;
784 int len
= 0, i
, retval
;
785 const int size
= 4096;
786 static const char *rxdma_err
[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX
] = {
787 "Overflow", "MPDU len", "FCS", "Decrypt", "TKIP MIC",
788 "Unencrypt", "MSDU len", "MSDU limit", "WiFi parse",
789 "AMSDU parse", "SA timeout", "DA timeout",
790 "Flow timeout", "Flush req"};
791 static const char *reo_err
[HAL_REO_DEST_RING_ERROR_CODE_MAX
] = {
792 "Desc addr zero", "Desc inval", "AMPDU in non BA",
793 "Non BA dup", "BA dup", "Frame 2k jump", "BAR 2k jump",
794 "Frame OOR", "BAR OOR", "No BA session",
795 "Frame SN equal SSN", "PN check fail", "2k err",
796 "PN err", "Desc blocked"};
800 buf
= kzalloc(size
, GFP_KERNEL
);
804 len
+= scnprintf(buf
+ len
, size
- len
, "SOC RX STATS:\n\n");
805 len
+= scnprintf(buf
+ len
, size
- len
, "err ring pkts: %u\n",
806 soc_stats
->err_ring_pkts
);
807 len
+= scnprintf(buf
+ len
, size
- len
, "Invalid RBM: %u\n\n",
808 soc_stats
->invalid_rbm
);
809 len
+= scnprintf(buf
+ len
, size
- len
, "RXDMA errors:\n");
810 for (i
= 0; i
< HAL_REO_ENTR_RING_RXDMA_ECODE_MAX
; i
++)
811 len
+= scnprintf(buf
+ len
, size
- len
, "%s: %u\n",
812 rxdma_err
[i
], soc_stats
->rxdma_error
[i
]);
814 len
+= scnprintf(buf
+ len
, size
- len
, "\nREO errors:\n");
815 for (i
= 0; i
< HAL_REO_DEST_RING_ERROR_CODE_MAX
; i
++)
816 len
+= scnprintf(buf
+ len
, size
- len
, "%s: %u\n",
817 reo_err
[i
], soc_stats
->reo_error
[i
]);
819 len
+= scnprintf(buf
+ len
, size
- len
, "\nHAL REO errors:\n");
820 len
+= scnprintf(buf
+ len
, size
- len
,
821 "ring0: %u\nring1: %u\nring2: %u\nring3: %u\n",
822 soc_stats
->hal_reo_error
[0],
823 soc_stats
->hal_reo_error
[1],
824 soc_stats
->hal_reo_error
[2],
825 soc_stats
->hal_reo_error
[3]);
827 len
+= scnprintf(buf
+ len
, size
- len
, "\nSOC TX STATS:\n");
828 len
+= scnprintf(buf
+ len
, size
- len
, "\nTCL Ring Full Failures:\n");
830 for (i
= 0; i
< ab
->hw_params
.max_tx_ring
; i
++)
831 len
+= scnprintf(buf
+ len
, size
- len
, "ring%d: %u\n",
832 i
, soc_stats
->tx_err
.desc_na
[i
]);
834 len
+= scnprintf(buf
+ len
, size
- len
,
835 "\nMisc Transmit Failures: %d\n",
836 atomic_read(&soc_stats
->tx_err
.misc_fail
));
838 len
+= ath11k_debugfs_dump_soc_ring_bp_stats(ab
, buf
+ len
, size
- len
);
842 retval
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
848 static const struct file_operations fops_soc_dp_stats
= {
849 .read
= ath11k_debugfs_dump_soc_dp_stats
,
851 .owner
= THIS_MODULE
,
852 .llseek
= default_llseek
,
855 static ssize_t
ath11k_write_fw_dbglog(struct file
*file
,
856 const char __user
*user_buf
,
857 size_t count
, loff_t
*ppos
)
859 struct ath11k
*ar
= file
->private_data
;
861 struct ath11k_fw_dbglog dbglog
;
862 unsigned int param
, mod_id_index
, is_end
;
866 ret
= simple_write_to_buffer(buf
, sizeof(buf
) - 1, ppos
,
871 num
= sscanf(buf
, "%u %llx %u %u", ¶m
, &value
, &mod_id_index
, &is_end
);
876 mutex_lock(&ar
->conf_mutex
);
877 if (param
== WMI_DEBUG_LOG_PARAM_MOD_ENABLE_BITMAP
||
878 param
== WMI_DEBUG_LOG_PARAM_WOW_MOD_ENABLE_BITMAP
) {
879 if (num
!= 4 || mod_id_index
> (MAX_MODULE_ID_BITMAP_WORDS
- 1)) {
883 ar
->debug
.module_id_bitmap
[mod_id_index
] = upper_32_bits(value
);
895 dbglog
.param
= param
;
896 dbglog
.value
= lower_32_bits(value
);
897 ret
= ath11k_wmi_fw_dbglog_cfg(ar
, ar
->debug
.module_id_bitmap
, &dbglog
);
899 ath11k_warn(ar
->ab
, "fw dbglog config failed from debugfs: %d\n",
907 mutex_unlock(&ar
->conf_mutex
);
911 static const struct file_operations fops_fw_dbglog
= {
912 .write
= ath11k_write_fw_dbglog
,
914 .owner
= THIS_MODULE
,
915 .llseek
= default_llseek
,
918 static int ath11k_open_sram_dump(struct inode
*inode
, struct file
*file
)
920 struct ath11k_base
*ab
= inode
->i_private
;
925 start
= ab
->hw_params
.sram_dump
.start
;
926 end
= ab
->hw_params
.sram_dump
.end
;
928 buf
= vmalloc(end
- start
+ 1);
932 ret
= ath11k_hif_read(ab
, buf
, start
, end
);
934 ath11k_warn(ab
, "failed to dump sram: %d\n", ret
);
939 file
->private_data
= buf
;
943 static ssize_t
ath11k_read_sram_dump(struct file
*file
,
944 char __user
*user_buf
,
945 size_t count
, loff_t
*ppos
)
947 struct ath11k_base
*ab
= file
->f_inode
->i_private
;
948 const char *buf
= file
->private_data
;
952 start
= ab
->hw_params
.sram_dump
.start
;
953 end
= ab
->hw_params
.sram_dump
.end
;
954 len
= end
- start
+ 1;
956 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
959 static int ath11k_release_sram_dump(struct inode
*inode
, struct file
*file
)
961 vfree(file
->private_data
);
962 file
->private_data
= NULL
;
967 static const struct file_operations fops_sram_dump
= {
968 .open
= ath11k_open_sram_dump
,
969 .read
= ath11k_read_sram_dump
,
970 .release
= ath11k_release_sram_dump
,
971 .owner
= THIS_MODULE
,
972 .llseek
= default_llseek
,
975 int ath11k_debugfs_pdev_create(struct ath11k_base
*ab
)
977 if (test_bit(ATH11K_FLAG_REGISTERED
, &ab
->dev_flags
))
980 debugfs_create_file("simulate_fw_crash", 0600, ab
->debugfs_soc
, ab
,
981 &fops_simulate_fw_crash
);
983 debugfs_create_file("soc_dp_stats", 0400, ab
->debugfs_soc
, ab
,
986 if (ab
->hw_params
.sram_dump
.start
!= 0)
987 debugfs_create_file("sram", 0400, ab
->debugfs_soc
, ab
,
993 void ath11k_debugfs_pdev_destroy(struct ath11k_base
*ab
)
995 debugfs_remove_recursive(ab
->debugfs_soc
);
996 ab
->debugfs_soc
= NULL
;
999 int ath11k_debugfs_soc_create(struct ath11k_base
*ab
)
1001 struct dentry
*root
;
1006 root
= debugfs_lookup("ath11k", NULL
);
1008 root
= debugfs_create_dir("ath11k", NULL
);
1009 if (IS_ERR_OR_NULL(root
))
1010 return PTR_ERR(root
);
1012 dput_needed
= false;
1014 /* a dentry from lookup() needs dput() after we don't use it */
1018 scnprintf(name
, sizeof(name
), "%s-%s", ath11k_bus_str(ab
->hif
.bus
),
1021 ab
->debugfs_soc
= debugfs_create_dir(name
, root
);
1022 if (IS_ERR_OR_NULL(ab
->debugfs_soc
)) {
1023 ret
= PTR_ERR(ab
->debugfs_soc
);
1036 void ath11k_debugfs_soc_destroy(struct ath11k_base
*ab
)
1038 debugfs_remove_recursive(ab
->debugfs_soc
);
1039 ab
->debugfs_soc
= NULL
;
1041 /* We are not removing ath11k directory on purpose, even if it
1042 * would be empty. This simplifies the directory handling and it's
1043 * a minor cosmetic issue to leave an empty ath11k directory to
1047 EXPORT_SYMBOL(ath11k_debugfs_soc_destroy
);
1049 void ath11k_debugfs_fw_stats_init(struct ath11k
*ar
)
1051 struct dentry
*fwstats_dir
= debugfs_create_dir("fw_stats",
1052 ar
->debug
.debugfs_pdev
);
1054 ar
->fw_stats
.debugfs_fwstats
= fwstats_dir
;
1056 /* all stats debugfs files created are under "fw_stats" directory
1059 debugfs_create_file("pdev_stats", 0600, fwstats_dir
, ar
,
1061 debugfs_create_file("vdev_stats", 0600, fwstats_dir
, ar
,
1063 debugfs_create_file("beacon_stats", 0600, fwstats_dir
, ar
,
1067 static ssize_t
ath11k_write_pktlog_filter(struct file
*file
,
1068 const char __user
*ubuf
,
1069 size_t count
, loff_t
*ppos
)
1071 struct ath11k
*ar
= file
->private_data
;
1072 struct ath11k_base
*ab
= ar
->ab
;
1073 struct htt_rx_ring_tlv_filter tlv_filter
= {0};
1074 u32 rx_filter
= 0, ring_id
, filter
, mode
;
1076 int i
, ret
, rx_buf_sz
= 0;
1079 mutex_lock(&ar
->conf_mutex
);
1080 if (ar
->state
!= ATH11K_STATE_ON
) {
1085 rc
= simple_write_to_buffer(buf
, sizeof(buf
) - 1, ppos
, ubuf
, count
);
1092 ret
= sscanf(buf
, "0x%x %u", &filter
, &mode
);
1099 ret
= ath11k_wmi_pdev_pktlog_enable(ar
, filter
);
1102 "failed to enable pktlog filter %x: %d\n",
1103 ar
->debug
.pktlog_filter
, ret
);
1107 ret
= ath11k_wmi_pdev_pktlog_disable(ar
);
1109 ath11k_warn(ar
->ab
, "failed to disable pktlog: %d\n", ret
);
1114 /* Clear rx filter set for monitor mode and rx status */
1115 for (i
= 0; i
< ab
->hw_params
.num_rxdma_per_pdev
; i
++) {
1116 ring_id
= ar
->dp
.rx_mon_status_refill_ring
[i
].refill_buf_ring
.ring_id
;
1117 ret
= ath11k_dp_tx_htt_rx_filter_setup(ar
->ab
, ring_id
, ar
->dp
.mac_id
,
1118 HAL_RXDMA_MONITOR_STATUS
,
1119 rx_buf_sz
, &tlv_filter
);
1121 ath11k_warn(ar
->ab
, "failed to set rx filter for monitor status ring\n");
1125 #define HTT_RX_FILTER_TLV_LITE_MODE \
1126 (HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
1127 HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
1128 HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \
1129 HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \
1130 HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \
1131 HTT_RX_FILTER_TLV_FLAGS_MPDU_START)
1133 if (mode
== ATH11K_PKTLOG_MODE_FULL
) {
1134 rx_filter
= HTT_RX_FILTER_TLV_LITE_MODE
|
1135 HTT_RX_FILTER_TLV_FLAGS_MSDU_START
|
1136 HTT_RX_FILTER_TLV_FLAGS_MSDU_END
|
1137 HTT_RX_FILTER_TLV_FLAGS_MPDU_END
|
1138 HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER
|
1139 HTT_RX_FILTER_TLV_FLAGS_ATTENTION
;
1140 rx_buf_sz
= DP_RX_BUFFER_SIZE
;
1141 } else if (mode
== ATH11K_PKTLOG_MODE_LITE
) {
1142 ret
= ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar
,
1143 HTT_PPDU_STATS_TAG_PKTLOG
);
1145 ath11k_err(ar
->ab
, "failed to enable pktlog lite: %d\n", ret
);
1149 rx_filter
= HTT_RX_FILTER_TLV_LITE_MODE
;
1150 rx_buf_sz
= DP_RX_BUFFER_SIZE_LITE
;
1152 rx_buf_sz
= DP_RX_BUFFER_SIZE
;
1153 tlv_filter
= ath11k_mac_mon_status_filter_default
;
1154 rx_filter
= tlv_filter
.rx_filter
;
1156 ret
= ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar
,
1157 HTT_PPDU_STATS_TAG_DEFAULT
);
1159 ath11k_err(ar
->ab
, "failed to send htt ppdu stats req: %d\n",
1165 tlv_filter
.rx_filter
= rx_filter
;
1167 tlv_filter
.pkt_filter_flags0
= HTT_RX_FP_MGMT_FILTER_FLAGS0
;
1168 tlv_filter
.pkt_filter_flags1
= HTT_RX_FP_MGMT_FILTER_FLAGS1
;
1169 tlv_filter
.pkt_filter_flags2
= HTT_RX_FP_CTRL_FILTER_FLASG2
;
1170 tlv_filter
.pkt_filter_flags3
= HTT_RX_FP_CTRL_FILTER_FLASG3
|
1171 HTT_RX_FP_DATA_FILTER_FLASG3
;
1174 for (i
= 0; i
< ab
->hw_params
.num_rxdma_per_pdev
; i
++) {
1175 ring_id
= ar
->dp
.rx_mon_status_refill_ring
[i
].refill_buf_ring
.ring_id
;
1176 ret
= ath11k_dp_tx_htt_rx_filter_setup(ab
, ring_id
,
1178 HAL_RXDMA_MONITOR_STATUS
,
1179 rx_buf_sz
, &tlv_filter
);
1182 ath11k_warn(ab
, "failed to set rx filter for monitor status ring\n");
1187 ath11k_info(ab
, "pktlog mode %s\n",
1188 ((mode
== ATH11K_PKTLOG_MODE_FULL
) ? "full" : "lite"));
1190 ar
->debug
.pktlog_filter
= filter
;
1191 ar
->debug
.pktlog_mode
= mode
;
1195 mutex_unlock(&ar
->conf_mutex
);
1199 static ssize_t
ath11k_read_pktlog_filter(struct file
*file
,
1201 size_t count
, loff_t
*ppos
)
1205 struct ath11k
*ar
= file
->private_data
;
1208 mutex_lock(&ar
->conf_mutex
);
1209 len
= scnprintf(buf
, sizeof(buf
) - len
, "%08x %08x\n",
1210 ar
->debug
.pktlog_filter
,
1211 ar
->debug
.pktlog_mode
);
1212 mutex_unlock(&ar
->conf_mutex
);
1214 return simple_read_from_buffer(ubuf
, count
, ppos
, buf
, len
);
1217 static const struct file_operations fops_pktlog_filter
= {
1218 .read
= ath11k_read_pktlog_filter
,
1219 .write
= ath11k_write_pktlog_filter
,
1223 static ssize_t
ath11k_write_simulate_radar(struct file
*file
,
1224 const char __user
*user_buf
,
1225 size_t count
, loff_t
*ppos
)
1227 struct ath11k
*ar
= file
->private_data
;
1230 ret
= ath11k_wmi_simulate_radar(ar
);
1237 static const struct file_operations fops_simulate_radar
= {
1238 .write
= ath11k_write_simulate_radar
,
1242 static ssize_t
ath11k_debug_dump_dbr_entries(struct file
*file
,
1243 char __user
*user_buf
,
1244 size_t count
, loff_t
*ppos
)
1246 struct ath11k_dbg_dbr_data
*dbr_dbg_data
= file
->private_data
;
1247 static const char * const event_id_to_string
[] = {"empty", "Rx", "Replenish"};
1248 int size
= ATH11K_DEBUG_DBR_ENTRIES_MAX
* 100;
1253 buf
= kzalloc(size
, GFP_KERNEL
);
1257 len
+= scnprintf(buf
+ len
, size
- len
,
1258 "-----------------------------------------\n");
1259 len
+= scnprintf(buf
+ len
, size
- len
,
1260 "| idx | hp | tp | timestamp | event |\n");
1261 len
+= scnprintf(buf
+ len
, size
- len
,
1262 "-----------------------------------------\n");
1264 spin_lock_bh(&dbr_dbg_data
->lock
);
1266 for (i
= 0; i
< dbr_dbg_data
->num_ring_debug_entries
; i
++) {
1267 len
+= scnprintf(buf
+ len
, size
- len
,
1268 "|%4u|%8u|%8u|%11llu|%8s|\n", i
,
1269 dbr_dbg_data
->entries
[i
].hp
,
1270 dbr_dbg_data
->entries
[i
].tp
,
1271 dbr_dbg_data
->entries
[i
].timestamp
,
1272 event_id_to_string
[dbr_dbg_data
->entries
[i
].event
]);
1275 spin_unlock_bh(&dbr_dbg_data
->lock
);
1277 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
1283 static const struct file_operations fops_debug_dump_dbr_entries
= {
1284 .read
= ath11k_debug_dump_dbr_entries
,
1285 .open
= simple_open
,
1286 .owner
= THIS_MODULE
,
1287 .llseek
= default_llseek
,
1290 static void ath11k_debugfs_dbr_dbg_destroy(struct ath11k
*ar
, int dbr_id
)
1292 struct ath11k_debug_dbr
*dbr_debug
;
1293 struct ath11k_dbg_dbr_data
*dbr_dbg_data
;
1295 if (!ar
->debug
.dbr_debug
[dbr_id
])
1298 dbr_debug
= ar
->debug
.dbr_debug
[dbr_id
];
1299 dbr_dbg_data
= &dbr_debug
->dbr_dbg_data
;
1301 debugfs_remove_recursive(dbr_debug
->dbr_debugfs
);
1302 kfree(dbr_dbg_data
->entries
);
1304 ar
->debug
.dbr_debug
[dbr_id
] = NULL
;
1307 static int ath11k_debugfs_dbr_dbg_init(struct ath11k
*ar
, int dbr_id
)
1309 struct ath11k_debug_dbr
*dbr_debug
;
1310 struct ath11k_dbg_dbr_data
*dbr_dbg_data
;
1311 static const char * const dbr_id_to_str
[] = {"spectral", "CFR"};
1313 if (ar
->debug
.dbr_debug
[dbr_id
])
1316 ar
->debug
.dbr_debug
[dbr_id
] = kzalloc(sizeof(*dbr_debug
),
1319 if (!ar
->debug
.dbr_debug
[dbr_id
])
1322 dbr_debug
= ar
->debug
.dbr_debug
[dbr_id
];
1323 dbr_dbg_data
= &dbr_debug
->dbr_dbg_data
;
1325 if (dbr_debug
->dbr_debugfs
)
1328 dbr_debug
->dbr_debugfs
= debugfs_create_dir(dbr_id_to_str
[dbr_id
],
1329 ar
->debug
.debugfs_pdev
);
1330 if (IS_ERR_OR_NULL(dbr_debug
->dbr_debugfs
)) {
1331 if (IS_ERR(dbr_debug
->dbr_debugfs
))
1332 return PTR_ERR(dbr_debug
->dbr_debugfs
);
1336 dbr_debug
->dbr_debug_enabled
= true;
1337 dbr_dbg_data
->num_ring_debug_entries
= ATH11K_DEBUG_DBR_ENTRIES_MAX
;
1338 dbr_dbg_data
->dbr_debug_idx
= 0;
1339 dbr_dbg_data
->entries
= kcalloc(ATH11K_DEBUG_DBR_ENTRIES_MAX
,
1340 sizeof(struct ath11k_dbg_dbr_entry
),
1342 if (!dbr_dbg_data
->entries
)
1345 spin_lock_init(&dbr_dbg_data
->lock
);
1347 debugfs_create_file("dump_dbr_debug", 0444, dbr_debug
->dbr_debugfs
,
1348 dbr_dbg_data
, &fops_debug_dump_dbr_entries
);
1353 static ssize_t
ath11k_debugfs_write_enable_dbr_dbg(struct file
*file
,
1354 const char __user
*ubuf
,
1355 size_t count
, loff_t
*ppos
)
1357 struct ath11k
*ar
= file
->private_data
;
1362 mutex_lock(&ar
->conf_mutex
);
1364 if (ar
->state
!= ATH11K_STATE_ON
) {
1369 ret
= simple_write_to_buffer(buf
, sizeof(buf
) - 1, ppos
, ubuf
, count
);
1374 ret
= sscanf(buf
, "%u %u", &dbr_id
, &enable
);
1375 if (ret
!= 2 || dbr_id
> 1 || enable
> 1) {
1377 ath11k_warn(ar
->ab
, "usage: echo <dbr_id> <val> dbr_id:0-Spectral 1-CFR val:0-disable 1-enable\n");
1382 ret
= ath11k_debugfs_dbr_dbg_init(ar
, dbr_id
);
1384 ath11k_warn(ar
->ab
, "db ring module debugfs init failed: %d\n",
1389 ath11k_debugfs_dbr_dbg_destroy(ar
, dbr_id
);
1394 mutex_unlock(&ar
->conf_mutex
);
1398 static const struct file_operations fops_dbr_debug
= {
1399 .write
= ath11k_debugfs_write_enable_dbr_dbg
,
1400 .open
= simple_open
,
1401 .owner
= THIS_MODULE
,
1402 .llseek
= default_llseek
,
1405 static ssize_t
ath11k_write_ps_timekeeper_enable(struct file
*file
,
1406 const char __user
*user_buf
,
1407 size_t count
, loff_t
*ppos
)
1409 struct ath11k
*ar
= file
->private_data
;
1411 u8 ps_timekeeper_enable
;
1413 if (kstrtou8_from_user(user_buf
, count
, 0, &ps_timekeeper_enable
))
1416 mutex_lock(&ar
->conf_mutex
);
1418 if (ar
->state
!= ATH11K_STATE_ON
) {
1423 if (!ar
->ps_state_enable
) {
1428 ar
->ps_timekeeper_enable
= !!ps_timekeeper_enable
;
1431 mutex_unlock(&ar
->conf_mutex
);
1436 static ssize_t
ath11k_read_ps_timekeeper_enable(struct file
*file
,
1437 char __user
*user_buf
,
1438 size_t count
, loff_t
*ppos
)
1440 struct ath11k
*ar
= file
->private_data
;
1444 mutex_lock(&ar
->conf_mutex
);
1445 len
= scnprintf(buf
, sizeof(buf
), "%d\n", ar
->ps_timekeeper_enable
);
1446 mutex_unlock(&ar
->conf_mutex
);
1448 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
1451 static const struct file_operations fops_ps_timekeeper_enable
= {
1452 .read
= ath11k_read_ps_timekeeper_enable
,
1453 .write
= ath11k_write_ps_timekeeper_enable
,
1454 .open
= simple_open
,
1455 .owner
= THIS_MODULE
,
1456 .llseek
= default_llseek
,
1459 static void ath11k_reset_peer_ps_duration(void *data
,
1460 struct ieee80211_sta
*sta
)
1462 struct ath11k
*ar
= data
;
1463 struct ath11k_sta
*arsta
= ath11k_sta_to_arsta(sta
);
1465 spin_lock_bh(&ar
->data_lock
);
1466 arsta
->ps_total_duration
= 0;
1467 spin_unlock_bh(&ar
->data_lock
);
1470 static ssize_t
ath11k_write_reset_ps_duration(struct file
*file
,
1471 const char __user
*user_buf
,
1472 size_t count
, loff_t
*ppos
)
1474 struct ath11k
*ar
= file
->private_data
;
1476 u8 reset_ps_duration
;
1478 if (kstrtou8_from_user(user_buf
, count
, 0, &reset_ps_duration
))
1481 mutex_lock(&ar
->conf_mutex
);
1483 if (ar
->state
!= ATH11K_STATE_ON
) {
1488 if (!ar
->ps_state_enable
) {
1493 ieee80211_iterate_stations_atomic(ar
->hw
,
1494 ath11k_reset_peer_ps_duration
,
1499 mutex_unlock(&ar
->conf_mutex
);
1503 static const struct file_operations fops_reset_ps_duration
= {
1504 .write
= ath11k_write_reset_ps_duration
,
1505 .open
= simple_open
,
1506 .owner
= THIS_MODULE
,
1507 .llseek
= default_llseek
,
1510 static void ath11k_peer_ps_state_disable(void *data
,
1511 struct ieee80211_sta
*sta
)
1513 struct ath11k
*ar
= data
;
1514 struct ath11k_sta
*arsta
= ath11k_sta_to_arsta(sta
);
1516 spin_lock_bh(&ar
->data_lock
);
1517 arsta
->peer_ps_state
= WMI_PEER_PS_STATE_DISABLED
;
1518 arsta
->ps_start_time
= 0;
1519 arsta
->ps_total_duration
= 0;
1520 spin_unlock_bh(&ar
->data_lock
);
1523 static ssize_t
ath11k_write_ps_state_enable(struct file
*file
,
1524 const char __user
*user_buf
,
1525 size_t count
, loff_t
*ppos
)
1527 struct ath11k
*ar
= file
->private_data
;
1528 struct ath11k_pdev
*pdev
= ar
->pdev
;
1533 if (kstrtou8_from_user(user_buf
, count
, 0, &ps_state_enable
))
1536 mutex_lock(&ar
->conf_mutex
);
1538 ps_state_enable
= !!ps_state_enable
;
1540 if (ar
->ps_state_enable
== ps_state_enable
) {
1545 param
= WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE
;
1546 ret
= ath11k_wmi_pdev_set_param(ar
, param
, ps_state_enable
, pdev
->pdev_id
);
1548 ath11k_warn(ar
->ab
, "failed to enable ps_state_enable: %d\n",
1552 ar
->ps_state_enable
= ps_state_enable
;
1554 if (!ar
->ps_state_enable
) {
1555 ar
->ps_timekeeper_enable
= false;
1556 ieee80211_iterate_stations_atomic(ar
->hw
,
1557 ath11k_peer_ps_state_disable
,
1564 mutex_unlock(&ar
->conf_mutex
);
1569 static ssize_t
ath11k_read_ps_state_enable(struct file
*file
,
1570 char __user
*user_buf
,
1571 size_t count
, loff_t
*ppos
)
1573 struct ath11k
*ar
= file
->private_data
;
1577 mutex_lock(&ar
->conf_mutex
);
1578 len
= scnprintf(buf
, sizeof(buf
), "%d\n", ar
->ps_state_enable
);
1579 mutex_unlock(&ar
->conf_mutex
);
1581 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
1584 static const struct file_operations fops_ps_state_enable
= {
1585 .read
= ath11k_read_ps_state_enable
,
1586 .write
= ath11k_write_ps_state_enable
,
1587 .open
= simple_open
,
1588 .owner
= THIS_MODULE
,
1589 .llseek
= default_llseek
,
1592 int ath11k_debugfs_register(struct ath11k
*ar
)
1594 struct ath11k_base
*ab
= ar
->ab
;
1596 char buf
[100] = {0};
1598 snprintf(pdev_name
, sizeof(pdev_name
), "%s%u", "mac", ar
->pdev_idx
);
1600 ar
->debug
.debugfs_pdev
= debugfs_create_dir(pdev_name
, ab
->debugfs_soc
);
1601 if (IS_ERR(ar
->debug
.debugfs_pdev
))
1602 return PTR_ERR(ar
->debug
.debugfs_pdev
);
1604 /* Create a symlink under ieee80211/phy* */
1605 snprintf(buf
, 100, "../../ath11k/%pd2", ar
->debug
.debugfs_pdev
);
1606 debugfs_create_symlink("ath11k", ar
->hw
->wiphy
->debugfsdir
, buf
);
1608 ath11k_debugfs_htt_stats_init(ar
);
1610 ath11k_debugfs_fw_stats_init(ar
);
1612 debugfs_create_file("ext_tx_stats", 0644,
1613 ar
->debug
.debugfs_pdev
, ar
,
1614 &fops_extd_tx_stats
);
1615 debugfs_create_file("ext_rx_stats", 0644,
1616 ar
->debug
.debugfs_pdev
, ar
,
1617 &fops_extd_rx_stats
);
1618 debugfs_create_file("pktlog_filter", 0644,
1619 ar
->debug
.debugfs_pdev
, ar
,
1620 &fops_pktlog_filter
);
1621 debugfs_create_file("fw_dbglog_config", 0600,
1622 ar
->debug
.debugfs_pdev
, ar
,
1625 if (ar
->hw
->wiphy
->bands
[NL80211_BAND_5GHZ
]) {
1626 debugfs_create_file("dfs_simulate_radar", 0200,
1627 ar
->debug
.debugfs_pdev
, ar
,
1628 &fops_simulate_radar
);
1629 debugfs_create_bool("dfs_block_radar_events", 0200,
1630 ar
->debug
.debugfs_pdev
,
1631 &ar
->dfs_block_radar_events
);
1634 if (ab
->hw_params
.dbr_debug_support
)
1635 debugfs_create_file("enable_dbr_debug", 0200, ar
->debug
.debugfs_pdev
,
1636 ar
, &fops_dbr_debug
);
1638 debugfs_create_file("ps_state_enable", 0600, ar
->debug
.debugfs_pdev
, ar
,
1639 &fops_ps_state_enable
);
1641 if (test_bit(WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT
,
1642 ar
->ab
->wmi_ab
.svc_map
)) {
1643 debugfs_create_file("ps_timekeeper_enable", 0600,
1644 ar
->debug
.debugfs_pdev
, ar
,
1645 &fops_ps_timekeeper_enable
);
1647 debugfs_create_file("reset_ps_duration", 0200,
1648 ar
->debug
.debugfs_pdev
, ar
,
1649 &fops_reset_ps_duration
);
1655 void ath11k_debugfs_unregister(struct ath11k
*ar
)
1657 struct ath11k_debug_dbr
*dbr_debug
;
1658 struct ath11k_dbg_dbr_data
*dbr_dbg_data
;
1661 for (i
= 0; i
< WMI_DIRECT_BUF_MAX
; i
++) {
1662 dbr_debug
= ar
->debug
.dbr_debug
[i
];
1666 dbr_dbg_data
= &dbr_debug
->dbr_dbg_data
;
1667 kfree(dbr_dbg_data
->entries
);
1668 debugfs_remove_recursive(dbr_debug
->dbr_debugfs
);
1670 ar
->debug
.dbr_debug
[i
] = NULL
;
1674 static ssize_t
ath11k_write_twt_add_dialog(struct file
*file
,
1675 const char __user
*ubuf
,
1676 size_t count
, loff_t
*ppos
)
1678 struct ath11k_vif
*arvif
= file
->private_data
;
1679 struct wmi_twt_add_dialog_params params
= { 0 };
1680 struct wmi_twt_enable_params twt_params
= {0};
1681 struct ath11k
*ar
= arvif
->ar
;
1685 if (ar
->twt_enabled
== 0) {
1686 ath11k_err(ar
->ab
, "twt support is not enabled\n");
1690 ret
= simple_write_to_buffer(buf
, sizeof(buf
) - 1, ppos
, ubuf
, count
);
1696 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u %u %u %u %u %hhu %hhu %hhu %hhu %hhu",
1697 ¶ms
.peer_macaddr
[0],
1698 ¶ms
.peer_macaddr
[1],
1699 ¶ms
.peer_macaddr
[2],
1700 ¶ms
.peer_macaddr
[3],
1701 ¶ms
.peer_macaddr
[4],
1702 ¶ms
.peer_macaddr
[5],
1704 ¶ms
.wake_intvl_us
,
1705 ¶ms
.wake_intvl_mantis
,
1706 ¶ms
.wake_dura_us
,
1707 ¶ms
.sp_offset_us
,
1710 ¶ms
.flag_trigger
,
1711 ¶ms
.flag_flow_type
,
1712 ¶ms
.flag_protection
);
1716 /* In the case of station vif, TWT is entirely handled by
1717 * the firmware based on the input parameters in the TWT enable
1718 * WMI command that is sent to the target during assoc.
1719 * For manually testing the TWT feature, we need to first disable
1720 * TWT and send enable command again with TWT input parameter
1721 * sta_cong_timer_ms set to 0.
1723 if (arvif
->vif
->type
== NL80211_IFTYPE_STATION
) {
1724 ath11k_wmi_send_twt_disable_cmd(ar
, ar
->pdev
->pdev_id
);
1726 ath11k_wmi_fill_default_twt_params(&twt_params
);
1727 twt_params
.sta_cong_timer_ms
= 0;
1729 ath11k_wmi_send_twt_enable_cmd(ar
, ar
->pdev
->pdev_id
, &twt_params
);
1732 params
.vdev_id
= arvif
->vdev_id
;
1734 ret
= ath11k_wmi_send_twt_add_dialog_cmd(arvif
->ar
, ¶ms
);
1736 goto err_twt_add_dialog
;
1741 if (arvif
->vif
->type
== NL80211_IFTYPE_STATION
) {
1742 ath11k_wmi_send_twt_disable_cmd(ar
, ar
->pdev
->pdev_id
);
1743 ath11k_wmi_fill_default_twt_params(&twt_params
);
1744 ath11k_wmi_send_twt_enable_cmd(ar
, ar
->pdev
->pdev_id
, &twt_params
);
1750 static ssize_t
ath11k_write_twt_del_dialog(struct file
*file
,
1751 const char __user
*ubuf
,
1752 size_t count
, loff_t
*ppos
)
1754 struct ath11k_vif
*arvif
= file
->private_data
;
1755 struct wmi_twt_del_dialog_params params
= { 0 };
1756 struct wmi_twt_enable_params twt_params
= {0};
1757 struct ath11k
*ar
= arvif
->ar
;
1761 if (ar
->twt_enabled
== 0) {
1762 ath11k_err(ar
->ab
, "twt support is not enabled\n");
1766 ret
= simple_write_to_buffer(buf
, sizeof(buf
) - 1, ppos
, ubuf
, count
);
1771 ret
= sscanf(buf
, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u",
1772 ¶ms
.peer_macaddr
[0],
1773 ¶ms
.peer_macaddr
[1],
1774 ¶ms
.peer_macaddr
[2],
1775 ¶ms
.peer_macaddr
[3],
1776 ¶ms
.peer_macaddr
[4],
1777 ¶ms
.peer_macaddr
[5],
1782 params
.vdev_id
= arvif
->vdev_id
;
1784 ret
= ath11k_wmi_send_twt_del_dialog_cmd(arvif
->ar
, ¶ms
);
1788 if (arvif
->vif
->type
== NL80211_IFTYPE_STATION
) {
1789 ath11k_wmi_send_twt_disable_cmd(ar
, ar
->pdev
->pdev_id
);
1790 ath11k_wmi_fill_default_twt_params(&twt_params
);
1791 ath11k_wmi_send_twt_enable_cmd(ar
, ar
->pdev
->pdev_id
, &twt_params
);
1797 static ssize_t
ath11k_write_twt_pause_dialog(struct file
*file
,
1798 const char __user
*ubuf
,
1799 size_t count
, loff_t
*ppos
)
1801 struct ath11k_vif
*arvif
= file
->private_data
;
1802 struct wmi_twt_pause_dialog_params params
= { 0 };
1806 if (arvif
->ar
->twt_enabled
== 0) {
1807 ath11k_err(arvif
->ar
->ab
, "twt support is not enabled\n");
1811 ret
= simple_write_to_buffer(buf
, sizeof(buf
) - 1, ppos
, ubuf
, count
);
1816 ret
= sscanf(buf
, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u",
1817 ¶ms
.peer_macaddr
[0],
1818 ¶ms
.peer_macaddr
[1],
1819 ¶ms
.peer_macaddr
[2],
1820 ¶ms
.peer_macaddr
[3],
1821 ¶ms
.peer_macaddr
[4],
1822 ¶ms
.peer_macaddr
[5],
1827 params
.vdev_id
= arvif
->vdev_id
;
1829 ret
= ath11k_wmi_send_twt_pause_dialog_cmd(arvif
->ar
, ¶ms
);
1836 static ssize_t
ath11k_write_twt_resume_dialog(struct file
*file
,
1837 const char __user
*ubuf
,
1838 size_t count
, loff_t
*ppos
)
1840 struct ath11k_vif
*arvif
= file
->private_data
;
1841 struct wmi_twt_resume_dialog_params params
= { 0 };
1845 if (arvif
->ar
->twt_enabled
== 0) {
1846 ath11k_err(arvif
->ar
->ab
, "twt support is not enabled\n");
1850 ret
= simple_write_to_buffer(buf
, sizeof(buf
) - 1, ppos
, ubuf
, count
);
1855 ret
= sscanf(buf
, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u %u %u",
1856 ¶ms
.peer_macaddr
[0],
1857 ¶ms
.peer_macaddr
[1],
1858 ¶ms
.peer_macaddr
[2],
1859 ¶ms
.peer_macaddr
[3],
1860 ¶ms
.peer_macaddr
[4],
1861 ¶ms
.peer_macaddr
[5],
1863 ¶ms
.sp_offset_us
,
1864 ¶ms
.next_twt_size
);
1868 params
.vdev_id
= arvif
->vdev_id
;
1870 ret
= ath11k_wmi_send_twt_resume_dialog_cmd(arvif
->ar
, ¶ms
);
1877 static const struct file_operations ath11k_fops_twt_add_dialog
= {
1878 .write
= ath11k_write_twt_add_dialog
,
1882 static const struct file_operations ath11k_fops_twt_del_dialog
= {
1883 .write
= ath11k_write_twt_del_dialog
,
1887 static const struct file_operations ath11k_fops_twt_pause_dialog
= {
1888 .write
= ath11k_write_twt_pause_dialog
,
1892 static const struct file_operations ath11k_fops_twt_resume_dialog
= {
1893 .write
= ath11k_write_twt_resume_dialog
,
1897 void ath11k_debugfs_op_vif_add(struct ieee80211_hw
*hw
,
1898 struct ieee80211_vif
*vif
)
1900 struct ath11k_vif
*arvif
= ath11k_vif_to_arvif(vif
);
1901 struct ath11k_base
*ab
= arvif
->ar
->ab
;
1902 struct dentry
*debugfs_twt
;
1904 if (arvif
->vif
->type
!= NL80211_IFTYPE_AP
&&
1905 !(arvif
->vif
->type
== NL80211_IFTYPE_STATION
&&
1906 test_bit(WMI_TLV_SERVICE_STA_TWT
, ab
->wmi_ab
.svc_map
)))
1909 debugfs_twt
= debugfs_create_dir("twt",
1910 arvif
->vif
->debugfs_dir
);
1911 debugfs_create_file("add_dialog", 0200, debugfs_twt
,
1912 arvif
, &ath11k_fops_twt_add_dialog
);
1914 debugfs_create_file("del_dialog", 0200, debugfs_twt
,
1915 arvif
, &ath11k_fops_twt_del_dialog
);
1917 debugfs_create_file("pause_dialog", 0200, debugfs_twt
,
1918 arvif
, &ath11k_fops_twt_pause_dialog
);
1920 debugfs_create_file("resume_dialog", 0200, debugfs_twt
,
1921 arvif
, &ath11k_fops_twt_resume_dialog
);