xref: /linux/drivers/net/wireless/ath/ath11k/debugfs.c (revision b6459415b384cb829f0b2a4268f211c789f6cf0b)
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 
18 static const char *htt_bp_umac_ring[HTT_SW_UMAC_RING_IDX_MAX] = {
19 	"REO2SW1_RING",
20 	"REO2SW2_RING",
21 	"REO2SW3_RING",
22 	"REO2SW4_RING",
23 	"WBM2REO_LINK_RING",
24 	"REO2TCL_RING",
25 	"REO2FW_RING",
26 	"RELEASE_RING",
27 	"PPE_RELEASE_RING",
28 	"TCL2TQM_RING",
29 	"TQM_RELEASE_RING",
30 	"REO_RELEASE_RING",
31 	"WBM2SW0_RELEASE_RING",
32 	"WBM2SW1_RELEASE_RING",
33 	"WBM2SW2_RELEASE_RING",
34 	"WBM2SW3_RELEASE_RING",
35 	"REO_CMD_RING",
36 	"REO_STATUS_RING",
37 };
38 
39 static const char *htt_bp_lmac_ring[HTT_SW_LMAC_RING_IDX_MAX] = {
40 	"FW2RXDMA_BUF_RING",
41 	"FW2RXDMA_STATUS_RING",
42 	"FW2RXDMA_LINK_RING",
43 	"SW2RXDMA_BUF_RING",
44 	"WBM2RXDMA_LINK_RING",
45 	"RXDMA2FW_RING",
46 	"RXDMA2SW_RING",
47 	"RXDMA2RELEASE_RING",
48 	"RXDMA2REO_RING",
49 	"MONITOR_STATUS_RING",
50 	"MONITOR_BUF_RING",
51 	"MONITOR_DESC_RING",
52 	"MONITOR_DEST_RING",
53 };
54 
55 static void ath11k_fw_stats_pdevs_free(struct list_head *head)
56 {
57 	struct ath11k_fw_stats_pdev *i, *tmp;
58 
59 	list_for_each_entry_safe(i, tmp, head, list) {
60 		list_del(&i->list);
61 		kfree(i);
62 	}
63 }
64 
65 static void ath11k_fw_stats_vdevs_free(struct list_head *head)
66 {
67 	struct ath11k_fw_stats_vdev *i, *tmp;
68 
69 	list_for_each_entry_safe(i, tmp, head, list) {
70 		list_del(&i->list);
71 		kfree(i);
72 	}
73 }
74 
75 static void ath11k_fw_stats_bcn_free(struct list_head *head)
76 {
77 	struct ath11k_fw_stats_bcn *i, *tmp;
78 
79 	list_for_each_entry_safe(i, tmp, head, list) {
80 		list_del(&i->list);
81 		kfree(i);
82 	}
83 }
84 
85 static void ath11k_debugfs_fw_stats_reset(struct ath11k *ar)
86 {
87 	spin_lock_bh(&ar->data_lock);
88 	ar->debug.fw_stats_done = false;
89 	ath11k_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs);
90 	ath11k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
91 	spin_unlock_bh(&ar->data_lock);
92 }
93 
94 void ath11k_debugfs_fw_stats_process(struct ath11k_base *ab, struct sk_buff *skb)
95 {
96 	struct ath11k_fw_stats stats = {};
97 	struct ath11k *ar;
98 	struct ath11k_pdev *pdev;
99 	bool is_end;
100 	static unsigned int num_vdev, num_bcn;
101 	size_t total_vdevs_started = 0;
102 	int i, ret;
103 
104 	INIT_LIST_HEAD(&stats.pdevs);
105 	INIT_LIST_HEAD(&stats.vdevs);
106 	INIT_LIST_HEAD(&stats.bcn);
107 
108 	ret = ath11k_wmi_pull_fw_stats(ab, skb, &stats);
109 	if (ret) {
110 		ath11k_warn(ab, "failed to pull fw stats: %d\n", ret);
111 		goto free;
112 	}
113 
114 	rcu_read_lock();
115 	ar = ath11k_mac_get_ar_by_pdev_id(ab, stats.pdev_id);
116 	if (!ar) {
117 		rcu_read_unlock();
118 		ath11k_warn(ab, "failed to get ar for pdev_id %d: %d\n",
119 			    stats.pdev_id, ret);
120 		goto free;
121 	}
122 
123 	spin_lock_bh(&ar->data_lock);
124 
125 	if (stats.stats_id == WMI_REQUEST_PDEV_STAT) {
126 		list_splice_tail_init(&stats.pdevs, &ar->debug.fw_stats.pdevs);
127 		ar->debug.fw_stats_done = true;
128 		goto complete;
129 	}
130 
131 	if (stats.stats_id == WMI_REQUEST_VDEV_STAT) {
132 		if (list_empty(&stats.vdevs)) {
133 			ath11k_warn(ab, "empty vdev stats");
134 			goto complete;
135 		}
136 		/* FW sends all the active VDEV stats irrespective of PDEV,
137 		 * hence limit until the count of all VDEVs started
138 		 */
139 		for (i = 0; i < ab->num_radios; i++) {
140 			pdev = rcu_dereference(ab->pdevs_active[i]);
141 			if (pdev && pdev->ar)
142 				total_vdevs_started += ar->num_started_vdevs;
143 		}
144 
145 		is_end = ((++num_vdev) == total_vdevs_started);
146 
147 		list_splice_tail_init(&stats.vdevs,
148 				      &ar->debug.fw_stats.vdevs);
149 
150 		if (is_end) {
151 			ar->debug.fw_stats_done = true;
152 			num_vdev = 0;
153 		}
154 		goto complete;
155 	}
156 
157 	if (stats.stats_id == WMI_REQUEST_BCN_STAT) {
158 		if (list_empty(&stats.bcn)) {
159 			ath11k_warn(ab, "empty bcn stats");
160 			goto complete;
161 		}
162 		/* Mark end until we reached the count of all started VDEVs
163 		 * within the PDEV
164 		 */
165 		is_end = ((++num_bcn) == ar->num_started_vdevs);
166 
167 		list_splice_tail_init(&stats.bcn,
168 				      &ar->debug.fw_stats.bcn);
169 
170 		if (is_end) {
171 			ar->debug.fw_stats_done = true;
172 			num_bcn = 0;
173 		}
174 	}
175 complete:
176 	complete(&ar->debug.fw_stats_complete);
177 	rcu_read_unlock();
178 	spin_unlock_bh(&ar->data_lock);
179 
180 free:
181 	ath11k_fw_stats_pdevs_free(&stats.pdevs);
182 	ath11k_fw_stats_vdevs_free(&stats.vdevs);
183 	ath11k_fw_stats_bcn_free(&stats.bcn);
184 }
185 
186 static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
187 					   struct stats_request_params *req_param)
188 {
189 	struct ath11k_base *ab = ar->ab;
190 	unsigned long timeout, time_left;
191 	int ret;
192 
193 	lockdep_assert_held(&ar->conf_mutex);
194 
195 	/* FW stats can get split when exceeding the stats data buffer limit.
196 	 * In that case, since there is no end marking for the back-to-back
197 	 * received 'update stats' event, we keep a 3 seconds timeout in case,
198 	 * fw_stats_done is not marked yet
199 	 */
200 	timeout = jiffies + msecs_to_jiffies(3 * 1000);
201 
202 	ath11k_debugfs_fw_stats_reset(ar);
203 
204 	reinit_completion(&ar->debug.fw_stats_complete);
205 
206 	ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);
207 
208 	if (ret) {
209 		ath11k_warn(ab, "could not request fw stats (%d)\n",
210 			    ret);
211 		return ret;
212 	}
213 
214 	time_left =
215 	wait_for_completion_timeout(&ar->debug.fw_stats_complete,
216 				    1 * HZ);
217 	if (!time_left)
218 		return -ETIMEDOUT;
219 
220 	for (;;) {
221 		if (time_after(jiffies, timeout))
222 			break;
223 
224 		spin_lock_bh(&ar->data_lock);
225 		if (ar->debug.fw_stats_done) {
226 			spin_unlock_bh(&ar->data_lock);
227 			break;
228 		}
229 		spin_unlock_bh(&ar->data_lock);
230 	}
231 	return 0;
232 }
233 
234 static int ath11k_open_pdev_stats(struct inode *inode, struct file *file)
235 {
236 	struct ath11k *ar = inode->i_private;
237 	struct ath11k_base *ab = ar->ab;
238 	struct stats_request_params req_param;
239 	void *buf = NULL;
240 	int ret;
241 
242 	mutex_lock(&ar->conf_mutex);
243 
244 	if (ar->state != ATH11K_STATE_ON) {
245 		ret = -ENETDOWN;
246 		goto err_unlock;
247 	}
248 
249 	buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
250 	if (!buf) {
251 		ret = -ENOMEM;
252 		goto err_unlock;
253 	}
254 
255 	req_param.pdev_id = ar->pdev->pdev_id;
256 	req_param.vdev_id = 0;
257 	req_param.stats_id = WMI_REQUEST_PDEV_STAT;
258 
259 	ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
260 	if (ret) {
261 		ath11k_warn(ab, "failed to request fw pdev stats: %d\n", ret);
262 		goto err_free;
263 	}
264 
265 	ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id,
266 				 buf);
267 
268 	file->private_data = buf;
269 
270 	mutex_unlock(&ar->conf_mutex);
271 	return 0;
272 
273 err_free:
274 	vfree(buf);
275 
276 err_unlock:
277 	mutex_unlock(&ar->conf_mutex);
278 	return ret;
279 }
280 
281 static int ath11k_release_pdev_stats(struct inode *inode, struct file *file)
282 {
283 	vfree(file->private_data);
284 
285 	return 0;
286 }
287 
288 static ssize_t ath11k_read_pdev_stats(struct file *file,
289 				      char __user *user_buf,
290 				      size_t count, loff_t *ppos)
291 {
292 	const char *buf = file->private_data;
293 	size_t len = strlen(buf);
294 
295 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
296 }
297 
298 static const struct file_operations fops_pdev_stats = {
299 	.open = ath11k_open_pdev_stats,
300 	.release = ath11k_release_pdev_stats,
301 	.read = ath11k_read_pdev_stats,
302 	.owner = THIS_MODULE,
303 	.llseek = default_llseek,
304 };
305 
306 static int ath11k_open_vdev_stats(struct inode *inode, struct file *file)
307 {
308 	struct ath11k *ar = inode->i_private;
309 	struct stats_request_params req_param;
310 	void *buf = NULL;
311 	int ret;
312 
313 	mutex_lock(&ar->conf_mutex);
314 
315 	if (ar->state != ATH11K_STATE_ON) {
316 		ret = -ENETDOWN;
317 		goto err_unlock;
318 	}
319 
320 	buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
321 	if (!buf) {
322 		ret = -ENOMEM;
323 		goto err_unlock;
324 	}
325 
326 	req_param.pdev_id = ar->pdev->pdev_id;
327 	/* VDEV stats is always sent for all active VDEVs from FW */
328 	req_param.vdev_id = 0;
329 	req_param.stats_id = WMI_REQUEST_VDEV_STAT;
330 
331 	ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
332 	if (ret) {
333 		ath11k_warn(ar->ab, "failed to request fw vdev stats: %d\n", ret);
334 		goto err_free;
335 	}
336 
337 	ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id,
338 				 buf);
339 
340 	file->private_data = buf;
341 
342 	mutex_unlock(&ar->conf_mutex);
343 	return 0;
344 
345 err_free:
346 	vfree(buf);
347 
348 err_unlock:
349 	mutex_unlock(&ar->conf_mutex);
350 	return ret;
351 }
352 
353 static int ath11k_release_vdev_stats(struct inode *inode, struct file *file)
354 {
355 	vfree(file->private_data);
356 
357 	return 0;
358 }
359 
360 static ssize_t ath11k_read_vdev_stats(struct file *file,
361 				      char __user *user_buf,
362 				      size_t count, loff_t *ppos)
363 {
364 	const char *buf = file->private_data;
365 	size_t len = strlen(buf);
366 
367 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
368 }
369 
370 static const struct file_operations fops_vdev_stats = {
371 	.open = ath11k_open_vdev_stats,
372 	.release = ath11k_release_vdev_stats,
373 	.read = ath11k_read_vdev_stats,
374 	.owner = THIS_MODULE,
375 	.llseek = default_llseek,
376 };
377 
378 static int ath11k_open_bcn_stats(struct inode *inode, struct file *file)
379 {
380 	struct ath11k *ar = inode->i_private;
381 	struct ath11k_vif *arvif;
382 	struct stats_request_params req_param;
383 	void *buf = NULL;
384 	int ret;
385 
386 	mutex_lock(&ar->conf_mutex);
387 
388 	if (ar->state != ATH11K_STATE_ON) {
389 		ret = -ENETDOWN;
390 		goto err_unlock;
391 	}
392 
393 	buf = vmalloc(ATH11K_FW_STATS_BUF_SIZE);
394 	if (!buf) {
395 		ret = -ENOMEM;
396 		goto err_unlock;
397 	}
398 
399 	req_param.stats_id = WMI_REQUEST_BCN_STAT;
400 	req_param.pdev_id = ar->pdev->pdev_id;
401 
402 	/* loop all active VDEVs for bcn stats */
403 	list_for_each_entry(arvif, &ar->arvifs, list) {
404 		if (!arvif->is_up)
405 			continue;
406 
407 		req_param.vdev_id = arvif->vdev_id;
408 		ret = ath11k_debugfs_fw_stats_request(ar, &req_param);
409 		if (ret) {
410 			ath11k_warn(ar->ab, "failed to request fw bcn stats: %d\n", ret);
411 			goto err_free;
412 		}
413 	}
414 
415 	ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id,
416 				 buf);
417 
418 	/* since beacon stats request is looped for all active VDEVs, saved fw
419 	 * stats is not freed for each request until done for all active VDEVs
420 	 */
421 	spin_lock_bh(&ar->data_lock);
422 	ath11k_fw_stats_bcn_free(&ar->debug.fw_stats.bcn);
423 	spin_unlock_bh(&ar->data_lock);
424 
425 	file->private_data = buf;
426 
427 	mutex_unlock(&ar->conf_mutex);
428 	return 0;
429 
430 err_free:
431 	vfree(buf);
432 
433 err_unlock:
434 	mutex_unlock(&ar->conf_mutex);
435 	return ret;
436 }
437 
438 static int ath11k_release_bcn_stats(struct inode *inode, struct file *file)
439 {
440 	vfree(file->private_data);
441 
442 	return 0;
443 }
444 
445 static ssize_t ath11k_read_bcn_stats(struct file *file,
446 				     char __user *user_buf,
447 				     size_t count, loff_t *ppos)
448 {
449 	const char *buf = file->private_data;
450 	size_t len = strlen(buf);
451 
452 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
453 }
454 
455 static const struct file_operations fops_bcn_stats = {
456 	.open = ath11k_open_bcn_stats,
457 	.release = ath11k_release_bcn_stats,
458 	.read = ath11k_read_bcn_stats,
459 	.owner = THIS_MODULE,
460 	.llseek = default_llseek,
461 };
462 
463 static ssize_t ath11k_read_simulate_fw_crash(struct file *file,
464 					     char __user *user_buf,
465 					     size_t count, loff_t *ppos)
466 {
467 	const char buf[] =
468 		"To simulate firmware crash write one of the keywords to this file:\n"
469 		"`assert` - this will send WMI_FORCE_FW_HANG_CMDID to firmware to cause assert.\n"
470 		"`hw-restart` - this will simply queue hw restart without fw/hw actually crashing.\n";
471 
472 	return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
473 }
474 
475 /* Simulate firmware crash:
476  * 'soft': Call wmi command causing firmware hang. This firmware hang is
477  * recoverable by warm firmware reset.
478  * 'hard': Force firmware crash by setting any vdev parameter for not allowed
479  * vdev id. This is hard firmware crash because it is recoverable only by cold
480  * firmware reset.
481  */
482 static ssize_t ath11k_write_simulate_fw_crash(struct file *file,
483 					      const char __user *user_buf,
484 					      size_t count, loff_t *ppos)
485 {
486 	struct ath11k_base *ab = file->private_data;
487 	struct ath11k_pdev *pdev;
488 	struct ath11k *ar = ab->pdevs[0].ar;
489 	char buf[32] = {0};
490 	ssize_t rc;
491 	int i, ret, radioup = 0;
492 
493 	for (i = 0; i < ab->num_radios; i++) {
494 		pdev = &ab->pdevs[i];
495 		ar = pdev->ar;
496 		if (ar && ar->state == ATH11K_STATE_ON) {
497 			radioup = 1;
498 			break;
499 		}
500 	}
501 	/* filter partial writes and invalid commands */
502 	if (*ppos != 0 || count >= sizeof(buf) || count == 0)
503 		return -EINVAL;
504 
505 	rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
506 	if (rc < 0)
507 		return rc;
508 
509 	/* drop the possible '\n' from the end */
510 	if (buf[*ppos - 1] == '\n')
511 		buf[*ppos - 1] = '\0';
512 
513 	if (radioup == 0) {
514 		ret = -ENETDOWN;
515 		goto exit;
516 	}
517 
518 	if (!strcmp(buf, "assert")) {
519 		ath11k_info(ab, "simulating firmware assert crash\n");
520 		ret = ath11k_wmi_force_fw_hang_cmd(ar,
521 						   ATH11K_WMI_FW_HANG_ASSERT_TYPE,
522 						   ATH11K_WMI_FW_HANG_DELAY);
523 	} else {
524 		ret = -EINVAL;
525 		goto exit;
526 	}
527 
528 	if (ret) {
529 		ath11k_warn(ab, "failed to simulate firmware crash: %d\n", ret);
530 		goto exit;
531 	}
532 
533 	ret = count;
534 
535 exit:
536 	return ret;
537 }
538 
539 static const struct file_operations fops_simulate_fw_crash = {
540 	.read = ath11k_read_simulate_fw_crash,
541 	.write = ath11k_write_simulate_fw_crash,
542 	.open = simple_open,
543 	.owner = THIS_MODULE,
544 	.llseek = default_llseek,
545 };
546 
547 static ssize_t ath11k_write_enable_extd_tx_stats(struct file *file,
548 						 const char __user *ubuf,
549 						 size_t count, loff_t *ppos)
550 {
551 	struct ath11k *ar = file->private_data;
552 	u32 filter;
553 	int ret;
554 
555 	if (kstrtouint_from_user(ubuf, count, 0, &filter))
556 		return -EINVAL;
557 
558 	mutex_lock(&ar->conf_mutex);
559 
560 	if (ar->state != ATH11K_STATE_ON) {
561 		ret = -ENETDOWN;
562 		goto out;
563 	}
564 
565 	if (filter == ar->debug.extd_tx_stats) {
566 		ret = count;
567 		goto out;
568 	}
569 
570 	ar->debug.extd_tx_stats = filter;
571 	ret = count;
572 
573 out:
574 	mutex_unlock(&ar->conf_mutex);
575 	return ret;
576 }
577 
578 static ssize_t ath11k_read_enable_extd_tx_stats(struct file *file,
579 						char __user *ubuf,
580 						size_t count, loff_t *ppos)
581 
582 {
583 	char buf[32] = {0};
584 	struct ath11k *ar = file->private_data;
585 	int len = 0;
586 
587 	mutex_lock(&ar->conf_mutex);
588 	len = scnprintf(buf, sizeof(buf) - len, "%08x\n",
589 			ar->debug.extd_tx_stats);
590 	mutex_unlock(&ar->conf_mutex);
591 
592 	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
593 }
594 
595 static const struct file_operations fops_extd_tx_stats = {
596 	.read = ath11k_read_enable_extd_tx_stats,
597 	.write = ath11k_write_enable_extd_tx_stats,
598 	.open = simple_open
599 };
600 
601 static ssize_t ath11k_write_extd_rx_stats(struct file *file,
602 					  const char __user *ubuf,
603 					  size_t count, loff_t *ppos)
604 {
605 	struct ath11k *ar = file->private_data;
606 	struct ath11k_base *ab = ar->ab;
607 	struct htt_rx_ring_tlv_filter tlv_filter = {0};
608 	u32 enable, rx_filter = 0, ring_id;
609 	int i;
610 	int ret;
611 
612 	if (kstrtouint_from_user(ubuf, count, 0, &enable))
613 		return -EINVAL;
614 
615 	mutex_lock(&ar->conf_mutex);
616 
617 	if (ar->state != ATH11K_STATE_ON) {
618 		ret = -ENETDOWN;
619 		goto exit;
620 	}
621 
622 	if (enable > 1) {
623 		ret = -EINVAL;
624 		goto exit;
625 	}
626 
627 	if (enable == ar->debug.extd_rx_stats) {
628 		ret = count;
629 		goto exit;
630 	}
631 
632 	if (enable) {
633 		rx_filter =  HTT_RX_FILTER_TLV_FLAGS_MPDU_START;
634 		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_START;
635 		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END;
636 		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS;
637 		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT;
638 		rx_filter |= HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE;
639 
640 		tlv_filter.rx_filter = rx_filter;
641 		tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
642 		tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
643 		tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
644 		tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
645 			HTT_RX_FP_DATA_FILTER_FLASG3;
646 	} else {
647 		tlv_filter = ath11k_mac_mon_status_filter_default;
648 	}
649 
650 	ar->debug.rx_filter = tlv_filter.rx_filter;
651 
652 	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
653 		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
654 		ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
655 						       HAL_RXDMA_MONITOR_STATUS,
656 						       DP_RX_BUFFER_SIZE, &tlv_filter);
657 
658 		if (ret) {
659 			ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
660 			goto exit;
661 		}
662 	}
663 
664 	ar->debug.extd_rx_stats = enable;
665 	ret = count;
666 exit:
667 	mutex_unlock(&ar->conf_mutex);
668 	return ret;
669 }
670 
671 static ssize_t ath11k_read_extd_rx_stats(struct file *file,
672 					 char __user *ubuf,
673 					 size_t count, loff_t *ppos)
674 {
675 	struct ath11k *ar = file->private_data;
676 	char buf[32];
677 	int len = 0;
678 
679 	mutex_lock(&ar->conf_mutex);
680 	len = scnprintf(buf, sizeof(buf) - len, "%d\n",
681 			ar->debug.extd_rx_stats);
682 	mutex_unlock(&ar->conf_mutex);
683 
684 	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
685 }
686 
687 static const struct file_operations fops_extd_rx_stats = {
688 	.read = ath11k_read_extd_rx_stats,
689 	.write = ath11k_write_extd_rx_stats,
690 	.open = simple_open,
691 };
692 
693 static int ath11k_fill_bp_stats(struct ath11k_base *ab,
694 				struct ath11k_bp_stats *bp_stats,
695 				char *buf, int len, int size)
696 {
697 	lockdep_assert_held(&ab->base_lock);
698 
699 	len += scnprintf(buf + len, size - len, "count: %u\n",
700 			 bp_stats->count);
701 	len += scnprintf(buf + len, size - len, "hp: %u\n",
702 			 bp_stats->hp);
703 	len += scnprintf(buf + len, size - len, "tp: %u\n",
704 			 bp_stats->tp);
705 	len += scnprintf(buf + len, size - len, "seen before: %ums\n\n",
706 			 jiffies_to_msecs(jiffies - bp_stats->jiffies));
707 	return len;
708 }
709 
710 static ssize_t ath11k_debugfs_dump_soc_ring_bp_stats(struct ath11k_base *ab,
711 						     char *buf, int size)
712 {
713 	struct ath11k_bp_stats *bp_stats;
714 	bool stats_rxd = false;
715 	u8 i, pdev_idx;
716 	int len = 0;
717 
718 	len += scnprintf(buf + len, size - len, "\nBackpressure Stats\n");
719 	len += scnprintf(buf + len, size - len, "==================\n");
720 
721 	spin_lock_bh(&ab->base_lock);
722 	for (i = 0; i < HTT_SW_UMAC_RING_IDX_MAX; i++) {
723 		bp_stats = &ab->soc_stats.bp_stats.umac_ring_bp_stats[i];
724 
725 		if (!bp_stats->count)
726 			continue;
727 
728 		len += scnprintf(buf + len, size - len, "Ring: %s\n",
729 				 htt_bp_umac_ring[i]);
730 		len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
731 		stats_rxd = true;
732 	}
733 
734 	for (i = 0; i < HTT_SW_LMAC_RING_IDX_MAX; i++) {
735 		for (pdev_idx = 0; pdev_idx < MAX_RADIOS; pdev_idx++) {
736 			bp_stats =
737 				&ab->soc_stats.bp_stats.lmac_ring_bp_stats[i][pdev_idx];
738 
739 			if (!bp_stats->count)
740 				continue;
741 
742 			len += scnprintf(buf + len, size - len, "Ring: %s\n",
743 					 htt_bp_lmac_ring[i]);
744 			len += scnprintf(buf + len, size - len, "pdev: %d\n",
745 					 pdev_idx);
746 			len = ath11k_fill_bp_stats(ab, bp_stats, buf, len, size);
747 			stats_rxd = true;
748 		}
749 	}
750 	spin_unlock_bh(&ab->base_lock);
751 
752 	if (!stats_rxd)
753 		len += scnprintf(buf + len, size - len,
754 				 "No Ring Backpressure stats received\n\n");
755 
756 	return len;
757 }
758 
759 static ssize_t ath11k_debugfs_dump_soc_dp_stats(struct file *file,
760 						char __user *user_buf,
761 						size_t count, loff_t *ppos)
762 {
763 	struct ath11k_base *ab = file->private_data;
764 	struct ath11k_soc_dp_stats *soc_stats = &ab->soc_stats;
765 	int len = 0, i, retval;
766 	const int size = 4096;
767 	static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = {
768 			"Overflow", "MPDU len", "FCS", "Decrypt", "TKIP MIC",
769 			"Unencrypt", "MSDU len", "MSDU limit", "WiFi parse",
770 			"AMSDU parse", "SA timeout", "DA timeout",
771 			"Flow timeout", "Flush req"};
772 	static const char *reo_err[HAL_REO_DEST_RING_ERROR_CODE_MAX] = {
773 			"Desc addr zero", "Desc inval", "AMPDU in non BA",
774 			"Non BA dup", "BA dup", "Frame 2k jump", "BAR 2k jump",
775 			"Frame OOR", "BAR OOR", "No BA session",
776 			"Frame SN equal SSN", "PN check fail", "2k err",
777 			"PN err", "Desc blocked"};
778 
779 	char *buf;
780 
781 	buf = kzalloc(size, GFP_KERNEL);
782 	if (!buf)
783 		return -ENOMEM;
784 
785 	len += scnprintf(buf + len, size - len, "SOC RX STATS:\n\n");
786 	len += scnprintf(buf + len, size - len, "err ring pkts: %u\n",
787 			 soc_stats->err_ring_pkts);
788 	len += scnprintf(buf + len, size - len, "Invalid RBM: %u\n\n",
789 			 soc_stats->invalid_rbm);
790 	len += scnprintf(buf + len, size - len, "RXDMA errors:\n");
791 	for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++)
792 		len += scnprintf(buf + len, size - len, "%s: %u\n",
793 				 rxdma_err[i], soc_stats->rxdma_error[i]);
794 
795 	len += scnprintf(buf + len, size - len, "\nREO errors:\n");
796 	for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++)
797 		len += scnprintf(buf + len, size - len, "%s: %u\n",
798 				 reo_err[i], soc_stats->reo_error[i]);
799 
800 	len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n");
801 	len += scnprintf(buf + len, size - len,
802 			 "ring0: %u\nring1: %u\nring2: %u\nring3: %u\n",
803 			 soc_stats->hal_reo_error[0],
804 			 soc_stats->hal_reo_error[1],
805 			 soc_stats->hal_reo_error[2],
806 			 soc_stats->hal_reo_error[3]);
807 
808 	len += scnprintf(buf + len, size - len, "\nSOC TX STATS:\n");
809 	len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n");
810 
811 	for (i = 0; i < ab->hw_params.max_tx_ring; i++)
812 		len += scnprintf(buf + len, size - len, "ring%d: %u\n",
813 				 i, soc_stats->tx_err.desc_na[i]);
814 
815 	len += scnprintf(buf + len, size - len,
816 			 "\nMisc Transmit Failures: %d\n",
817 			 atomic_read(&soc_stats->tx_err.misc_fail));
818 
819 	len += ath11k_debugfs_dump_soc_ring_bp_stats(ab, buf + len, size - len);
820 
821 	if (len > size)
822 		len = size;
823 	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
824 	kfree(buf);
825 
826 	return retval;
827 }
828 
829 static const struct file_operations fops_soc_dp_stats = {
830 	.read = ath11k_debugfs_dump_soc_dp_stats,
831 	.open = simple_open,
832 	.owner = THIS_MODULE,
833 	.llseek = default_llseek,
834 };
835 
836 int ath11k_debugfs_pdev_create(struct ath11k_base *ab)
837 {
838 	if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
839 		return 0;
840 
841 	ab->debugfs_soc = debugfs_create_dir(ab->hw_params.name, ab->debugfs_ath11k);
842 	if (IS_ERR(ab->debugfs_soc))
843 		return PTR_ERR(ab->debugfs_soc);
844 
845 	debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
846 			    &fops_simulate_fw_crash);
847 
848 	debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab,
849 			    &fops_soc_dp_stats);
850 
851 	return 0;
852 }
853 
854 void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab)
855 {
856 	debugfs_remove_recursive(ab->debugfs_soc);
857 	ab->debugfs_soc = NULL;
858 }
859 
860 int ath11k_debugfs_soc_create(struct ath11k_base *ab)
861 {
862 	ab->debugfs_ath11k = debugfs_create_dir("ath11k", NULL);
863 
864 	return PTR_ERR_OR_ZERO(ab->debugfs_ath11k);
865 }
866 
867 void ath11k_debugfs_soc_destroy(struct ath11k_base *ab)
868 {
869 	debugfs_remove_recursive(ab->debugfs_ath11k);
870 	ab->debugfs_ath11k = NULL;
871 }
872 EXPORT_SYMBOL(ath11k_debugfs_soc_destroy);
873 
874 void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
875 {
876 	struct dentry *fwstats_dir = debugfs_create_dir("fw_stats",
877 							ar->debug.debugfs_pdev);
878 
879 	ar->debug.fw_stats.debugfs_fwstats = fwstats_dir;
880 
881 	/* all stats debugfs files created are under "fw_stats" directory
882 	 * created per PDEV
883 	 */
884 	debugfs_create_file("pdev_stats", 0600, fwstats_dir, ar,
885 			    &fops_pdev_stats);
886 	debugfs_create_file("vdev_stats", 0600, fwstats_dir, ar,
887 			    &fops_vdev_stats);
888 	debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar,
889 			    &fops_bcn_stats);
890 
891 	INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs);
892 	INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs);
893 	INIT_LIST_HEAD(&ar->debug.fw_stats.bcn);
894 
895 	init_completion(&ar->debug.fw_stats_complete);
896 }
897 
898 static ssize_t ath11k_write_pktlog_filter(struct file *file,
899 					  const char __user *ubuf,
900 					  size_t count, loff_t *ppos)
901 {
902 	struct ath11k *ar = file->private_data;
903 	struct ath11k_base *ab = ar->ab;
904 	struct htt_rx_ring_tlv_filter tlv_filter = {0};
905 	u32 rx_filter = 0, ring_id, filter, mode;
906 	u8 buf[128] = {0};
907 	int i, ret, rx_buf_sz = 0;
908 	ssize_t rc;
909 
910 	mutex_lock(&ar->conf_mutex);
911 	if (ar->state != ATH11K_STATE_ON) {
912 		ret = -ENETDOWN;
913 		goto out;
914 	}
915 
916 	rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
917 	if (rc < 0) {
918 		ret = rc;
919 		goto out;
920 	}
921 	buf[rc] = '\0';
922 
923 	ret = sscanf(buf, "0x%x %u", &filter, &mode);
924 	if (ret != 2) {
925 		ret = -EINVAL;
926 		goto out;
927 	}
928 
929 	if (filter) {
930 		ret = ath11k_wmi_pdev_pktlog_enable(ar, filter);
931 		if (ret) {
932 			ath11k_warn(ar->ab,
933 				    "failed to enable pktlog filter %x: %d\n",
934 				    ar->debug.pktlog_filter, ret);
935 			goto out;
936 		}
937 	} else {
938 		ret = ath11k_wmi_pdev_pktlog_disable(ar);
939 		if (ret) {
940 			ath11k_warn(ar->ab, "failed to disable pktlog: %d\n", ret);
941 			goto out;
942 		}
943 	}
944 
945 	/* Clear rx filter set for monitor mode and rx status */
946 	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
947 		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
948 		ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
949 						       HAL_RXDMA_MONITOR_STATUS,
950 						       rx_buf_sz, &tlv_filter);
951 		if (ret) {
952 			ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
953 			goto out;
954 		}
955 	}
956 #define HTT_RX_FILTER_TLV_LITE_MODE \
957 			(HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
958 			HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
959 			HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS | \
960 			HTT_RX_FILTER_TLV_FLAGS_PPDU_END_USER_STATS_EXT | \
961 			HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE | \
962 			HTT_RX_FILTER_TLV_FLAGS_MPDU_START)
963 
964 	if (mode == ATH11K_PKTLOG_MODE_FULL) {
965 		rx_filter = HTT_RX_FILTER_TLV_LITE_MODE |
966 			    HTT_RX_FILTER_TLV_FLAGS_MSDU_START |
967 			    HTT_RX_FILTER_TLV_FLAGS_MSDU_END |
968 			    HTT_RX_FILTER_TLV_FLAGS_MPDU_END |
969 			    HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER |
970 			    HTT_RX_FILTER_TLV_FLAGS_ATTENTION;
971 		rx_buf_sz = DP_RX_BUFFER_SIZE;
972 	} else if (mode == ATH11K_PKTLOG_MODE_LITE) {
973 		ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
974 							  HTT_PPDU_STATS_TAG_PKTLOG);
975 		if (ret) {
976 			ath11k_err(ar->ab, "failed to enable pktlog lite: %d\n", ret);
977 			goto out;
978 		}
979 
980 		rx_filter = HTT_RX_FILTER_TLV_LITE_MODE;
981 		rx_buf_sz = DP_RX_BUFFER_SIZE_LITE;
982 	} else {
983 		rx_buf_sz = DP_RX_BUFFER_SIZE;
984 		tlv_filter = ath11k_mac_mon_status_filter_default;
985 		rx_filter = tlv_filter.rx_filter;
986 
987 		ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
988 							  HTT_PPDU_STATS_TAG_DEFAULT);
989 		if (ret) {
990 			ath11k_err(ar->ab, "failed to send htt ppdu stats req: %d\n",
991 				   ret);
992 			goto out;
993 		}
994 	}
995 
996 	tlv_filter.rx_filter = rx_filter;
997 	if (rx_filter) {
998 		tlv_filter.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0;
999 		tlv_filter.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1;
1000 		tlv_filter.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2;
1001 		tlv_filter.pkt_filter_flags3 = HTT_RX_FP_CTRL_FILTER_FLASG3 |
1002 					       HTT_RX_FP_DATA_FILTER_FLASG3;
1003 	}
1004 
1005 	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
1006 		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
1007 		ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id,
1008 						       ar->dp.mac_id + i,
1009 						       HAL_RXDMA_MONITOR_STATUS,
1010 						       rx_buf_sz, &tlv_filter);
1011 
1012 		if (ret) {
1013 			ath11k_warn(ab, "failed to set rx filter for monitor status ring\n");
1014 			goto out;
1015 		}
1016 	}
1017 
1018 	ath11k_info(ab, "pktlog mode %s\n",
1019 		    ((mode == ATH11K_PKTLOG_MODE_FULL) ? "full" : "lite"));
1020 
1021 	ar->debug.pktlog_filter = filter;
1022 	ar->debug.pktlog_mode = mode;
1023 	ret = count;
1024 
1025 out:
1026 	mutex_unlock(&ar->conf_mutex);
1027 	return ret;
1028 }
1029 
1030 static ssize_t ath11k_read_pktlog_filter(struct file *file,
1031 					 char __user *ubuf,
1032 					 size_t count, loff_t *ppos)
1033 
1034 {
1035 	char buf[32] = {0};
1036 	struct ath11k *ar = file->private_data;
1037 	int len = 0;
1038 
1039 	mutex_lock(&ar->conf_mutex);
1040 	len = scnprintf(buf, sizeof(buf) - len, "%08x %08x\n",
1041 			ar->debug.pktlog_filter,
1042 			ar->debug.pktlog_mode);
1043 	mutex_unlock(&ar->conf_mutex);
1044 
1045 	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
1046 }
1047 
1048 static const struct file_operations fops_pktlog_filter = {
1049 	.read = ath11k_read_pktlog_filter,
1050 	.write = ath11k_write_pktlog_filter,
1051 	.open = simple_open
1052 };
1053 
1054 static ssize_t ath11k_write_simulate_radar(struct file *file,
1055 					   const char __user *user_buf,
1056 					   size_t count, loff_t *ppos)
1057 {
1058 	struct ath11k *ar = file->private_data;
1059 	int ret;
1060 
1061 	ret = ath11k_wmi_simulate_radar(ar);
1062 	if (ret)
1063 		return ret;
1064 
1065 	return count;
1066 }
1067 
1068 static const struct file_operations fops_simulate_radar = {
1069 	.write = ath11k_write_simulate_radar,
1070 	.open = simple_open
1071 };
1072 
1073 int ath11k_debugfs_register(struct ath11k *ar)
1074 {
1075 	struct ath11k_base *ab = ar->ab;
1076 	char pdev_name[5];
1077 	char buf[100] = {0};
1078 
1079 	snprintf(pdev_name, sizeof(pdev_name), "%s%d", "mac", ar->pdev_idx);
1080 
1081 	ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc);
1082 	if (IS_ERR(ar->debug.debugfs_pdev))
1083 		return PTR_ERR(ar->debug.debugfs_pdev);
1084 
1085 	/* Create a symlink under ieee80211/phy* */
1086 	snprintf(buf, 100, "../../ath11k/%pd2", ar->debug.debugfs_pdev);
1087 	debugfs_create_symlink("ath11k", ar->hw->wiphy->debugfsdir, buf);
1088 
1089 	ath11k_debugfs_htt_stats_init(ar);
1090 
1091 	ath11k_debugfs_fw_stats_init(ar);
1092 
1093 	debugfs_create_file("ext_tx_stats", 0644,
1094 			    ar->debug.debugfs_pdev, ar,
1095 			    &fops_extd_tx_stats);
1096 	debugfs_create_file("ext_rx_stats", 0644,
1097 			    ar->debug.debugfs_pdev, ar,
1098 			    &fops_extd_rx_stats);
1099 	debugfs_create_file("pktlog_filter", 0644,
1100 			    ar->debug.debugfs_pdev, ar,
1101 			    &fops_pktlog_filter);
1102 
1103 	if (ar->hw->wiphy->bands[NL80211_BAND_5GHZ]) {
1104 		debugfs_create_file("dfs_simulate_radar", 0200,
1105 				    ar->debug.debugfs_pdev, ar,
1106 				    &fops_simulate_radar);
1107 		debugfs_create_bool("dfs_block_radar_events", 0200,
1108 				    ar->debug.debugfs_pdev,
1109 				    &ar->dfs_block_radar_events);
1110 	}
1111 
1112 	return 0;
1113 }
1114 
1115 void ath11k_debugfs_unregister(struct ath11k *ar)
1116 {
1117 }
1118