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