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