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