xref: /linux/drivers/net/wireless/ath/ath11k/debugfs.c (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3  * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
4  * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
5  */
6 
7 #include <linux/vmalloc.h>
8 
9 #include "debugfs.h"
10 
11 #include "core.h"
12 #include "debug.h"
13 #include "wmi.h"
14 #include "hal_rx.h"
15 #include "dp_tx.h"
16 #include "debugfs_htt_stats.h"
17 #include "peer.h"
18 #include "hif.h"
19 
20 static const char *htt_bp_umac_ring[HTT_SW_UMAC_RING_IDX_MAX] = {
21 	"REO2SW1_RING",
22 	"REO2SW2_RING",
23 	"REO2SW3_RING",
24 	"REO2SW4_RING",
25 	"WBM2REO_LINK_RING",
26 	"REO2TCL_RING",
27 	"REO2FW_RING",
28 	"RELEASE_RING",
29 	"PPE_RELEASE_RING",
30 	"TCL2TQM_RING",
31 	"TQM_RELEASE_RING",
32 	"REO_RELEASE_RING",
33 	"WBM2SW0_RELEASE_RING",
34 	"WBM2SW1_RELEASE_RING",
35 	"WBM2SW2_RELEASE_RING",
36 	"WBM2SW3_RELEASE_RING",
37 	"REO_CMD_RING",
38 	"REO_STATUS_RING",
39 };
40 
41 static const char *htt_bp_lmac_ring[HTT_SW_LMAC_RING_IDX_MAX] = {
42 	"FW2RXDMA_BUF_RING",
43 	"FW2RXDMA_STATUS_RING",
44 	"FW2RXDMA_LINK_RING",
45 	"SW2RXDMA_BUF_RING",
46 	"WBM2RXDMA_LINK_RING",
47 	"RXDMA2FW_RING",
48 	"RXDMA2SW_RING",
49 	"RXDMA2RELEASE_RING",
50 	"RXDMA2REO_RING",
51 	"MONITOR_STATUS_RING",
52 	"MONITOR_BUF_RING",
53 	"MONITOR_DESC_RING",
54 	"MONITOR_DEST_RING",
55 };
56 
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)
61 {
62 	struct ath11k_debug_dbr *dbr_debug;
63 	struct ath11k_dbg_dbr_data *dbr_data;
64 	struct ath11k_dbg_dbr_entry *entry;
65 
66 	if (id >= WMI_DIRECT_BUF_MAX || event >= ATH11K_DBG_DBR_EVENT_MAX)
67 		return;
68 
69 	dbr_debug = ar->debug.dbr_debug[id];
70 	if (!dbr_debug)
71 		return;
72 
73 	if (!dbr_debug->dbr_debug_enabled)
74 		return;
75 
76 	dbr_data = &dbr_debug->dbr_dbg_data;
77 
78 	spin_lock_bh(&dbr_data->lock);
79 
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;
85 		entry->event = event;
86 
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;
91 	}
92 
93 	spin_unlock_bh(&dbr_data->lock);
94 }
95 
96 static void ath11k_debugfs_fw_stats_reset(struct ath11k *ar)
97 {
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);
103 }
104 
105 void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *stats)
106 {
107 	struct ath11k_base *ab = ar->ab;
108 	struct ath11k_pdev *pdev;
109 	bool is_end;
110 	static unsigned int num_vdev, num_bcn;
111 	size_t total_vdevs_started = 0;
112 	int i;
113 
114 	/* WMI_REQUEST_PDEV_STAT request has been already processed */
115 
116 	if (stats->stats_id == WMI_REQUEST_RSSI_PER_CHAIN_STAT) {
117 		ar->fw_stats_done = true;
118 		return;
119 	}
120 
121 	if (stats->stats_id == WMI_REQUEST_VDEV_STAT) {
122 		if (list_empty(&stats->vdevs)) {
123 			ath11k_warn(ab, "empty vdev stats");
124 			return;
125 		}
126 		/* FW sends all the active VDEV stats irrespective of PDEV,
127 		 * hence limit until the count of all VDEVs started
128 		 */
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;
133 		}
134 
135 		is_end = ((++num_vdev) == total_vdevs_started);
136 
137 		list_splice_tail_init(&stats->vdevs,
138 				      &ar->fw_stats.vdevs);
139 
140 		if (is_end) {
141 			ar->fw_stats_done = true;
142 			num_vdev = 0;
143 		}
144 		return;
145 	}
146 
147 	if (stats->stats_id == WMI_REQUEST_BCN_STAT) {
148 		if (list_empty(&stats->bcn)) {
149 			ath11k_warn(ab, "empty bcn stats");
150 			return;
151 		}
152 		/* Mark end until we reached the count of all started VDEVs
153 		 * within the PDEV
154 		 */
155 		is_end = ((++num_bcn) == ar->num_started_vdevs);
156 
157 		list_splice_tail_init(&stats->bcn,
158 				      &ar->fw_stats.bcn);
159 
160 		if (is_end) {
161 			ar->fw_stats_done = true;
162 			num_bcn = 0;
163 		}
164 	}
165 }
166 
167 static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
168 					   struct stats_request_params *req_param)
169 {
170 	struct ath11k_base *ab = ar->ab;
171 	unsigned long timeout, time_left;
172 	int ret;
173 
174 	lockdep_assert_held(&ar->conf_mutex);
175 
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
180 	 */
181 	timeout = jiffies + msecs_to_jiffies(3 * 1000);
182 
183 	ath11k_debugfs_fw_stats_reset(ar);
184 
185 	reinit_completion(&ar->fw_stats_complete);
186 
187 	ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);
188 
189 	if (ret) {
190 		ath11k_warn(ab, "could not request fw stats (%d)\n",
191 			    ret);
192 		return ret;
193 	}
194 
195 	time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ);
196 
197 	if (!time_left)
198 		return -ETIMEDOUT;
199 
200 	for (;;) {
201 		if (time_after(jiffies, timeout))
202 			break;
203 
204 		spin_lock_bh(&ar->data_lock);
205 		if (ar->fw_stats_done) {
206 			spin_unlock_bh(&ar->data_lock);
207 			break;
208 		}
209 		spin_unlock_bh(&ar->data_lock);
210 	}
211 	return 0;
212 }
213 
214 int ath11k_debugfs_get_fw_stats(struct ath11k *ar, u32 pdev_id,
215 				u32 vdev_id, u32 stats_id)
216 {
217 	struct ath11k_base *ab = ar->ab;
218 	struct stats_request_params req_param;
219 	int ret;
220 
221 	mutex_lock(&ar->conf_mutex);
222 
223 	if (ar->state != ATH11K_STATE_ON) {
224 		ret = -ENETDOWN;
225 		goto err_unlock;
226 	}
227 
228 	req_param.pdev_id = pdev_id;
229 	req_param.vdev_id = vdev_id;
230 	req_param.stats_id = stats_id;
231 
232 	ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
233 	if (ret)
234 		ath11k_warn(ab, "failed to request fw stats: %d\n", ret);
235 
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);
239 
240 err_unlock:
241 	mutex_unlock(&ar->conf_mutex);
242 
243 	return ret;
244 }
245 
246 static int ath11k_open_pdev_stats(struct inode *inode, struct file *file)
247 {
248 	struct ath11k *ar = inode->i_private;
249 	struct ath11k_base *ab = ar->ab;
250 	struct stats_request_params req_param;
251 	void *buf = NULL;
252 	int ret;
253 
254 	mutex_lock(&ar->conf_mutex);
255 
256 	if (ar->state != ATH11K_STATE_ON) {
257 		ret = -ENETDOWN;
258 		goto err_unlock;
259 	}
260 
261 	buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
262 	if (!buf) {
263 		ret = -ENOMEM;
264 		goto err_unlock;
265 	}
266 
267 	req_param.pdev_id = ar->pdev->pdev_id;
268 	req_param.vdev_id = 0;
269 	req_param.stats_id = WMI_REQUEST_PDEV_STAT;
270 
271 	ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
272 	if (ret) {
273 		ath11k_warn(ab, "failed to request fw pdev stats: %d\n", ret);
274 		goto err_free;
275 	}
276 
277 	ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
278 
279 	file->private_data = buf;
280 
281 	mutex_unlock(&ar->conf_mutex);
282 	return 0;
283 
284 err_free:
285 	vfree(buf);
286 
287 err_unlock:
288 	mutex_unlock(&ar->conf_mutex);
289 	return ret;
290 }
291 
292 static int ath11k_release_pdev_stats(struct inode *inode, struct file *file)
293 {
294 	vfree(file->private_data);
295 
296 	return 0;
297 }
298 
299 static ssize_t ath11k_read_pdev_stats(struct file *file,
300 				      char __user *user_buf,
301 				      size_t count, loff_t *ppos)
302 {
303 	const char *buf = file->private_data;
304 	size_t len = strlen(buf);
305 
306 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
307 }
308 
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,
315 };
316 
317 static int ath11k_open_vdev_stats(struct inode *inode, struct file *file)
318 {
319 	struct ath11k *ar = inode->i_private;
320 	struct stats_request_params req_param;
321 	void *buf = NULL;
322 	int ret;
323 
324 	mutex_lock(&ar->conf_mutex);
325 
326 	if (ar->state != ATH11K_STATE_ON) {
327 		ret = -ENETDOWN;
328 		goto err_unlock;
329 	}
330 
331 	buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
332 	if (!buf) {
333 		ret = -ENOMEM;
334 		goto err_unlock;
335 	}
336 
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;
341 
342 	ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
343 	if (ret) {
344 		ath11k_warn(ar->ab, "failed to request fw vdev stats: %d\n", ret);
345 		goto err_free;
346 	}
347 
348 	ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
349 
350 	file->private_data = buf;
351 
352 	mutex_unlock(&ar->conf_mutex);
353 	return 0;
354 
355 err_free:
356 	vfree(buf);
357 
358 err_unlock:
359 	mutex_unlock(&ar->conf_mutex);
360 	return ret;
361 }
362 
363 static int ath11k_release_vdev_stats(struct inode *inode, struct file *file)
364 {
365 	vfree(file->private_data);
366 
367 	return 0;
368 }
369 
370 static ssize_t ath11k_read_vdev_stats(struct file *file,
371 				      char __user *user_buf,
372 				      size_t count, loff_t *ppos)
373 {
374 	const char *buf = file->private_data;
375 	size_t len = strlen(buf);
376 
377 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
378 }
379 
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,
386 };
387 
388 static int ath11k_open_bcn_stats(struct inode *inode, struct file *file)
389 {
390 	struct ath11k *ar = inode->i_private;
391 	struct ath11k_vif *arvif;
392 	struct stats_request_params req_param;
393 	void *buf = NULL;
394 	int ret;
395 
396 	mutex_lock(&ar->conf_mutex);
397 
398 	if (ar->state != ATH11K_STATE_ON) {
399 		ret = -ENETDOWN;
400 		goto err_unlock;
401 	}
402 
403 	buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
404 	if (!buf) {
405 		ret = -ENOMEM;
406 		goto err_unlock;
407 	}
408 
409 	req_param.stats_id = WMI_REQUEST_BCN_STAT;
410 	req_param.pdev_id = ar->pdev->pdev_id;
411 
412 	/* loop all active VDEVs for bcn stats */
413 	list_for_each_entry(arvif, &ar->arvifs, list) {
414 		if (!arvif->is_up)
415 			continue;
416 
417 		req_param.vdev_id = arvif->vdev_id;
418 		ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
419 		if (ret) {
420 			ath11k_warn(ar->ab, "failed to request fw bcn stats: %d\n", ret);
421 			goto err_free;
422 		}
423 	}
424 
425 	ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
426 
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
429 	 */
430 	spin_lock_bh(&ar->data_lock);
431 	ath11k_fw_stats_bcn_free(&ar->fw_stats.bcn);
432 	spin_unlock_bh(&ar->data_lock);
433 
434 	file->private_data = buf;
435 
436 	mutex_unlock(&ar->conf_mutex);
437 	return 0;
438 
439 err_free:
440 	vfree(buf);
441 
442 err_unlock:
443 	mutex_unlock(&ar->conf_mutex);
444 	return ret;
445 }
446 
447 static int ath11k_release_bcn_stats(struct inode *inode, struct file *file)
448 {
449 	vfree(file->private_data);
450 
451 	return 0;
452 }
453 
454 static ssize_t ath11k_read_bcn_stats(struct file *file,
455 				     char __user *user_buf,
456 				     size_t count, loff_t *ppos)
457 {
458 	const char *buf = file->private_data;
459 	size_t len = strlen(buf);
460 
461 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
462 }
463 
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,
470 };
471 
472 static ssize_t ath11k_read_simulate_fw_crash(struct file *file,
473 					     char __user *user_buf,
474 					     size_t count, loff_t *ppos)
475 {
476 	const char buf[] =
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";
480 
481 	return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
482 }
483 
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
489  * firmware reset.
490  */
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)
494 {
495 	struct ath11k_base *ab = file->private_data;
496 	struct ath11k_pdev *pdev;
497 	struct ath11k *ar = ab->pdevs[0].ar;
498 	char buf[32] = {0};
499 	ssize_t rc;
500 	int i, ret, radioup = 0;
501 
502 	for (i = 0; i < ab->num_radios; i++) {
503 		pdev = &ab->pdevs[i];
504 		ar = pdev->ar;
505 		if (ar && ar->state == ATH11K_STATE_ON) {
506 			radioup = 1;
507 			break;
508 		}
509 	}
510 	/* filter partial writes and invalid commands */
511 	if (*ppos != 0 || count >= sizeof(buf) || count == 0)
512 		return -EINVAL;
513 
514 	rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
515 	if (rc < 0)
516 		return rc;
517 
518 	/* drop the possible '\n' from the end */
519 	if (buf[*ppos - 1] == '\n')
520 		buf[*ppos - 1] = '\0';
521 
522 	if (radioup == 0) {
523 		ret = -ENETDOWN;
524 		goto exit;
525 	}
526 
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);
535 		ret = 0;
536 	} else {
537 		ret = -EINVAL;
538 		goto exit;
539 	}
540 
541 	if (ret) {
542 		ath11k_warn(ab, "failed to simulate firmware crash: %d\n", ret);
543 		goto exit;
544 	}
545 
546 	ret = count;
547 
548 exit:
549 	return ret;
550 }
551 
552 static const struct file_operations fops_simulate_fw_crash = {
553 	.read = ath11k_read_simulate_fw_crash,
554 	.write = ath11k_write_simulate_fw_crash,
555 	.open = simple_open,
556 	.owner = THIS_MODULE,
557 	.llseek = default_llseek,
558 };
559 
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)
563 {
564 	struct ath11k *ar = file->private_data;
565 	u32 filter;
566 	int ret;
567 
568 	if (kstrtouint_from_user(ubuf, count, 0, &filter))
569 		return -EINVAL;
570 
571 	mutex_lock(&ar->conf_mutex);
572 
573 	if (ar->state != ATH11K_STATE_ON) {
574 		ret = -ENETDOWN;
575 		goto out;
576 	}
577 
578 	if (filter == ar->debug.extd_tx_stats) {
579 		ret = count;
580 		goto out;
581 	}
582 
583 	ar->debug.extd_tx_stats = filter;
584 	ret = count;
585 
586 out:
587 	mutex_unlock(&ar->conf_mutex);
588 	return ret;
589 }
590 
591 static ssize_t ath11k_read_enable_extd_tx_stats(struct file *file,
592 						char __user *ubuf,
593 						size_t count, loff_t *ppos)
594 
595 {
596 	char buf[32] = {0};
597 	struct ath11k *ar = file->private_data;
598 	int len = 0;
599 
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);
604 
605 	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
606 }
607 
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,
611 	.open = simple_open
612 };
613 
614 static ssize_t ath11k_write_extd_rx_stats(struct file *file,
615 					  const char __user *ubuf,
616 					  size_t count, loff_t *ppos)
617 {
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;
622 	int i;
623 	int ret;
624 
625 	if (kstrtouint_from_user(ubuf, count, 0, &enable))
626 		return -EINVAL;
627 
628 	mutex_lock(&ar->conf_mutex);
629 
630 	if (ar->state != ATH11K_STATE_ON) {
631 		ret = -ENETDOWN;
632 		goto exit;
633 	}
634 
635 	if (enable > 1) {
636 		ret = -EINVAL;
637 		goto exit;
638 	}
639 
640 	if (enable == ar->debug.extd_rx_stats) {
641 		ret = count;
642 		goto exit;
643 	}
644 
645 	if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags)) {
646 		ar->debug.extd_rx_stats = enable;
647 		ret = count;
648 		goto exit;
649 	}
650 
651 	if (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;
658 
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;
665 	} else {
666 		tlv_filter = ath11k_mac_mon_status_filter_default;
667 	}
668 
669 	ar->debug.rx_filter = tlv_filter.rx_filter;
670 
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);
676 
677 		if (ret) {
678 			ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
679 			goto exit;
680 		}
681 	}
682 
683 	ar->debug.extd_rx_stats = enable;
684 	ret = count;
685 exit:
686 	mutex_unlock(&ar->conf_mutex);
687 	return ret;
688 }
689 
690 static ssize_t ath11k_read_extd_rx_stats(struct file *file,
691 					 char __user *ubuf,
692 					 size_t count, loff_t *ppos)
693 {
694 	struct ath11k *ar = file->private_data;
695 	char buf[32];
696 	int len = 0;
697 
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);
702 
703 	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
704 }
705 
706 static const struct file_operations fops_extd_rx_stats = {
707 	.read = ath11k_read_extd_rx_stats,
708 	.write = ath11k_write_extd_rx_stats,
709 	.open = simple_open,
710 };
711 
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)
715 {
716 	lockdep_assert_held(&ab->base_lock);
717 
718 	len += scnprintf(buf + len, size - len, "count: %u\n",
719 			 bp_stats->count);
720 	len += scnprintf(buf + len, size - len, "hp: %u\n",
721 			 bp_stats->hp);
722 	len += scnprintf(buf + len, size - len, "tp: %u\n",
723 			 bp_stats->tp);
724 	len += scnprintf(buf + len, size - len, "seen before: %ums\n\n",
725 			 jiffies_to_msecs(jiffies - bp_stats->jiffies));
726 	return len;
727 }
728 
729 static ssize_t ath11k_debugfs_dump_soc_ring_bp_stats(struct ath11k_base *ab,
730 						     char *buf, int size)
731 {
732 	struct ath11k_bp_stats *bp_stats;
733 	bool stats_rxd = false;
734 	u8 i, pdev_idx;
735 	int len = 0;
736 
737 	len += scnprintf(buf + len, size - len, "\nBackpressure Stats\n");
738 	len += scnprintf(buf + len, size - len, "==================\n");
739 
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];
743 
744 		if (!bp_stats->count)
745 			continue;
746 
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);
750 		stats_rxd = true;
751 	}
752 
753 	for (i = 0; i < HTT_SW_LMAC_RING_IDX_MAX; i++) {
754 		for (pdev_idx = 0; pdev_idx < MAX_RADIOS; pdev_idx++) {
755 			bp_stats =
756 				&ab->soc_stats.bp_stats.lmac_ring_bp_stats[i][pdev_idx];
757 
758 			if (!bp_stats->count)
759 				continue;
760 
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",
764 					 pdev_idx);
765 			len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
766 			stats_rxd = true;
767 		}
768 	}
769 	spin_unlock_bh(&ab->base_lock);
770 
771 	if (!stats_rxd)
772 		len += scnprintf(buf + len, size - len,
773 				 "No Ring Backpressure stats received\n\n");
774 
775 	return len;
776 }
777 
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)
781 {
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"};
797 
798 	char *buf;
799 
800 	buf = kzalloc(size, GFP_KERNEL);
801 	if (!buf)
802 		return -ENOMEM;
803 
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]);
813 
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]);
818 
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]);
826 
827 	len += scnprintf(buf + len, size - len, "\nSOC TX STATS:\n");
828 	len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n");
829 
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]);
833 
834 	len += scnprintf(buf + len, size - len,
835 			 "\nMisc Transmit Failures: %d\n",
836 			 atomic_read(&soc_stats->tx_err.misc_fail));
837 
838 	len += ath11k_debugfs_dump_soc_ring_bp_stats(ab, buf + len, size - len);
839 
840 	if (len > size)
841 		len = size;
842 	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
843 	kfree(buf);
844 
845 	return retval;
846 }
847 
848 static const struct file_operations fops_soc_dp_stats = {
849 	.read = ath11k_debugfs_dump_soc_dp_stats,
850 	.open = simple_open,
851 	.owner = THIS_MODULE,
852 	.llseek = default_llseek,
853 };
854 
855 static ssize_t ath11k_write_fw_dbglog(struct file *file,
856 				      const char __user *user_buf,
857 				      size_t count, loff_t *ppos)
858 {
859 	struct ath11k *ar = file->private_data;
860 	char buf[128] = {0};
861 	struct ath11k_fw_dbglog dbglog;
862 	unsigned int param, mod_id_index, is_end;
863 	u64 value;
864 	int ret, num;
865 
866 	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
867 				     user_buf, count);
868 	if (ret <= 0)
869 		return ret;
870 
871 	num = sscanf(buf, "%u %llx %u %u", &param, &value, &mod_id_index, &is_end);
872 
873 	if (num < 2)
874 		return -EINVAL;
875 
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)) {
880 			ret = -EINVAL;
881 			goto out;
882 		}
883 		ar->debug.module_id_bitmap[mod_id_index] = upper_32_bits(value);
884 		if (!is_end) {
885 			ret = count;
886 			goto out;
887 		}
888 	} else {
889 		if (num != 2) {
890 			ret = -EINVAL;
891 			goto out;
892 		}
893 	}
894 
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);
898 	if (ret) {
899 		ath11k_warn(ar->ab, "fw dbglog config failed from debugfs: %d\n",
900 			    ret);
901 		goto out;
902 	}
903 
904 	ret = count;
905 
906 out:
907 	mutex_unlock(&ar->conf_mutex);
908 	return ret;
909 }
910 
911 static const struct file_operations fops_fw_dbglog = {
912 	.write = ath11k_write_fw_dbglog,
913 	.open = simple_open,
914 	.owner = THIS_MODULE,
915 	.llseek = default_llseek,
916 };
917 
918 static int ath11k_open_sram_dump(struct inode *inode, struct file *file)
919 {
920 	struct ath11k_base *ab = inode->i_private;
921 	u8 *buf;
922 	u32 start, end;
923 	int ret;
924 
925 	start = ab->hw_params.sram_dump.start;
926 	end = ab->hw_params.sram_dump.end;
927 
928 	buf = vmalloc(end - start + 1);
929 	if (!buf)
930 		return -ENOMEM;
931 
932 	ret = ath11k_hif_read(ab, buf, start, end);
933 	if (ret) {
934 		ath11k_warn(ab, "failed to dump sram: %d\n", ret);
935 		vfree(buf);
936 		return ret;
937 	}
938 
939 	file->private_data = buf;
940 	return 0;
941 }
942 
943 static ssize_t ath11k_read_sram_dump(struct file *file,
944 				     char __user *user_buf,
945 				     size_t count, loff_t *ppos)
946 {
947 	struct ath11k_base *ab = file->f_inode->i_private;
948 	const char *buf = file->private_data;
949 	int len;
950 	u32 start, end;
951 
952 	start = ab->hw_params.sram_dump.start;
953 	end = ab->hw_params.sram_dump.end;
954 	len = end - start + 1;
955 
956 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
957 }
958 
959 static int ath11k_release_sram_dump(struct inode *inode, struct file *file)
960 {
961 	vfree(file->private_data);
962 	file->private_data = NULL;
963 
964 	return 0;
965 }
966 
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,
973 };
974 
975 int ath11k_debugfs_pdev_create(struct ath11k_base *ab)
976 {
977 	if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
978 		return 0;
979 
980 	debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
981 			    &fops_simulate_fw_crash);
982 
983 	debugfs_create_file("soc_dp_stats", 0400, ab->debugfs_soc, ab,
984 			    &fops_soc_dp_stats);
985 
986 	if (ab->hw_params.sram_dump.start != 0)
987 		debugfs_create_file("sram", 0400, ab->debugfs_soc, ab,
988 				    &fops_sram_dump);
989 
990 	return 0;
991 }
992 
993 void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab)
994 {
995 	debugfs_remove_recursive(ab->debugfs_soc);
996 	ab->debugfs_soc = NULL;
997 }
998 
999 int ath11k_debugfs_soc_create(struct ath11k_base *ab)
1000 {
1001 	struct dentry *root;
1002 	bool dput_needed;
1003 	char name[64];
1004 	int ret;
1005 
1006 	root = debugfs_lookup("ath11k", NULL);
1007 	if (!root) {
1008 		root = debugfs_create_dir("ath11k", NULL);
1009 		if (IS_ERR_OR_NULL(root))
1010 			return PTR_ERR(root);
1011 
1012 		dput_needed = false;
1013 	} else {
1014 		/* a dentry from lookup() needs dput() after we don't use it */
1015 		dput_needed = true;
1016 	}
1017 
1018 	scnprintf(name, sizeof(name), "%s-%s", ath11k_bus_str(ab->hif.bus),
1019 		  dev_name(ab->dev));
1020 
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);
1024 		goto out;
1025 	}
1026 
1027 	ret = 0;
1028 
1029 out:
1030 	if (dput_needed)
1031 		dput(root);
1032 
1033 	return ret;
1034 }
1035 
1036 void ath11k_debugfs_soc_destroy(struct ath11k_base *ab)
1037 {
1038 	debugfs_remove_recursive(ab->debugfs_soc);
1039 	ab->debugfs_soc = NULL;
1040 
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
1044 	 * debugfs.
1045 	 */
1046 }
1047 EXPORT_SYMBOL(ath11k_debugfs_soc_destroy);
1048 
1049 void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
1050 {
1051 	struct dentry *fwstats_dir = debugfs_create_dir("fw_stats",
1052 							ar->debug.debugfs_pdev);
1053 
1054 	ar->fw_stats.debugfs_fwstats = fwstats_dir;
1055 
1056 	/* all stats debugfs files created are under "fw_stats" directory
1057 	 * created per PDEV
1058 	 */
1059 	debugfs_create_file("pdev_stats", 0600, fwstats_dir, ar,
1060 			    &fops_pdev_stats);
1061 	debugfs_create_file("vdev_stats", 0600, fwstats_dir, ar,
1062 			    &fops_vdev_stats);
1063 	debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar,
1064 			    &fops_bcn_stats);
1065 }
1066 
1067 static ssize_t ath11k_write_pktlog_filter(struct file *file,
1068 					  const char __user *ubuf,
1069 					  size_t count, loff_t *ppos)
1070 {
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;
1075 	u8 buf[128] = {0};
1076 	int i, ret, rx_buf_sz = 0;
1077 	ssize_t rc;
1078 
1079 	mutex_lock(&ar->conf_mutex);
1080 	if (ar->state != ATH11K_STATE_ON) {
1081 		ret = -ENETDOWN;
1082 		goto out;
1083 	}
1084 
1085 	rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1086 	if (rc < 0) {
1087 		ret = rc;
1088 		goto out;
1089 	}
1090 	buf[rc] = '\0';
1091 
1092 	ret = sscanf(buf, "0x%x %u", &filter, &mode);
1093 	if (ret != 2) {
1094 		ret = -EINVAL;
1095 		goto out;
1096 	}
1097 
1098 	if (filter) {
1099 		ret = ath11k_wmi_pdev_pktlog_enable(ar, filter);
1100 		if (ret) {
1101 			ath11k_warn(ar->ab,
1102 				    "failed to enable pktlog filter %x: %d\n",
1103 				    ar->debug.pktlog_filter, ret);
1104 			goto out;
1105 		}
1106 	} else {
1107 		ret = ath11k_wmi_pdev_pktlog_disable(ar);
1108 		if (ret) {
1109 			ath11k_warn(ar->ab, "failed to disable pktlog: %d\n", ret);
1110 			goto out;
1111 		}
1112 	}
1113 
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);
1120 		if (ret) {
1121 			ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
1122 			goto out;
1123 		}
1124 	}
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)
1132 
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);
1144 		if (ret) {
1145 			ath11k_err(ar->ab, "failed to enable pktlog lite: %d\n", ret);
1146 			goto out;
1147 		}
1148 
1149 		rx_filter = HTT_RX_FILTER_TLV_LITE_MODE;
1150 		rx_buf_sz = DP_RX_BUFFER_SIZE_LITE;
1151 	} else {
1152 		rx_buf_sz = DP_RX_BUFFER_SIZE;
1153 		tlv_filter = ath11k_mac_mon_status_filter_default;
1154 		rx_filter = tlv_filter.rx_filter;
1155 
1156 		ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
1157 							  HTT_PPDU_STATS_TAG_DEFAULT);
1158 		if (ret) {
1159 			ath11k_err(ar->ab, "failed to send htt ppdu stats req: %d\n",
1160 				   ret);
1161 			goto out;
1162 		}
1163 	}
1164 
1165 	tlv_filter.rx_filter = rx_filter;
1166 	if (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;
1172 	}
1173 
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,
1177 						       ar->dp.mac_id + i,
1178 						       HAL_RXDMA_MONITOR_STATUS,
1179 						       rx_buf_sz, &tlv_filter);
1180 
1181 		if (ret) {
1182 			ath11k_warn(ab, "failed to set rx filter for monitor status ring\n");
1183 			goto out;
1184 		}
1185 	}
1186 
1187 	ath11k_info(ab, "pktlog mode %s\n",
1188 		    ((mode == ATH11K_PKTLOG_MODE_FULL) ? "full" : "lite"));
1189 
1190 	ar->debug.pktlog_filter = filter;
1191 	ar->debug.pktlog_mode = mode;
1192 	ret = count;
1193 
1194 out:
1195 	mutex_unlock(&ar->conf_mutex);
1196 	return ret;
1197 }
1198 
1199 static ssize_t ath11k_read_pktlog_filter(struct file *file,
1200 					 char __user *ubuf,
1201 					 size_t count, loff_t *ppos)
1202 
1203 {
1204 	char buf[32] = {0};
1205 	struct ath11k *ar = file->private_data;
1206 	int len = 0;
1207 
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);
1213 
1214 	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
1215 }
1216 
1217 static const struct file_operations fops_pktlog_filter = {
1218 	.read = ath11k_read_pktlog_filter,
1219 	.write = ath11k_write_pktlog_filter,
1220 	.open = simple_open
1221 };
1222 
1223 static ssize_t ath11k_write_simulate_radar(struct file *file,
1224 					   const char __user *user_buf,
1225 					   size_t count, loff_t *ppos)
1226 {
1227 	struct ath11k *ar = file->private_data;
1228 	int ret;
1229 
1230 	ret = ath11k_wmi_simulate_radar(ar);
1231 	if (ret)
1232 		return ret;
1233 
1234 	return count;
1235 }
1236 
1237 static const struct file_operations fops_simulate_radar = {
1238 	.write = ath11k_write_simulate_radar,
1239 	.open = simple_open
1240 };
1241 
1242 static ssize_t ath11k_debug_dump_dbr_entries(struct file *file,
1243 					     char __user *user_buf,
1244 					     size_t count, loff_t *ppos)
1245 {
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;
1249 	char *buf;
1250 	int i, ret;
1251 	int len = 0;
1252 
1253 	buf = kzalloc(size, GFP_KERNEL);
1254 	if (!buf)
1255 		return -ENOMEM;
1256 
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");
1263 
1264 	spin_lock_bh(&dbr_dbg_data->lock);
1265 
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]);
1273 	}
1274 
1275 	spin_unlock_bh(&dbr_dbg_data->lock);
1276 
1277 	ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1278 	kfree(buf);
1279 
1280 	return ret;
1281 }
1282 
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,
1288 };
1289 
1290 static void ath11k_debugfs_dbr_dbg_destroy(struct ath11k *ar, int dbr_id)
1291 {
1292 	struct ath11k_debug_dbr *dbr_debug;
1293 	struct ath11k_dbg_dbr_data *dbr_dbg_data;
1294 
1295 	if (!ar->debug.dbr_debug[dbr_id])
1296 		return;
1297 
1298 	dbr_debug = ar->debug.dbr_debug[dbr_id];
1299 	dbr_dbg_data = &dbr_debug->dbr_dbg_data;
1300 
1301 	debugfs_remove_recursive(dbr_debug->dbr_debugfs);
1302 	kfree(dbr_dbg_data->entries);
1303 	kfree(dbr_debug);
1304 	ar->debug.dbr_debug[dbr_id] = NULL;
1305 }
1306 
1307 static int ath11k_debugfs_dbr_dbg_init(struct ath11k *ar, int dbr_id)
1308 {
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"};
1312 
1313 	if (ar->debug.dbr_debug[dbr_id])
1314 		return 0;
1315 
1316 	ar->debug.dbr_debug[dbr_id] = kzalloc(sizeof(*dbr_debug),
1317 					      GFP_KERNEL);
1318 
1319 	if (!ar->debug.dbr_debug[dbr_id])
1320 		return -ENOMEM;
1321 
1322 	dbr_debug = ar->debug.dbr_debug[dbr_id];
1323 	dbr_dbg_data = &dbr_debug->dbr_dbg_data;
1324 
1325 	if (dbr_debug->dbr_debugfs)
1326 		return 0;
1327 
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);
1333 		return -ENOMEM;
1334 	}
1335 
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),
1341 					GFP_KERNEL);
1342 	if (!dbr_dbg_data->entries)
1343 		return -ENOMEM;
1344 
1345 	spin_lock_init(&dbr_dbg_data->lock);
1346 
1347 	debugfs_create_file("dump_dbr_debug", 0444, dbr_debug->dbr_debugfs,
1348 			    dbr_dbg_data, &fops_debug_dump_dbr_entries);
1349 
1350 	return 0;
1351 }
1352 
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)
1356 {
1357 	struct ath11k *ar = file->private_data;
1358 	char buf[32] = {0};
1359 	u32 dbr_id, enable;
1360 	int ret;
1361 
1362 	mutex_lock(&ar->conf_mutex);
1363 
1364 	if (ar->state != ATH11K_STATE_ON) {
1365 		ret = -ENETDOWN;
1366 		goto out;
1367 	}
1368 
1369 	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1370 	if (ret < 0)
1371 		goto out;
1372 
1373 	buf[ret] = '\0';
1374 	ret = sscanf(buf, "%u %u", &dbr_id, &enable);
1375 	if (ret != 2 || dbr_id > 1 || enable > 1) {
1376 		ret = -EINVAL;
1377 		ath11k_warn(ar->ab, "usage: echo <dbr_id> <val> dbr_id:0-Spectral 1-CFR val:0-disable 1-enable\n");
1378 		goto out;
1379 	}
1380 
1381 	if (enable) {
1382 		ret = ath11k_debugfs_dbr_dbg_init(ar, dbr_id);
1383 		if (ret) {
1384 			ath11k_warn(ar->ab, "db ring module debugfs init failed: %d\n",
1385 				    ret);
1386 			goto out;
1387 		}
1388 	} else {
1389 		ath11k_debugfs_dbr_dbg_destroy(ar, dbr_id);
1390 	}
1391 
1392 	ret = count;
1393 out:
1394 	mutex_unlock(&ar->conf_mutex);
1395 	return ret;
1396 }
1397 
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,
1403 };
1404 
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)
1408 {
1409 	struct ath11k *ar = file->private_data;
1410 	ssize_t ret;
1411 	u8 ps_timekeeper_enable;
1412 
1413 	if (kstrtou8_from_user(user_buf, count, 0, &ps_timekeeper_enable))
1414 		return -EINVAL;
1415 
1416 	mutex_lock(&ar->conf_mutex);
1417 
1418 	if (ar->state != ATH11K_STATE_ON) {
1419 		ret = -ENETDOWN;
1420 		goto exit;
1421 	}
1422 
1423 	if (!ar->ps_state_enable) {
1424 		ret = -EINVAL;
1425 		goto exit;
1426 	}
1427 
1428 	ar->ps_timekeeper_enable = !!ps_timekeeper_enable;
1429 	ret = count;
1430 exit:
1431 	mutex_unlock(&ar->conf_mutex);
1432 
1433 	return ret;
1434 }
1435 
1436 static ssize_t ath11k_read_ps_timekeeper_enable(struct file *file,
1437 						char __user *user_buf,
1438 						size_t count, loff_t *ppos)
1439 {
1440 	struct ath11k *ar = file->private_data;
1441 	char buf[32];
1442 	int len;
1443 
1444 	mutex_lock(&ar->conf_mutex);
1445 	len = scnprintf(buf, sizeof(buf), "%d\n", ar->ps_timekeeper_enable);
1446 	mutex_unlock(&ar->conf_mutex);
1447 
1448 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1449 }
1450 
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,
1457 };
1458 
1459 static void ath11k_reset_peer_ps_duration(void *data,
1460 					  struct ieee80211_sta *sta)
1461 {
1462 	struct ath11k *ar = data;
1463 	struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
1464 
1465 	spin_lock_bh(&ar->data_lock);
1466 	arsta->ps_total_duration = 0;
1467 	spin_unlock_bh(&ar->data_lock);
1468 }
1469 
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)
1473 {
1474 	struct ath11k *ar = file->private_data;
1475 	int ret;
1476 	u8 reset_ps_duration;
1477 
1478 	if (kstrtou8_from_user(user_buf, count, 0, &reset_ps_duration))
1479 		return -EINVAL;
1480 
1481 	mutex_lock(&ar->conf_mutex);
1482 
1483 	if (ar->state != ATH11K_STATE_ON) {
1484 		ret = -ENETDOWN;
1485 		goto exit;
1486 	}
1487 
1488 	if (!ar->ps_state_enable) {
1489 		ret = -EINVAL;
1490 		goto exit;
1491 	}
1492 
1493 	ieee80211_iterate_stations_atomic(ar->hw,
1494 					  ath11k_reset_peer_ps_duration,
1495 					  ar);
1496 
1497 	ret = count;
1498 exit:
1499 	mutex_unlock(&ar->conf_mutex);
1500 	return ret;
1501 }
1502 
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,
1508 };
1509 
1510 static void ath11k_peer_ps_state_disable(void *data,
1511 					 struct ieee80211_sta *sta)
1512 {
1513 	struct ath11k *ar = data;
1514 	struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
1515 
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);
1521 }
1522 
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)
1526 {
1527 	struct ath11k *ar = file->private_data;
1528 	struct ath11k_pdev *pdev = ar->pdev;
1529 	int ret;
1530 	u32 param;
1531 	u8 ps_state_enable;
1532 
1533 	if (kstrtou8_from_user(user_buf, count, 0, &ps_state_enable))
1534 		return -EINVAL;
1535 
1536 	mutex_lock(&ar->conf_mutex);
1537 
1538 	ps_state_enable = !!ps_state_enable;
1539 
1540 	if (ar->ps_state_enable == ps_state_enable) {
1541 		ret = count;
1542 		goto exit;
1543 	}
1544 
1545 	param = WMI_PDEV_PEER_STA_PS_STATECHG_ENABLE;
1546 	ret = ath11k_wmi_pdev_set_param(ar, param, ps_state_enable, pdev->pdev_id);
1547 	if (ret) {
1548 		ath11k_warn(ar->ab, "failed to enable ps_state_enable: %d\n",
1549 			    ret);
1550 		goto exit;
1551 	}
1552 	ar->ps_state_enable = ps_state_enable;
1553 
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,
1558 						  ar);
1559 	}
1560 
1561 	ret = count;
1562 
1563 exit:
1564 	mutex_unlock(&ar->conf_mutex);
1565 
1566 	return ret;
1567 }
1568 
1569 static ssize_t ath11k_read_ps_state_enable(struct file *file,
1570 					   char __user *user_buf,
1571 					   size_t count, loff_t *ppos)
1572 {
1573 	struct ath11k *ar = file->private_data;
1574 	char buf[32];
1575 	int len;
1576 
1577 	mutex_lock(&ar->conf_mutex);
1578 	len = scnprintf(buf, sizeof(buf), "%d\n", ar->ps_state_enable);
1579 	mutex_unlock(&ar->conf_mutex);
1580 
1581 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1582 }
1583 
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,
1590 };
1591 
1592 int ath11k_debugfs_register(struct ath11k *ar)
1593 {
1594 	struct ath11k_base *ab = ar->ab;
1595 	char pdev_name[10];
1596 	char buf[100] = {0};
1597 
1598 	snprintf(pdev_name, sizeof(pdev_name), "%s%u", "mac", ar->pdev_idx);
1599 
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);
1603 
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);
1607 
1608 	ath11k_debugfs_htt_stats_init(ar);
1609 
1610 	ath11k_debugfs_fw_stats_init(ar);
1611 
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,
1623 			    &fops_fw_dbglog);
1624 
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);
1632 	}
1633 
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);
1637 
1638 	debugfs_create_file("ps_state_enable", 0600, ar->debug.debugfs_pdev, ar,
1639 			    &fops_ps_state_enable);
1640 
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);
1646 
1647 		debugfs_create_file("reset_ps_duration", 0200,
1648 				    ar->debug.debugfs_pdev, ar,
1649 				    &fops_reset_ps_duration);
1650 	}
1651 
1652 	return 0;
1653 }
1654 
1655 void ath11k_debugfs_unregister(struct ath11k *ar)
1656 {
1657 	struct ath11k_debug_dbr *dbr_debug;
1658 	struct ath11k_dbg_dbr_data *dbr_dbg_data;
1659 	int i;
1660 
1661 	for (i = 0; i < WMI_DIRECT_BUF_MAX; i++) {
1662 		dbr_debug = ar->debug.dbr_debug[i];
1663 		if (!dbr_debug)
1664 			continue;
1665 
1666 		dbr_dbg_data = &dbr_debug->dbr_dbg_data;
1667 		kfree(dbr_dbg_data->entries);
1668 		debugfs_remove_recursive(dbr_debug->dbr_debugfs);
1669 		kfree(dbr_debug);
1670 		ar->debug.dbr_debug[i] = NULL;
1671 	}
1672 }
1673 
1674 static ssize_t ath11k_write_twt_add_dialog(struct file *file,
1675 					   const char __user *ubuf,
1676 					   size_t count, loff_t *ppos)
1677 {
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;
1682 	u8 buf[128] = {0};
1683 	int ret;
1684 
1685 	if (ar->twt_enabled == 0) {
1686 		ath11k_err(ar->ab, "twt support is not enabled\n");
1687 		return -EOPNOTSUPP;
1688 	}
1689 
1690 	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1691 	if (ret < 0)
1692 		return ret;
1693 
1694 	buf[ret] = '\0';
1695 	ret = sscanf(buf,
1696 		     "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u %u %u %u %u %hhu %hhu %hhu %hhu %hhu",
1697 		     &params.peer_macaddr[0],
1698 		     &params.peer_macaddr[1],
1699 		     &params.peer_macaddr[2],
1700 		     &params.peer_macaddr[3],
1701 		     &params.peer_macaddr[4],
1702 		     &params.peer_macaddr[5],
1703 		     &params.dialog_id,
1704 		     &params.wake_intvl_us,
1705 		     &params.wake_intvl_mantis,
1706 		     &params.wake_dura_us,
1707 		     &params.sp_offset_us,
1708 		     &params.twt_cmd,
1709 		     &params.flag_bcast,
1710 		     &params.flag_trigger,
1711 		     &params.flag_flow_type,
1712 		     &params.flag_protection);
1713 	if (ret != 16)
1714 		return -EINVAL;
1715 
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.
1722 	 */
1723 	if (arvif->vif->type == NL80211_IFTYPE_STATION) {
1724 		ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
1725 
1726 		ath11k_wmi_fill_default_twt_params(&twt_params);
1727 		twt_params.sta_cong_timer_ms = 0;
1728 
1729 		ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id, &twt_params);
1730 	}
1731 
1732 	params.vdev_id = arvif->vdev_id;
1733 
1734 	ret = ath11k_wmi_send_twt_add_dialog_cmd(arvif->ar, &params);
1735 	if (ret)
1736 		goto err_twt_add_dialog;
1737 
1738 	return count;
1739 
1740 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);
1745 	}
1746 
1747 	return ret;
1748 }
1749 
1750 static ssize_t ath11k_write_twt_del_dialog(struct file *file,
1751 					   const char __user *ubuf,
1752 					   size_t count, loff_t *ppos)
1753 {
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;
1758 	u8 buf[64] = {0};
1759 	int ret;
1760 
1761 	if (ar->twt_enabled == 0) {
1762 		ath11k_err(ar->ab, "twt support is not enabled\n");
1763 		return -EOPNOTSUPP;
1764 	}
1765 
1766 	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1767 	if (ret < 0)
1768 		return ret;
1769 
1770 	buf[ret] = '\0';
1771 	ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u",
1772 		     &params.peer_macaddr[0],
1773 		     &params.peer_macaddr[1],
1774 		     &params.peer_macaddr[2],
1775 		     &params.peer_macaddr[3],
1776 		     &params.peer_macaddr[4],
1777 		     &params.peer_macaddr[5],
1778 		     &params.dialog_id);
1779 	if (ret != 7)
1780 		return -EINVAL;
1781 
1782 	params.vdev_id = arvif->vdev_id;
1783 
1784 	ret = ath11k_wmi_send_twt_del_dialog_cmd(arvif->ar, &params);
1785 	if (ret)
1786 		return ret;
1787 
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);
1792 	}
1793 
1794 	return count;
1795 }
1796 
1797 static ssize_t ath11k_write_twt_pause_dialog(struct file *file,
1798 					     const char __user *ubuf,
1799 					     size_t count, loff_t *ppos)
1800 {
1801 	struct ath11k_vif *arvif = file->private_data;
1802 	struct wmi_twt_pause_dialog_params params = { 0 };
1803 	u8 buf[64] = {0};
1804 	int ret;
1805 
1806 	if (arvif->ar->twt_enabled == 0) {
1807 		ath11k_err(arvif->ar->ab, "twt support is not enabled\n");
1808 		return -EOPNOTSUPP;
1809 	}
1810 
1811 	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1812 	if (ret < 0)
1813 		return ret;
1814 
1815 	buf[ret] = '\0';
1816 	ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u",
1817 		     &params.peer_macaddr[0],
1818 		     &params.peer_macaddr[1],
1819 		     &params.peer_macaddr[2],
1820 		     &params.peer_macaddr[3],
1821 		     &params.peer_macaddr[4],
1822 		     &params.peer_macaddr[5],
1823 		     &params.dialog_id);
1824 	if (ret != 7)
1825 		return -EINVAL;
1826 
1827 	params.vdev_id = arvif->vdev_id;
1828 
1829 	ret = ath11k_wmi_send_twt_pause_dialog_cmd(arvif->ar, &params);
1830 	if (ret)
1831 		return ret;
1832 
1833 	return count;
1834 }
1835 
1836 static ssize_t ath11k_write_twt_resume_dialog(struct file *file,
1837 					      const char __user *ubuf,
1838 					      size_t count, loff_t *ppos)
1839 {
1840 	struct ath11k_vif *arvif = file->private_data;
1841 	struct wmi_twt_resume_dialog_params params = { 0 };
1842 	u8 buf[64] = {0};
1843 	int ret;
1844 
1845 	if (arvif->ar->twt_enabled == 0) {
1846 		ath11k_err(arvif->ar->ab, "twt support is not enabled\n");
1847 		return -EOPNOTSUPP;
1848 	}
1849 
1850 	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
1851 	if (ret < 0)
1852 		return ret;
1853 
1854 	buf[ret] = '\0';
1855 	ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u %u %u",
1856 		     &params.peer_macaddr[0],
1857 		     &params.peer_macaddr[1],
1858 		     &params.peer_macaddr[2],
1859 		     &params.peer_macaddr[3],
1860 		     &params.peer_macaddr[4],
1861 		     &params.peer_macaddr[5],
1862 		     &params.dialog_id,
1863 		     &params.sp_offset_us,
1864 		     &params.next_twt_size);
1865 	if (ret != 9)
1866 		return -EINVAL;
1867 
1868 	params.vdev_id = arvif->vdev_id;
1869 
1870 	ret = ath11k_wmi_send_twt_resume_dialog_cmd(arvif->ar, &params);
1871 	if (ret)
1872 		return ret;
1873 
1874 	return count;
1875 }
1876 
1877 static const struct file_operations ath11k_fops_twt_add_dialog = {
1878 	.write = ath11k_write_twt_add_dialog,
1879 	.open = simple_open
1880 };
1881 
1882 static const struct file_operations ath11k_fops_twt_del_dialog = {
1883 	.write = ath11k_write_twt_del_dialog,
1884 	.open = simple_open
1885 };
1886 
1887 static const struct file_operations ath11k_fops_twt_pause_dialog = {
1888 	.write = ath11k_write_twt_pause_dialog,
1889 	.open = simple_open
1890 };
1891 
1892 static const struct file_operations ath11k_fops_twt_resume_dialog = {
1893 	.write = ath11k_write_twt_resume_dialog,
1894 	.open = simple_open
1895 };
1896 
1897 void ath11k_debugfs_op_vif_add(struct ieee80211_hw *hw,
1898 			       struct ieee80211_vif *vif)
1899 {
1900 	struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
1901 	struct ath11k_base *ab = arvif->ar->ab;
1902 	struct dentry *debugfs_twt;
1903 
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)))
1907 		return;
1908 
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);
1913 
1914 	debugfs_create_file("del_dialog", 0200, debugfs_twt,
1915 			    arvif, &ath11k_fops_twt_del_dialog);
1916 
1917 	debugfs_create_file("pause_dialog", 0200, debugfs_twt,
1918 			    arvif, &ath11k_fops_twt_pause_dialog);
1919 
1920 	debugfs_create_file("resume_dialog", 0200, debugfs_twt,
1921 			    arvif, &ath11k_fops_twt_resume_dialog);
1922 }
1923 
1924