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