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