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