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

source code of linux/drivers/net/wireless/realtek/rtw89/debug.c