1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2/* Copyright(c) 2019-2020  Realtek Corporation
3 */
4
5#include <linux/vmalloc.h>
6
7#include "coex.h"
8#include "debug.h"
9#include "fw.h"
10#include "mac.h"
11#include "pci.h"
12#include "ps.h"
13#include "reg.h"
14#include "sar.h"
15
16#ifdef CONFIG_RTW89_DEBUGMSG
17unsigned int rtw89_debug_mask;
18EXPORT_SYMBOL(rtw89_debug_mask);
19module_param_named(debug_mask, rtw89_debug_mask, uint, 0644);
20MODULE_PARM_DESC(debug_mask, "Debugging mask");
21#endif
22
23#ifdef CONFIG_RTW89_DEBUGFS
24struct rtw89_debugfs_priv {
25	struct rtw89_dev *rtwdev;
26	int (*cb_read)(struct seq_file *m, void *v);
27	ssize_t (*cb_write)(struct file *filp, const char __user *buffer,
28			    size_t count, loff_t *loff);
29	union {
30		u32 cb_data;
31		struct {
32			u32 addr;
33			u32 len;
34		} read_reg;
35		struct {
36			u32 addr;
37			u32 mask;
38			u8 path;
39		} read_rf;
40		struct {
41			u8 ss_dbg:1;
42			u8 dle_dbg:1;
43			u8 dmac_dbg:1;
44			u8 cmac_dbg:1;
45			u8 dbg_port:1;
46		} dbgpkg_en;
47		struct {
48			u32 start;
49			u32 len;
50			u8 sel;
51		} mac_mem;
52	};
53};
54
55static const u16 rtw89_rate_info_bw_to_mhz_map[] = {
56	[RATE_INFO_BW_20] = 20,
57	[RATE_INFO_BW_40] = 40,
58	[RATE_INFO_BW_80] = 80,
59	[RATE_INFO_BW_160] = 160,
60	[RATE_INFO_BW_320] = 320,
61};
62
63static u16 rtw89_rate_info_bw_to_mhz(enum rate_info_bw bw)
64{
65	if (bw < ARRAY_SIZE(rtw89_rate_info_bw_to_mhz_map))
66		return rtw89_rate_info_bw_to_mhz_map[bw];
67
68	return 0;
69}
70
71static int rtw89_debugfs_single_show(struct seq_file *m, void *v)
72{
73	struct rtw89_debugfs_priv *debugfs_priv = m->private;
74
75	return debugfs_priv->cb_read(m, v);
76}
77
78static ssize_t rtw89_debugfs_single_write(struct file *filp,
79					  const char __user *buffer,
80					  size_t count, loff_t *loff)
81{
82	struct rtw89_debugfs_priv *debugfs_priv = filp->private_data;
83
84	return debugfs_priv->cb_write(filp, buffer, count, loff);
85}
86
87static ssize_t rtw89_debugfs_seq_file_write(struct file *filp,
88					    const char __user *buffer,
89					    size_t count, loff_t *loff)
90{
91	struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
92	struct rtw89_debugfs_priv *debugfs_priv = seqpriv->private;
93
94	return debugfs_priv->cb_write(filp, buffer, count, loff);
95}
96
97static int rtw89_debugfs_single_open(struct inode *inode, struct file *filp)
98{
99	return single_open(filp, rtw89_debugfs_single_show, inode->i_private);
100}
101
102static int rtw89_debugfs_close(struct inode *inode, struct file *filp)
103{
104	return 0;
105}
106
107static const struct file_operations file_ops_single_r = {
108	.owner = THIS_MODULE,
109	.open = rtw89_debugfs_single_open,
110	.read = seq_read,
111	.llseek = seq_lseek,
112	.release = single_release,
113};
114
115static const struct file_operations file_ops_common_rw = {
116	.owner = THIS_MODULE,
117	.open = rtw89_debugfs_single_open,
118	.release = single_release,
119	.read = seq_read,
120	.llseek = seq_lseek,
121	.write = rtw89_debugfs_seq_file_write,
122};
123
124static const struct file_operations file_ops_single_w = {
125	.owner = THIS_MODULE,
126	.write = rtw89_debugfs_single_write,
127	.open = simple_open,
128	.release = rtw89_debugfs_close,
129};
130
131static ssize_t
132rtw89_debug_priv_read_reg_select(struct file *filp,
133				 const char __user *user_buf,
134				 size_t count, loff_t *loff)
135{
136	struct seq_file *m = (struct seq_file *)filp->private_data;
137	struct rtw89_debugfs_priv *debugfs_priv = m->private;
138	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
139	char buf[32];
140	size_t buf_size;
141	u32 addr, len;
142	int num;
143
144	buf_size = min(count, sizeof(buf) - 1);
145	if (copy_from_user(buf, user_buf, buf_size))
146		return -EFAULT;
147
148	buf[buf_size] = '\0';
149	num = sscanf(buf, "%x %x", &addr, &len);
150	if (num != 2) {
151		rtw89_info(rtwdev, "invalid format: <addr> <len>\n");
152		return -EINVAL;
153	}
154
155	debugfs_priv->read_reg.addr = addr;
156	debugfs_priv->read_reg.len = len;
157
158	rtw89_info(rtwdev, "select read %d bytes from 0x%08x\n", len, addr);
159
160	return count;
161}
162
163static int rtw89_debug_priv_read_reg_get(struct seq_file *m, void *v)
164{
165	struct rtw89_debugfs_priv *debugfs_priv = m->private;
166	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
167	u32 addr, end, data, k;
168	u32 len;
169
170	len = debugfs_priv->read_reg.len;
171	addr = debugfs_priv->read_reg.addr;
172
173	if (len > 4)
174		goto ndata;
175
176	switch (len) {
177	case 1:
178		data = rtw89_read8(rtwdev, addr);
179		break;
180	case 2:
181		data = rtw89_read16(rtwdev, addr);
182		break;
183	case 4:
184		data = rtw89_read32(rtwdev, addr);
185		break;
186	default:
187		rtw89_info(rtwdev, "invalid read reg len %d\n", len);
188		return -EINVAL;
189	}
190
191	seq_printf(m, "get %d bytes at 0x%08x=0x%08x\n", len, addr, data);
192
193	return 0;
194
195ndata:
196	end = addr + len;
197
198	for (; addr < end; addr += 16) {
199		seq_printf(m, "%08xh : ", 0x18600000 + addr);
200		for (k = 0; k < 16; k += 4) {
201			data = rtw89_read32(rtwdev, addr + k);
202			seq_printf(m, "%08x ", data);
203		}
204		seq_puts(m, "\n");
205	}
206
207	return 0;
208}
209
210static ssize_t rtw89_debug_priv_write_reg_set(struct file *filp,
211					      const char __user *user_buf,
212					      size_t count, loff_t *loff)
213{
214	struct rtw89_debugfs_priv *debugfs_priv = filp->private_data;
215	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
216	char buf[32];
217	size_t buf_size;
218	u32 addr, val, len;
219	int num;
220
221	buf_size = min(count, sizeof(buf) - 1);
222	if (copy_from_user(buf, user_buf, buf_size))
223		return -EFAULT;
224
225	buf[buf_size] = '\0';
226	num = sscanf(buf, "%x %x %x", &addr, &val, &len);
227	if (num !=  3) {
228		rtw89_info(rtwdev, "invalid format: <addr> <val> <len>\n");
229		return -EINVAL;
230	}
231
232	switch (len) {
233	case 1:
234		rtw89_info(rtwdev, "reg write8 0x%08x: 0x%02x\n", addr, val);
235		rtw89_write8(rtwdev, addr, (u8)val);
236		break;
237	case 2:
238		rtw89_info(rtwdev, "reg write16 0x%08x: 0x%04x\n", addr, val);
239		rtw89_write16(rtwdev, addr, (u16)val);
240		break;
241	case 4:
242		rtw89_info(rtwdev, "reg write32 0x%08x: 0x%08x\n", addr, val);
243		rtw89_write32(rtwdev, addr, (u32)val);
244		break;
245	default:
246		rtw89_info(rtwdev, "invalid read write len %d\n", len);
247		break;
248	}
249
250	return count;
251}
252
253static ssize_t
254rtw89_debug_priv_read_rf_select(struct file *filp,
255				const char __user *user_buf,
256				size_t count, loff_t *loff)
257{
258	struct seq_file *m = (struct seq_file *)filp->private_data;
259	struct rtw89_debugfs_priv *debugfs_priv = m->private;
260	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
261	char buf[32];
262	size_t buf_size;
263	u32 addr, mask;
264	u8 path;
265	int num;
266
267	buf_size = min(count, sizeof(buf) - 1);
268	if (copy_from_user(buf, user_buf, buf_size))
269		return -EFAULT;
270
271	buf[buf_size] = '\0';
272	num = sscanf(buf, "%hhd %x %x", &path, &addr, &mask);
273	if (num != 3) {
274		rtw89_info(rtwdev, "invalid format: <path> <addr> <mask>\n");
275		return -EINVAL;
276	}
277
278	if (path >= rtwdev->chip->rf_path_num) {
279		rtw89_info(rtwdev, "wrong rf path\n");
280		return -EINVAL;
281	}
282	debugfs_priv->read_rf.addr = addr;
283	debugfs_priv->read_rf.mask = mask;
284	debugfs_priv->read_rf.path = path;
285
286	rtw89_info(rtwdev, "select read rf path %d from 0x%08x\n", path, addr);
287
288	return count;
289}
290
291static int rtw89_debug_priv_read_rf_get(struct seq_file *m, void *v)
292{
293	struct rtw89_debugfs_priv *debugfs_priv = m->private;
294	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
295	u32 addr, data, mask;
296	u8 path;
297
298	addr = debugfs_priv->read_rf.addr;
299	mask = debugfs_priv->read_rf.mask;
300	path = debugfs_priv->read_rf.path;
301
302	data = rtw89_read_rf(rtwdev, path, addr, mask);
303
304	seq_printf(m, "path %d, rf register 0x%08x=0x%08x\n", path, addr, data);
305
306	return 0;
307}
308
309static ssize_t rtw89_debug_priv_write_rf_set(struct file *filp,
310					     const char __user *user_buf,
311					     size_t count, loff_t *loff)
312{
313	struct rtw89_debugfs_priv *debugfs_priv = filp->private_data;
314	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
315	char buf[32];
316	size_t buf_size;
317	u32 addr, val, mask;
318	u8 path;
319	int num;
320
321	buf_size = min(count, sizeof(buf) - 1);
322	if (copy_from_user(buf, user_buf, buf_size))
323		return -EFAULT;
324
325	buf[buf_size] = '\0';
326	num = sscanf(buf, "%hhd %x %x %x", &path, &addr, &mask, &val);
327	if (num != 4) {
328		rtw89_info(rtwdev, "invalid format: <path> <addr> <mask> <val>\n");
329		return -EINVAL;
330	}
331
332	if (path >= rtwdev->chip->rf_path_num) {
333		rtw89_info(rtwdev, "wrong rf path\n");
334		return -EINVAL;
335	}
336
337	rtw89_info(rtwdev, "path %d, rf register write 0x%08x=0x%08x (mask = 0x%08x)\n",
338		   path, addr, val, mask);
339	rtw89_write_rf(rtwdev, path, addr, mask, val);
340
341	return count;
342}
343
344static int rtw89_debug_priv_rf_reg_dump_get(struct seq_file *m, void *v)
345{
346	struct rtw89_debugfs_priv *debugfs_priv = m->private;
347	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
348	const struct rtw89_chip_info *chip = rtwdev->chip;
349	u32 addr, offset, data;
350	u8 path;
351
352	for (path = 0; path < chip->rf_path_num; path++) {
353		seq_printf(m, "RF path %d:\n\n", path);
354		for (addr = 0; addr < 0x100; addr += 4) {
355			seq_printf(m, "0x%08x: ", addr);
356			for (offset = 0; offset < 4; offset++) {
357				data = rtw89_read_rf(rtwdev, path,
358						     addr + offset, RFREG_MASK);
359				seq_printf(m, "0x%05x  ", data);
360			}
361			seq_puts(m, "\n");
362		}
363		seq_puts(m, "\n");
364	}
365
366	return 0;
367}
368
369struct txpwr_ent {
370	bool nested;
371	union {
372		const char *txt;
373		const struct txpwr_ent *ptr;
374	};
375	u8 len;
376};
377
378struct txpwr_map {
379	const struct txpwr_ent *ent;
380	u8 size;
381	u32 addr_from;
382	u32 addr_to;
383	u32 addr_to_1ss;
384};
385
386#define __GEN_TXPWR_ENT_NESTED(_e) \
387	{ .nested = true, .ptr = __txpwr_ent_##_e, \
388	  .len = ARRAY_SIZE(__txpwr_ent_##_e) }
389
390#define __GEN_TXPWR_ENT0(_t) { .len = 0, .txt = _t }
391
392#define __GEN_TXPWR_ENT2(_t, _e0, _e1) \
393	{ .len = 2, .txt = _t "\t-  " _e0 "  " _e1 }
394
395#define __GEN_TXPWR_ENT4(_t, _e0, _e1, _e2, _e3) \
396	{ .len = 4, .txt = _t "\t-  " _e0 "  " _e1 "  " _e2 "  " _e3 }
397
398#define __GEN_TXPWR_ENT8(_t, _e0, _e1, _e2, _e3, _e4, _e5, _e6, _e7) \
399	{ .len = 8, .txt = _t "\t-  " \
400	  _e0 "  " _e1 "  " _e2 "  " _e3 "  " \
401	  _e4 "  " _e5 "  " _e6 "  " _e7 }
402
403static const struct txpwr_ent __txpwr_ent_byr_ax[] = {
404	__GEN_TXPWR_ENT4("CCK       ", "1M   ", "2M   ", "5.5M ", "11M  "),
405	__GEN_TXPWR_ENT4("LEGACY    ", "6M   ", "9M   ", "12M  ", "18M  "),
406	__GEN_TXPWR_ENT4("LEGACY    ", "24M  ", "36M  ", "48M  ", "54M  "),
407	/* 1NSS */
408	__GEN_TXPWR_ENT4("MCS_1NSS  ", "MCS0 ", "MCS1 ", "MCS2 ", "MCS3 "),
409	__GEN_TXPWR_ENT4("MCS_1NSS  ", "MCS4 ", "MCS5 ", "MCS6 ", "MCS7 "),
410	__GEN_TXPWR_ENT4("MCS_1NSS  ", "MCS8 ", "MCS9 ", "MCS10", "MCS11"),
411	__GEN_TXPWR_ENT4("HEDCM_1NSS", "MCS0 ", "MCS1 ", "MCS3 ", "MCS4 "),
412	/* 2NSS */
413	__GEN_TXPWR_ENT4("MCS_2NSS  ", "MCS0 ", "MCS1 ", "MCS2 ", "MCS3 "),
414	__GEN_TXPWR_ENT4("MCS_2NSS  ", "MCS4 ", "MCS5 ", "MCS6 ", "MCS7 "),
415	__GEN_TXPWR_ENT4("MCS_2NSS  ", "MCS8 ", "MCS9 ", "MCS10", "MCS11"),
416	__GEN_TXPWR_ENT4("HEDCM_2NSS", "MCS0 ", "MCS1 ", "MCS3 ", "MCS4 "),
417};
418
419static_assert((ARRAY_SIZE(__txpwr_ent_byr_ax) * 4) ==
420	(R_AX_PWR_BY_RATE_MAX - R_AX_PWR_BY_RATE + 4));
421
422static const struct txpwr_map __txpwr_map_byr_ax = {
423	.ent = __txpwr_ent_byr_ax,
424	.size = ARRAY_SIZE(__txpwr_ent_byr_ax),
425	.addr_from = R_AX_PWR_BY_RATE,
426	.addr_to = R_AX_PWR_BY_RATE_MAX,
427	.addr_to_1ss = R_AX_PWR_BY_RATE_1SS_MAX,
428};
429
430static const struct txpwr_ent __txpwr_ent_lmt_ax[] = {
431	/* 1TX */
432	__GEN_TXPWR_ENT2("CCK_1TX_20M    ", "NON_BF", "BF"),
433	__GEN_TXPWR_ENT2("CCK_1TX_40M    ", "NON_BF", "BF"),
434	__GEN_TXPWR_ENT2("OFDM_1TX       ", "NON_BF", "BF"),
435	__GEN_TXPWR_ENT2("MCS_1TX_20M_0  ", "NON_BF", "BF"),
436	__GEN_TXPWR_ENT2("MCS_1TX_20M_1  ", "NON_BF", "BF"),
437	__GEN_TXPWR_ENT2("MCS_1TX_20M_2  ", "NON_BF", "BF"),
438	__GEN_TXPWR_ENT2("MCS_1TX_20M_3  ", "NON_BF", "BF"),
439	__GEN_TXPWR_ENT2("MCS_1TX_20M_4  ", "NON_BF", "BF"),
440	__GEN_TXPWR_ENT2("MCS_1TX_20M_5  ", "NON_BF", "BF"),
441	__GEN_TXPWR_ENT2("MCS_1TX_20M_6  ", "NON_BF", "BF"),
442	__GEN_TXPWR_ENT2("MCS_1TX_20M_7  ", "NON_BF", "BF"),
443	__GEN_TXPWR_ENT2("MCS_1TX_40M_0  ", "NON_BF", "BF"),
444	__GEN_TXPWR_ENT2("MCS_1TX_40M_1  ", "NON_BF", "BF"),
445	__GEN_TXPWR_ENT2("MCS_1TX_40M_2  ", "NON_BF", "BF"),
446	__GEN_TXPWR_ENT2("MCS_1TX_40M_3  ", "NON_BF", "BF"),
447	__GEN_TXPWR_ENT2("MCS_1TX_80M_0  ", "NON_BF", "BF"),
448	__GEN_TXPWR_ENT2("MCS_1TX_80M_1  ", "NON_BF", "BF"),
449	__GEN_TXPWR_ENT2("MCS_1TX_160M   ", "NON_BF", "BF"),
450	__GEN_TXPWR_ENT2("MCS_1TX_40M_0p5", "NON_BF", "BF"),
451	__GEN_TXPWR_ENT2("MCS_1TX_40M_2p5", "NON_BF", "BF"),
452	/* 2TX */
453	__GEN_TXPWR_ENT2("CCK_2TX_20M    ", "NON_BF", "BF"),
454	__GEN_TXPWR_ENT2("CCK_2TX_40M    ", "NON_BF", "BF"),
455	__GEN_TXPWR_ENT2("OFDM_2TX       ", "NON_BF", "BF"),
456	__GEN_TXPWR_ENT2("MCS_2TX_20M_0  ", "NON_BF", "BF"),
457	__GEN_TXPWR_ENT2("MCS_2TX_20M_1  ", "NON_BF", "BF"),
458	__GEN_TXPWR_ENT2("MCS_2TX_20M_2  ", "NON_BF", "BF"),
459	__GEN_TXPWR_ENT2("MCS_2TX_20M_3  ", "NON_BF", "BF"),
460	__GEN_TXPWR_ENT2("MCS_2TX_20M_4  ", "NON_BF", "BF"),
461	__GEN_TXPWR_ENT2("MCS_2TX_20M_5  ", "NON_BF", "BF"),
462	__GEN_TXPWR_ENT2("MCS_2TX_20M_6  ", "NON_BF", "BF"),
463	__GEN_TXPWR_ENT2("MCS_2TX_20M_7  ", "NON_BF", "BF"),
464	__GEN_TXPWR_ENT2("MCS_2TX_40M_0  ", "NON_BF", "BF"),
465	__GEN_TXPWR_ENT2("MCS_2TX_40M_1  ", "NON_BF", "BF"),
466	__GEN_TXPWR_ENT2("MCS_2TX_40M_2  ", "NON_BF", "BF"),
467	__GEN_TXPWR_ENT2("MCS_2TX_40M_3  ", "NON_BF", "BF"),
468	__GEN_TXPWR_ENT2("MCS_2TX_80M_0  ", "NON_BF", "BF"),
469	__GEN_TXPWR_ENT2("MCS_2TX_80M_1  ", "NON_BF", "BF"),
470	__GEN_TXPWR_ENT2("MCS_2TX_160M   ", "NON_BF", "BF"),
471	__GEN_TXPWR_ENT2("MCS_2TX_40M_0p5", "NON_BF", "BF"),
472	__GEN_TXPWR_ENT2("MCS_2TX_40M_2p5", "NON_BF", "BF"),
473};
474
475static_assert((ARRAY_SIZE(__txpwr_ent_lmt_ax) * 2) ==
476	(R_AX_PWR_LMT_MAX - R_AX_PWR_LMT + 4));
477
478static const struct txpwr_map __txpwr_map_lmt_ax = {
479	.ent = __txpwr_ent_lmt_ax,
480	.size = ARRAY_SIZE(__txpwr_ent_lmt_ax),
481	.addr_from = R_AX_PWR_LMT,
482	.addr_to = R_AX_PWR_LMT_MAX,
483	.addr_to_1ss = R_AX_PWR_LMT_1SS_MAX,
484};
485
486static const struct txpwr_ent __txpwr_ent_lmt_ru_ax[] = {
487	/* 1TX */
488	__GEN_TXPWR_ENT8("1TX", "RU26__0", "RU26__1", "RU26__2", "RU26__3",
489			 "RU26__4", "RU26__5", "RU26__6", "RU26__7"),
490	__GEN_TXPWR_ENT8("1TX", "RU52__0", "RU52__1", "RU52__2", "RU52__3",
491			 "RU52__4", "RU52__5", "RU52__6", "RU52__7"),
492	__GEN_TXPWR_ENT8("1TX", "RU106_0", "RU106_1", "RU106_2", "RU106_3",
493			 "RU106_4", "RU106_5", "RU106_6", "RU106_7"),
494	/* 2TX */
495	__GEN_TXPWR_ENT8("2TX", "RU26__0", "RU26__1", "RU26__2", "RU26__3",
496			 "RU26__4", "RU26__5", "RU26__6", "RU26__7"),
497	__GEN_TXPWR_ENT8("2TX", "RU52__0", "RU52__1", "RU52__2", "RU52__3",
498			 "RU52__4", "RU52__5", "RU52__6", "RU52__7"),
499	__GEN_TXPWR_ENT8("2TX", "RU106_0", "RU106_1", "RU106_2", "RU106_3",
500			 "RU106_4", "RU106_5", "RU106_6", "RU106_7"),
501};
502
503static_assert((ARRAY_SIZE(__txpwr_ent_lmt_ru_ax) * 8) ==
504	(R_AX_PWR_RU_LMT_MAX - R_AX_PWR_RU_LMT + 4));
505
506static const struct txpwr_map __txpwr_map_lmt_ru_ax = {
507	.ent = __txpwr_ent_lmt_ru_ax,
508	.size = ARRAY_SIZE(__txpwr_ent_lmt_ru_ax),
509	.addr_from = R_AX_PWR_RU_LMT,
510	.addr_to = R_AX_PWR_RU_LMT_MAX,
511	.addr_to_1ss = R_AX_PWR_RU_LMT_1SS_MAX,
512};
513
514static const struct txpwr_ent __txpwr_ent_byr_mcs_be[] = {
515	__GEN_TXPWR_ENT4("MCS_1SS       ", "MCS0  ", "MCS1  ", "MCS2 ", "MCS3 "),
516	__GEN_TXPWR_ENT4("MCS_1SS       ", "MCS4  ", "MCS5  ", "MCS6 ", "MCS7 "),
517	__GEN_TXPWR_ENT4("MCS_1SS       ", "MCS8  ", "MCS9  ", "MCS10", "MCS11"),
518	__GEN_TXPWR_ENT2("MCS_1SS       ", "MCS12 ", "MCS13 \t"),
519	__GEN_TXPWR_ENT4("HEDCM_1SS     ", "MCS0  ", "MCS1  ", "MCS3 ", "MCS4 "),
520	__GEN_TXPWR_ENT4("DLRU_MCS_1SS  ", "MCS0  ", "MCS1  ", "MCS2 ", "MCS3 "),
521	__GEN_TXPWR_ENT4("DLRU_MCS_1SS  ", "MCS4  ", "MCS5  ", "MCS6 ", "MCS7 "),
522	__GEN_TXPWR_ENT4("DLRU_MCS_1SS  ", "MCS8  ", "MCS9  ", "MCS10", "MCS11"),
523	__GEN_TXPWR_ENT2("DLRU_MCS_1SS  ", "MCS12 ", "MCS13 \t"),
524	__GEN_TXPWR_ENT4("DLRU_HEDCM_1SS", "MCS0  ", "MCS1  ", "MCS3 ", "MCS4 "),
525	__GEN_TXPWR_ENT4("MCS_2SS       ", "MCS0  ", "MCS1  ", "MCS2 ", "MCS3 "),
526	__GEN_TXPWR_ENT4("MCS_2SS       ", "MCS4  ", "MCS5  ", "MCS6 ", "MCS7 "),
527	__GEN_TXPWR_ENT4("MCS_2SS       ", "MCS8  ", "MCS9  ", "MCS10", "MCS11"),
528	__GEN_TXPWR_ENT2("MCS_2SS       ", "MCS12 ", "MCS13 \t"),
529	__GEN_TXPWR_ENT4("HEDCM_2SS     ", "MCS0  ", "MCS1  ", "MCS3 ", "MCS4 "),
530	__GEN_TXPWR_ENT4("DLRU_MCS_2SS  ", "MCS0  ", "MCS1  ", "MCS2 ", "MCS3 "),
531	__GEN_TXPWR_ENT4("DLRU_MCS_2SS  ", "MCS4  ", "MCS5  ", "MCS6 ", "MCS7 "),
532	__GEN_TXPWR_ENT4("DLRU_MCS_2SS  ", "MCS8  ", "MCS9  ", "MCS10", "MCS11"),
533	__GEN_TXPWR_ENT2("DLRU_MCS_2SS  ", "MCS12 ", "MCS13 \t"),
534	__GEN_TXPWR_ENT4("DLRU_HEDCM_2SS", "MCS0  ", "MCS1  ", "MCS3 ", "MCS4 "),
535};
536
537static const struct txpwr_ent __txpwr_ent_byr_be[] = {
538	__GEN_TXPWR_ENT0("BW20"),
539	__GEN_TXPWR_ENT4("CCK       ", "1M    ", "2M    ", "5.5M ", "11M  "),
540	__GEN_TXPWR_ENT4("LEGACY    ", "6M    ", "9M    ", "12M  ", "18M  "),
541	__GEN_TXPWR_ENT4("LEGACY    ", "24M   ", "36M   ", "48M  ", "54M  "),
542	__GEN_TXPWR_ENT2("EHT       ", "MCS14 ", "MCS15 \t"),
543	__GEN_TXPWR_ENT2("DLRU_EHT  ", "MCS14 ", "MCS15 \t"),
544	__GEN_TXPWR_ENT_NESTED(byr_mcs_be),
545
546	__GEN_TXPWR_ENT0("BW40"),
547	__GEN_TXPWR_ENT4("CCK       ", "1M    ", "2M    ", "5.5M ", "11M  "),
548	__GEN_TXPWR_ENT4("LEGACY    ", "6M    ", "9M    ", "12M  ", "18M  "),
549	__GEN_TXPWR_ENT4("LEGACY    ", "24M   ", "36M   ", "48M  ", "54M  "),
550	__GEN_TXPWR_ENT2("EHT       ", "MCS14 ", "MCS15 \t"),
551	__GEN_TXPWR_ENT2("DLRU_EHT  ", "MCS14 ", "MCS15 \t"),
552	__GEN_TXPWR_ENT_NESTED(byr_mcs_be),
553
554	/* there is no CCK section after BW80 */
555	__GEN_TXPWR_ENT0("BW80"),
556	__GEN_TXPWR_ENT4("LEGACY    ", "6M    ", "9M    ", "12M  ", "18M  "),
557	__GEN_TXPWR_ENT4("LEGACY    ", "24M   ", "36M   ", "48M  ", "54M  "),
558	__GEN_TXPWR_ENT2("EHT       ", "MCS14 ", "MCS15 \t"),
559	__GEN_TXPWR_ENT2("DLRU_EHT  ", "MCS14 ", "MCS15 \t"),
560	__GEN_TXPWR_ENT_NESTED(byr_mcs_be),
561
562	__GEN_TXPWR_ENT0("BW160"),
563	__GEN_TXPWR_ENT4("LEGACY    ", "6M    ", "9M    ", "12M  ", "18M  "),
564	__GEN_TXPWR_ENT4("LEGACY    ", "24M   ", "36M   ", "48M  ", "54M  "),
565	__GEN_TXPWR_ENT2("EHT       ", "MCS14 ", "MCS15 \t"),
566	__GEN_TXPWR_ENT2("DLRU_EHT  ", "MCS14 ", "MCS15 \t"),
567	__GEN_TXPWR_ENT_NESTED(byr_mcs_be),
568
569	__GEN_TXPWR_ENT0("BW320"),
570	__GEN_TXPWR_ENT4("LEGACY    ", "6M    ", "9M    ", "12M  ", "18M  "),
571	__GEN_TXPWR_ENT4("LEGACY    ", "24M   ", "36M   ", "48M  ", "54M  "),
572	__GEN_TXPWR_ENT2("EHT       ", "MCS14 ", "MCS15 \t"),
573	__GEN_TXPWR_ENT2("DLRU_EHT  ", "MCS14 ", "MCS15 \t"),
574	__GEN_TXPWR_ENT_NESTED(byr_mcs_be),
575};
576
577static const struct txpwr_map __txpwr_map_byr_be = {
578	.ent = __txpwr_ent_byr_be,
579	.size = ARRAY_SIZE(__txpwr_ent_byr_be),
580	.addr_from = R_BE_PWR_BY_RATE,
581	.addr_to = R_BE_PWR_BY_RATE_MAX,
582	.addr_to_1ss = 0, /* not support */
583};
584
585static const struct txpwr_ent __txpwr_ent_lmt_mcs_be[] = {
586	__GEN_TXPWR_ENT2("MCS_20M_0  ", "NON_BF", "BF"),
587	__GEN_TXPWR_ENT2("MCS_20M_1  ", "NON_BF", "BF"),
588	__GEN_TXPWR_ENT2("MCS_20M_2  ", "NON_BF", "BF"),
589	__GEN_TXPWR_ENT2("MCS_20M_3  ", "NON_BF", "BF"),
590	__GEN_TXPWR_ENT2("MCS_20M_4  ", "NON_BF", "BF"),
591	__GEN_TXPWR_ENT2("MCS_20M_5  ", "NON_BF", "BF"),
592	__GEN_TXPWR_ENT2("MCS_20M_6  ", "NON_BF", "BF"),
593	__GEN_TXPWR_ENT2("MCS_20M_7  ", "NON_BF", "BF"),
594	__GEN_TXPWR_ENT2("MCS_20M_8  ", "NON_BF", "BF"),
595	__GEN_TXPWR_ENT2("MCS_20M_9  ", "NON_BF", "BF"),
596	__GEN_TXPWR_ENT2("MCS_20M_10 ", "NON_BF", "BF"),
597	__GEN_TXPWR_ENT2("MCS_20M_11 ", "NON_BF", "BF"),
598	__GEN_TXPWR_ENT2("MCS_20M_12 ", "NON_BF", "BF"),
599	__GEN_TXPWR_ENT2("MCS_20M_13 ", "NON_BF", "BF"),
600	__GEN_TXPWR_ENT2("MCS_20M_14 ", "NON_BF", "BF"),
601	__GEN_TXPWR_ENT2("MCS_20M_15 ", "NON_BF", "BF"),
602	__GEN_TXPWR_ENT2("MCS_40M_0  ", "NON_BF", "BF"),
603	__GEN_TXPWR_ENT2("MCS_40M_1  ", "NON_BF", "BF"),
604	__GEN_TXPWR_ENT2("MCS_40M_2  ", "NON_BF", "BF"),
605	__GEN_TXPWR_ENT2("MCS_40M_3  ", "NON_BF", "BF"),
606	__GEN_TXPWR_ENT2("MCS_40M_4  ", "NON_BF", "BF"),
607	__GEN_TXPWR_ENT2("MCS_40M_5  ", "NON_BF", "BF"),
608	__GEN_TXPWR_ENT2("MCS_40M_6  ", "NON_BF", "BF"),
609	__GEN_TXPWR_ENT2("MCS_40M_7  ", "NON_BF", "BF"),
610	__GEN_TXPWR_ENT2("MCS_80M_0  ", "NON_BF", "BF"),
611	__GEN_TXPWR_ENT2("MCS_80M_1  ", "NON_BF", "BF"),
612	__GEN_TXPWR_ENT2("MCS_80M_2  ", "NON_BF", "BF"),
613	__GEN_TXPWR_ENT2("MCS_80M_3  ", "NON_BF", "BF"),
614	__GEN_TXPWR_ENT2("MCS_160M_0 ", "NON_BF", "BF"),
615	__GEN_TXPWR_ENT2("MCS_160M_1 ", "NON_BF", "BF"),
616	__GEN_TXPWR_ENT2("MCS_320M   ", "NON_BF", "BF"),
617	__GEN_TXPWR_ENT2("MCS_40M_0p5", "NON_BF", "BF"),
618	__GEN_TXPWR_ENT2("MCS_40M_2p5", "NON_BF", "BF"),
619	__GEN_TXPWR_ENT2("MCS_40M_4p5", "NON_BF", "BF"),
620	__GEN_TXPWR_ENT2("MCS_40M_6p5", "NON_BF", "BF"),
621};
622
623static const struct txpwr_ent __txpwr_ent_lmt_be[] = {
624	__GEN_TXPWR_ENT0("1TX"),
625	__GEN_TXPWR_ENT2("CCK_20M    ", "NON_BF", "BF"),
626	__GEN_TXPWR_ENT2("CCK_40M    ", "NON_BF", "BF"),
627	__GEN_TXPWR_ENT2("OFDM       ", "NON_BF", "BF"),
628	__GEN_TXPWR_ENT_NESTED(lmt_mcs_be),
629
630	__GEN_TXPWR_ENT0("2TX"),
631	__GEN_TXPWR_ENT2("CCK_20M    ", "NON_BF", "BF"),
632	__GEN_TXPWR_ENT2("CCK_40M    ", "NON_BF", "BF"),
633	__GEN_TXPWR_ENT2("OFDM       ", "NON_BF", "BF"),
634	__GEN_TXPWR_ENT_NESTED(lmt_mcs_be),
635};
636
637static const struct txpwr_map __txpwr_map_lmt_be = {
638	.ent = __txpwr_ent_lmt_be,
639	.size = ARRAY_SIZE(__txpwr_ent_lmt_be),
640	.addr_from = R_BE_PWR_LMT,
641	.addr_to = R_BE_PWR_LMT_MAX,
642	.addr_to_1ss = 0, /* not support */
643};
644
645static const struct txpwr_ent __txpwr_ent_lmt_ru_indexes_be[] = {
646	__GEN_TXPWR_ENT8("RU26    ", "IDX_0 ", "IDX_1 ", "IDX_2 ", "IDX_3 ",
647			 "IDX_4 ", "IDX_5 ", "IDX_6 ", "IDX_7 "),
648	__GEN_TXPWR_ENT8("RU26    ", "IDX_8 ", "IDX_9 ", "IDX_10", "IDX_11",
649			 "IDX_12", "IDX_13", "IDX_14", "IDX_15"),
650	__GEN_TXPWR_ENT8("RU52    ", "IDX_0 ", "IDX_1 ", "IDX_2 ", "IDX_3 ",
651			 "IDX_4 ", "IDX_5 ", "IDX_6 ", "IDX_7 "),
652	__GEN_TXPWR_ENT8("RU52    ", "IDX_8 ", "IDX_9 ", "IDX_10", "IDX_11",
653			 "IDX_12", "IDX_13", "IDX_14", "IDX_15"),
654	__GEN_TXPWR_ENT8("RU106   ", "IDX_0 ", "IDX_1 ", "IDX_2 ", "IDX_3 ",
655			 "IDX_4 ", "IDX_5 ", "IDX_6 ", "IDX_7 "),
656	__GEN_TXPWR_ENT8("RU106   ", "IDX_8 ", "IDX_9 ", "IDX_10", "IDX_11",
657			 "IDX_12", "IDX_13", "IDX_14", "IDX_15"),
658	__GEN_TXPWR_ENT8("RU52_26 ", "IDX_0 ", "IDX_1 ", "IDX_2 ", "IDX_3 ",
659			 "IDX_4 ", "IDX_5 ", "IDX_6 ", "IDX_7 "),
660	__GEN_TXPWR_ENT8("RU52_26 ", "IDX_8 ", "IDX_9 ", "IDX_10", "IDX_11",
661			 "IDX_12", "IDX_13", "IDX_14", "IDX_15"),
662	__GEN_TXPWR_ENT8("RU106_26", "IDX_0 ", "IDX_1 ", "IDX_2 ", "IDX_3 ",
663			 "IDX_4 ", "IDX_5 ", "IDX_6 ", "IDX_7 "),
664	__GEN_TXPWR_ENT8("RU106_26", "IDX_8 ", "IDX_9 ", "IDX_10", "IDX_11",
665			 "IDX_12", "IDX_13", "IDX_14", "IDX_15"),
666};
667
668static const struct txpwr_ent __txpwr_ent_lmt_ru_be[] = {
669	__GEN_TXPWR_ENT0("1TX"),
670	__GEN_TXPWR_ENT_NESTED(lmt_ru_indexes_be),
671
672	__GEN_TXPWR_ENT0("2TX"),
673	__GEN_TXPWR_ENT_NESTED(lmt_ru_indexes_be),
674};
675
676static const struct txpwr_map __txpwr_map_lmt_ru_be = {
677	.ent = __txpwr_ent_lmt_ru_be,
678	.size = ARRAY_SIZE(__txpwr_ent_lmt_ru_be),
679	.addr_from = R_BE_PWR_RU_LMT,
680	.addr_to = R_BE_PWR_RU_LMT_MAX,
681	.addr_to_1ss = 0, /* not support */
682};
683
684static unsigned int
685__print_txpwr_ent(struct seq_file *m, const struct txpwr_ent *ent,
686		  const s8 *buf, const unsigned int cur)
687{
688	unsigned int cnt, i;
689	char *fmt;
690
691	if (ent->nested) {
692		for (cnt = 0, i = 0; i < ent->len; i++)
693			cnt += __print_txpwr_ent(m, ent->ptr + i, buf,
694						 cur + cnt);
695		return cnt;
696	}
697
698	switch (ent->len) {
699	case 0:
700		seq_printf(m, "\t<< %s >>\n", ent->txt);
701		return 0;
702	case 2:
703		fmt = "%s\t| %3d, %3d,\t\tdBm\n";
704		seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1]);
705		return 2;
706	case 4:
707		fmt = "%s\t| %3d, %3d, %3d, %3d,\tdBm\n";
708		seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1],
709			   buf[cur + 2], buf[cur + 3]);
710		return 4;
711	case 8:
712		fmt = "%s\t| %3d, %3d, %3d, %3d, %3d, %3d, %3d, %3d,\tdBm\n";
713		seq_printf(m, fmt, ent->txt, buf[cur], buf[cur + 1],
714			   buf[cur + 2], buf[cur + 3], buf[cur + 4],
715			   buf[cur + 5], buf[cur + 6], buf[cur + 7]);
716		return 8;
717	default:
718		return 0;
719	}
720}
721
722static int __print_txpwr_map(struct seq_file *m, struct rtw89_dev *rtwdev,
723			     const struct txpwr_map *map)
724{
725	u8 fct = rtwdev->chip->txpwr_factor_mac;
726	u8 path_num = rtwdev->chip->rf_path_num;
727	unsigned int cur, i;
728	u32 max_valid_addr;
729	u32 val, addr;
730	s8 *buf, tmp;
731	int ret;
732
733	buf = vzalloc(map->addr_to - map->addr_from + 4);
734	if (!buf)
735		return -ENOMEM;
736
737	if (path_num == 1)
738		max_valid_addr = map->addr_to_1ss;
739	else
740		max_valid_addr = map->addr_to;
741
742	if (max_valid_addr == 0)
743		return -EOPNOTSUPP;
744
745	for (addr = map->addr_from; addr <= max_valid_addr; addr += 4) {
746		ret = rtw89_mac_txpwr_read32(rtwdev, RTW89_PHY_0, addr, &val);
747		if (ret)
748			val = MASKDWORD;
749
750		cur = addr - map->addr_from;
751		for (i = 0; i < 4; i++, val >>= 8) {
752			/* signed 7 bits, and reserved BIT(7) */
753			tmp = sign_extend32(val, 6);
754			buf[cur + i] = tmp >> fct;
755		}
756	}
757
758	for (cur = 0, i = 0; i < map->size; i++)
759		cur += __print_txpwr_ent(m, &map->ent[i], buf, cur);
760
761	vfree(buf);
762	return 0;
763}
764
765#define case_REGD(_regd) \
766	case RTW89_ ## _regd: \
767		seq_puts(m, #_regd "\n"); \
768		break
769
770static void __print_regd(struct seq_file *m, struct rtw89_dev *rtwdev,
771			 const struct rtw89_chan *chan)
772{
773	u8 band = chan->band_type;
774	u8 regd = rtw89_regd_get(rtwdev, band);
775
776	switch (regd) {
777	default:
778		seq_printf(m, "UNKNOWN: %d\n", regd);
779		break;
780	case_REGD(WW);
781	case_REGD(ETSI);
782	case_REGD(FCC);
783	case_REGD(MKK);
784	case_REGD(NA);
785	case_REGD(IC);
786	case_REGD(KCC);
787	case_REGD(NCC);
788	case_REGD(CHILE);
789	case_REGD(ACMA);
790	case_REGD(MEXICO);
791	case_REGD(UKRAINE);
792	case_REGD(CN);
793	}
794}
795
796#undef case_REGD
797
798struct dbgfs_txpwr_table {
799	const struct txpwr_map *byr;
800	const struct txpwr_map *lmt;
801	const struct txpwr_map *lmt_ru;
802};
803
804static const struct dbgfs_txpwr_table dbgfs_txpwr_table_ax = {
805	.byr = &__txpwr_map_byr_ax,
806	.lmt = &__txpwr_map_lmt_ax,
807	.lmt_ru = &__txpwr_map_lmt_ru_ax,
808};
809
810static const struct dbgfs_txpwr_table dbgfs_txpwr_table_be = {
811	.byr = &__txpwr_map_byr_be,
812	.lmt = &__txpwr_map_lmt_be,
813	.lmt_ru = &__txpwr_map_lmt_ru_be,
814};
815
816static const struct dbgfs_txpwr_table *dbgfs_txpwr_tables[RTW89_CHIP_GEN_NUM] = {
817	[RTW89_CHIP_AX] = &dbgfs_txpwr_table_ax,
818	[RTW89_CHIP_BE] = &dbgfs_txpwr_table_be,
819};
820
821static int rtw89_debug_priv_txpwr_table_get(struct seq_file *m, void *v)
822{
823	struct rtw89_debugfs_priv *debugfs_priv = m->private;
824	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
825	enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen;
826	const struct dbgfs_txpwr_table *tbl;
827	const struct rtw89_chan *chan;
828	int ret = 0;
829
830	mutex_lock(&rtwdev->mutex);
831	rtw89_leave_ps_mode(rtwdev);
832	chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
833
834	seq_puts(m, "[Regulatory] ");
835	__print_regd(m, rtwdev, chan);
836
837	seq_puts(m, "[SAR]\n");
838	rtw89_print_sar(m, rtwdev, chan->freq);
839
840	seq_puts(m, "[TAS]\n");
841	rtw89_print_tas(m, rtwdev);
842
843	tbl = dbgfs_txpwr_tables[chip_gen];
844	if (!tbl) {
845		ret = -EOPNOTSUPP;
846		goto err;
847	}
848
849	seq_puts(m, "\n[TX power byrate]\n");
850	ret = __print_txpwr_map(m, rtwdev, tbl->byr);
851	if (ret)
852		goto err;
853
854	seq_puts(m, "\n[TX power limit]\n");
855	ret = __print_txpwr_map(m, rtwdev, tbl->lmt);
856	if (ret)
857		goto err;
858
859	seq_puts(m, "\n[TX power limit_ru]\n");
860	ret = __print_txpwr_map(m, rtwdev, tbl->lmt_ru);
861	if (ret)
862		goto err;
863
864err:
865	mutex_unlock(&rtwdev->mutex);
866	return ret;
867}
868
869static ssize_t
870rtw89_debug_priv_mac_reg_dump_select(struct file *filp,
871				     const char __user *user_buf,
872				     size_t count, loff_t *loff)
873{
874	struct seq_file *m = (struct seq_file *)filp->private_data;
875	struct rtw89_debugfs_priv *debugfs_priv = m->private;
876	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
877	const struct rtw89_chip_info *chip = rtwdev->chip;
878	char buf[32];
879	size_t buf_size;
880	int sel;
881	int ret;
882
883	buf_size = min(count, sizeof(buf) - 1);
884	if (copy_from_user(buf, user_buf, buf_size))
885		return -EFAULT;
886
887	buf[buf_size] = '\0';
888	ret = kstrtoint(buf, 0, &sel);
889	if (ret)
890		return ret;
891
892	if (sel < RTW89_DBG_SEL_MAC_00 || sel > RTW89_DBG_SEL_RFC) {
893		rtw89_info(rtwdev, "invalid args: %d\n", sel);
894		return -EINVAL;
895	}
896
897	if (sel == RTW89_DBG_SEL_MAC_30 && chip->chip_id != RTL8852C) {
898		rtw89_info(rtwdev, "sel %d is address hole on chip %d\n", sel,
899			   chip->chip_id);
900		return -EINVAL;
901	}
902
903	debugfs_priv->cb_data = sel;
904	rtw89_info(rtwdev, "select mac page dump %d\n", debugfs_priv->cb_data);
905
906	return count;
907}
908
909#define RTW89_MAC_PAGE_SIZE		0x100
910
911static int rtw89_debug_priv_mac_reg_dump_get(struct seq_file *m, void *v)
912{
913	struct rtw89_debugfs_priv *debugfs_priv = m->private;
914	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
915	enum rtw89_debug_mac_reg_sel reg_sel = debugfs_priv->cb_data;
916	u32 start, end;
917	u32 i, j, k, page;
918	u32 val;
919
920	switch (reg_sel) {
921	case RTW89_DBG_SEL_MAC_00:
922		seq_puts(m, "Debug selected MAC page 0x00\n");
923		start = 0x000;
924		end = 0x014;
925		break;
926	case RTW89_DBG_SEL_MAC_30:
927		seq_puts(m, "Debug selected MAC page 0x30\n");
928		start = 0x030;
929		end = 0x033;
930		break;
931	case RTW89_DBG_SEL_MAC_40:
932		seq_puts(m, "Debug selected MAC page 0x40\n");
933		start = 0x040;
934		end = 0x07f;
935		break;
936	case RTW89_DBG_SEL_MAC_80:
937		seq_puts(m, "Debug selected MAC page 0x80\n");
938		start = 0x080;
939		end = 0x09f;
940		break;
941	case RTW89_DBG_SEL_MAC_C0:
942		seq_puts(m, "Debug selected MAC page 0xc0\n");
943		start = 0x0c0;
944		end = 0x0df;
945		break;
946	case RTW89_DBG_SEL_MAC_E0:
947		seq_puts(m, "Debug selected MAC page 0xe0\n");
948		start = 0x0e0;
949		end = 0x0ff;
950		break;
951	case RTW89_DBG_SEL_BB:
952		seq_puts(m, "Debug selected BB register\n");
953		start = 0x100;
954		end = 0x17f;
955		break;
956	case RTW89_DBG_SEL_IQK:
957		seq_puts(m, "Debug selected IQK register\n");
958		start = 0x180;
959		end = 0x1bf;
960		break;
961	case RTW89_DBG_SEL_RFC:
962		seq_puts(m, "Debug selected RFC register\n");
963		start = 0x1c0;
964		end = 0x1ff;
965		break;
966	default:
967		seq_puts(m, "Selected invalid register page\n");
968		return -EINVAL;
969	}
970
971	for (i = start; i <= end; i++) {
972		page = i << 8;
973		for (j = page; j < page + RTW89_MAC_PAGE_SIZE; j += 16) {
974			seq_printf(m, "%08xh : ", 0x18600000 + j);
975			for (k = 0; k < 4; k++) {
976				val = rtw89_read32(rtwdev, j + (k << 2));
977				seq_printf(m, "%08x ", val);
978			}
979			seq_puts(m, "\n");
980		}
981	}
982
983	return 0;
984}
985
986static ssize_t
987rtw89_debug_priv_mac_mem_dump_select(struct file *filp,
988				     const char __user *user_buf,
989				     size_t count, loff_t *loff)
990{
991	struct seq_file *m = (struct seq_file *)filp->private_data;
992	struct rtw89_debugfs_priv *debugfs_priv = m->private;
993	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
994	char buf[32];
995	size_t buf_size;
996	u32 sel, start_addr, len;
997	int num;
998
999	buf_size = min(count, sizeof(buf) - 1);
1000	if (copy_from_user(buf, user_buf, buf_size))
1001		return -EFAULT;
1002
1003	buf[buf_size] = '\0';
1004	num = sscanf(buf, "%x %x %x", &sel, &start_addr, &len);
1005	if (num != 3) {
1006		rtw89_info(rtwdev, "invalid format: <sel> <start> <len>\n");
1007		return -EINVAL;
1008	}
1009
1010	debugfs_priv->mac_mem.sel = sel;
1011	debugfs_priv->mac_mem.start = start_addr;
1012	debugfs_priv->mac_mem.len = len;
1013
1014	rtw89_info(rtwdev, "select mem %d start %d len %d\n",
1015		   sel, start_addr, len);
1016
1017	return count;
1018}
1019
1020static void rtw89_debug_dump_mac_mem(struct seq_file *m,
1021				     struct rtw89_dev *rtwdev,
1022				     u8 sel, u32 start_addr, u32 len)
1023{
1024	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
1025	u32 filter_model_addr = mac->filter_model_addr;
1026	u32 indir_access_addr = mac->indir_access_addr;
1027	u32 base_addr, start_page, residue;
1028	u32 i, j, p, pages;
1029	u32 dump_len, remain;
1030	u32 val;
1031
1032	remain = len;
1033	pages = len / MAC_MEM_DUMP_PAGE_SIZE + 1;
1034	start_page = start_addr / MAC_MEM_DUMP_PAGE_SIZE;
1035	residue = start_addr % MAC_MEM_DUMP_PAGE_SIZE;
1036	base_addr = mac->mem_base_addrs[sel];
1037	base_addr += start_page * MAC_MEM_DUMP_PAGE_SIZE;
1038
1039	for (p = 0; p < pages; p++) {
1040		dump_len = min_t(u32, remain, MAC_MEM_DUMP_PAGE_SIZE);
1041		rtw89_write32(rtwdev, filter_model_addr, base_addr);
1042		for (i = indir_access_addr + residue;
1043		     i < indir_access_addr + dump_len;) {
1044			seq_printf(m, "%08xh:", i);
1045			for (j = 0;
1046			     j < 4 && i < indir_access_addr + dump_len;
1047			     j++, i += 4) {
1048				val = rtw89_read32(rtwdev, i);
1049				seq_printf(m, "  %08x", val);
1050				remain -= 4;
1051			}
1052			seq_puts(m, "\n");
1053		}
1054		base_addr += MAC_MEM_DUMP_PAGE_SIZE;
1055	}
1056}
1057
1058static int
1059rtw89_debug_priv_mac_mem_dump_get(struct seq_file *m, void *v)
1060{
1061	struct rtw89_debugfs_priv *debugfs_priv = m->private;
1062	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
1063	bool grant_read = false;
1064
1065	if (debugfs_priv->mac_mem.sel >= RTW89_MAC_MEM_NUM)
1066		return -ENOENT;
1067
1068	if (rtwdev->chip->chip_id == RTL8852C) {
1069		switch (debugfs_priv->mac_mem.sel) {
1070		case RTW89_MAC_MEM_TXD_FIFO_0_V1:
1071		case RTW89_MAC_MEM_TXD_FIFO_1_V1:
1072		case RTW89_MAC_MEM_TXDATA_FIFO_0:
1073		case RTW89_MAC_MEM_TXDATA_FIFO_1:
1074			grant_read = true;
1075			break;
1076		default:
1077			break;
1078		}
1079	}
1080
1081	mutex_lock(&rtwdev->mutex);
1082	rtw89_leave_ps_mode(rtwdev);
1083	if (grant_read)
1084		rtw89_write32_set(rtwdev, R_AX_TCR1, B_AX_TCR_FORCE_READ_TXDFIFO);
1085	rtw89_debug_dump_mac_mem(m, rtwdev,
1086				 debugfs_priv->mac_mem.sel,
1087				 debugfs_priv->mac_mem.start,
1088				 debugfs_priv->mac_mem.len);
1089	if (grant_read)
1090		rtw89_write32_clr(rtwdev, R_AX_TCR1, B_AX_TCR_FORCE_READ_TXDFIFO);
1091	mutex_unlock(&rtwdev->mutex);
1092
1093	return 0;
1094}
1095
1096static ssize_t
1097rtw89_debug_priv_mac_dbg_port_dump_select(struct file *filp,
1098					  const char __user *user_buf,
1099					  size_t count, loff_t *loff)
1100{
1101	struct seq_file *m = (struct seq_file *)filp->private_data;
1102	struct rtw89_debugfs_priv *debugfs_priv = m->private;
1103	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
1104	char buf[32];
1105	size_t buf_size;
1106	int sel, set;
1107	int num;
1108	bool enable;
1109
1110	buf_size = min(count, sizeof(buf) - 1);
1111	if (copy_from_user(buf, user_buf, buf_size))
1112		return -EFAULT;
1113
1114	buf[buf_size] = '\0';
1115	num = sscanf(buf, "%d %d", &sel, &set);
1116	if (num != 2) {
1117		rtw89_info(rtwdev, "invalid format: <sel> <set>\n");
1118		return -EINVAL;
1119	}
1120
1121	enable = set != 0;
1122	switch (sel) {
1123	case 0:
1124		debugfs_priv->dbgpkg_en.ss_dbg = enable;
1125		break;
1126	case 1:
1127		debugfs_priv->dbgpkg_en.dle_dbg = enable;
1128		break;
1129	case 2:
1130		debugfs_priv->dbgpkg_en.dmac_dbg = enable;
1131		break;
1132	case 3:
1133		debugfs_priv->dbgpkg_en.cmac_dbg = enable;
1134		break;
1135	case 4:
1136		debugfs_priv->dbgpkg_en.dbg_port = enable;
1137		break;
1138	default:
1139		rtw89_info(rtwdev, "invalid args: sel %d set %d\n", sel, set);
1140		return -EINVAL;
1141	}
1142
1143	rtw89_info(rtwdev, "%s debug port dump %d\n",
1144		   enable ? "Enable" : "Disable", sel);
1145
1146	return count;
1147}
1148
1149static int rtw89_debug_mac_dump_ss_dbg(struct rtw89_dev *rtwdev,
1150				       struct seq_file *m)
1151{
1152	return 0;
1153}
1154
1155static int rtw89_debug_mac_dump_dle_dbg(struct rtw89_dev *rtwdev,
1156					struct seq_file *m)
1157{
1158#define DLE_DFI_DUMP(__type, __target, __sel)				\
1159({									\
1160	u32 __ctrl;							\
1161	u32 __reg_ctrl = R_AX_##__type##_DBG_FUN_INTF_CTL;		\
1162	u32 __reg_data = R_AX_##__type##_DBG_FUN_INTF_DATA;		\
1163	u32 __data, __val32;						\
1164	int __ret;							\
1165									\
1166	__ctrl = FIELD_PREP(B_AX_##__type##_DFI_TRGSEL_MASK,		\
1167			    DLE_DFI_TYPE_##__target) |			\
1168		 FIELD_PREP(B_AX_##__type##_DFI_ADDR_MASK, __sel) |	\
1169		 B_AX_WDE_DFI_ACTIVE;					\
1170	rtw89_write32(rtwdev, __reg_ctrl, __ctrl);			\
1171	__ret = read_poll_timeout(rtw89_read32, __val32,		\
1172			!(__val32 & B_AX_##__type##_DFI_ACTIVE),	\
1173			1000, 50000, false,				\
1174			rtwdev, __reg_ctrl);				\
1175	if (__ret) {							\
1176		rtw89_err(rtwdev, "failed to dump DLE %s %s %d\n",	\
1177			  #__type, #__target, __sel);			\
1178		return __ret;						\
1179	}								\
1180									\
1181	__data = rtw89_read32(rtwdev, __reg_data);			\
1182	__data;								\
1183})
1184
1185#define DLE_DFI_FREE_PAGE_DUMP(__m, __type)				\
1186({									\
1187	u32 __freepg, __pubpg;						\
1188	u32 __freepg_head, __freepg_tail, __pubpg_num;			\
1189									\
1190	__freepg = DLE_DFI_DUMP(__type, FREEPG, 0);			\
1191	__pubpg = DLE_DFI_DUMP(__type, FREEPG, 1);			\
1192	__freepg_head = FIELD_GET(B_AX_DLE_FREE_HEADPG, __freepg);	\
1193	__freepg_tail = FIELD_GET(B_AX_DLE_FREE_TAILPG, __freepg);	\
1194	__pubpg_num = FIELD_GET(B_AX_DLE_PUB_PGNUM, __pubpg);		\
1195	seq_printf(__m, "[%s] freepg head: %d\n",			\
1196		   #__type, __freepg_head);				\
1197	seq_printf(__m, "[%s] freepg tail: %d\n",			\
1198		   #__type, __freepg_tail);				\
1199	seq_printf(__m, "[%s] pubpg num  : %d\n",			\
1200		  #__type, __pubpg_num);				\
1201})
1202
1203#define case_QUOTA(__m, __type, __id)					\
1204	case __type##_QTAID_##__id:					\
1205		val32 = DLE_DFI_DUMP(__type, QUOTA, __type##_QTAID_##__id);	\
1206		rsv_pgnum = FIELD_GET(B_AX_DLE_RSV_PGNUM, val32);	\
1207		use_pgnum = FIELD_GET(B_AX_DLE_USE_PGNUM, val32);	\
1208		seq_printf(__m, "[%s][%s] rsv_pgnum: %d\n",		\
1209			   #__type, #__id, rsv_pgnum);			\
1210		seq_printf(__m, "[%s][%s] use_pgnum: %d\n",		\
1211			   #__type, #__id, use_pgnum);			\
1212		break
1213	u32 quota_id;
1214	u32 val32;
1215	u16 rsv_pgnum, use_pgnum;
1216	int ret;
1217
1218	ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL);
1219	if (ret) {
1220		seq_puts(m, "[DLE]  : DMAC not enabled\n");
1221		return ret;
1222	}
1223
1224	DLE_DFI_FREE_PAGE_DUMP(m, WDE);
1225	DLE_DFI_FREE_PAGE_DUMP(m, PLE);
1226	for (quota_id = 0; quota_id <= WDE_QTAID_CPUIO; quota_id++) {
1227		switch (quota_id) {
1228		case_QUOTA(m, WDE, HOST_IF);
1229		case_QUOTA(m, WDE, WLAN_CPU);
1230		case_QUOTA(m, WDE, DATA_CPU);
1231		case_QUOTA(m, WDE, PKTIN);
1232		case_QUOTA(m, WDE, CPUIO);
1233		}
1234	}
1235	for (quota_id = 0; quota_id <= PLE_QTAID_CPUIO; quota_id++) {
1236		switch (quota_id) {
1237		case_QUOTA(m, PLE, B0_TXPL);
1238		case_QUOTA(m, PLE, B1_TXPL);
1239		case_QUOTA(m, PLE, C2H);
1240		case_QUOTA(m, PLE, H2C);
1241		case_QUOTA(m, PLE, WLAN_CPU);
1242		case_QUOTA(m, PLE, MPDU);
1243		case_QUOTA(m, PLE, CMAC0_RX);
1244		case_QUOTA(m, PLE, CMAC1_RX);
1245		case_QUOTA(m, PLE, CMAC1_BBRPT);
1246		case_QUOTA(m, PLE, WDRLS);
1247		case_QUOTA(m, PLE, CPUIO);
1248		}
1249	}
1250
1251	return 0;
1252
1253#undef case_QUOTA
1254#undef DLE_DFI_DUMP
1255#undef DLE_DFI_FREE_PAGE_DUMP
1256}
1257
1258static int rtw89_debug_mac_dump_dmac_dbg(struct rtw89_dev *rtwdev,
1259					 struct seq_file *m)
1260{
1261	const struct rtw89_chip_info *chip = rtwdev->chip;
1262	u32 dmac_err;
1263	int i, ret;
1264
1265	ret = rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL);
1266	if (ret) {
1267		seq_puts(m, "[DMAC] : DMAC not enabled\n");
1268		return ret;
1269	}
1270
1271	dmac_err = rtw89_read32(rtwdev, R_AX_DMAC_ERR_ISR);
1272	seq_printf(m, "R_AX_DMAC_ERR_ISR=0x%08x\n", dmac_err);
1273	seq_printf(m, "R_AX_DMAC_ERR_IMR=0x%08x\n",
1274		   rtw89_read32(rtwdev, R_AX_DMAC_ERR_IMR));
1275
1276	if (dmac_err) {
1277		seq_printf(m, "R_AX_WDE_ERR_FLAG_CFG=0x%08x\n",
1278			   rtw89_read32(rtwdev, R_AX_WDE_ERR_FLAG_CFG_NUM1));
1279		seq_printf(m, "R_AX_PLE_ERR_FLAG_CFG=0x%08x\n",
1280			   rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_CFG_NUM1));
1281		if (chip->chip_id == RTL8852C) {
1282			seq_printf(m, "R_AX_PLE_ERRFLAG_MSG=0x%08x\n",
1283				   rtw89_read32(rtwdev, R_AX_PLE_ERRFLAG_MSG));
1284			seq_printf(m, "R_AX_WDE_ERRFLAG_MSG=0x%08x\n",
1285				   rtw89_read32(rtwdev, R_AX_WDE_ERRFLAG_MSG));
1286			seq_printf(m, "R_AX_PLE_DBGERR_LOCKEN=0x%08x\n",
1287				   rtw89_read32(rtwdev, R_AX_PLE_DBGERR_LOCKEN));
1288			seq_printf(m, "R_AX_PLE_DBGERR_STS=0x%08x\n",
1289				   rtw89_read32(rtwdev, R_AX_PLE_DBGERR_STS));
1290		}
1291	}
1292
1293	if (dmac_err & B_AX_WDRLS_ERR_FLAG) {
1294		seq_printf(m, "R_AX_WDRLS_ERR_IMR=0x%08x\n",
1295			   rtw89_read32(rtwdev, R_AX_WDRLS_ERR_IMR));
1296		seq_printf(m, "R_AX_WDRLS_ERR_ISR=0x%08x\n",
1297			   rtw89_read32(rtwdev, R_AX_WDRLS_ERR_ISR));
1298		if (chip->chip_id == RTL8852C)
1299			seq_printf(m, "R_AX_RPQ_RXBD_IDX=0x%08x\n",
1300				   rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX_V1));
1301		else
1302			seq_printf(m, "R_AX_RPQ_RXBD_IDX=0x%08x\n",
1303				   rtw89_read32(rtwdev, R_AX_RPQ_RXBD_IDX));
1304	}
1305
1306	if (dmac_err & B_AX_WSEC_ERR_FLAG) {
1307		if (chip->chip_id == RTL8852C) {
1308			seq_printf(m, "R_AX_SEC_ERR_IMR=0x%08x\n",
1309				   rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG_IMR));
1310			seq_printf(m, "R_AX_SEC_ERR_ISR=0x%08x\n",
1311				   rtw89_read32(rtwdev, R_AX_SEC_ERROR_FLAG));
1312			seq_printf(m, "R_AX_SEC_ENG_CTRL=0x%08x\n",
1313				   rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL));
1314			seq_printf(m, "R_AX_SEC_MPDU_PROC=0x%08x\n",
1315				   rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC));
1316			seq_printf(m, "R_AX_SEC_CAM_ACCESS=0x%08x\n",
1317				   rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS));
1318			seq_printf(m, "R_AX_SEC_CAM_RDATA=0x%08x\n",
1319				   rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA));
1320			seq_printf(m, "R_AX_SEC_DEBUG1=0x%08x\n",
1321				   rtw89_read32(rtwdev, R_AX_SEC_DEBUG1));
1322			seq_printf(m, "R_AX_SEC_TX_DEBUG=0x%08x\n",
1323				   rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG));
1324			seq_printf(m, "R_AX_SEC_RX_DEBUG=0x%08x\n",
1325				   rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG));
1326
1327			rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL,
1328					   B_AX_DBG_SEL0, 0x8B);
1329			rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL,
1330					   B_AX_DBG_SEL1, 0x8B);
1331			rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1,
1332					   B_AX_SEL_0XC0_MASK, 1);
1333			for (i = 0; i < 0x10; i++) {
1334				rtw89_write32_mask(rtwdev, R_AX_SEC_ENG_CTRL,
1335						   B_AX_SEC_DBG_PORT_FIELD_MASK, i);
1336				seq_printf(m, "sel=%x,R_AX_SEC_DEBUG2=0x%08x\n",
1337					   i, rtw89_read32(rtwdev, R_AX_SEC_DEBUG2));
1338			}
1339		} else {
1340			seq_printf(m, "R_AX_SEC_ERR_IMR_ISR=0x%08x\n",
1341				   rtw89_read32(rtwdev, R_AX_SEC_DEBUG));
1342			seq_printf(m, "R_AX_SEC_ENG_CTRL=0x%08x\n",
1343				   rtw89_read32(rtwdev, R_AX_SEC_ENG_CTRL));
1344			seq_printf(m, "R_AX_SEC_MPDU_PROC=0x%08x\n",
1345				   rtw89_read32(rtwdev, R_AX_SEC_MPDU_PROC));
1346			seq_printf(m, "R_AX_SEC_CAM_ACCESS=0x%08x\n",
1347				   rtw89_read32(rtwdev, R_AX_SEC_CAM_ACCESS));
1348			seq_printf(m, "R_AX_SEC_CAM_RDATA=0x%08x\n",
1349				   rtw89_read32(rtwdev, R_AX_SEC_CAM_RDATA));
1350			seq_printf(m, "R_AX_SEC_CAM_WDATA=0x%08x\n",
1351				   rtw89_read32(rtwdev, R_AX_SEC_CAM_WDATA));
1352			seq_printf(m, "R_AX_SEC_TX_DEBUG=0x%08x\n",
1353				   rtw89_read32(rtwdev, R_AX_SEC_TX_DEBUG));
1354			seq_printf(m, "R_AX_SEC_RX_DEBUG=0x%08x\n",
1355				   rtw89_read32(rtwdev, R_AX_SEC_RX_DEBUG));
1356			seq_printf(m, "R_AX_SEC_TRX_PKT_CNT=0x%08x\n",
1357				   rtw89_read32(rtwdev, R_AX_SEC_TRX_PKT_CNT));
1358			seq_printf(m, "R_AX_SEC_TRX_BLK_CNT=0x%08x\n",
1359				   rtw89_read32(rtwdev, R_AX_SEC_TRX_BLK_CNT));
1360		}
1361	}
1362
1363	if (dmac_err & B_AX_MPDU_ERR_FLAG) {
1364		seq_printf(m, "R_AX_MPDU_TX_ERR_IMR=0x%08x\n",
1365			   rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_IMR));
1366		seq_printf(m, "R_AX_MPDU_TX_ERR_ISR=0x%08x\n",
1367			   rtw89_read32(rtwdev, R_AX_MPDU_TX_ERR_ISR));
1368		seq_printf(m, "R_AX_MPDU_RX_ERR_IMR=0x%08x\n",
1369			   rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_IMR));
1370		seq_printf(m, "R_AX_MPDU_RX_ERR_ISR=0x%08x\n",
1371			   rtw89_read32(rtwdev, R_AX_MPDU_RX_ERR_ISR));
1372	}
1373
1374	if (dmac_err & B_AX_STA_SCHEDULER_ERR_FLAG) {
1375		seq_printf(m, "R_AX_STA_SCHEDULER_ERR_IMR=0x%08x\n",
1376			   rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_IMR));
1377		seq_printf(m, "R_AX_STA_SCHEDULER_ERR_ISR=0x%08x\n",
1378			   rtw89_read32(rtwdev, R_AX_STA_SCHEDULER_ERR_ISR));
1379	}
1380
1381	if (dmac_err & B_AX_WDE_DLE_ERR_FLAG) {
1382		seq_printf(m, "R_AX_WDE_ERR_IMR=0x%08x\n",
1383			   rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR));
1384		seq_printf(m, "R_AX_WDE_ERR_ISR=0x%08x\n",
1385			   rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR));
1386		seq_printf(m, "R_AX_PLE_ERR_IMR=0x%08x\n",
1387			   rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR));
1388		seq_printf(m, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n",
1389			   rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR));
1390	}
1391
1392	if (dmac_err & B_AX_TXPKTCTRL_ERR_FLAG) {
1393		if (chip->chip_id == RTL8852C) {
1394			seq_printf(m, "R_AX_TXPKTCTL_B0_ERRFLAG_IMR=0x%08x\n",
1395				   rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_IMR));
1396			seq_printf(m, "R_AX_TXPKTCTL_B0_ERRFLAG_ISR=0x%08x\n",
1397				   rtw89_read32(rtwdev, R_AX_TXPKTCTL_B0_ERRFLAG_ISR));
1398			seq_printf(m, "R_AX_TXPKTCTL_B1_ERRFLAG_IMR=0x%08x\n",
1399				   rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_IMR));
1400			seq_printf(m, "R_AX_TXPKTCTL_B1_ERRFLAG_ISR=0x%08x\n",
1401				   rtw89_read32(rtwdev, R_AX_TXPKTCTL_B1_ERRFLAG_ISR));
1402		} else {
1403			seq_printf(m, "R_AX_TXPKTCTL_ERR_IMR_ISR=0x%08x\n",
1404				   rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR));
1405			seq_printf(m, "R_AX_TXPKTCTL_ERR_IMR_ISR_B1=0x%08x\n",
1406				   rtw89_read32(rtwdev, R_AX_TXPKTCTL_ERR_IMR_ISR_B1));
1407		}
1408	}
1409
1410	if (dmac_err & B_AX_PLE_DLE_ERR_FLAG) {
1411		seq_printf(m, "R_AX_WDE_ERR_IMR=0x%08x\n",
1412			   rtw89_read32(rtwdev, R_AX_WDE_ERR_IMR));
1413		seq_printf(m, "R_AX_WDE_ERR_ISR=0x%08x\n",
1414			   rtw89_read32(rtwdev, R_AX_WDE_ERR_ISR));
1415		seq_printf(m, "R_AX_PLE_ERR_IMR=0x%08x\n",
1416			   rtw89_read32(rtwdev, R_AX_PLE_ERR_IMR));
1417		seq_printf(m, "R_AX_PLE_ERR_FLAG_ISR=0x%08x\n",
1418			   rtw89_read32(rtwdev, R_AX_PLE_ERR_FLAG_ISR));
1419		seq_printf(m, "R_AX_WD_CPUQ_OP_0=0x%08x\n",
1420			   rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_0));
1421		seq_printf(m, "R_AX_WD_CPUQ_OP_1=0x%08x\n",
1422			   rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_1));
1423		seq_printf(m, "R_AX_WD_CPUQ_OP_2=0x%08x\n",
1424			   rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_2));
1425		seq_printf(m, "R_AX_WD_CPUQ_OP_STATUS=0x%08x\n",
1426			   rtw89_read32(rtwdev, R_AX_WD_CPUQ_OP_STATUS));
1427		seq_printf(m, "R_AX_PL_CPUQ_OP_0=0x%08x\n",
1428			   rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_0));
1429		seq_printf(m, "R_AX_PL_CPUQ_OP_1=0x%08x\n",
1430			   rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_1));
1431		seq_printf(m, "R_AX_PL_CPUQ_OP_2=0x%08x\n",
1432			   rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_2));
1433		seq_printf(m, "R_AX_PL_CPUQ_OP_STATUS=0x%08x\n",
1434			   rtw89_read32(rtwdev, R_AX_PL_CPUQ_OP_STATUS));
1435		if (chip->chip_id == RTL8852C) {
1436			seq_printf(m, "R_AX_RX_CTRL0=0x%08x\n",
1437				   rtw89_read32(rtwdev, R_AX_RX_CTRL0));
1438			seq_printf(m, "R_AX_RX_CTRL1=0x%08x\n",
1439				   rtw89_read32(rtwdev, R_AX_RX_CTRL1));
1440			seq_printf(m, "R_AX_RX_CTRL2=0x%08x\n",
1441				   rtw89_read32(rtwdev, R_AX_RX_CTRL2));
1442		} else {
1443			seq_printf(m, "R_AX_RXDMA_PKT_INFO_0=0x%08x\n",
1444				   rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_0));
1445			seq_printf(m, "R_AX_RXDMA_PKT_INFO_1=0x%08x\n",
1446				   rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_1));
1447			seq_printf(m, "R_AX_RXDMA_PKT_INFO_2=0x%08x\n",
1448				   rtw89_read32(rtwdev, R_AX_RXDMA_PKT_INFO_2));
1449		}
1450	}
1451
1452	if (dmac_err & B_AX_PKTIN_ERR_FLAG) {
1453		seq_printf(m, "R_AX_PKTIN_ERR_IMR=0x%08x\n",
1454			   rtw89_read32(rtwdev, R_AX_PKTIN_ERR_IMR));
1455		seq_printf(m, "R_AX_PKTIN_ERR_ISR=0x%08x\n",
1456			   rtw89_read32(rtwdev, R_AX_PKTIN_ERR_ISR));
1457	}
1458
1459	if (dmac_err & B_AX_DISPATCH_ERR_FLAG) {
1460		seq_printf(m, "R_AX_HOST_DISPATCHER_ERR_IMR=0x%08x\n",
1461			   rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_IMR));
1462		seq_printf(m, "R_AX_HOST_DISPATCHER_ERR_ISR=0x%08x\n",
1463			   rtw89_read32(rtwdev, R_AX_HOST_DISPATCHER_ERR_ISR));
1464		seq_printf(m, "R_AX_CPU_DISPATCHER_ERR_IMR=0x%08x\n",
1465			   rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_IMR));
1466		seq_printf(m, "R_AX_CPU_DISPATCHER_ERR_ISR=0x%08x\n",
1467			   rtw89_read32(rtwdev, R_AX_CPU_DISPATCHER_ERR_ISR));
1468		seq_printf(m, "R_AX_OTHER_DISPATCHER_ERR_IMR=0x%08x\n",
1469			   rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_IMR));
1470		seq_printf(m, "R_AX_OTHER_DISPATCHER_ERR_ISR=0x%08x\n",
1471			   rtw89_read32(rtwdev, R_AX_OTHER_DISPATCHER_ERR_ISR));
1472	}
1473
1474	if (dmac_err & B_AX_BBRPT_ERR_FLAG) {
1475		if (chip->chip_id == RTL8852C) {
1476			seq_printf(m, "R_AX_BBRPT_COM_ERR_IMR=0x%08x\n",
1477				   rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR));
1478			seq_printf(m, "R_AX_BBRPT_COM_ERR_ISR=0x%08x\n",
1479				   rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_ISR));
1480			seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n",
1481				   rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR));
1482			seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n",
1483				   rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR));
1484			seq_printf(m, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n",
1485				   rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR));
1486			seq_printf(m, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n",
1487				   rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR));
1488		} else {
1489			seq_printf(m, "R_AX_BBRPT_COM_ERR_IMR_ISR=0x%08x\n",
1490				   rtw89_read32(rtwdev, R_AX_BBRPT_COM_ERR_IMR_ISR));
1491			seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_ISR=0x%08x\n",
1492				   rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_ISR));
1493			seq_printf(m, "R_AX_BBRPT_CHINFO_ERR_IMR=0x%08x\n",
1494				   rtw89_read32(rtwdev, R_AX_BBRPT_CHINFO_ERR_IMR));
1495			seq_printf(m, "R_AX_BBRPT_DFS_ERR_IMR=0x%08x\n",
1496				   rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_IMR));
1497			seq_printf(m, "R_AX_BBRPT_DFS_ERR_ISR=0x%08x\n",
1498				   rtw89_read32(rtwdev, R_AX_BBRPT_DFS_ERR_ISR));
1499		}
1500	}
1501
1502	if (dmac_err & B_AX_HAXIDMA_ERR_FLAG && chip->chip_id == RTL8852C) {
1503		seq_printf(m, "R_AX_HAXIDMA_ERR_IMR=0x%08x\n",
1504			   rtw89_read32(rtwdev, R_AX_HAXI_IDCT_MSK));
1505		seq_printf(m, "R_AX_HAXIDMA_ERR_ISR=0x%08x\n",
1506			   rtw89_read32(rtwdev, R_AX_HAXI_IDCT));
1507	}
1508
1509	return 0;
1510}
1511
1512static int rtw89_debug_mac_dump_cmac_err(struct rtw89_dev *rtwdev,
1513					 struct seq_file *m,
1514					 enum rtw89_mac_idx band)
1515{
1516	const struct rtw89_chip_info *chip = rtwdev->chip;
1517	u32 offset = 0;
1518	u32 cmac_err;
1519	int ret;
1520
1521	ret = rtw89_mac_check_mac_en(rtwdev, band, RTW89_CMAC_SEL);
1522	if (ret) {
1523		if (band)
1524			seq_puts(m, "[CMAC] : CMAC1 not enabled\n");
1525		else
1526			seq_puts(m, "[CMAC] : CMAC0 not enabled\n");
1527		return ret;
1528	}
1529
1530	if (band)
1531		offset = RTW89_MAC_AX_BAND_REG_OFFSET;
1532
1533	cmac_err = rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset);
1534	seq_printf(m, "R_AX_CMAC_ERR_ISR [%d]=0x%08x\n", band,
1535		   rtw89_read32(rtwdev, R_AX_CMAC_ERR_ISR + offset));
1536	seq_printf(m, "R_AX_CMAC_FUNC_EN [%d]=0x%08x\n", band,
1537		   rtw89_read32(rtwdev, R_AX_CMAC_FUNC_EN + offset));
1538	seq_printf(m, "R_AX_CK_EN [%d]=0x%08x\n", band,
1539		   rtw89_read32(rtwdev, R_AX_CK_EN + offset));
1540
1541	if (cmac_err & B_AX_SCHEDULE_TOP_ERR_IND) {
1542		seq_printf(m, "R_AX_SCHEDULE_ERR_IMR [%d]=0x%08x\n", band,
1543			   rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_IMR + offset));
1544		seq_printf(m, "R_AX_SCHEDULE_ERR_ISR [%d]=0x%08x\n", band,
1545			   rtw89_read32(rtwdev, R_AX_SCHEDULE_ERR_ISR + offset));
1546	}
1547
1548	if (cmac_err & B_AX_PTCL_TOP_ERR_IND) {
1549		seq_printf(m, "R_AX_PTCL_IMR0 [%d]=0x%08x\n", band,
1550			   rtw89_read32(rtwdev, R_AX_PTCL_IMR0 + offset));
1551		seq_printf(m, "R_AX_PTCL_ISR0 [%d]=0x%08x\n", band,
1552			   rtw89_read32(rtwdev, R_AX_PTCL_ISR0 + offset));
1553	}
1554
1555	if (cmac_err & B_AX_DMA_TOP_ERR_IND) {
1556		if (chip->chip_id == RTL8852C) {
1557			seq_printf(m, "R_AX_RX_ERR_FLAG [%d]=0x%08x\n", band,
1558				   rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG + offset));
1559			seq_printf(m, "R_AX_RX_ERR_FLAG_IMR [%d]=0x%08x\n", band,
1560				   rtw89_read32(rtwdev, R_AX_RX_ERR_FLAG_IMR + offset));
1561		} else {
1562			seq_printf(m, "R_AX_DLE_CTRL [%d]=0x%08x\n", band,
1563				   rtw89_read32(rtwdev, R_AX_DLE_CTRL + offset));
1564		}
1565	}
1566
1567	if (cmac_err & B_AX_DMA_TOP_ERR_IND || cmac_err & B_AX_WMAC_RX_ERR_IND) {
1568		if (chip->chip_id == RTL8852C) {
1569			seq_printf(m, "R_AX_PHYINFO_ERR_ISR [%d]=0x%08x\n", band,
1570				   rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_ISR + offset));
1571			seq_printf(m, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band,
1572				   rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset));
1573		} else {
1574			seq_printf(m, "R_AX_PHYINFO_ERR_IMR [%d]=0x%08x\n", band,
1575				   rtw89_read32(rtwdev, R_AX_PHYINFO_ERR_IMR + offset));
1576		}
1577	}
1578
1579	if (cmac_err & B_AX_TXPWR_CTRL_ERR_IND) {
1580		seq_printf(m, "R_AX_TXPWR_IMR [%d]=0x%08x\n", band,
1581			   rtw89_read32(rtwdev, R_AX_TXPWR_IMR + offset));
1582		seq_printf(m, "R_AX_TXPWR_ISR [%d]=0x%08x\n", band,
1583			   rtw89_read32(rtwdev, R_AX_TXPWR_ISR + offset));
1584	}
1585
1586	if (cmac_err & B_AX_WMAC_TX_ERR_IND) {
1587		if (chip->chip_id == RTL8852C) {
1588			seq_printf(m, "R_AX_TRXPTCL_ERROR_INDICA [%d]=0x%08x\n", band,
1589				   rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA + offset));
1590			seq_printf(m, "R_AX_TRXPTCL_ERROR_INDICA_MASK [%d]=0x%08x\n", band,
1591				   rtw89_read32(rtwdev, R_AX_TRXPTCL_ERROR_INDICA_MASK + offset));
1592		} else {
1593			seq_printf(m, "R_AX_TMAC_ERR_IMR_ISR [%d]=0x%08x\n", band,
1594				   rtw89_read32(rtwdev, R_AX_TMAC_ERR_IMR_ISR + offset));
1595		}
1596		seq_printf(m, "R_AX_DBGSEL_TRXPTCL [%d]=0x%08x\n", band,
1597			   rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL + offset));
1598	}
1599
1600	seq_printf(m, "R_AX_CMAC_ERR_IMR [%d]=0x%08x\n", band,
1601		   rtw89_read32(rtwdev, R_AX_CMAC_ERR_IMR + offset));
1602
1603	return 0;
1604}
1605
1606static int rtw89_debug_mac_dump_cmac_dbg(struct rtw89_dev *rtwdev,
1607					 struct seq_file *m)
1608{
1609	rtw89_debug_mac_dump_cmac_err(rtwdev, m, RTW89_MAC_0);
1610	if (rtwdev->dbcc_en)
1611		rtw89_debug_mac_dump_cmac_err(rtwdev, m, RTW89_MAC_1);
1612
1613	return 0;
1614}
1615
1616static const struct rtw89_mac_dbg_port_info dbg_port_ptcl_c0 = {
1617	.sel_addr = R_AX_PTCL_DBG,
1618	.sel_byte = 1,
1619	.sel_msk = B_AX_PTCL_DBG_SEL_MASK,
1620	.srt = 0x00,
1621	.end = 0x3F,
1622	.rd_addr = R_AX_PTCL_DBG_INFO,
1623	.rd_byte = 4,
1624	.rd_msk = B_AX_PTCL_DBG_INFO_MASK
1625};
1626
1627static const struct rtw89_mac_dbg_port_info dbg_port_ptcl_c1 = {
1628	.sel_addr = R_AX_PTCL_DBG_C1,
1629	.sel_byte = 1,
1630	.sel_msk = B_AX_PTCL_DBG_SEL_MASK,
1631	.srt = 0x00,
1632	.end = 0x3F,
1633	.rd_addr = R_AX_PTCL_DBG_INFO_C1,
1634	.rd_byte = 4,
1635	.rd_msk = B_AX_PTCL_DBG_INFO_MASK
1636};
1637
1638static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx0_5 = {
1639	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1640	.sel_byte = 2,
1641	.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
1642	.srt = 0x0,
1643	.end = 0xD,
1644	.rd_addr = R_AX_DBG_PORT_SEL,
1645	.rd_byte = 4,
1646	.rd_msk = B_AX_DEBUG_ST_MASK
1647};
1648
1649static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx6 = {
1650	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1651	.sel_byte = 2,
1652	.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
1653	.srt = 0x0,
1654	.end = 0x5,
1655	.rd_addr = R_AX_DBG_PORT_SEL,
1656	.rd_byte = 4,
1657	.rd_msk = B_AX_DEBUG_ST_MASK
1658};
1659
1660static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx7 = {
1661	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1662	.sel_byte = 2,
1663	.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
1664	.srt = 0x0,
1665	.end = 0x9,
1666	.rd_addr = R_AX_DBG_PORT_SEL,
1667	.rd_byte = 4,
1668	.rd_msk = B_AX_DEBUG_ST_MASK
1669};
1670
1671static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx8 = {
1672	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1673	.sel_byte = 2,
1674	.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
1675	.srt = 0x0,
1676	.end = 0x3,
1677	.rd_addr = R_AX_DBG_PORT_SEL,
1678	.rd_byte = 4,
1679	.rd_msk = B_AX_DEBUG_ST_MASK
1680};
1681
1682static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_tx9_C = {
1683	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1684	.sel_byte = 2,
1685	.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
1686	.srt = 0x0,
1687	.end = 0x1,
1688	.rd_addr = R_AX_DBG_PORT_SEL,
1689	.rd_byte = 4,
1690	.rd_msk = B_AX_DEBUG_ST_MASK
1691};
1692
1693static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_txD = {
1694	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1695	.sel_byte = 2,
1696	.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
1697	.srt = 0x0,
1698	.end = 0x0,
1699	.rd_addr = R_AX_DBG_PORT_SEL,
1700	.rd_byte = 4,
1701	.rd_msk = B_AX_DEBUG_ST_MASK
1702};
1703
1704static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx0 = {
1705	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1706	.sel_byte = 2,
1707	.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
1708	.srt = 0x0,
1709	.end = 0xB,
1710	.rd_addr = R_AX_DBG_PORT_SEL,
1711	.rd_byte = 4,
1712	.rd_msk = B_AX_DEBUG_ST_MASK
1713};
1714
1715static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx1 = {
1716	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1717	.sel_byte = 2,
1718	.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
1719	.srt = 0x0,
1720	.end = 0x4,
1721	.rd_addr = R_AX_DBG_PORT_SEL,
1722	.rd_byte = 4,
1723	.rd_msk = B_AX_DEBUG_ST_MASK
1724};
1725
1726static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx3 = {
1727	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1728	.sel_byte = 2,
1729	.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
1730	.srt = 0x0,
1731	.end = 0x8,
1732	.rd_addr = R_AX_DBG_PORT_SEL,
1733	.rd_byte = 4,
1734	.rd_msk = B_AX_DEBUG_ST_MASK
1735};
1736
1737static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx4 = {
1738	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1739	.sel_byte = 2,
1740	.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
1741	.srt = 0x0,
1742	.end = 0x7,
1743	.rd_addr = R_AX_DBG_PORT_SEL,
1744	.rd_byte = 4,
1745	.rd_msk = B_AX_DEBUG_ST_MASK
1746};
1747
1748static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx5_8 = {
1749	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1750	.sel_byte = 2,
1751	.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
1752	.srt = 0x0,
1753	.end = 0x1,
1754	.rd_addr = R_AX_DBG_PORT_SEL,
1755	.rd_byte = 4,
1756	.rd_msk = B_AX_DEBUG_ST_MASK
1757};
1758
1759static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_tx9 = {
1760	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1761	.sel_byte = 2,
1762	.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
1763	.srt = 0x0,
1764	.end = 0x3,
1765	.rd_addr = R_AX_DBG_PORT_SEL,
1766	.rd_byte = 4,
1767	.rd_msk = B_AX_DEBUG_ST_MASK
1768};
1769
1770static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_txA_C = {
1771	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1772	.sel_byte = 2,
1773	.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
1774	.srt = 0x0,
1775	.end = 0x0,
1776	.rd_addr = R_AX_DBG_PORT_SEL,
1777	.rd_byte = 4,
1778	.rd_msk = B_AX_DEBUG_ST_MASK
1779};
1780
1781static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx0 = {
1782	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1783	.sel_byte = 2,
1784	.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
1785	.srt = 0x0,
1786	.end = 0x8,
1787	.rd_addr = R_AX_DBG_PORT_SEL,
1788	.rd_byte = 4,
1789	.rd_msk = B_AX_DEBUG_ST_MASK
1790};
1791
1792static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx1_2 = {
1793	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1794	.sel_byte = 2,
1795	.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
1796	.srt = 0x0,
1797	.end = 0x0,
1798	.rd_addr = R_AX_DBG_PORT_SEL,
1799	.rd_byte = 4,
1800	.rd_msk = B_AX_DEBUG_ST_MASK
1801};
1802
1803static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx3 = {
1804	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1805	.sel_byte = 2,
1806	.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
1807	.srt = 0x0,
1808	.end = 0x6,
1809	.rd_addr = R_AX_DBG_PORT_SEL,
1810	.rd_byte = 4,
1811	.rd_msk = B_AX_DEBUG_ST_MASK
1812};
1813
1814static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx4 = {
1815	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1816	.sel_byte = 2,
1817	.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
1818	.srt = 0x0,
1819	.end = 0x0,
1820	.rd_addr = R_AX_DBG_PORT_SEL,
1821	.rd_byte = 4,
1822	.rd_msk = B_AX_DEBUG_ST_MASK
1823};
1824
1825static const struct rtw89_mac_dbg_port_info dbg_port_dspt_hdt_rx5 = {
1826	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1827	.sel_byte = 2,
1828	.sel_msk = B_AX_DISPATCHER_DBG_SEL_MASK,
1829	.srt = 0x0,
1830	.end = 0x0,
1831	.rd_addr = R_AX_DBG_PORT_SEL,
1832	.rd_byte = 4,
1833	.rd_msk = B_AX_DEBUG_ST_MASK
1834};
1835
1836static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p0_0 = {
1837	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1838	.sel_byte = 1,
1839	.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
1840	.srt = 0x0,
1841	.end = 0x3,
1842	.rd_addr = R_AX_DBG_PORT_SEL,
1843	.rd_byte = 4,
1844	.rd_msk = B_AX_DEBUG_ST_MASK
1845};
1846
1847static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p0_1 = {
1848	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1849	.sel_byte = 1,
1850	.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
1851	.srt = 0x0,
1852	.end = 0x6,
1853	.rd_addr = R_AX_DBG_PORT_SEL,
1854	.rd_byte = 4,
1855	.rd_msk = B_AX_DEBUG_ST_MASK
1856};
1857
1858static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p0_2 = {
1859	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1860	.sel_byte = 1,
1861	.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
1862	.srt = 0x0,
1863	.end = 0x0,
1864	.rd_addr = R_AX_DBG_PORT_SEL,
1865	.rd_byte = 4,
1866	.rd_msk = B_AX_DEBUG_ST_MASK
1867};
1868
1869static const struct rtw89_mac_dbg_port_info dbg_port_dspt_cdt_rx_p1 = {
1870	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1871	.sel_byte = 1,
1872	.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
1873	.srt = 0x8,
1874	.end = 0xE,
1875	.rd_addr = R_AX_DBG_PORT_SEL,
1876	.rd_byte = 4,
1877	.rd_msk = B_AX_DEBUG_ST_MASK
1878};
1879
1880static const struct rtw89_mac_dbg_port_info dbg_port_dspt_stf_ctrl = {
1881	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1882	.sel_byte = 1,
1883	.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
1884	.srt = 0x0,
1885	.end = 0x5,
1886	.rd_addr = R_AX_DBG_PORT_SEL,
1887	.rd_byte = 4,
1888	.rd_msk = B_AX_DEBUG_ST_MASK
1889};
1890
1891static const struct rtw89_mac_dbg_port_info dbg_port_dspt_addr_ctrl = {
1892	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1893	.sel_byte = 1,
1894	.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
1895	.srt = 0x0,
1896	.end = 0x6,
1897	.rd_addr = R_AX_DBG_PORT_SEL,
1898	.rd_byte = 4,
1899	.rd_msk = B_AX_DEBUG_ST_MASK
1900};
1901
1902static const struct rtw89_mac_dbg_port_info dbg_port_dspt_wde_intf = {
1903	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1904	.sel_byte = 1,
1905	.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
1906	.srt = 0x0,
1907	.end = 0xF,
1908	.rd_addr = R_AX_DBG_PORT_SEL,
1909	.rd_byte = 4,
1910	.rd_msk = B_AX_DEBUG_ST_MASK
1911};
1912
1913static const struct rtw89_mac_dbg_port_info dbg_port_dspt_ple_intf = {
1914	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1915	.sel_byte = 1,
1916	.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
1917	.srt = 0x0,
1918	.end = 0x9,
1919	.rd_addr = R_AX_DBG_PORT_SEL,
1920	.rd_byte = 4,
1921	.rd_msk = B_AX_DEBUG_ST_MASK
1922};
1923
1924static const struct rtw89_mac_dbg_port_info dbg_port_dspt_flow_ctrl = {
1925	.sel_addr = R_AX_DISPATCHER_DBG_PORT,
1926	.sel_byte = 1,
1927	.sel_msk = B_AX_DISPATCHER_CH_SEL_MASK,
1928	.srt = 0x0,
1929	.end = 0x3,
1930	.rd_addr = R_AX_DBG_PORT_SEL,
1931	.rd_byte = 4,
1932	.rd_msk = B_AX_DEBUG_ST_MASK
1933};
1934
1935static const struct rtw89_mac_dbg_port_info dbg_port_sch_c0 = {
1936	.sel_addr = R_AX_SCH_DBG_SEL,
1937	.sel_byte = 1,
1938	.sel_msk = B_AX_SCH_DBG_SEL_MASK,
1939	.srt = 0x00,
1940	.end = 0x2F,
1941	.rd_addr = R_AX_SCH_DBG,
1942	.rd_byte = 4,
1943	.rd_msk = B_AX_SCHEDULER_DBG_MASK
1944};
1945
1946static const struct rtw89_mac_dbg_port_info dbg_port_sch_c1 = {
1947	.sel_addr = R_AX_SCH_DBG_SEL_C1,
1948	.sel_byte = 1,
1949	.sel_msk = B_AX_SCH_DBG_SEL_MASK,
1950	.srt = 0x00,
1951	.end = 0x2F,
1952	.rd_addr = R_AX_SCH_DBG_C1,
1953	.rd_byte = 4,
1954	.rd_msk = B_AX_SCHEDULER_DBG_MASK
1955};
1956
1957static const struct rtw89_mac_dbg_port_info dbg_port_tmac_c0 = {
1958	.sel_addr = R_AX_MACTX_DBG_SEL_CNT,
1959	.sel_byte = 1,
1960	.sel_msk = B_AX_DBGSEL_MACTX_MASK,
1961	.srt = 0x00,
1962	.end = 0x19,
1963	.rd_addr = R_AX_DBG_PORT_SEL,
1964	.rd_byte = 4,
1965	.rd_msk = B_AX_DEBUG_ST_MASK
1966};
1967
1968static const struct rtw89_mac_dbg_port_info dbg_port_tmac_c1 = {
1969	.sel_addr = R_AX_MACTX_DBG_SEL_CNT_C1,
1970	.sel_byte = 1,
1971	.sel_msk = B_AX_DBGSEL_MACTX_MASK,
1972	.srt = 0x00,
1973	.end = 0x19,
1974	.rd_addr = R_AX_DBG_PORT_SEL,
1975	.rd_byte = 4,
1976	.rd_msk = B_AX_DEBUG_ST_MASK
1977};
1978
1979static const struct rtw89_mac_dbg_port_info dbg_port_rmac_c0 = {
1980	.sel_addr = R_AX_RX_DEBUG_SELECT,
1981	.sel_byte = 1,
1982	.sel_msk = B_AX_DEBUG_SEL_MASK,
1983	.srt = 0x00,
1984	.end = 0x58,
1985	.rd_addr = R_AX_DBG_PORT_SEL,
1986	.rd_byte = 4,
1987	.rd_msk = B_AX_DEBUG_ST_MASK
1988};
1989
1990static const struct rtw89_mac_dbg_port_info dbg_port_rmac_c1 = {
1991	.sel_addr = R_AX_RX_DEBUG_SELECT_C1,
1992	.sel_byte = 1,
1993	.sel_msk = B_AX_DEBUG_SEL_MASK,
1994	.srt = 0x00,
1995	.end = 0x58,
1996	.rd_addr = R_AX_DBG_PORT_SEL,
1997	.rd_byte = 4,
1998	.rd_msk = B_AX_DEBUG_ST_MASK
1999};
2000
2001static const struct rtw89_mac_dbg_port_info dbg_port_rmacst_c0 = {
2002	.sel_addr = R_AX_RX_STATE_MONITOR,
2003	.sel_byte = 1,
2004	.sel_msk = B_AX_STATE_SEL_MASK,
2005	.srt = 0x00,
2006	.end = 0x17,
2007	.rd_addr = R_AX_RX_STATE_MONITOR,
2008	.rd_byte = 4,
2009	.rd_msk = B_AX_RX_STATE_MONITOR_MASK
2010};
2011
2012static const struct rtw89_mac_dbg_port_info dbg_port_rmacst_c1 = {
2013	.sel_addr = R_AX_RX_STATE_MONITOR_C1,
2014	.sel_byte = 1,
2015	.sel_msk = B_AX_STATE_SEL_MASK,
2016	.srt = 0x00,
2017	.end = 0x17,
2018	.rd_addr = R_AX_RX_STATE_MONITOR_C1,
2019	.rd_byte = 4,
2020	.rd_msk = B_AX_RX_STATE_MONITOR_MASK
2021};
2022
2023static const struct rtw89_mac_dbg_port_info dbg_port_rmac_plcp_c0 = {
2024	.sel_addr = R_AX_RMAC_PLCP_MON,
2025	.sel_byte = 4,
2026	.sel_msk = B_AX_PCLP_MON_SEL_MASK,
2027	.srt = 0x0,
2028	.end = 0xF,
2029	.rd_addr = R_AX_RMAC_PLCP_MON,
2030	.rd_byte = 4,
2031	.rd_msk = B_AX_RMAC_PLCP_MON_MASK
2032};
2033
2034static const struct rtw89_mac_dbg_port_info dbg_port_rmac_plcp_c1 = {
2035	.sel_addr = R_AX_RMAC_PLCP_MON_C1,
2036	.sel_byte = 4,
2037	.sel_msk = B_AX_PCLP_MON_SEL_MASK,
2038	.srt = 0x0,
2039	.end = 0xF,
2040	.rd_addr = R_AX_RMAC_PLCP_MON_C1,
2041	.rd_byte = 4,
2042	.rd_msk = B_AX_RMAC_PLCP_MON_MASK
2043};
2044
2045static const struct rtw89_mac_dbg_port_info dbg_port_trxptcl_c0 = {
2046	.sel_addr = R_AX_DBGSEL_TRXPTCL,
2047	.sel_byte = 1,
2048	.sel_msk = B_AX_DBGSEL_TRXPTCL_MASK,
2049	.srt = 0x08,
2050	.end = 0x10,
2051	.rd_addr = R_AX_DBG_PORT_SEL,
2052	.rd_byte = 4,
2053	.rd_msk = B_AX_DEBUG_ST_MASK
2054};
2055
2056static const struct rtw89_mac_dbg_port_info dbg_port_trxptcl_c1 = {
2057	.sel_addr = R_AX_DBGSEL_TRXPTCL_C1,
2058	.sel_byte = 1,
2059	.sel_msk = B_AX_DBGSEL_TRXPTCL_MASK,
2060	.srt = 0x08,
2061	.end = 0x10,
2062	.rd_addr = R_AX_DBG_PORT_SEL,
2063	.rd_byte = 4,
2064	.rd_msk = B_AX_DEBUG_ST_MASK
2065};
2066
2067static const struct rtw89_mac_dbg_port_info dbg_port_tx_infol_c0 = {
2068	.sel_addr = R_AX_WMAC_TX_CTRL_DEBUG,
2069	.sel_byte = 1,
2070	.sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK,
2071	.srt = 0x00,
2072	.end = 0x07,
2073	.rd_addr = R_AX_WMAC_TX_INFO0_DEBUG,
2074	.rd_byte = 4,
2075	.rd_msk = B_AX_TX_CTRL_INFO_P0_MASK
2076};
2077
2078static const struct rtw89_mac_dbg_port_info dbg_port_tx_infoh_c0 = {
2079	.sel_addr = R_AX_WMAC_TX_CTRL_DEBUG,
2080	.sel_byte = 1,
2081	.sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK,
2082	.srt = 0x00,
2083	.end = 0x07,
2084	.rd_addr = R_AX_WMAC_TX_INFO1_DEBUG,
2085	.rd_byte = 4,
2086	.rd_msk = B_AX_TX_CTRL_INFO_P1_MASK
2087};
2088
2089static const struct rtw89_mac_dbg_port_info dbg_port_tx_infol_c1 = {
2090	.sel_addr = R_AX_WMAC_TX_CTRL_DEBUG_C1,
2091	.sel_byte = 1,
2092	.sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK,
2093	.srt = 0x00,
2094	.end = 0x07,
2095	.rd_addr = R_AX_WMAC_TX_INFO0_DEBUG_C1,
2096	.rd_byte = 4,
2097	.rd_msk = B_AX_TX_CTRL_INFO_P0_MASK
2098};
2099
2100static const struct rtw89_mac_dbg_port_info dbg_port_tx_infoh_c1 = {
2101	.sel_addr = R_AX_WMAC_TX_CTRL_DEBUG_C1,
2102	.sel_byte = 1,
2103	.sel_msk = B_AX_TX_CTRL_DEBUG_SEL_MASK,
2104	.srt = 0x00,
2105	.end = 0x07,
2106	.rd_addr = R_AX_WMAC_TX_INFO1_DEBUG_C1,
2107	.rd_byte = 4,
2108	.rd_msk = B_AX_TX_CTRL_INFO_P1_MASK
2109};
2110
2111static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infol_c0 = {
2112	.sel_addr = R_AX_WMAC_TX_TF_INFO_0,
2113	.sel_byte = 1,
2114	.sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK,
2115	.srt = 0x00,
2116	.end = 0x04,
2117	.rd_addr = R_AX_WMAC_TX_TF_INFO_1,
2118	.rd_byte = 4,
2119	.rd_msk = B_AX_WMAC_TX_TF_INFO_P0_MASK
2120};
2121
2122static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infoh_c0 = {
2123	.sel_addr = R_AX_WMAC_TX_TF_INFO_0,
2124	.sel_byte = 1,
2125	.sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK,
2126	.srt = 0x00,
2127	.end = 0x04,
2128	.rd_addr = R_AX_WMAC_TX_TF_INFO_2,
2129	.rd_byte = 4,
2130	.rd_msk = B_AX_WMAC_TX_TF_INFO_P1_MASK
2131};
2132
2133static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infol_c1 = {
2134	.sel_addr = R_AX_WMAC_TX_TF_INFO_0_C1,
2135	.sel_byte = 1,
2136	.sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK,
2137	.srt = 0x00,
2138	.end = 0x04,
2139	.rd_addr = R_AX_WMAC_TX_TF_INFO_1_C1,
2140	.rd_byte = 4,
2141	.rd_msk = B_AX_WMAC_TX_TF_INFO_P0_MASK
2142};
2143
2144static const struct rtw89_mac_dbg_port_info dbg_port_txtf_infoh_c1 = {
2145	.sel_addr = R_AX_WMAC_TX_TF_INFO_0_C1,
2146	.sel_byte = 1,
2147	.sel_msk = B_AX_WMAC_TX_TF_INFO_SEL_MASK,
2148	.srt = 0x00,
2149	.end = 0x04,
2150	.rd_addr = R_AX_WMAC_TX_TF_INFO_2_C1,
2151	.rd_byte = 4,
2152	.rd_msk = B_AX_WMAC_TX_TF_INFO_P1_MASK
2153};
2154
2155static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_freepg = {
2156	.sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL,
2157	.sel_byte = 4,
2158	.sel_msk = B_AX_WDE_DFI_DATA_MASK,
2159	.srt = 0x80000000,
2160	.end = 0x80000001,
2161	.rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA,
2162	.rd_byte = 4,
2163	.rd_msk = B_AX_WDE_DFI_DATA_MASK
2164};
2165
2166static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_quota = {
2167	.sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL,
2168	.sel_byte = 4,
2169	.sel_msk = B_AX_WDE_DFI_DATA_MASK,
2170	.srt = 0x80010000,
2171	.end = 0x80010004,
2172	.rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA,
2173	.rd_byte = 4,
2174	.rd_msk = B_AX_WDE_DFI_DATA_MASK
2175};
2176
2177static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_pagellt = {
2178	.sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL,
2179	.sel_byte = 4,
2180	.sel_msk = B_AX_WDE_DFI_DATA_MASK,
2181	.srt = 0x80020000,
2182	.end = 0x80020FFF,
2183	.rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA,
2184	.rd_byte = 4,
2185	.rd_msk = B_AX_WDE_DFI_DATA_MASK
2186};
2187
2188static const struct rtw89_mac_dbg_port_info dbg_port_wde_bufmgn_pktinfo = {
2189	.sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL,
2190	.sel_byte = 4,
2191	.sel_msk = B_AX_WDE_DFI_DATA_MASK,
2192	.srt = 0x80030000,
2193	.end = 0x80030FFF,
2194	.rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA,
2195	.rd_byte = 4,
2196	.rd_msk = B_AX_WDE_DFI_DATA_MASK
2197};
2198
2199static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_prepkt = {
2200	.sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL,
2201	.sel_byte = 4,
2202	.sel_msk = B_AX_WDE_DFI_DATA_MASK,
2203	.srt = 0x80040000,
2204	.end = 0x80040FFF,
2205	.rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA,
2206	.rd_byte = 4,
2207	.rd_msk = B_AX_WDE_DFI_DATA_MASK
2208};
2209
2210static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_nxtpkt = {
2211	.sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL,
2212	.sel_byte = 4,
2213	.sel_msk = B_AX_WDE_DFI_DATA_MASK,
2214	.srt = 0x80050000,
2215	.end = 0x80050FFF,
2216	.rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA,
2217	.rd_byte = 4,
2218	.rd_msk = B_AX_WDE_DFI_DATA_MASK
2219};
2220
2221static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_qlnktbl = {
2222	.sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL,
2223	.sel_byte = 4,
2224	.sel_msk = B_AX_WDE_DFI_DATA_MASK,
2225	.srt = 0x80060000,
2226	.end = 0x80060453,
2227	.rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA,
2228	.rd_byte = 4,
2229	.rd_msk = B_AX_WDE_DFI_DATA_MASK
2230};
2231
2232static const struct rtw89_mac_dbg_port_info dbg_port_wde_quemgn_qempty = {
2233	.sel_addr = R_AX_WDE_DBG_FUN_INTF_CTL,
2234	.sel_byte = 4,
2235	.sel_msk = B_AX_WDE_DFI_DATA_MASK,
2236	.srt = 0x80070000,
2237	.end = 0x80070011,
2238	.rd_addr = R_AX_WDE_DBG_FUN_INTF_DATA,
2239	.rd_byte = 4,
2240	.rd_msk = B_AX_WDE_DFI_DATA_MASK
2241};
2242
2243static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_freepg = {
2244	.sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL,
2245	.sel_byte = 4,
2246	.sel_msk = B_AX_PLE_DFI_DATA_MASK,
2247	.srt = 0x80000000,
2248	.end = 0x80000001,
2249	.rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA,
2250	.rd_byte = 4,
2251	.rd_msk = B_AX_PLE_DFI_DATA_MASK
2252};
2253
2254static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_quota = {
2255	.sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL,
2256	.sel_byte = 4,
2257	.sel_msk = B_AX_PLE_DFI_DATA_MASK,
2258	.srt = 0x80010000,
2259	.end = 0x8001000A,
2260	.rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA,
2261	.rd_byte = 4,
2262	.rd_msk = B_AX_PLE_DFI_DATA_MASK
2263};
2264
2265static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_pagellt = {
2266	.sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL,
2267	.sel_byte = 4,
2268	.sel_msk = B_AX_PLE_DFI_DATA_MASK,
2269	.srt = 0x80020000,
2270	.end = 0x80020DBF,
2271	.rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA,
2272	.rd_byte = 4,
2273	.rd_msk = B_AX_PLE_DFI_DATA_MASK
2274};
2275
2276static const struct rtw89_mac_dbg_port_info dbg_port_ple_bufmgn_pktinfo = {
2277	.sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL,
2278	.sel_byte = 4,
2279	.sel_msk = B_AX_PLE_DFI_DATA_MASK,
2280	.srt = 0x80030000,
2281	.end = 0x80030DBF,
2282	.rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA,
2283	.rd_byte = 4,
2284	.rd_msk = B_AX_PLE_DFI_DATA_MASK
2285};
2286
2287static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_prepkt = {
2288	.sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL,
2289	.sel_byte = 4,
2290	.sel_msk = B_AX_PLE_DFI_DATA_MASK,
2291	.srt = 0x80040000,
2292	.end = 0x80040DBF,
2293	.rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA,
2294	.rd_byte = 4,
2295	.rd_msk = B_AX_PLE_DFI_DATA_MASK
2296};
2297
2298static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_nxtpkt = {
2299	.sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL,
2300	.sel_byte = 4,
2301	.sel_msk = B_AX_PLE_DFI_DATA_MASK,
2302	.srt = 0x80050000,
2303	.end = 0x80050DBF,
2304	.rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA,
2305	.rd_byte = 4,
2306	.rd_msk = B_AX_PLE_DFI_DATA_MASK
2307};
2308
2309static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_qlnktbl = {
2310	.sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL,
2311	.sel_byte = 4,
2312	.sel_msk = B_AX_PLE_DFI_DATA_MASK,
2313	.srt = 0x80060000,
2314	.end = 0x80060041,
2315	.rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA,
2316	.rd_byte = 4,
2317	.rd_msk = B_AX_PLE_DFI_DATA_MASK
2318};
2319
2320static const struct rtw89_mac_dbg_port_info dbg_port_ple_quemgn_qempty = {
2321	.sel_addr = R_AX_PLE_DBG_FUN_INTF_CTL,
2322	.sel_byte = 4,
2323	.sel_msk = B_AX_PLE_DFI_DATA_MASK,
2324	.srt = 0x80070000,
2325	.end = 0x80070001,
2326	.rd_addr = R_AX_PLE_DBG_FUN_INTF_DATA,
2327	.rd_byte = 4,
2328	.rd_msk = B_AX_PLE_DFI_DATA_MASK
2329};
2330
2331static const struct rtw89_mac_dbg_port_info dbg_port_pktinfo = {
2332	.sel_addr = R_AX_DBG_FUN_INTF_CTL,
2333	.sel_byte = 4,
2334	.sel_msk = B_AX_DFI_DATA_MASK,
2335	.srt = 0x80000000,
2336	.end = 0x8000017f,
2337	.rd_addr = R_AX_DBG_FUN_INTF_DATA,
2338	.rd_byte = 4,
2339	.rd_msk = B_AX_DFI_DATA_MASK
2340};
2341
2342static const struct rtw89_mac_dbg_port_info dbg_port_pcie_txdma = {
2343	.sel_addr = R_AX_PCIE_DBG_CTRL,
2344	.sel_byte = 2,
2345	.sel_msk = B_AX_PCIE_DBG_SEL_MASK,
2346	.srt = 0x00,
2347	.end = 0x03,
2348	.rd_addr = R_AX_DBG_PORT_SEL,
2349	.rd_byte = 4,
2350	.rd_msk = B_AX_DEBUG_ST_MASK
2351};
2352
2353static const struct rtw89_mac_dbg_port_info dbg_port_pcie_rxdma = {
2354	.sel_addr = R_AX_PCIE_DBG_CTRL,
2355	.sel_byte = 2,
2356	.sel_msk = B_AX_PCIE_DBG_SEL_MASK,
2357	.srt = 0x00,
2358	.end = 0x04,
2359	.rd_addr = R_AX_DBG_PORT_SEL,
2360	.rd_byte = 4,
2361	.rd_msk = B_AX_DEBUG_ST_MASK
2362};
2363
2364static const struct rtw89_mac_dbg_port_info dbg_port_pcie_cvt = {
2365	.sel_addr = R_AX_PCIE_DBG_CTRL,
2366	.sel_byte = 2,
2367	.sel_msk = B_AX_PCIE_DBG_SEL_MASK,
2368	.srt = 0x00,
2369	.end = 0x01,
2370	.rd_addr = R_AX_DBG_PORT_SEL,
2371	.rd_byte = 4,
2372	.rd_msk = B_AX_DEBUG_ST_MASK
2373};
2374
2375static const struct rtw89_mac_dbg_port_info dbg_port_pcie_cxpl = {
2376	.sel_addr = R_AX_PCIE_DBG_CTRL,
2377	.sel_byte = 2,
2378	.sel_msk = B_AX_PCIE_DBG_SEL_MASK,
2379	.srt = 0x00,
2380	.end = 0x05,
2381	.rd_addr = R_AX_DBG_PORT_SEL,
2382	.rd_byte = 4,
2383	.rd_msk = B_AX_DEBUG_ST_MASK
2384};
2385
2386static const struct rtw89_mac_dbg_port_info dbg_port_pcie_io = {
2387	.sel_addr = R_AX_PCIE_DBG_CTRL,
2388	.sel_byte = 2,
2389	.sel_msk = B_AX_PCIE_DBG_SEL_MASK,
2390	.srt = 0x00,
2391	.end = 0x05,
2392	.rd_addr = R_AX_DBG_PORT_SEL,
2393	.rd_byte = 4,
2394	.rd_msk = B_AX_DEBUG_ST_MASK
2395};
2396
2397static const struct rtw89_mac_dbg_port_info dbg_port_pcie_misc = {
2398	.sel_addr = R_AX_PCIE_DBG_CTRL,
2399	.sel_byte = 2,
2400	.sel_msk = B_AX_PCIE_DBG_SEL_MASK,
2401	.srt = 0x00,
2402	.end = 0x06,
2403	.rd_addr = R_AX_DBG_PORT_SEL,
2404	.rd_byte = 4,
2405	.rd_msk = B_AX_DEBUG_ST_MASK
2406};
2407
2408static const struct rtw89_mac_dbg_port_info dbg_port_pcie_misc2 = {
2409	.sel_addr = R_AX_DBG_CTRL,
2410	.sel_byte = 1,
2411	.sel_msk = B_AX_DBG_SEL0,
2412	.srt = 0x34,
2413	.end = 0x3C,
2414	.rd_addr = R_AX_DBG_PORT_SEL,
2415	.rd_byte = 4,
2416	.rd_msk = B_AX_DEBUG_ST_MASK
2417};
2418
2419static const struct rtw89_mac_dbg_port_info *
2420rtw89_debug_mac_dbg_port_sel(struct seq_file *m,
2421			     struct rtw89_dev *rtwdev, u32 sel)
2422{
2423	const struct rtw89_mac_dbg_port_info *info;
2424	u32 index;
2425	u32 val32;
2426	u16 val16;
2427	u8 val8;
2428
2429	switch (sel) {
2430	case RTW89_DBG_PORT_SEL_PTCL_C0:
2431		info = &dbg_port_ptcl_c0;
2432		val16 = rtw89_read16(rtwdev, R_AX_PTCL_DBG);
2433		val16 |= B_AX_PTCL_DBG_EN;
2434		rtw89_write16(rtwdev, R_AX_PTCL_DBG, val16);
2435		seq_puts(m, "Enable PTCL C0 dbgport.\n");
2436		break;
2437	case RTW89_DBG_PORT_SEL_PTCL_C1:
2438		info = &dbg_port_ptcl_c1;
2439		val16 = rtw89_read16(rtwdev, R_AX_PTCL_DBG_C1);
2440		val16 |= B_AX_PTCL_DBG_EN;
2441		rtw89_write16(rtwdev, R_AX_PTCL_DBG_C1, val16);
2442		seq_puts(m, "Enable PTCL C1 dbgport.\n");
2443		break;
2444	case RTW89_DBG_PORT_SEL_SCH_C0:
2445		info = &dbg_port_sch_c0;
2446		val32 = rtw89_read32(rtwdev, R_AX_SCH_DBG_SEL);
2447		val32 |= B_AX_SCH_DBG_EN;
2448		rtw89_write32(rtwdev, R_AX_SCH_DBG_SEL, val32);
2449		seq_puts(m, "Enable SCH C0 dbgport.\n");
2450		break;
2451	case RTW89_DBG_PORT_SEL_SCH_C1:
2452		info = &dbg_port_sch_c1;
2453		val32 = rtw89_read32(rtwdev, R_AX_SCH_DBG_SEL_C1);
2454		val32 |= B_AX_SCH_DBG_EN;
2455		rtw89_write32(rtwdev, R_AX_SCH_DBG_SEL_C1, val32);
2456		seq_puts(m, "Enable SCH C1 dbgport.\n");
2457		break;
2458	case RTW89_DBG_PORT_SEL_TMAC_C0:
2459		info = &dbg_port_tmac_c0;
2460		val32 = rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL);
2461		val32 = u32_replace_bits(val32, TRXPTRL_DBG_SEL_TMAC,
2462					 B_AX_DBGSEL_TRXPTCL_MASK);
2463		rtw89_write32(rtwdev, R_AX_DBGSEL_TRXPTCL, val32);
2464
2465		val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL);
2466		val32 = u32_replace_bits(val32, TMAC_DBG_SEL_C0, B_AX_DBG_SEL0);
2467		val32 = u32_replace_bits(val32, TMAC_DBG_SEL_C0, B_AX_DBG_SEL1);
2468		rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32);
2469
2470		val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1);
2471		val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK);
2472		rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32);
2473		seq_puts(m, "Enable TMAC C0 dbgport.\n");
2474		break;
2475	case RTW89_DBG_PORT_SEL_TMAC_C1:
2476		info = &dbg_port_tmac_c1;
2477		val32 = rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL_C1);
2478		val32 = u32_replace_bits(val32, TRXPTRL_DBG_SEL_TMAC,
2479					 B_AX_DBGSEL_TRXPTCL_MASK);
2480		rtw89_write32(rtwdev, R_AX_DBGSEL_TRXPTCL_C1, val32);
2481
2482		val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL);
2483		val32 = u32_replace_bits(val32, TMAC_DBG_SEL_C1, B_AX_DBG_SEL0);
2484		val32 = u32_replace_bits(val32, TMAC_DBG_SEL_C1, B_AX_DBG_SEL1);
2485		rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32);
2486
2487		val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1);
2488		val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK);
2489		rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32);
2490		seq_puts(m, "Enable TMAC C1 dbgport.\n");
2491		break;
2492	case RTW89_DBG_PORT_SEL_RMAC_C0:
2493		info = &dbg_port_rmac_c0;
2494		val32 = rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL);
2495		val32 = u32_replace_bits(val32, TRXPTRL_DBG_SEL_RMAC,
2496					 B_AX_DBGSEL_TRXPTCL_MASK);
2497		rtw89_write32(rtwdev, R_AX_DBGSEL_TRXPTCL, val32);
2498
2499		val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL);
2500		val32 = u32_replace_bits(val32, RMAC_DBG_SEL_C0, B_AX_DBG_SEL0);
2501		val32 = u32_replace_bits(val32, RMAC_DBG_SEL_C0, B_AX_DBG_SEL1);
2502		rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32);
2503
2504		val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1);
2505		val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK);
2506		rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32);
2507
2508		val8 = rtw89_read8(rtwdev, R_AX_DBGSEL_TRXPTCL);
2509		val8 = u8_replace_bits(val8, RMAC_CMAC_DBG_SEL,
2510				       B_AX_DBGSEL_TRXPTCL_MASK);
2511		rtw89_write8(rtwdev, R_AX_DBGSEL_TRXPTCL, val8);
2512		seq_puts(m, "Enable RMAC C0 dbgport.\n");
2513		break;
2514	case RTW89_DBG_PORT_SEL_RMAC_C1:
2515		info = &dbg_port_rmac_c1;
2516		val32 = rtw89_read32(rtwdev, R_AX_DBGSEL_TRXPTCL_C1);
2517		val32 = u32_replace_bits(val32, TRXPTRL_DBG_SEL_RMAC,
2518					 B_AX_DBGSEL_TRXPTCL_MASK);
2519		rtw89_write32(rtwdev, R_AX_DBGSEL_TRXPTCL_C1, val32);
2520
2521		val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL);
2522		val32 = u32_replace_bits(val32, RMAC_DBG_SEL_C1, B_AX_DBG_SEL0);
2523		val32 = u32_replace_bits(val32, RMAC_DBG_SEL_C1, B_AX_DBG_SEL1);
2524		rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32);
2525
2526		val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1);
2527		val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK);
2528		rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32);
2529
2530		val8 = rtw89_read8(rtwdev, R_AX_DBGSEL_TRXPTCL_C1);
2531		val8 = u8_replace_bits(val8, RMAC_CMAC_DBG_SEL,
2532				       B_AX_DBGSEL_TRXPTCL_MASK);
2533		rtw89_write8(rtwdev, R_AX_DBGSEL_TRXPTCL_C1, val8);
2534		seq_puts(m, "Enable RMAC C1 dbgport.\n");
2535		break;
2536	case RTW89_DBG_PORT_SEL_RMACST_C0:
2537		info = &dbg_port_rmacst_c0;
2538		seq_puts(m, "Enable RMAC state C0 dbgport.\n");
2539		break;
2540	case RTW89_DBG_PORT_SEL_RMACST_C1:
2541		info = &dbg_port_rmacst_c1;
2542		seq_puts(m, "Enable RMAC state C1 dbgport.\n");
2543		break;
2544	case RTW89_DBG_PORT_SEL_RMAC_PLCP_C0:
2545		info = &dbg_port_rmac_plcp_c0;
2546		seq_puts(m, "Enable RMAC PLCP C0 dbgport.\n");
2547		break;
2548	case RTW89_DBG_PORT_SEL_RMAC_PLCP_C1:
2549		info = &dbg_port_rmac_plcp_c1;
2550		seq_puts(m, "Enable RMAC PLCP C1 dbgport.\n");
2551		break;
2552	case RTW89_DBG_PORT_SEL_TRXPTCL_C0:
2553		info = &dbg_port_trxptcl_c0;
2554		val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL);
2555		val32 = u32_replace_bits(val32, TRXPTCL_DBG_SEL_C0, B_AX_DBG_SEL0);
2556		val32 = u32_replace_bits(val32, TRXPTCL_DBG_SEL_C0, B_AX_DBG_SEL1);
2557		rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32);
2558
2559		val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1);
2560		val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK);
2561		rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32);
2562		seq_puts(m, "Enable TRXPTCL C0 dbgport.\n");
2563		break;
2564	case RTW89_DBG_PORT_SEL_TRXPTCL_C1:
2565		info = &dbg_port_trxptcl_c1;
2566		val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL);
2567		val32 = u32_replace_bits(val32, TRXPTCL_DBG_SEL_C1, B_AX_DBG_SEL0);
2568		val32 = u32_replace_bits(val32, TRXPTCL_DBG_SEL_C1, B_AX_DBG_SEL1);
2569		rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32);
2570
2571		val32 = rtw89_read32(rtwdev, R_AX_SYS_STATUS1);
2572		val32 = u32_replace_bits(val32, MAC_DBG_SEL, B_AX_SEL_0XC0_MASK);
2573		rtw89_write32(rtwdev, R_AX_SYS_STATUS1, val32);
2574		seq_puts(m, "Enable TRXPTCL C1 dbgport.\n");
2575		break;
2576	case RTW89_DBG_PORT_SEL_TX_INFOL_C0:
2577		info = &dbg_port_tx_infol_c0;
2578		val32 = rtw89_read32(rtwdev, R_AX_TCR1);
2579		val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;
2580		rtw89_write32(rtwdev, R_AX_TCR1, val32);
2581		seq_puts(m, "Enable tx infol dump.\n");
2582		break;
2583	case RTW89_DBG_PORT_SEL_TX_INFOH_C0:
2584		info = &dbg_port_tx_infoh_c0;
2585		val32 = rtw89_read32(rtwdev, R_AX_TCR1);
2586		val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;
2587		rtw89_write32(rtwdev, R_AX_TCR1, val32);
2588		seq_puts(m, "Enable tx infoh dump.\n");
2589		break;
2590	case RTW89_DBG_PORT_SEL_TX_INFOL_C1:
2591		info = &dbg_port_tx_infol_c1;
2592		val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1);
2593		val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;
2594		rtw89_write32(rtwdev, R_AX_TCR1_C1, val32);
2595		seq_puts(m, "Enable tx infol dump.\n");
2596		break;
2597	case RTW89_DBG_PORT_SEL_TX_INFOH_C1:
2598		info = &dbg_port_tx_infoh_c1;
2599		val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1);
2600		val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;
2601		rtw89_write32(rtwdev, R_AX_TCR1_C1, val32);
2602		seq_puts(m, "Enable tx infoh dump.\n");
2603		break;
2604	case RTW89_DBG_PORT_SEL_TXTF_INFOL_C0:
2605		info = &dbg_port_txtf_infol_c0;
2606		val32 = rtw89_read32(rtwdev, R_AX_TCR1);
2607		val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;
2608		rtw89_write32(rtwdev, R_AX_TCR1, val32);
2609		seq_puts(m, "Enable tx tf infol dump.\n");
2610		break;
2611	case RTW89_DBG_PORT_SEL_TXTF_INFOH_C0:
2612		info = &dbg_port_txtf_infoh_c0;
2613		val32 = rtw89_read32(rtwdev, R_AX_TCR1);
2614		val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;
2615		rtw89_write32(rtwdev, R_AX_TCR1, val32);
2616		seq_puts(m, "Enable tx tf infoh dump.\n");
2617		break;
2618	case RTW89_DBG_PORT_SEL_TXTF_INFOL_C1:
2619		info = &dbg_port_txtf_infol_c1;
2620		val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1);
2621		val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;
2622		rtw89_write32(rtwdev, R_AX_TCR1_C1, val32);
2623		seq_puts(m, "Enable tx tf infol dump.\n");
2624		break;
2625	case RTW89_DBG_PORT_SEL_TXTF_INFOH_C1:
2626		info = &dbg_port_txtf_infoh_c1;
2627		val32 = rtw89_read32(rtwdev, R_AX_TCR1_C1);
2628		val32 |= B_AX_TCR_FORCE_READ_TXDFIFO;
2629		rtw89_write32(rtwdev, R_AX_TCR1_C1, val32);
2630		seq_puts(m, "Enable tx tf infoh dump.\n");
2631		break;
2632	case RTW89_DBG_PORT_SEL_WDE_BUFMGN_FREEPG:
2633		info = &dbg_port_wde_bufmgn_freepg;
2634		seq_puts(m, "Enable wde bufmgn freepg dump.\n");
2635		break;
2636	case RTW89_DBG_PORT_SEL_WDE_BUFMGN_QUOTA:
2637		info = &dbg_port_wde_bufmgn_quota;
2638		seq_puts(m, "Enable wde bufmgn quota dump.\n");
2639		break;
2640	case RTW89_DBG_PORT_SEL_WDE_BUFMGN_PAGELLT:
2641		info = &dbg_port_wde_bufmgn_pagellt;
2642		seq_puts(m, "Enable wde bufmgn pagellt dump.\n");
2643		break;
2644	case RTW89_DBG_PORT_SEL_WDE_BUFMGN_PKTINFO:
2645		info = &dbg_port_wde_bufmgn_pktinfo;
2646		seq_puts(m, "Enable wde bufmgn pktinfo dump.\n");
2647		break;
2648	case RTW89_DBG_PORT_SEL_WDE_QUEMGN_PREPKT:
2649		info = &dbg_port_wde_quemgn_prepkt;
2650		seq_puts(m, "Enable wde quemgn prepkt dump.\n");
2651		break;
2652	case RTW89_DBG_PORT_SEL_WDE_QUEMGN_NXTPKT:
2653		info = &dbg_port_wde_quemgn_nxtpkt;
2654		seq_puts(m, "Enable wde quemgn nxtpkt dump.\n");
2655		break;
2656	case RTW89_DBG_PORT_SEL_WDE_QUEMGN_QLNKTBL:
2657		info = &dbg_port_wde_quemgn_qlnktbl;
2658		seq_puts(m, "Enable wde quemgn qlnktbl dump.\n");
2659		break;
2660	case RTW89_DBG_PORT_SEL_WDE_QUEMGN_QEMPTY:
2661		info = &dbg_port_wde_quemgn_qempty;
2662		seq_puts(m, "Enable wde quemgn qempty dump.\n");
2663		break;
2664	case RTW89_DBG_PORT_SEL_PLE_BUFMGN_FREEPG:
2665		info = &dbg_port_ple_bufmgn_freepg;
2666		seq_puts(m, "Enable ple bufmgn freepg dump.\n");
2667		break;
2668	case RTW89_DBG_PORT_SEL_PLE_BUFMGN_QUOTA:
2669		info = &dbg_port_ple_bufmgn_quota;
2670		seq_puts(m, "Enable ple bufmgn quota dump.\n");
2671		break;
2672	case RTW89_DBG_PORT_SEL_PLE_BUFMGN_PAGELLT:
2673		info = &dbg_port_ple_bufmgn_pagellt;
2674		seq_puts(m, "Enable ple bufmgn pagellt dump.\n");
2675		break;
2676	case RTW89_DBG_PORT_SEL_PLE_BUFMGN_PKTINFO:
2677		info = &dbg_port_ple_bufmgn_pktinfo;
2678		seq_puts(m, "Enable ple bufmgn pktinfo dump.\n");
2679		break;
2680	case RTW89_DBG_PORT_SEL_PLE_QUEMGN_PREPKT:
2681		info = &dbg_port_ple_quemgn_prepkt;
2682		seq_puts(m, "Enable ple quemgn prepkt dump.\n");
2683		break;
2684	case RTW89_DBG_PORT_SEL_PLE_QUEMGN_NXTPKT:
2685		info = &dbg_port_ple_quemgn_nxtpkt;
2686		seq_puts(m, "Enable ple quemgn nxtpkt dump.\n");
2687		break;
2688	case RTW89_DBG_PORT_SEL_PLE_QUEMGN_QLNKTBL:
2689		info = &dbg_port_ple_quemgn_qlnktbl;
2690		seq_puts(m, "Enable ple quemgn qlnktbl dump.\n");
2691		break;
2692	case RTW89_DBG_PORT_SEL_PLE_QUEMGN_QEMPTY:
2693		info = &dbg_port_ple_quemgn_qempty;
2694		seq_puts(m, "Enable ple quemgn qempty dump.\n");
2695		break;
2696	case RTW89_DBG_PORT_SEL_PKTINFO:
2697		info = &dbg_port_pktinfo;
2698		seq_puts(m, "Enable pktinfo dump.\n");
2699		break;
2700	case RTW89_DBG_PORT_SEL_DSPT_HDT_TX0:
2701		rtw89_write32_mask(rtwdev, R_AX_DBG_CTRL,
2702				   B_AX_DBG_SEL0, 0x80);
2703		rtw89_write32_mask(rtwdev, R_AX_SYS_STATUS1,
2704				   B_AX_SEL_0XC0_MASK, 1);
2705		fallthrough;
2706	case RTW89_DBG_PORT_SEL_DSPT_HDT_TX1:
2707	case RTW89_DBG_PORT_SEL_DSPT_HDT_TX2:
2708	case RTW89_DBG_PORT_SEL_DSPT_HDT_TX3:
2709	case RTW89_DBG_PORT_SEL_DSPT_HDT_TX4:
2710	case RTW89_DBG_PORT_SEL_DSPT_HDT_TX5:
2711		info = &dbg_port_dspt_hdt_tx0_5;
2712		index = sel - RTW89_DBG_PORT_SEL_DSPT_HDT_TX0;
2713		rtw89_write16_mask(rtwdev, info->sel_addr,
2714				   B_AX_DISPATCHER_INTN_SEL_MASK, 0);
2715		rtw89_write16_mask(rtwdev, info->sel_addr,
2716				   B_AX_DISPATCHER_CH_SEL_MASK, index);
2717		seq_printf(m, "Enable Dispatcher hdt tx%x dump.\n", index);
2718		break;
2719	case RTW89_DBG_PORT_SEL_DSPT_HDT_TX6:
2720		info = &dbg_port_dspt_hdt_tx6;
2721		rtw89_write16_mask(rtwdev, info->sel_addr,
2722				   B_AX_DISPATCHER_INTN_SEL_MASK, 0);
2723		rtw89_write16_mask(rtwdev, info->sel_addr,
2724				   B_AX_DISPATCHER_CH_SEL_MASK, 6);
2725		seq_puts(m, "Enable Dispatcher hdt tx6 dump.\n");
2726		break;
2727	case RTW89_DBG_PORT_SEL_DSPT_HDT_TX7:
2728		info = &dbg_port_dspt_hdt_tx7;
2729		rtw89_write16_mask(rtwdev, info->sel_addr,
2730				   B_AX_DISPATCHER_INTN_SEL_MASK, 0);
2731		rtw89_write16_mask(rtwdev, info->sel_addr,
2732				   B_AX_DISPATCHER_CH_SEL_MASK, 7);
2733		seq_puts(m, "Enable Dispatcher hdt tx7 dump.\n");
2734		break;
2735	case RTW89_DBG_PORT_SEL_DSPT_HDT_TX8:
2736		info = &dbg_port_dspt_hdt_tx8;
2737		rtw89_write16_mask(rtwdev, info->sel_addr,
2738				   B_AX_DISPATCHER_INTN_SEL_MASK, 0);
2739		rtw89_write16_mask(rtwdev, info->sel_addr,
2740				   B_AX_DISPATCHER_CH_SEL_MASK, 8);
2741		seq_puts(m, "Enable Dispatcher hdt tx8 dump.\n");
2742		break;
2743	case RTW89_DBG_PORT_SEL_DSPT_HDT_TX9:
2744	case RTW89_DBG_PORT_SEL_DSPT_HDT_TXA:
2745	case RTW89_DBG_PORT_SEL_DSPT_HDT_TXB:
2746	case RTW89_DBG_PORT_SEL_DSPT_HDT_TXC:
2747		info = &dbg_port_dspt_hdt_tx9_C;
2748		index = sel + 9 - RTW89_DBG_PORT_SEL_DSPT_HDT_TX9;
2749		rtw89_write16_mask(rtwdev, info->sel_addr,
2750				   B_AX_DISPATCHER_INTN_SEL_MASK, 0);
2751		rtw89_write16_mask(rtwdev, info->sel_addr,
2752				   B_AX_DISPATCHER_CH_SEL_MASK, index);
2753		seq_printf(m, "Enable Dispatcher hdt tx%x dump.\n", index);
2754		break;
2755	case RTW89_DBG_PORT_SEL_DSPT_HDT_TXD:
2756		info = &dbg_port_dspt_hdt_txD;
2757		rtw89_write16_mask(rtwdev, info->sel_addr,
2758				   B_AX_DISPATCHER_INTN_SEL_MASK, 0);
2759		rtw89_write16_mask(rtwdev, info->sel_addr,
2760				   B_AX_DISPATCHER_CH_SEL_MASK, 0xD);
2761		seq_puts(m, "Enable Dispatcher hdt txD dump.\n");
2762		break;
2763	case RTW89_DBG_PORT_SEL_DSPT_CDT_TX0:
2764		info = &dbg_port_dspt_cdt_tx0;
2765		rtw89_write16_mask(rtwdev, info->sel_addr,
2766				   B_AX_DISPATCHER_INTN_SEL_MASK, 1);
2767		rtw89_write16_mask(rtwdev, info->sel_addr,
2768				   B_AX_DISPATCHER_CH_SEL_MASK, 0);
2769		seq_puts(m, "Enable Dispatcher cdt tx0 dump.\n");
2770		break;
2771	case RTW89_DBG_PORT_SEL_DSPT_CDT_TX1:
2772		info = &dbg_port_dspt_cdt_tx1;
2773		rtw89_write16_mask(rtwdev, info->sel_addr,
2774				   B_AX_DISPATCHER_INTN_SEL_MASK, 1);
2775		rtw89_write16_mask(rtwdev, info->sel_addr,
2776				   B_AX_DISPATCHER_CH_SEL_MASK, 1);
2777		seq_puts(m, "Enable Dispatcher cdt tx1 dump.\n");
2778		break;
2779	case RTW89_DBG_PORT_SEL_DSPT_CDT_TX3:
2780		info = &dbg_port_dspt_cdt_tx3;
2781		rtw89_write16_mask(rtwdev, info->sel_addr,
2782				   B_AX_DISPATCHER_INTN_SEL_MASK, 1);
2783		rtw89_write16_mask(rtwdev, info->sel_addr,
2784				   B_AX_DISPATCHER_CH_SEL_MASK, 3);
2785		seq_puts(m, "Enable Dispatcher cdt tx3 dump.\n");
2786		break;
2787	case RTW89_DBG_PORT_SEL_DSPT_CDT_TX4:
2788		info = &dbg_port_dspt_cdt_tx4;
2789		rtw89_write16_mask(rtwdev, info->sel_addr,
2790				   B_AX_DISPATCHER_INTN_SEL_MASK, 1);
2791		rtw89_write16_mask(rtwdev, info->sel_addr,
2792				   B_AX_DISPATCHER_CH_SEL_MASK, 4);
2793		seq_puts(m, "Enable Dispatcher cdt tx4 dump.\n");
2794		break;
2795	case RTW89_DBG_PORT_SEL_DSPT_CDT_TX5:
2796	case RTW89_DBG_PORT_SEL_DSPT_CDT_TX6:
2797	case RTW89_DBG_PORT_SEL_DSPT_CDT_TX7:
2798	case RTW89_DBG_PORT_SEL_DSPT_CDT_TX8:
2799		info = &dbg_port_dspt_cdt_tx5_8;
2800		index = sel + 5 - RTW89_DBG_PORT_SEL_DSPT_CDT_TX5;
2801		rtw89_write16_mask(rtwdev, info->sel_addr,
2802				   B_AX_DISPATCHER_INTN_SEL_MASK, 1);
2803		rtw89_write16_mask(rtwdev, info->sel_addr,
2804				   B_AX_DISPATCHER_CH_SEL_MASK, index);
2805		seq_printf(m, "Enable Dispatcher cdt tx%x dump.\n", index);
2806		break;
2807	case RTW89_DBG_PORT_SEL_DSPT_CDT_TX9:
2808		info = &dbg_port_dspt_cdt_tx9;
2809		rtw89_write16_mask(rtwdev, info->sel_addr,
2810				   B_AX_DISPATCHER_INTN_SEL_MASK, 1);
2811		rtw89_write16_mask(rtwdev, info->sel_addr,
2812				   B_AX_DISPATCHER_CH_SEL_MASK, 9);
2813		seq_puts(m, "Enable Dispatcher cdt tx9 dump.\n");
2814		break;
2815	case RTW89_DBG_PORT_SEL_DSPT_CDT_TXA:
2816	case RTW89_DBG_PORT_SEL_DSPT_CDT_TXB:
2817	case RTW89_DBG_PORT_SEL_DSPT_CDT_TXC:
2818		info = &dbg_port_dspt_cdt_txA_C;
2819		index = sel + 0xA - RTW89_DBG_PORT_SEL_DSPT_CDT_TXA;
2820		rtw89_write16_mask(rtwdev, info->sel_addr,
2821				   B_AX_DISPATCHER_INTN_SEL_MASK, 1);
2822		rtw89_write16_mask(rtwdev, info->sel_addr,
2823				   B_AX_DISPATCHER_CH_SEL_MASK, index);
2824		seq_printf(m, "Enable Dispatcher cdt tx%x dump.\n", index);
2825		break;
2826	case RTW89_DBG_PORT_SEL_DSPT_HDT_RX0:
2827		info = &dbg_port_dspt_hdt_rx0;
2828		rtw89_write16_mask(rtwdev, info->sel_addr,
2829				   B_AX_DISPATCHER_INTN_SEL_MASK, 2);
2830		rtw89_write16_mask(rtwdev, info->sel_addr,
2831				   B_AX_DISPATCHER_CH_SEL_MASK, 0);
2832		seq_puts(m, "Enable Dispatcher hdt rx0 dump.\n");
2833		break;
2834	case RTW89_DBG_PORT_SEL_DSPT_HDT_RX1:
2835	case RTW89_DBG_PORT_SEL_DSPT_HDT_RX2:
2836		info = &dbg_port_dspt_hdt_rx1_2;
2837		index = sel + 1 - RTW89_DBG_PORT_SEL_DSPT_HDT_RX1;
2838		rtw89_write16_mask(rtwdev, info->sel_addr,
2839				   B_AX_DISPATCHER_INTN_SEL_MASK, 2);
2840		rtw89_write16_mask(rtwdev, info->sel_addr,
2841				   B_AX_DISPATCHER_CH_SEL_MASK, index);
2842		seq_printf(m, "Enable Dispatcher hdt rx%x dump.\n", index);
2843		break;
2844	case RTW89_DBG_PORT_SEL_DSPT_HDT_RX3:
2845		info = &dbg_port_dspt_hdt_rx3;
2846		rtw89_write16_mask(rtwdev, info->sel_addr,
2847				   B_AX_DISPATCHER_INTN_SEL_MASK, 2);
2848		rtw89_write16_mask(rtwdev, info->sel_addr,
2849				   B_AX_DISPATCHER_CH_SEL_MASK, 3);
2850		seq_puts(m, "Enable Dispatcher hdt rx3 dump.\n");
2851		break;
2852	case RTW89_DBG_PORT_SEL_DSPT_HDT_RX4:
2853		info = &dbg_port_dspt_hdt_rx4;
2854		rtw89_write16_mask(rtwdev, info->sel_addr,
2855				   B_AX_DISPATCHER_INTN_SEL_MASK, 2);
2856		rtw89_write16_mask(rtwdev, info->sel_addr,
2857				   B_AX_DISPATCHER_CH_SEL_MASK, 4);
2858		seq_puts(m, "Enable Dispatcher hdt rx4 dump.\n");
2859		break;
2860	case RTW89_DBG_PORT_SEL_DSPT_HDT_RX5:
2861		info = &dbg_port_dspt_hdt_rx5;
2862		rtw89_write16_mask(rtwdev, info->sel_addr,
2863				   B_AX_DISPATCHER_INTN_SEL_MASK, 2);
2864		rtw89_write16_mask(rtwdev, info->sel_addr,
2865				   B_AX_DISPATCHER_CH_SEL_MASK, 5);
2866		seq_puts(m, "Enable Dispatcher hdt rx5 dump.\n");
2867		break;
2868	case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_0:
2869		info = &dbg_port_dspt_cdt_rx_p0_0;
2870		rtw89_write16_mask(rtwdev, info->sel_addr,
2871				   B_AX_DISPATCHER_INTN_SEL_MASK, 3);
2872		rtw89_write16_mask(rtwdev, info->sel_addr,
2873				   B_AX_DISPATCHER_CH_SEL_MASK, 0);
2874		seq_puts(m, "Enable Dispatcher cdt rx part0 0 dump.\n");
2875		break;
2876	case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0:
2877	case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_1:
2878		info = &dbg_port_dspt_cdt_rx_p0_1;
2879		rtw89_write16_mask(rtwdev, info->sel_addr,
2880				   B_AX_DISPATCHER_INTN_SEL_MASK, 3);
2881		rtw89_write16_mask(rtwdev, info->sel_addr,
2882				   B_AX_DISPATCHER_CH_SEL_MASK, 1);
2883		seq_puts(m, "Enable Dispatcher cdt rx part0 1 dump.\n");
2884		break;
2885	case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P0_2:
2886		info = &dbg_port_dspt_cdt_rx_p0_2;
2887		rtw89_write16_mask(rtwdev, info->sel_addr,
2888				   B_AX_DISPATCHER_INTN_SEL_MASK, 3);
2889		rtw89_write16_mask(rtwdev, info->sel_addr,
2890				   B_AX_DISPATCHER_CH_SEL_MASK, 2);
2891		seq_puts(m, "Enable Dispatcher cdt rx part0 2 dump.\n");
2892		break;
2893	case RTW89_DBG_PORT_SEL_DSPT_CDT_RX_P1:
2894		info = &dbg_port_dspt_cdt_rx_p1;
2895		rtw89_write8_mask(rtwdev, info->sel_addr,
2896				  B_AX_DISPATCHER_INTN_SEL_MASK, 3);
2897		seq_puts(m, "Enable Dispatcher cdt rx part1 dump.\n");
2898		break;
2899	case RTW89_DBG_PORT_SEL_DSPT_STF_CTRL:
2900		info = &dbg_port_dspt_stf_ctrl;
2901		rtw89_write8_mask(rtwdev, info->sel_addr,
2902				  B_AX_DISPATCHER_INTN_SEL_MASK, 4);
2903		seq_puts(m, "Enable Dispatcher stf control dump.\n");
2904		break;
2905	case RTW89_DBG_PORT_SEL_DSPT_ADDR_CTRL:
2906		info = &dbg_port_dspt_addr_ctrl;
2907		rtw89_write8_mask(rtwdev, info->sel_addr,
2908				  B_AX_DISPATCHER_INTN_SEL_MASK, 5);
2909		seq_puts(m, "Enable Dispatcher addr control dump.\n");
2910		break;
2911	case RTW89_DBG_PORT_SEL_DSPT_WDE_INTF:
2912		info = &dbg_port_dspt_wde_intf;
2913		rtw89_write8_mask(rtwdev, info->sel_addr,
2914				  B_AX_DISPATCHER_INTN_SEL_MASK, 6);
2915		seq_puts(m, "Enable Dispatcher wde interface dump.\n");
2916		break;
2917	case RTW89_DBG_PORT_SEL_DSPT_PLE_INTF:
2918		info = &dbg_port_dspt_ple_intf;
2919		rtw89_write8_mask(rtwdev, info->sel_addr,
2920				  B_AX_DISPATCHER_INTN_SEL_MASK, 7);
2921		seq_puts(m, "Enable Dispatcher ple interface dump.\n");
2922		break;
2923	case RTW89_DBG_PORT_SEL_DSPT_FLOW_CTRL:
2924		info = &dbg_port_dspt_flow_ctrl;
2925		rtw89_write8_mask(rtwdev, info->sel_addr,
2926				  B_AX_DISPATCHER_INTN_SEL_MASK, 8);
2927		seq_puts(m, "Enable Dispatcher flow control dump.\n");
2928		break;
2929	case RTW89_DBG_PORT_SEL_PCIE_TXDMA:
2930		info = &dbg_port_pcie_txdma;
2931		val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL);
2932		val32 = u32_replace_bits(val32, PCIE_TXDMA_DBG_SEL, B_AX_DBG_SEL0);
2933		val32 = u32_replace_bits(val32, PCIE_TXDMA_DBG_SEL, B_AX_DBG_SEL1);
2934		rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32);
2935		seq_puts(m, "Enable pcie txdma dump.\n");
2936		break;
2937	case RTW89_DBG_PORT_SEL_PCIE_RXDMA:
2938		info = &dbg_port_pcie_rxdma;
2939		val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL);
2940		val32 = u32_replace_bits(val32, PCIE_RXDMA_DBG_SEL, B_AX_DBG_SEL0);
2941		val32 = u32_replace_bits(val32, PCIE_RXDMA_DBG_SEL, B_AX_DBG_SEL1);
2942		rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32);
2943		seq_puts(m, "Enable pcie rxdma dump.\n");
2944		break;
2945	case RTW89_DBG_PORT_SEL_PCIE_CVT:
2946		info = &dbg_port_pcie_cvt;
2947		val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL);
2948		val32 = u32_replace_bits(val32, PCIE_CVT_DBG_SEL, B_AX_DBG_SEL0);
2949		val32 = u32_replace_bits(val32, PCIE_CVT_DBG_SEL, B_AX_DBG_SEL1);
2950		rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32);
2951		seq_puts(m, "Enable pcie cvt dump.\n");
2952		break;
2953	case RTW89_DBG_PORT_SEL_PCIE_CXPL:
2954		info = &dbg_port_pcie_cxpl;
2955		val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL);
2956		val32 = u32_replace_bits(val32, PCIE_CXPL_DBG_SEL, B_AX_DBG_SEL0);
2957		val32 = u32_replace_bits(val32, PCIE_CXPL_DBG_SEL, B_AX_DBG_SEL1);
2958		rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32);
2959		seq_puts(m, "Enable pcie cxpl dump.\n");
2960		break;
2961	case RTW89_DBG_PORT_SEL_PCIE_IO:
2962		info = &dbg_port_pcie_io;
2963		val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL);
2964		val32 = u32_replace_bits(val32, PCIE_IO_DBG_SEL, B_AX_DBG_SEL0);
2965		val32 = u32_replace_bits(val32, PCIE_IO_DBG_SEL, B_AX_DBG_SEL1);
2966		rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32);
2967		seq_puts(m, "Enable pcie io dump.\n");
2968		break;
2969	case RTW89_DBG_PORT_SEL_PCIE_MISC:
2970		info = &dbg_port_pcie_misc;
2971		val32 = rtw89_read32(rtwdev, R_AX_DBG_CTRL);
2972		val32 = u32_replace_bits(val32, PCIE_MISC_DBG_SEL, B_AX_DBG_SEL0);
2973		val32 = u32_replace_bits(val32, PCIE_MISC_DBG_SEL, B_AX_DBG_SEL1);
2974		rtw89_write32(rtwdev, R_AX_DBG_CTRL, val32);
2975		seq_puts(m, "Enable pcie misc dump.\n");
2976		break;
2977	case RTW89_DBG_PORT_SEL_PCIE_MISC2:
2978		info = &dbg_port_pcie_misc2;
2979		val16 = rtw89_read16(rtwdev, R_AX_PCIE_DBG_CTRL);
2980		val16 = u16_replace_bits(val16, PCIE_MISC2_DBG_SEL,
2981					 B_AX_PCIE_DBG_SEL_MASK);
2982		rtw89_write16(rtwdev, R_AX_PCIE_DBG_CTRL, val16);
2983		seq_puts(m, "Enable pcie misc2 dump.\n");
2984		break;
2985	default:
2986		seq_puts(m, "Dbg port select err\n");
2987		return NULL;
2988	}
2989
2990	return info;
2991}
2992
2993static bool is_dbg_port_valid(struct rtw89_dev *rtwdev, u32 sel)
2994{
2995	if (rtwdev->hci.type != RTW89_HCI_TYPE_PCIE &&
2996	    sel >= RTW89_DBG_PORT_SEL_PCIE_TXDMA &&
2997	    sel <= RTW89_DBG_PORT_SEL_PCIE_MISC2)
2998		return false;
2999	if (rtwdev->chip->chip_id == RTL8852B &&
3000	    sel >= RTW89_DBG_PORT_SEL_PTCL_C1 &&
3001	    sel <= RTW89_DBG_PORT_SEL_TXTF_INFOH_C1)
3002		return false;
3003	if (rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL) &&
3004	    sel >= RTW89_DBG_PORT_SEL_WDE_BUFMGN_FREEPG &&
3005	    sel <= RTW89_DBG_PORT_SEL_PKTINFO)
3006		return false;
3007	if (rtw89_mac_check_mac_en(rtwdev, 0, RTW89_DMAC_SEL) &&
3008	    sel >= RTW89_DBG_PORT_SEL_DSPT_HDT_TX0 &&
3009	    sel <= RTW89_DBG_PORT_SEL_DSPT_FLOW_CTRL)
3010		return false;
3011	if (rtw89_mac_check_mac_en(rtwdev, 0, RTW89_CMAC_SEL) &&
3012	    sel >= RTW89_DBG_PORT_SEL_PTCL_C0 &&
3013	    sel <= RTW89_DBG_PORT_SEL_TXTF_INFOH_C0)
3014		return false;
3015	if (rtw89_mac_check_mac_en(rtwdev, 1, RTW89_CMAC_SEL) &&
3016	    sel >= RTW89_DBG_PORT_SEL_PTCL_C1 &&
3017	    sel <= RTW89_DBG_PORT_SEL_TXTF_INFOH_C1)
3018		return false;
3019
3020	return true;
3021}
3022
3023static int rtw89_debug_mac_dbg_port_dump(struct rtw89_dev *rtwdev,
3024					 struct seq_file *m, u32 sel)
3025{
3026	const struct rtw89_mac_dbg_port_info *info;
3027	u8 val8;
3028	u16 val16;
3029	u32 val32;
3030	u32 i;
3031
3032	info = rtw89_debug_mac_dbg_port_sel(m, rtwdev, sel);
3033	if (!info) {
3034		rtw89_err(rtwdev, "failed to select debug port %d\n", sel);
3035		return -EINVAL;
3036	}
3037
3038#define case_DBG_SEL(__sel) \
3039	case RTW89_DBG_PORT_SEL_##__sel: \
3040		seq_puts(m, "Dump debug port " #__sel ":\n"); \
3041		break
3042
3043	switch (sel) {
3044	case_DBG_SEL(PTCL_C0);
3045	case_DBG_SEL(PTCL_C1);
3046	case_DBG_SEL(SCH_C0);
3047	case_DBG_SEL(SCH_C1);
3048	case_DBG_SEL(TMAC_C0);
3049	case_DBG_SEL(TMAC_C1);
3050	case_DBG_SEL(RMAC_C0);
3051	case_DBG_SEL(RMAC_C1);
3052	case_DBG_SEL(RMACST_C0);
3053	case_DBG_SEL(RMACST_C1);
3054	case_DBG_SEL(TRXPTCL_C0);
3055	case_DBG_SEL(TRXPTCL_C1);
3056	case_DBG_SEL(TX_INFOL_C0);
3057	case_DBG_SEL(TX_INFOH_C0);
3058	case_DBG_SEL(TX_INFOL_C1);
3059	case_DBG_SEL(TX_INFOH_C1);
3060	case_DBG_SEL(TXTF_INFOL_C0);
3061	case_DBG_SEL(TXTF_INFOH_C0);
3062	case_DBG_SEL(TXTF_INFOL_C1);
3063	case_DBG_SEL(TXTF_INFOH_C1);
3064	case_DBG_SEL(WDE_BUFMGN_FREEPG);
3065	case_DBG_SEL(WDE_BUFMGN_QUOTA);
3066	case_DBG_SEL(WDE_BUFMGN_PAGELLT);
3067	case_DBG_SEL(WDE_BUFMGN_PKTINFO);
3068	case_DBG_SEL(WDE_QUEMGN_PREPKT);
3069	case_DBG_SEL(WDE_QUEMGN_NXTPKT);
3070	case_DBG_SEL(WDE_QUEMGN_QLNKTBL);
3071	case_DBG_SEL(WDE_QUEMGN_QEMPTY);
3072	case_DBG_SEL(PLE_BUFMGN_FREEPG);
3073	case_DBG_SEL(PLE_BUFMGN_QUOTA);
3074	case_DBG_SEL(PLE_BUFMGN_PAGELLT);
3075	case_DBG_SEL(PLE_BUFMGN_PKTINFO);
3076	case_DBG_SEL(PLE_QUEMGN_PREPKT);
3077	case_DBG_SEL(PLE_QUEMGN_NXTPKT);
3078	case_DBG_SEL(PLE_QUEMGN_QLNKTBL);
3079	case_DBG_SEL(PLE_QUEMGN_QEMPTY);
3080	case_DBG_SEL(PKTINFO);
3081	case_DBG_SEL(DSPT_HDT_TX0);
3082	case_DBG_SEL(DSPT_HDT_TX1);
3083	case_DBG_SEL(DSPT_HDT_TX2);
3084	case_DBG_SEL(DSPT_HDT_TX3);
3085	case_DBG_SEL(DSPT_HDT_TX4);
3086	case_DBG_SEL(DSPT_HDT_TX5);
3087	case_DBG_SEL(DSPT_HDT_TX6);
3088	case_DBG_SEL(DSPT_HDT_TX7);
3089	case_DBG_SEL(DSPT_HDT_TX8);
3090	case_DBG_SEL(DSPT_HDT_TX9);
3091	case_DBG_SEL(DSPT_HDT_TXA);
3092	case_DBG_SEL(DSPT_HDT_TXB);
3093	case_DBG_SEL(DSPT_HDT_TXC);
3094	case_DBG_SEL(DSPT_HDT_TXD);
3095	case_DBG_SEL(DSPT_HDT_TXE);
3096	case_DBG_SEL(DSPT_HDT_TXF);
3097	case_DBG_SEL(DSPT_CDT_TX0);
3098	case_DBG_SEL(DSPT_CDT_TX1);
3099	case_DBG_SEL(DSPT_CDT_TX3);
3100	case_DBG_SEL(DSPT_CDT_TX4);
3101	case_DBG_SEL(DSPT_CDT_TX5);
3102	case_DBG_SEL(DSPT_CDT_TX6);
3103	case_DBG_SEL(DSPT_CDT_TX7);
3104	case_DBG_SEL(DSPT_CDT_TX8);
3105	case_DBG_SEL(DSPT_CDT_TX9);
3106	case_DBG_SEL(DSPT_CDT_TXA);
3107	case_DBG_SEL(DSPT_CDT_TXB);
3108	case_DBG_SEL(DSPT_CDT_TXC);
3109	case_DBG_SEL(DSPT_HDT_RX0);
3110	case_DBG_SEL(DSPT_HDT_RX1);
3111	case_DBG_SEL(DSPT_HDT_RX2);
3112	case_DBG_SEL(DSPT_HDT_RX3);
3113	case_DBG_SEL(DSPT_HDT_RX4);
3114	case_DBG_SEL(DSPT_HDT_RX5);
3115	case_DBG_SEL(DSPT_CDT_RX_P0);
3116	case_DBG_SEL(DSPT_CDT_RX_P0_0);
3117	case_DBG_SEL(DSPT_CDT_RX_P0_1);
3118	case_DBG_SEL(DSPT_CDT_RX_P0_2);
3119	case_DBG_SEL(DSPT_CDT_RX_P1);
3120	case_DBG_SEL(DSPT_STF_CTRL);
3121	case_DBG_SEL(DSPT_ADDR_CTRL);
3122	case_DBG_SEL(DSPT_WDE_INTF);
3123	case_DBG_SEL(DSPT_PLE_INTF);
3124	case_DBG_SEL(DSPT_FLOW_CTRL);
3125	case_DBG_SEL(PCIE_TXDMA);
3126	case_DBG_SEL(PCIE_RXDMA);
3127	case_DBG_SEL(PCIE_CVT);
3128	case_DBG_SEL(PCIE_CXPL);
3129	case_DBG_SEL(PCIE_IO);
3130	case_DBG_SEL(PCIE_MISC);
3131	case_DBG_SEL(PCIE_MISC2);
3132	}
3133
3134#undef case_DBG_SEL
3135
3136	seq_printf(m, "Sel addr = 0x%X\n", info->sel_addr);
3137	seq_printf(m, "Read addr = 0x%X\n", info->rd_addr);
3138
3139	for (i = info->srt; i <= info->end; i++) {
3140		switch (info->sel_byte) {
3141		case 1:
3142		default:
3143			rtw89_write8_mask(rtwdev, info->sel_addr,
3144					  info->sel_msk, i);
3145			seq_printf(m, "0x%02X: ", i);
3146			break;
3147		case 2:
3148			rtw89_write16_mask(rtwdev, info->sel_addr,
3149					   info->sel_msk, i);
3150			seq_printf(m, "0x%04X: ", i);
3151			break;
3152		case 4:
3153			rtw89_write32_mask(rtwdev, info->sel_addr,
3154					   info->sel_msk, i);
3155			seq_printf(m, "0x%04X: ", i);
3156			break;
3157		}
3158
3159		udelay(10);
3160
3161		switch (info->rd_byte) {
3162		case 1:
3163		default:
3164			val8 = rtw89_read8_mask(rtwdev,
3165						info->rd_addr, info->rd_msk);
3166			seq_printf(m, "0x%02X\n", val8);
3167			break;
3168		case 2:
3169			val16 = rtw89_read16_mask(rtwdev,
3170						  info->rd_addr, info->rd_msk);
3171			seq_printf(m, "0x%04X\n", val16);
3172			break;
3173		case 4:
3174			val32 = rtw89_read32_mask(rtwdev,
3175						  info->rd_addr, info->rd_msk);
3176			seq_printf(m, "0x%08X\n", val32);
3177			break;
3178		}
3179	}
3180
3181	return 0;
3182}
3183
3184static int rtw89_debug_mac_dump_dbg_port(struct rtw89_dev *rtwdev,
3185					 struct seq_file *m)
3186{
3187	u32 sel;
3188	int ret = 0;
3189
3190	for (sel = RTW89_DBG_PORT_SEL_PTCL_C0;
3191	     sel < RTW89_DBG_PORT_SEL_LAST; sel++) {
3192		if (!is_dbg_port_valid(rtwdev, sel))
3193			continue;
3194		ret = rtw89_debug_mac_dbg_port_dump(rtwdev, m, sel);
3195		if (ret) {
3196			rtw89_err(rtwdev,
3197				  "failed to dump debug port %d\n", sel);
3198			break;
3199		}
3200	}
3201
3202	return ret;
3203}
3204
3205static int
3206rtw89_debug_priv_mac_dbg_port_dump_get(struct seq_file *m, void *v)
3207{
3208	struct rtw89_debugfs_priv *debugfs_priv = m->private;
3209	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
3210
3211	if (debugfs_priv->dbgpkg_en.ss_dbg)
3212		rtw89_debug_mac_dump_ss_dbg(rtwdev, m);
3213	if (debugfs_priv->dbgpkg_en.dle_dbg)
3214		rtw89_debug_mac_dump_dle_dbg(rtwdev, m);
3215	if (debugfs_priv->dbgpkg_en.dmac_dbg)
3216		rtw89_debug_mac_dump_dmac_dbg(rtwdev, m);
3217	if (debugfs_priv->dbgpkg_en.cmac_dbg)
3218		rtw89_debug_mac_dump_cmac_dbg(rtwdev, m);
3219	if (debugfs_priv->dbgpkg_en.dbg_port)
3220		rtw89_debug_mac_dump_dbg_port(rtwdev, m);
3221
3222	return 0;
3223};
3224
3225static u8 *rtw89_hex2bin_user(struct rtw89_dev *rtwdev,
3226			      const char __user *user_buf, size_t count)
3227{
3228	char *buf;
3229	u8 *bin;
3230	int num;
3231	int err = 0;
3232
3233	buf = memdup_user(user_buf, count);
3234	if (IS_ERR(buf))
3235		return buf;
3236
3237	num = count / 2;
3238	bin = kmalloc(num, GFP_KERNEL);
3239	if (!bin) {
3240		err = -EFAULT;
3241		goto out;
3242	}
3243
3244	if (hex2bin(bin, buf, num)) {
3245		rtw89_info(rtwdev, "valid format: H1H2H3...\n");
3246		kfree(bin);
3247		err = -EINVAL;
3248	}
3249
3250out:
3251	kfree(buf);
3252
3253	return err ? ERR_PTR(err) : bin;
3254}
3255
3256static ssize_t rtw89_debug_priv_send_h2c_set(struct file *filp,
3257					     const char __user *user_buf,
3258					     size_t count, loff_t *loff)
3259{
3260	struct rtw89_debugfs_priv *debugfs_priv = filp->private_data;
3261	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
3262	u8 *h2c;
3263	int ret;
3264	u16 h2c_len = count / 2;
3265
3266	h2c = rtw89_hex2bin_user(rtwdev, user_buf, count);
3267	if (IS_ERR(h2c))
3268		return -EFAULT;
3269
3270	ret = rtw89_fw_h2c_raw(rtwdev, h2c, h2c_len);
3271
3272	kfree(h2c);
3273
3274	return ret ? ret : count;
3275}
3276
3277static int
3278rtw89_debug_priv_early_h2c_get(struct seq_file *m, void *v)
3279{
3280	struct rtw89_debugfs_priv *debugfs_priv = m->private;
3281	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
3282	struct rtw89_early_h2c *early_h2c;
3283	int seq = 0;
3284
3285	mutex_lock(&rtwdev->mutex);
3286	list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list)
3287		seq_printf(m, "%d: %*ph\n", ++seq, early_h2c->h2c_len, early_h2c->h2c);
3288	mutex_unlock(&rtwdev->mutex);
3289
3290	return 0;
3291}
3292
3293static ssize_t
3294rtw89_debug_priv_early_h2c_set(struct file *filp, const char __user *user_buf,
3295			       size_t count, loff_t *loff)
3296{
3297	struct seq_file *m = (struct seq_file *)filp->private_data;
3298	struct rtw89_debugfs_priv *debugfs_priv = m->private;
3299	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
3300	struct rtw89_early_h2c *early_h2c;
3301	u8 *h2c;
3302	u16 h2c_len = count / 2;
3303
3304	h2c = rtw89_hex2bin_user(rtwdev, user_buf, count);
3305	if (IS_ERR(h2c))
3306		return -EFAULT;
3307
3308	if (h2c_len >= 2 && h2c[0] == 0x00 && h2c[1] == 0x00) {
3309		kfree(h2c);
3310		rtw89_fw_free_all_early_h2c(rtwdev);
3311		goto out;
3312	}
3313
3314	early_h2c = kmalloc(sizeof(*early_h2c), GFP_KERNEL);
3315	if (!early_h2c) {
3316		kfree(h2c);
3317		return -EFAULT;
3318	}
3319
3320	early_h2c->h2c = h2c;
3321	early_h2c->h2c_len = h2c_len;
3322
3323	mutex_lock(&rtwdev->mutex);
3324	list_add_tail(&early_h2c->list, &rtwdev->early_h2c_list);
3325	mutex_unlock(&rtwdev->mutex);
3326
3327out:
3328	return count;
3329}
3330
3331static int rtw89_dbg_trigger_ctrl_error(struct rtw89_dev *rtwdev)
3332{
3333	const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
3334	struct rtw89_cpuio_ctrl ctrl_para = {0};
3335	u16 pkt_id;
3336	int ret;
3337
3338	rtw89_leave_ps_mode(rtwdev);
3339
3340	ret = mac->dle_buf_req(rtwdev, 0x20, true, &pkt_id);
3341	if (ret)
3342		return ret;
3343
3344	/* intentionally, enqueue two pkt, but has only one pkt id */
3345	ctrl_para.cmd_type = CPUIO_OP_CMD_ENQ_TO_HEAD;
3346	ctrl_para.start_pktid = pkt_id;
3347	ctrl_para.end_pktid = pkt_id;
3348	ctrl_para.pkt_num = 1; /* start from 0 */
3349	ctrl_para.dst_pid = WDE_DLE_PORT_ID_WDRLS;
3350	ctrl_para.dst_qid = WDE_DLE_QUEID_NO_REPORT;
3351
3352	if (mac->set_cpuio(rtwdev, &ctrl_para, true))
3353		return -EFAULT;
3354
3355	return 0;
3356}
3357
3358static int
3359rtw89_debug_priv_fw_crash_get(struct seq_file *m, void *v)
3360{
3361	struct rtw89_debugfs_priv *debugfs_priv = m->private;
3362	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
3363
3364	seq_printf(m, "%d\n",
3365		   test_bit(RTW89_FLAG_CRASH_SIMULATING, rtwdev->flags));
3366	return 0;
3367}
3368
3369enum rtw89_dbg_crash_simulation_type {
3370	RTW89_DBG_SIM_CPU_EXCEPTION = 1,
3371	RTW89_DBG_SIM_CTRL_ERROR = 2,
3372};
3373
3374static ssize_t
3375rtw89_debug_priv_fw_crash_set(struct file *filp, const char __user *user_buf,
3376			      size_t count, loff_t *loff)
3377{
3378	struct seq_file *m = (struct seq_file *)filp->private_data;
3379	struct rtw89_debugfs_priv *debugfs_priv = m->private;
3380	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
3381	int (*sim)(struct rtw89_dev *rtwdev);
3382	u8 crash_type;
3383	int ret;
3384
3385	ret = kstrtou8_from_user(user_buf, count, 0, &crash_type);
3386	if (ret)
3387		return -EINVAL;
3388
3389	switch (crash_type) {
3390	case RTW89_DBG_SIM_CPU_EXCEPTION:
3391		if (!RTW89_CHK_FW_FEATURE(CRASH_TRIGGER, &rtwdev->fw))
3392			return -EOPNOTSUPP;
3393		sim = rtw89_fw_h2c_trigger_cpu_exception;
3394		break;
3395	case RTW89_DBG_SIM_CTRL_ERROR:
3396		sim = rtw89_dbg_trigger_ctrl_error;
3397		break;
3398	default:
3399		return -EINVAL;
3400	}
3401
3402	mutex_lock(&rtwdev->mutex);
3403	set_bit(RTW89_FLAG_CRASH_SIMULATING, rtwdev->flags);
3404	ret = sim(rtwdev);
3405	mutex_unlock(&rtwdev->mutex);
3406
3407	if (ret)
3408		return ret;
3409
3410	return count;
3411}
3412
3413static int rtw89_debug_priv_btc_info_get(struct seq_file *m, void *v)
3414{
3415	struct rtw89_debugfs_priv *debugfs_priv = m->private;
3416	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
3417
3418	rtw89_btc_dump_info(rtwdev, m);
3419
3420	return 0;
3421}
3422
3423static ssize_t rtw89_debug_priv_btc_manual_set(struct file *filp,
3424					       const char __user *user_buf,
3425					       size_t count, loff_t *loff)
3426{
3427	struct rtw89_debugfs_priv *debugfs_priv = filp->private_data;
3428	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
3429	struct rtw89_btc *btc = &rtwdev->btc;
3430	const struct rtw89_btc_ver *ver = btc->ver;
3431	int ret;
3432
3433	ret = kstrtobool_from_user(user_buf, count, &btc->manual_ctrl);
3434	if (ret)
3435		return ret;
3436
3437	if (ver->fcxctrl == 7)
3438		btc->ctrl.ctrl_v7.manual = btc->manual_ctrl;
3439	else
3440		btc->ctrl.ctrl.manual = btc->manual_ctrl;
3441
3442	return count;
3443}
3444
3445static ssize_t rtw89_debug_fw_log_manual_set(struct file *filp,
3446					     const char __user *user_buf,
3447					     size_t count, loff_t *loff)
3448{
3449	struct rtw89_debugfs_priv *debugfs_priv = filp->private_data;
3450	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
3451	struct rtw89_fw_log *log = &rtwdev->fw.log;
3452	bool fw_log_manual;
3453
3454	if (kstrtobool_from_user(user_buf, count, &fw_log_manual))
3455		goto out;
3456
3457	mutex_lock(&rtwdev->mutex);
3458	log->enable = fw_log_manual;
3459	if (log->enable)
3460		rtw89_fw_log_prepare(rtwdev);
3461	rtw89_fw_h2c_fw_log(rtwdev, fw_log_manual);
3462	mutex_unlock(&rtwdev->mutex);
3463out:
3464	return count;
3465}
3466
3467static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta)
3468{
3469	static const char * const he_gi_str[] = {
3470		[NL80211_RATE_INFO_HE_GI_0_8] = "0.8",
3471		[NL80211_RATE_INFO_HE_GI_1_6] = "1.6",
3472		[NL80211_RATE_INFO_HE_GI_3_2] = "3.2",
3473	};
3474	static const char * const eht_gi_str[] = {
3475		[NL80211_RATE_INFO_EHT_GI_0_8] = "0.8",
3476		[NL80211_RATE_INFO_EHT_GI_1_6] = "1.6",
3477		[NL80211_RATE_INFO_EHT_GI_3_2] = "3.2",
3478	};
3479	struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
3480	struct rate_info *rate = &rtwsta->ra_report.txrate;
3481	struct ieee80211_rx_status *status = &rtwsta->rx_status;
3482	struct seq_file *m = (struct seq_file *)data;
3483	struct rtw89_dev *rtwdev = rtwsta->rtwdev;
3484	struct rtw89_hal *hal = &rtwdev->hal;
3485	u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num;
3486	bool ant_asterisk = hal->tx_path_diversity || hal->ant_diversity;
3487	u8 evm_min, evm_max;
3488	u8 rssi;
3489	u8 snr;
3490	int i;
3491
3492	seq_printf(m, "TX rate [%d]: ", rtwsta->mac_id);
3493
3494	if (rate->flags & RATE_INFO_FLAGS_MCS)
3495		seq_printf(m, "HT MCS-%d%s", rate->mcs,
3496			   rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : "");
3497	else if (rate->flags & RATE_INFO_FLAGS_VHT_MCS)
3498		seq_printf(m, "VHT %dSS MCS-%d%s", rate->nss, rate->mcs,
3499			   rate->flags & RATE_INFO_FLAGS_SHORT_GI ? " SGI" : "");
3500	else if (rate->flags & RATE_INFO_FLAGS_HE_MCS)
3501		seq_printf(m, "HE %dSS MCS-%d GI:%s", rate->nss, rate->mcs,
3502			   rate->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ?
3503			   he_gi_str[rate->he_gi] : "N/A");
3504	else if (rate->flags & RATE_INFO_FLAGS_EHT_MCS)
3505		seq_printf(m, "EHT %dSS MCS-%d GI:%s", rate->nss, rate->mcs,
3506			   rate->eht_gi < ARRAY_SIZE(eht_gi_str) ?
3507			   eht_gi_str[rate->eht_gi] : "N/A");
3508	else
3509		seq_printf(m, "Legacy %d", rate->legacy);
3510	seq_printf(m, "%s", rtwsta->ra_report.might_fallback_legacy ? " FB_G" : "");
3511	seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(rate->bw));
3512	seq_printf(m, "\t(hw_rate=0x%x)", rtwsta->ra_report.hw_rate);
3513	seq_printf(m, "\t==> agg_wait=%d (%d)\n", rtwsta->max_agg_wait,
3514		   sta->deflink.agg.max_rc_amsdu_len);
3515
3516	seq_printf(m, "RX rate [%d]: ", rtwsta->mac_id);
3517
3518	switch (status->encoding) {
3519	case RX_ENC_LEGACY:
3520		seq_printf(m, "Legacy %d", status->rate_idx +
3521			   (status->band != NL80211_BAND_2GHZ ? 4 : 0));
3522		break;
3523	case RX_ENC_HT:
3524		seq_printf(m, "HT MCS-%d%s", status->rate_idx,
3525			   status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : "");
3526		break;
3527	case RX_ENC_VHT:
3528		seq_printf(m, "VHT %dSS MCS-%d%s", status->nss, status->rate_idx,
3529			   status->enc_flags & RX_ENC_FLAG_SHORT_GI ? " SGI" : "");
3530		break;
3531	case RX_ENC_HE:
3532		seq_printf(m, "HE %dSS MCS-%d GI:%s", status->nss, status->rate_idx,
3533			   status->he_gi <= NL80211_RATE_INFO_HE_GI_3_2 ?
3534			   he_gi_str[rate->he_gi] : "N/A");
3535		break;
3536	case RX_ENC_EHT:
3537		seq_printf(m, "EHT %dSS MCS-%d GI:%s", status->nss, status->rate_idx,
3538			   status->eht.gi < ARRAY_SIZE(eht_gi_str) ?
3539			   eht_gi_str[status->eht.gi] : "N/A");
3540		break;
3541	}
3542	seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(status->bw));
3543	seq_printf(m, "\t(hw_rate=0x%x)\n", rtwsta->rx_hw_rate);
3544
3545	rssi = ewma_rssi_read(&rtwsta->avg_rssi);
3546	seq_printf(m, "RSSI: %d dBm (raw=%d, prev=%d) [",
3547		   RTW89_RSSI_RAW_TO_DBM(rssi), rssi, rtwsta->prev_rssi);
3548	for (i = 0; i < ant_num; i++) {
3549		rssi = ewma_rssi_read(&rtwsta->rssi[i]);
3550		seq_printf(m, "%d%s%s", RTW89_RSSI_RAW_TO_DBM(rssi),
3551			   ant_asterisk && (hal->antenna_tx & BIT(i)) ? "*" : "",
3552			   i + 1 == ant_num ? "" : ", ");
3553	}
3554	seq_puts(m, "]\n");
3555
3556	seq_puts(m, "EVM: [");
3557	for (i = 0; i < (hal->ant_diversity ? 2 : 1); i++) {
3558		evm_min = ewma_evm_read(&rtwsta->evm_min[i]);
3559		evm_max = ewma_evm_read(&rtwsta->evm_max[i]);
3560
3561		seq_printf(m, "%s(%2u.%02u, %2u.%02u)", i == 0 ? "" : " ",
3562			   evm_min >> 2, (evm_min & 0x3) * 25,
3563			   evm_max >> 2, (evm_max & 0x3) * 25);
3564	}
3565	seq_puts(m, "]\t");
3566
3567	snr = ewma_snr_read(&rtwsta->avg_snr);
3568	seq_printf(m, "SNR: %u\n", snr);
3569}
3570
3571static void
3572rtw89_debug_append_rx_rate(struct seq_file *m, struct rtw89_pkt_stat *pkt_stat,
3573			   enum rtw89_hw_rate first_rate, int len)
3574{
3575	int i;
3576
3577	for (i = 0; i < len; i++)
3578		seq_printf(m, "%s%u", i == 0 ? "" : ", ",
3579			   pkt_stat->rx_rate_cnt[first_rate + i]);
3580}
3581
3582#define FIRST_RATE_SAME(rate) {RTW89_HW_RATE_ ## rate, RTW89_HW_RATE_ ## rate}
3583#define FIRST_RATE_ENUM(rate) {RTW89_HW_RATE_ ## rate, RTW89_HW_RATE_V1_ ## rate}
3584#define FIRST_RATE_GEV1(rate) {RTW89_HW_RATE_INVAL, RTW89_HW_RATE_V1_ ## rate}
3585
3586static const struct rtw89_rx_rate_cnt_info {
3587	enum rtw89_hw_rate first_rate[RTW89_CHIP_GEN_NUM];
3588	int len;
3589	int ext;
3590	const char *rate_mode;
3591} rtw89_rx_rate_cnt_infos[] = {
3592	{FIRST_RATE_SAME(CCK1), 4, 0, "Legacy:"},
3593	{FIRST_RATE_SAME(OFDM6), 8, 0, "OFDM:"},
3594	{FIRST_RATE_ENUM(MCS0), 8, 0, "HT 0:"},
3595	{FIRST_RATE_ENUM(MCS8), 8, 0, "HT 1:"},
3596	{FIRST_RATE_ENUM(VHT_NSS1_MCS0), 10, 2, "VHT 1SS:"},
3597	{FIRST_RATE_ENUM(VHT_NSS2_MCS0), 10, 2, "VHT 2SS:"},
3598	{FIRST_RATE_ENUM(HE_NSS1_MCS0), 12, 0, "HE 1SS:"},
3599	{FIRST_RATE_ENUM(HE_NSS2_MCS0), 12, 0, "HE 2SS:"},
3600	{FIRST_RATE_GEV1(EHT_NSS1_MCS0), 14, 2, "EHT 1SS:"},
3601	{FIRST_RATE_GEV1(EHT_NSS2_MCS0), 14, 0, "EHT 2SS:"},
3602};
3603
3604static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v)
3605{
3606	struct rtw89_debugfs_priv *debugfs_priv = m->private;
3607	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
3608	struct rtw89_traffic_stats *stats = &rtwdev->stats;
3609	struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.last_pkt_stat;
3610	const struct rtw89_chip_info *chip = rtwdev->chip;
3611	const struct rtw89_rx_rate_cnt_info *info;
3612	enum rtw89_hw_rate first_rate;
3613	int i;
3614
3615	seq_printf(m, "TP TX: %u [%u] Mbps (lv: %d), RX: %u [%u] Mbps (lv: %d)\n",
3616		   stats->tx_throughput, stats->tx_throughput_raw, stats->tx_tfc_lv,
3617		   stats->rx_throughput, stats->rx_throughput_raw, stats->rx_tfc_lv);
3618	seq_printf(m, "Beacon: %u, TF: %u\n", pkt_stat->beacon_nr,
3619		   stats->rx_tf_periodic);
3620	seq_printf(m, "Avg packet length: TX=%u, RX=%u\n", stats->tx_avg_len,
3621		   stats->rx_avg_len);
3622
3623	seq_puts(m, "RX count:\n");
3624
3625	for (i = 0; i < ARRAY_SIZE(rtw89_rx_rate_cnt_infos); i++) {
3626		info = &rtw89_rx_rate_cnt_infos[i];
3627		first_rate = info->first_rate[chip->chip_gen];
3628		if (first_rate >= RTW89_HW_RATE_NR)
3629			continue;
3630
3631		seq_printf(m, "%10s [", info->rate_mode);
3632		rtw89_debug_append_rx_rate(m, pkt_stat,
3633					   first_rate, info->len);
3634		if (info->ext) {
3635			seq_puts(m, "][");
3636			rtw89_debug_append_rx_rate(m, pkt_stat,
3637						   first_rate + info->len, info->ext);
3638		}
3639		seq_puts(m, "]\n");
3640	}
3641
3642	ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_info_get_iter, m);
3643
3644	return 0;
3645}
3646
3647static void rtw89_dump_addr_cam(struct seq_file *m,
3648				struct rtw89_addr_cam_entry *addr_cam)
3649{
3650	struct rtw89_sec_cam_entry *sec_entry;
3651	int i;
3652
3653	seq_printf(m, "\taddr_cam_idx=%u\n", addr_cam->addr_cam_idx);
3654	seq_printf(m, "\t-> bssid_cam_idx=%u\n", addr_cam->bssid_cam_idx);
3655	seq_printf(m, "\tsec_cam_bitmap=%*ph\n", (int)sizeof(addr_cam->sec_cam_map),
3656		   addr_cam->sec_cam_map);
3657	for (i = 0; i < RTW89_SEC_CAM_IN_ADDR_CAM; i++) {
3658		sec_entry = addr_cam->sec_entries[i];
3659		if (!sec_entry)
3660			continue;
3661		seq_printf(m, "\tsec[%d]: sec_cam_idx %u", i, sec_entry->sec_cam_idx);
3662		if (sec_entry->ext_key)
3663			seq_printf(m, ", %u", sec_entry->sec_cam_idx + 1);
3664		seq_puts(m, "\n");
3665	}
3666}
3667
3668__printf(3, 4)
3669static void rtw89_dump_pkt_offload(struct seq_file *m, struct list_head *pkt_list,
3670				   const char *fmt, ...)
3671{
3672	struct rtw89_pktofld_info *info;
3673	struct va_format vaf;
3674	va_list args;
3675
3676	if (list_empty(pkt_list))
3677		return;
3678
3679	va_start(args, fmt);
3680	vaf.va = &args;
3681	vaf.fmt = fmt;
3682
3683	seq_printf(m, "%pV", &vaf);
3684
3685	va_end(args);
3686
3687	list_for_each_entry(info, pkt_list, list)
3688		seq_printf(m, "%d ", info->id);
3689
3690	seq_puts(m, "\n");
3691}
3692
3693static
3694void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
3695{
3696	struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
3697	struct seq_file *m = (struct seq_file *)data;
3698	struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
3699
3700	seq_printf(m, "VIF [%d] %pM\n", rtwvif->mac_id, rtwvif->mac_addr);
3701	seq_printf(m, "\tbssid_cam_idx=%u\n", bssid_cam->bssid_cam_idx);
3702	rtw89_dump_addr_cam(m, &rtwvif->addr_cam);
3703	rtw89_dump_pkt_offload(m, &rtwvif->general_pkt_list, "\tpkt_ofld[GENERAL]: ");
3704}
3705
3706static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_sta *rtwsta)
3707{
3708	struct rtw89_vif *rtwvif = rtwsta->rtwvif;
3709	struct rtw89_dev *rtwdev = rtwvif->rtwdev;
3710	struct rtw89_ba_cam_entry *entry;
3711	bool first = true;
3712
3713	list_for_each_entry(entry, &rtwsta->ba_cam_list, list) {
3714		if (first) {
3715			seq_puts(m, "\tba_cam ");
3716			first = false;
3717		} else {
3718			seq_puts(m, ", ");
3719		}
3720		seq_printf(m, "tid[%u]=%d", entry->tid,
3721			   (int)(entry - rtwdev->cam_info.ba_cam_entry));
3722	}
3723	seq_puts(m, "\n");
3724}
3725
3726static void rtw89_sta_ids_get_iter(void *data, struct ieee80211_sta *sta)
3727{
3728	struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
3729	struct seq_file *m = (struct seq_file *)data;
3730
3731	seq_printf(m, "STA [%d] %pM %s\n", rtwsta->mac_id, sta->addr,
3732		   sta->tdls ? "(TDLS)" : "");
3733	rtw89_dump_addr_cam(m, &rtwsta->addr_cam);
3734	rtw89_dump_ba_cam(m, rtwsta);
3735}
3736
3737static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v)
3738{
3739	struct rtw89_debugfs_priv *debugfs_priv = m->private;
3740	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
3741	struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
3742	u8 idx;
3743
3744	mutex_lock(&rtwdev->mutex);
3745
3746	seq_puts(m, "map:\n");
3747	seq_printf(m, "\tmac_id:    %*ph\n", (int)sizeof(rtwdev->mac_id_map),
3748		   rtwdev->mac_id_map);
3749	seq_printf(m, "\taddr_cam:  %*ph\n", (int)sizeof(cam_info->addr_cam_map),
3750		   cam_info->addr_cam_map);
3751	seq_printf(m, "\tbssid_cam: %*ph\n", (int)sizeof(cam_info->bssid_cam_map),
3752		   cam_info->bssid_cam_map);
3753	seq_printf(m, "\tsec_cam:   %*ph\n", (int)sizeof(cam_info->sec_cam_map),
3754		   cam_info->sec_cam_map);
3755	seq_printf(m, "\tba_cam:    %*ph\n", (int)sizeof(cam_info->ba_cam_map),
3756		   cam_info->ba_cam_map);
3757	seq_printf(m, "\tpkt_ofld:  %*ph\n", (int)sizeof(rtwdev->pkt_offload),
3758		   rtwdev->pkt_offload);
3759
3760	for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) {
3761		if (!(rtwdev->chip->support_bands & BIT(idx)))
3762			continue;
3763		rtw89_dump_pkt_offload(m, &rtwdev->scan_info.pkt_list[idx],
3764				       "\t\t[SCAN %u]: ", idx);
3765	}
3766
3767	ieee80211_iterate_active_interfaces_atomic(rtwdev->hw,
3768		IEEE80211_IFACE_ITER_NORMAL, rtw89_vif_ids_get_iter, m);
3769
3770	ieee80211_iterate_stations_atomic(rtwdev->hw, rtw89_sta_ids_get_iter, m);
3771
3772	mutex_unlock(&rtwdev->mutex);
3773
3774	return 0;
3775}
3776
3777#define DM_INFO(type) {RTW89_DM_ ## type, #type}
3778
3779static const struct rtw89_disabled_dm_info {
3780	enum rtw89_dm_type type;
3781	const char *name;
3782} rtw89_disabled_dm_infos[] = {
3783	DM_INFO(DYNAMIC_EDCCA),
3784};
3785
3786static int
3787rtw89_debug_priv_disable_dm_get(struct seq_file *m, void *v)
3788{
3789	struct rtw89_debugfs_priv *debugfs_priv = m->private;
3790	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
3791	const struct rtw89_disabled_dm_info *info;
3792	struct rtw89_hal *hal = &rtwdev->hal;
3793	u32 disabled;
3794	int i;
3795
3796	seq_printf(m, "Disabled DM: 0x%x\n", hal->disabled_dm_bitmap);
3797
3798	for (i = 0; i < ARRAY_SIZE(rtw89_disabled_dm_infos); i++) {
3799		info = &rtw89_disabled_dm_infos[i];
3800		disabled = BIT(info->type) & hal->disabled_dm_bitmap;
3801
3802		seq_printf(m, "[%d] %s: %c\n", info->type, info->name,
3803			   disabled ? 'X' : 'O');
3804	}
3805
3806	return 0;
3807}
3808
3809static ssize_t
3810rtw89_debug_priv_disable_dm_set(struct file *filp, const char __user *user_buf,
3811				size_t count, loff_t *loff)
3812{
3813	struct seq_file *m = (struct seq_file *)filp->private_data;
3814	struct rtw89_debugfs_priv *debugfs_priv = m->private;
3815	struct rtw89_dev *rtwdev = debugfs_priv->rtwdev;
3816	struct rtw89_hal *hal = &rtwdev->hal;
3817	u32 conf;
3818	int ret;
3819
3820	ret = kstrtou32_from_user(user_buf, count, 0, &conf);
3821	if (ret)
3822		return -EINVAL;
3823
3824	hal->disabled_dm_bitmap = conf;
3825
3826	return count;
3827}
3828
3829static struct rtw89_debugfs_priv rtw89_debug_priv_read_reg = {
3830	.cb_read = rtw89_debug_priv_read_reg_get,
3831	.cb_write = rtw89_debug_priv_read_reg_select,
3832};
3833
3834static struct rtw89_debugfs_priv rtw89_debug_priv_write_reg = {
3835	.cb_write = rtw89_debug_priv_write_reg_set,
3836};
3837
3838static struct rtw89_debugfs_priv rtw89_debug_priv_read_rf = {
3839	.cb_read = rtw89_debug_priv_read_rf_get,
3840	.cb_write = rtw89_debug_priv_read_rf_select,
3841};
3842
3843static struct rtw89_debugfs_priv rtw89_debug_priv_write_rf = {
3844	.cb_write = rtw89_debug_priv_write_rf_set,
3845};
3846
3847static struct rtw89_debugfs_priv rtw89_debug_priv_rf_reg_dump = {
3848	.cb_read = rtw89_debug_priv_rf_reg_dump_get,
3849};
3850
3851static struct rtw89_debugfs_priv rtw89_debug_priv_txpwr_table = {
3852	.cb_read = rtw89_debug_priv_txpwr_table_get,
3853};
3854
3855static struct rtw89_debugfs_priv rtw89_debug_priv_mac_reg_dump = {
3856	.cb_read = rtw89_debug_priv_mac_reg_dump_get,
3857	.cb_write = rtw89_debug_priv_mac_reg_dump_select,
3858};
3859
3860static struct rtw89_debugfs_priv rtw89_debug_priv_mac_mem_dump = {
3861	.cb_read = rtw89_debug_priv_mac_mem_dump_get,
3862	.cb_write = rtw89_debug_priv_mac_mem_dump_select,
3863};
3864
3865static struct rtw89_debugfs_priv rtw89_debug_priv_mac_dbg_port_dump = {
3866	.cb_read = rtw89_debug_priv_mac_dbg_port_dump_get,
3867	.cb_write = rtw89_debug_priv_mac_dbg_port_dump_select,
3868};
3869
3870static struct rtw89_debugfs_priv rtw89_debug_priv_send_h2c = {
3871	.cb_write = rtw89_debug_priv_send_h2c_set,
3872};
3873
3874static struct rtw89_debugfs_priv rtw89_debug_priv_early_h2c = {
3875	.cb_read = rtw89_debug_priv_early_h2c_get,
3876	.cb_write = rtw89_debug_priv_early_h2c_set,
3877};
3878
3879static struct rtw89_debugfs_priv rtw89_debug_priv_fw_crash = {
3880	.cb_read = rtw89_debug_priv_fw_crash_get,
3881	.cb_write = rtw89_debug_priv_fw_crash_set,
3882};
3883
3884static struct rtw89_debugfs_priv rtw89_debug_priv_btc_info = {
3885	.cb_read = rtw89_debug_priv_btc_info_get,
3886};
3887
3888static struct rtw89_debugfs_priv rtw89_debug_priv_btc_manual = {
3889	.cb_write = rtw89_debug_priv_btc_manual_set,
3890};
3891
3892static struct rtw89_debugfs_priv rtw89_debug_priv_fw_log_manual = {
3893	.cb_write = rtw89_debug_fw_log_manual_set,
3894};
3895
3896static struct rtw89_debugfs_priv rtw89_debug_priv_phy_info = {
3897	.cb_read = rtw89_debug_priv_phy_info_get,
3898};
3899
3900static struct rtw89_debugfs_priv rtw89_debug_priv_stations = {
3901	.cb_read = rtw89_debug_priv_stations_get,
3902};
3903
3904static struct rtw89_debugfs_priv rtw89_debug_priv_disable_dm = {
3905	.cb_read = rtw89_debug_priv_disable_dm_get,
3906	.cb_write = rtw89_debug_priv_disable_dm_set,
3907};
3908
3909#define rtw89_debugfs_add(name, mode, fopname, parent)				\
3910	do {									\
3911		rtw89_debug_priv_ ##name.rtwdev = rtwdev;			\
3912		if (!debugfs_create_file(#name, mode,				\
3913					 parent, &rtw89_debug_priv_ ##name,	\
3914					 &file_ops_ ##fopname))			\
3915			pr_debug("Unable to initialize debugfs:%s\n", #name);	\
3916	} while (0)
3917
3918#define rtw89_debugfs_add_w(name)						\
3919	rtw89_debugfs_add(name, S_IFREG | 0222, single_w, debugfs_topdir)
3920#define rtw89_debugfs_add_rw(name)						\
3921	rtw89_debugfs_add(name, S_IFREG | 0666, common_rw, debugfs_topdir)
3922#define rtw89_debugfs_add_r(name)						\
3923	rtw89_debugfs_add(name, S_IFREG | 0444, single_r, debugfs_topdir)
3924
3925void rtw89_debugfs_init(struct rtw89_dev *rtwdev)
3926{
3927	struct dentry *debugfs_topdir;
3928
3929	debugfs_topdir = debugfs_create_dir("rtw89",
3930					    rtwdev->hw->wiphy->debugfsdir);
3931
3932	rtw89_debugfs_add_rw(read_reg);
3933	rtw89_debugfs_add_w(write_reg);
3934	rtw89_debugfs_add_rw(read_rf);
3935	rtw89_debugfs_add_w(write_rf);
3936	rtw89_debugfs_add_r(rf_reg_dump);
3937	rtw89_debugfs_add_r(txpwr_table);
3938	rtw89_debugfs_add_rw(mac_reg_dump);
3939	rtw89_debugfs_add_rw(mac_mem_dump);
3940	rtw89_debugfs_add_rw(mac_dbg_port_dump);
3941	rtw89_debugfs_add_w(send_h2c);
3942	rtw89_debugfs_add_rw(early_h2c);
3943	rtw89_debugfs_add_rw(fw_crash);
3944	rtw89_debugfs_add_r(btc_info);
3945	rtw89_debugfs_add_w(btc_manual);
3946	rtw89_debugfs_add_w(fw_log_manual);
3947	rtw89_debugfs_add_r(phy_info);
3948	rtw89_debugfs_add_r(stations);
3949	rtw89_debugfs_add_rw(disable_dm);
3950}
3951#endif
3952
3953#ifdef CONFIG_RTW89_DEBUGMSG
3954void rtw89_debug(struct rtw89_dev *rtwdev, enum rtw89_debug_mask mask,
3955		 const char *fmt, ...)
3956{
3957	struct va_format vaf = {
3958	.fmt = fmt,
3959	};
3960
3961	va_list args;
3962
3963	va_start(args, fmt);
3964	vaf.va = &args;
3965
3966	if (rtw89_debug_mask & mask)
3967		dev_printk(KERN_DEBUG, rtwdev->dev, "%pV", &vaf);
3968
3969	va_end(args);
3970}
3971EXPORT_SYMBOL(rtw89_debug);
3972#endif
3973