Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 : : /* Copyright(c) 2018-2019 Realtek Corporation
3 : : */
4 : :
5 : : #include <linux/debugfs.h>
6 : : #include <linux/seq_file.h>
7 : : #include "main.h"
8 : : #include "sec.h"
9 : : #include "fw.h"
10 : : #include "debug.h"
11 : : #include "phy.h"
12 : :
13 : : #ifdef CONFIG_RTW88_DEBUGFS
14 : :
15 : : struct rtw_debugfs_priv {
16 : : struct rtw_dev *rtwdev;
17 : : int (*cb_read)(struct seq_file *m, void *v);
18 : : ssize_t (*cb_write)(struct file *filp, const char __user *buffer,
19 : : size_t count, loff_t *loff);
20 : : union {
21 : : u32 cb_data;
22 : : u8 *buf;
23 : : struct {
24 : : u32 page_offset;
25 : : u32 page_num;
26 : : } rsvd_page;
27 : : struct {
28 : : u8 rf_path;
29 : : u32 rf_addr;
30 : : u32 rf_mask;
31 : : };
32 : : struct {
33 : : u32 addr;
34 : : u32 len;
35 : : } read_reg;
36 : : };
37 : : };
38 : :
39 : 0 : static int rtw_debugfs_single_show(struct seq_file *m, void *v)
40 : : {
41 : 0 : struct rtw_debugfs_priv *debugfs_priv = m->private;
42 : :
43 : 0 : return debugfs_priv->cb_read(m, v);
44 : : }
45 : :
46 : 0 : static ssize_t rtw_debugfs_common_write(struct file *filp,
47 : : const char __user *buffer,
48 : : size_t count, loff_t *loff)
49 : : {
50 : 0 : struct rtw_debugfs_priv *debugfs_priv = filp->private_data;
51 : :
52 : 0 : return debugfs_priv->cb_write(filp, buffer, count, loff);
53 : : }
54 : :
55 : 0 : static ssize_t rtw_debugfs_single_write(struct file *filp,
56 : : const char __user *buffer,
57 : : size_t count, loff_t *loff)
58 : : {
59 : 0 : struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
60 : 0 : struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
61 : :
62 : 0 : return debugfs_priv->cb_write(filp, buffer, count, loff);
63 : : }
64 : :
65 : 0 : static int rtw_debugfs_single_open_rw(struct inode *inode, struct file *filp)
66 : : {
67 : 0 : return single_open(filp, rtw_debugfs_single_show, inode->i_private);
68 : : }
69 : :
70 : 0 : static int rtw_debugfs_close(struct inode *inode, struct file *filp)
71 : : {
72 : 0 : return 0;
73 : : }
74 : :
75 : : static const struct file_operations file_ops_single_r = {
76 : : .owner = THIS_MODULE,
77 : : .open = rtw_debugfs_single_open_rw,
78 : : .read = seq_read,
79 : : .llseek = seq_lseek,
80 : : .release = single_release,
81 : : };
82 : :
83 : : static const struct file_operations file_ops_single_rw = {
84 : : .owner = THIS_MODULE,
85 : : .open = rtw_debugfs_single_open_rw,
86 : : .release = single_release,
87 : : .read = seq_read,
88 : : .llseek = seq_lseek,
89 : : .write = rtw_debugfs_single_write,
90 : : };
91 : :
92 : : static const struct file_operations file_ops_common_write = {
93 : : .owner = THIS_MODULE,
94 : : .write = rtw_debugfs_common_write,
95 : : .open = simple_open,
96 : : .release = rtw_debugfs_close,
97 : : };
98 : :
99 : 0 : static int rtw_debugfs_get_read_reg(struct seq_file *m, void *v)
100 : : {
101 : 0 : struct rtw_debugfs_priv *debugfs_priv = m->private;
102 : 0 : struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
103 : 0 : u32 val, len, addr;
104 : :
105 : 0 : len = debugfs_priv->read_reg.len;
106 : 0 : addr = debugfs_priv->read_reg.addr;
107 [ # # # # ]: 0 : switch (len) {
108 : : case 1:
109 : 0 : val = rtw_read8(rtwdev, addr);
110 : 0 : seq_printf(m, "reg 0x%03x: 0x%02x\n", addr, val);
111 : 0 : break;
112 : : case 2:
113 : 0 : val = rtw_read16(rtwdev, addr);
114 : 0 : seq_printf(m, "reg 0x%03x: 0x%04x\n", addr, val);
115 : 0 : break;
116 : : case 4:
117 : 0 : val = rtw_read32(rtwdev, addr);
118 : 0 : seq_printf(m, "reg 0x%03x: 0x%08x\n", addr, val);
119 : 0 : break;
120 : : }
121 : 0 : return 0;
122 : : }
123 : :
124 : 0 : static int rtw_debugfs_get_rf_read(struct seq_file *m, void *v)
125 : : {
126 : 0 : struct rtw_debugfs_priv *debugfs_priv = m->private;
127 : 0 : struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
128 : 0 : u32 val, addr, mask;
129 : 0 : u8 path;
130 : :
131 : 0 : path = debugfs_priv->rf_path;
132 : 0 : addr = debugfs_priv->rf_addr;
133 : 0 : mask = debugfs_priv->rf_mask;
134 : :
135 : 0 : val = rtw_read_rf(rtwdev, path, addr, mask);
136 : :
137 : 0 : seq_printf(m, "rf_read path:%d addr:0x%08x mask:0x%08x val=0x%08x\n",
138 : : path, addr, mask, val);
139 : :
140 : 0 : return 0;
141 : : }
142 : :
143 : 0 : static int rtw_debugfs_copy_from_user(char tmp[], int size,
144 : : const char __user *buffer, size_t count,
145 : : int num)
146 : : {
147 : 0 : int tmp_len;
148 : :
149 [ # # ]: 0 : if (count < num)
150 : : return -EFAULT;
151 : :
152 : 0 : tmp_len = (count > size - 1 ? size - 1 : count);
153 : :
154 [ # # # # : 0 : if (!buffer || copy_from_user(tmp, buffer, tmp_len))
# # ]
155 : 0 : return count;
156 : :
157 : 0 : tmp[tmp_len] = '\0';
158 : :
159 : 0 : return 0;
160 : : }
161 : :
162 : 0 : static ssize_t rtw_debugfs_set_read_reg(struct file *filp,
163 : : const char __user *buffer,
164 : : size_t count, loff_t *loff)
165 : : {
166 : 0 : struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
167 : 0 : struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
168 : 0 : struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
169 : 0 : char tmp[32 + 1];
170 : 0 : u32 addr, len;
171 : 0 : int num;
172 : :
173 : 0 : rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2);
174 : :
175 : 0 : num = sscanf(tmp, "%x %x", &addr, &len);
176 : :
177 [ # # ]: 0 : if (num != 2)
178 : 0 : return count;
179 : :
180 [ # # # # ]: 0 : if (len != 1 && len != 2 && len != 4) {
181 : 0 : rtw_warn(rtwdev, "read reg setting wrong len\n");
182 : 0 : return -EINVAL;
183 : : }
184 : 0 : debugfs_priv->read_reg.addr = addr;
185 : 0 : debugfs_priv->read_reg.len = len;
186 : :
187 : 0 : return count;
188 : : }
189 : :
190 : 0 : static int rtw_debugfs_get_dump_cam(struct seq_file *m, void *v)
191 : : {
192 : 0 : struct rtw_debugfs_priv *debugfs_priv = m->private;
193 : 0 : struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
194 : 0 : u32 val, command;
195 : 0 : u32 hw_key_idx = debugfs_priv->cb_data << RTW_SEC_CAM_ENTRY_SHIFT;
196 : 0 : u32 read_cmd = RTW_SEC_CMD_POLLING;
197 : 0 : int i;
198 : :
199 : 0 : seq_printf(m, "cam entry%d\n", debugfs_priv->cb_data);
200 : 0 : seq_puts(m, "0x0 0x1 0x2 0x3 ");
201 : 0 : seq_puts(m, "0x4 0x5\n");
202 : 0 : mutex_lock(&rtwdev->mutex);
203 [ # # ]: 0 : for (i = 0; i <= 5; i++) {
204 : 0 : command = read_cmd | (hw_key_idx + i);
205 : 0 : rtw_write32(rtwdev, RTW_SEC_CMD_REG, command);
206 : 0 : val = rtw_read32(rtwdev, RTW_SEC_READ_REG);
207 : 0 : seq_printf(m, "%8.8x", val);
208 [ # # ]: 0 : if (i < 2)
209 : 0 : seq_puts(m, " ");
210 : : }
211 : 0 : seq_puts(m, "\n");
212 : 0 : mutex_unlock(&rtwdev->mutex);
213 : 0 : return 0;
214 : : }
215 : :
216 : 0 : static int rtw_debugfs_get_rsvd_page(struct seq_file *m, void *v)
217 : : {
218 : 0 : struct rtw_debugfs_priv *debugfs_priv = m->private;
219 : 0 : struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
220 : 0 : u8 page_size = rtwdev->chip->page_size;
221 : 0 : u32 buf_size = debugfs_priv->rsvd_page.page_num * page_size;
222 : 0 : u32 offset = debugfs_priv->rsvd_page.page_offset * page_size;
223 : 0 : u8 *buf;
224 : 0 : int i;
225 : 0 : int ret;
226 : :
227 : 0 : buf = vzalloc(buf_size);
228 [ # # ]: 0 : if (!buf)
229 : : return -ENOMEM;
230 : :
231 : 0 : ret = rtw_dump_drv_rsvd_page(rtwdev, offset, buf_size, (u32 *)buf);
232 [ # # ]: 0 : if (ret) {
233 : 0 : rtw_err(rtwdev, "failed to dump rsvd page\n");
234 : 0 : vfree(buf);
235 : 0 : return ret;
236 : : }
237 : :
238 [ # # ]: 0 : for (i = 0 ; i < buf_size ; i += 8) {
239 [ # # ]: 0 : if (i % page_size == 0)
240 : 0 : seq_printf(m, "PAGE %d\n", (i + offset) / page_size);
241 : 0 : seq_printf(m, "%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
242 : 0 : *(buf + i), *(buf + i + 1),
243 : 0 : *(buf + i + 2), *(buf + i + 3),
244 : 0 : *(buf + i + 4), *(buf + i + 5),
245 : 0 : *(buf + i + 6), *(buf + i + 7));
246 : : }
247 : 0 : vfree(buf);
248 : :
249 : 0 : return 0;
250 : : }
251 : :
252 : 0 : static ssize_t rtw_debugfs_set_rsvd_page(struct file *filp,
253 : : const char __user *buffer,
254 : : size_t count, loff_t *loff)
255 : : {
256 : 0 : struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
257 : 0 : struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
258 : 0 : struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
259 : 0 : char tmp[32 + 1];
260 : 0 : u32 offset, page_num;
261 : 0 : int num;
262 : :
263 : 0 : rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2);
264 : :
265 : 0 : num = sscanf(tmp, "%d %d", &offset, &page_num);
266 : :
267 [ # # ]: 0 : if (num != 2) {
268 : 0 : rtw_warn(rtwdev, "invalid arguments\n");
269 : 0 : return num;
270 : : }
271 : :
272 : 0 : debugfs_priv->rsvd_page.page_offset = offset;
273 : 0 : debugfs_priv->rsvd_page.page_num = page_num;
274 : :
275 : 0 : return count;
276 : : }
277 : :
278 : 0 : static ssize_t rtw_debugfs_set_single_input(struct file *filp,
279 : : const char __user *buffer,
280 : : size_t count, loff_t *loff)
281 : : {
282 : 0 : struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
283 : 0 : struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
284 : 0 : struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
285 : 0 : char tmp[32 + 1];
286 : 0 : u32 input;
287 : 0 : int num;
288 : :
289 : 0 : rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1);
290 : :
291 : 0 : num = kstrtoint(tmp, 0, &input);
292 : :
293 [ # # ]: 0 : if (num) {
294 : 0 : rtw_warn(rtwdev, "kstrtoint failed\n");
295 : 0 : return num;
296 : : }
297 : :
298 : 0 : debugfs_priv->cb_data = input;
299 : :
300 : 0 : return count;
301 : : }
302 : :
303 : 0 : static ssize_t rtw_debugfs_set_write_reg(struct file *filp,
304 : : const char __user *buffer,
305 : : size_t count, loff_t *loff)
306 : : {
307 : 0 : struct rtw_debugfs_priv *debugfs_priv = filp->private_data;
308 : 0 : struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
309 : 0 : char tmp[32 + 1];
310 : 0 : u32 addr, val, len;
311 : 0 : int num;
312 : :
313 : 0 : rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3);
314 : :
315 : : /* write BB/MAC register */
316 : 0 : num = sscanf(tmp, "%x %x %x", &addr, &val, &len);
317 : :
318 [ # # ]: 0 : if (num != 3)
319 : 0 : return count;
320 : :
321 [ # # # # ]: 0 : switch (len) {
322 : 0 : case 1:
323 : 0 : rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,
324 : : "reg write8 0x%03x: 0x%08x\n", addr, val);
325 : 0 : rtw_write8(rtwdev, addr, (u8)val);
326 : : break;
327 : 0 : case 2:
328 : 0 : rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,
329 : : "reg write16 0x%03x: 0x%08x\n", addr, val);
330 : 0 : rtw_write16(rtwdev, addr, (u16)val);
331 : : break;
332 : 0 : case 4:
333 : 0 : rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,
334 : : "reg write32 0x%03x: 0x%08x\n", addr, val);
335 : 0 : rtw_write32(rtwdev, addr, (u32)val);
336 : : break;
337 : 0 : default:
338 : 0 : rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,
339 : : "error write length = %d\n", len);
340 : 0 : break;
341 : : }
342 : :
343 : 0 : return count;
344 : : }
345 : :
346 : 0 : static ssize_t rtw_debugfs_set_rf_write(struct file *filp,
347 : : const char __user *buffer,
348 : : size_t count, loff_t *loff)
349 : : {
350 : 0 : struct rtw_debugfs_priv *debugfs_priv = filp->private_data;
351 : 0 : struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
352 : 0 : char tmp[32 + 1];
353 : 0 : u32 path, addr, mask, val;
354 : 0 : int num;
355 : :
356 : 0 : rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4);
357 : :
358 : 0 : num = sscanf(tmp, "%x %x %x %x", &path, &addr, &mask, &val);
359 : :
360 [ # # ]: 0 : if (num != 4) {
361 : 0 : rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n");
362 : 0 : return count;
363 : : }
364 : :
365 : 0 : rtw_write_rf(rtwdev, path, addr, mask, val);
366 : 0 : rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,
367 : : "write_rf path:%d addr:0x%08x mask:0x%08x, val:0x%08x\n",
368 : : path, addr, mask, val);
369 : :
370 : 0 : return count;
371 : : }
372 : :
373 : 0 : static ssize_t rtw_debugfs_set_rf_read(struct file *filp,
374 : : const char __user *buffer,
375 : : size_t count, loff_t *loff)
376 : : {
377 : 0 : struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
378 : 0 : struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
379 : 0 : struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
380 : 0 : char tmp[32 + 1];
381 : 0 : u32 path, addr, mask;
382 : 0 : int num;
383 : :
384 : 0 : rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3);
385 : :
386 : 0 : num = sscanf(tmp, "%x %x %x", &path, &addr, &mask);
387 : :
388 [ # # ]: 0 : if (num != 3) {
389 : 0 : rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n");
390 : 0 : return count;
391 : : }
392 : :
393 : 0 : debugfs_priv->rf_path = path;
394 : 0 : debugfs_priv->rf_addr = addr;
395 : 0 : debugfs_priv->rf_mask = mask;
396 : :
397 : 0 : return count;
398 : : }
399 : :
400 : 0 : static int rtw_debug_get_mac_page(struct seq_file *m, void *v)
401 : : {
402 : 0 : struct rtw_debugfs_priv *debugfs_priv = m->private;
403 : 0 : struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
404 : 0 : u32 val;
405 : 0 : u32 page = debugfs_priv->cb_data;
406 : 0 : int i, n;
407 : 0 : int max = 0xff;
408 : :
409 : 0 : val = rtw_read32(rtwdev, debugfs_priv->cb_data);
410 [ # # ]: 0 : for (n = 0; n <= max; ) {
411 : 0 : seq_printf(m, "\n%8.8x ", n + page);
412 [ # # # # ]: 0 : for (i = 0; i < 4 && n <= max; i++, n += 4)
413 : 0 : seq_printf(m, "%8.8x ",
414 : : rtw_read32(rtwdev, (page | n)));
415 : : }
416 : 0 : seq_puts(m, "\n");
417 : 0 : return 0;
418 : : }
419 : :
420 : 0 : static int rtw_debug_get_bb_page(struct seq_file *m, void *v)
421 : : {
422 : 0 : struct rtw_debugfs_priv *debugfs_priv = m->private;
423 : 0 : struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
424 : 0 : u32 val;
425 : 0 : u32 page = debugfs_priv->cb_data;
426 : 0 : int i, n;
427 : 0 : int max = 0xff;
428 : :
429 : 0 : val = rtw_read32(rtwdev, debugfs_priv->cb_data);
430 [ # # ]: 0 : for (n = 0; n <= max; ) {
431 : 0 : seq_printf(m, "\n%8.8x ", n + page);
432 [ # # # # ]: 0 : for (i = 0; i < 4 && n <= max; i++, n += 4)
433 : 0 : seq_printf(m, "%8.8x ",
434 : : rtw_read32(rtwdev, (page | n)));
435 : : }
436 : 0 : seq_puts(m, "\n");
437 : 0 : return 0;
438 : : }
439 : :
440 : 0 : static int rtw_debug_get_rf_dump(struct seq_file *m, void *v)
441 : : {
442 : 0 : struct rtw_debugfs_priv *debugfs_priv = m->private;
443 : 0 : struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
444 : 0 : u32 addr, offset, data;
445 : 0 : u8 path;
446 : :
447 [ # # ]: 0 : for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
448 : 0 : seq_printf(m, "RF path:%d\n", path);
449 [ # # ]: 0 : for (addr = 0; addr < 0x100; addr += 4) {
450 : 0 : seq_printf(m, "%8.8x ", addr);
451 [ # # ]: 0 : for (offset = 0; offset < 4; offset++) {
452 : 0 : data = rtw_read_rf(rtwdev, path, addr + offset,
453 : : 0xffffffff);
454 : 0 : seq_printf(m, "%8.8x ", data);
455 : : }
456 : 0 : seq_puts(m, "\n");
457 : : }
458 : 0 : seq_puts(m, "\n");
459 : : }
460 : :
461 : 0 : return 0;
462 : : }
463 : :
464 : 0 : static void rtw_print_cck_rate_txt(struct seq_file *m, u8 rate)
465 : : {
466 : 0 : static const char * const
467 : : cck_rate[] = {"1M", "2M", "5.5M", "11M"};
468 : 0 : u8 idx = rate - DESC_RATE1M;
469 : :
470 : 0 : seq_printf(m, " CCK_%-5s", cck_rate[idx]);
471 : 0 : }
472 : :
473 : 0 : static void rtw_print_ofdm_rate_txt(struct seq_file *m, u8 rate)
474 : : {
475 : 0 : static const char * const
476 : : ofdm_rate[] = {"6M", "9M", "12M", "18M", "24M", "36M", "48M", "54M"};
477 : 0 : u8 idx = rate - DESC_RATE6M;
478 : :
479 : 0 : seq_printf(m, " OFDM_%-4s", ofdm_rate[idx]);
480 : 0 : }
481 : :
482 : 0 : static void rtw_print_ht_rate_txt(struct seq_file *m, u8 rate)
483 : : {
484 : 0 : u8 mcs_n = rate - DESC_RATEMCS0;
485 : :
486 : 0 : seq_printf(m, " MCS%-6u", mcs_n);
487 : 0 : }
488 : :
489 : 0 : static void rtw_print_vht_rate_txt(struct seq_file *m, u8 rate)
490 : : {
491 : 0 : u8 idx = rate - DESC_RATEVHT1SS_MCS0;
492 : 0 : u8 n_ss, mcs_n;
493 : :
494 : : /* n spatial stream */
495 : 0 : n_ss = 1 + idx / 10;
496 : : /* MCS n */
497 : 0 : mcs_n = idx % 10;
498 : 0 : seq_printf(m, " VHT%uSMCS%u", n_ss, mcs_n);
499 : 0 : }
500 : :
501 : 0 : static void rtw_print_rate(struct seq_file *m, u8 rate)
502 : : {
503 [ # # # # : 0 : switch (rate) {
# ]
504 : 0 : case DESC_RATE1M...DESC_RATE11M:
505 : 0 : rtw_print_cck_rate_txt(m, rate);
506 : : break;
507 : 0 : case DESC_RATE6M...DESC_RATE54M:
508 : 0 : rtw_print_ofdm_rate_txt(m, rate);
509 : : break;
510 : 0 : case DESC_RATEMCS0...DESC_RATEMCS15:
511 : 0 : rtw_print_ht_rate_txt(m, rate);
512 : : break;
513 : 0 : case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT2SS_MCS9:
514 : 0 : rtw_print_vht_rate_txt(m, rate);
515 : : break;
516 : 0 : default:
517 : 0 : seq_printf(m, " Unknown rate=0x%x\n", rate);
518 : 0 : break;
519 : : }
520 : 0 : }
521 : :
522 : 0 : static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v)
523 : : {
524 : 0 : struct rtw_debugfs_priv *debugfs_priv = m->private;
525 : 0 : struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
526 : 0 : struct rtw_hal *hal = &rtwdev->hal;
527 : 0 : u8 path, rate;
528 : 0 : struct rtw_power_params pwr_param = {0};
529 : 0 : u8 bw = hal->current_band_width;
530 : 0 : u8 ch = hal->current_channel;
531 : 0 : u8 regd = rtwdev->regd.txpwr_regd;
532 : :
533 : 0 : seq_printf(m, "%-4s %-10s %-3s%6s %-4s %4s (%-4s %-4s)\n",
534 : : "path", "rate", "pwr", "", "base", "", "byr", "lmt");
535 : :
536 : 0 : mutex_lock(&hal->tx_power_mutex);
537 [ # # ]: 0 : for (path = RF_PATH_A; path <= RF_PATH_B; path++) {
538 : : /* there is no CCK rates used in 5G */
539 [ # # ]: 0 : if (hal->current_band_type == RTW_BAND_5G)
540 : : rate = DESC_RATE6M;
541 : : else
542 : 0 : rate = DESC_RATE1M;
543 : :
544 : : /* now, not support vht 3ss and vht 4ss*/
545 [ # # ]: 0 : for (; rate <= DESC_RATEVHT2SS_MCS9; rate++) {
546 : : /* now, not support ht 3ss and ht 4ss*/
547 [ # # ]: 0 : if (rate > DESC_RATEMCS15 &&
548 : : rate < DESC_RATEVHT1SS_MCS0)
549 : 0 : continue;
550 : :
551 : 0 : rtw_get_tx_power_params(rtwdev, path, rate, bw,
552 : : ch, regd, &pwr_param);
553 : :
554 : 0 : seq_printf(m, "%4c ", path + 'A');
555 : 0 : rtw_print_rate(m, rate);
556 : 0 : seq_printf(m, " %3u(0x%02x) %4u %4d (%4d %4d)\n",
557 : : hal->tx_pwr_tbl[path][rate],
558 : 0 : hal->tx_pwr_tbl[path][rate],
559 : 0 : pwr_param.pwr_base,
560 : 0 : min_t(s8, pwr_param.pwr_offset,
561 : : pwr_param.pwr_limit),
562 : 0 : pwr_param.pwr_offset, pwr_param.pwr_limit);
563 : : }
564 : : }
565 : :
566 : 0 : mutex_unlock(&hal->tx_power_mutex);
567 : :
568 : 0 : return 0;
569 : : }
570 : :
571 : 0 : static int rtw_debugfs_get_phy_info(struct seq_file *m, void *v)
572 : : {
573 : 0 : struct rtw_debugfs_priv *debugfs_priv = m->private;
574 : 0 : struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
575 : 0 : struct rtw_dm_info *dm_info = &rtwdev->dm_info;
576 : 0 : struct rtw_traffic_stats *stats = &rtwdev->stats;
577 : 0 : struct rtw_pkt_count *last_cnt = &dm_info->last_pkt_count;
578 : 0 : struct rtw_efuse *efuse = &rtwdev->efuse;
579 : 0 : struct ewma_evm *ewma_evm = dm_info->ewma_evm;
580 : 0 : struct ewma_snr *ewma_snr = dm_info->ewma_snr;
581 : 0 : u8 ss, rate_id;
582 : :
583 : 0 : seq_puts(m, "==========[Common Info]========\n");
584 [ # # ]: 0 : seq_printf(m, "Is link = %c\n", rtw_is_assoc(rtwdev) ? 'Y' : 'N');
585 : 0 : seq_printf(m, "Current CH(fc) = %u\n", rtwdev->hal.current_channel);
586 : 0 : seq_printf(m, "Current BW = %u\n", rtwdev->hal.current_band_width);
587 : 0 : seq_printf(m, "Current IGI = 0x%x\n", dm_info->igi_history[0]);
588 : 0 : seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n\n",
589 : : stats->tx_throughput, stats->rx_throughput);
590 : :
591 : 0 : seq_puts(m, "==========[Tx Phy Info]========\n");
592 : 0 : seq_puts(m, "[Tx Rate] = ");
593 : 0 : rtw_print_rate(m, dm_info->tx_rate);
594 : 0 : seq_printf(m, "(0x%x)\n\n", dm_info->tx_rate);
595 : :
596 : 0 : seq_puts(m, "==========[Rx Phy Info]========\n");
597 : 0 : seq_printf(m, "[Rx Beacon Count] = %u\n", last_cnt->num_bcn_pkt);
598 : 0 : seq_puts(m, "[Rx Rate] = ");
599 : 0 : rtw_print_rate(m, dm_info->curr_rx_rate);
600 : 0 : seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate);
601 : :
602 : 0 : seq_puts(m, "[Rx Rate Count]:\n");
603 : 0 : seq_printf(m, " * CCK = {%u, %u, %u, %u}\n",
604 : 0 : last_cnt->num_qry_pkt[DESC_RATE1M],
605 : 0 : last_cnt->num_qry_pkt[DESC_RATE2M],
606 : 0 : last_cnt->num_qry_pkt[DESC_RATE5_5M],
607 : 0 : last_cnt->num_qry_pkt[DESC_RATE11M]);
608 : :
609 : 0 : seq_printf(m, " * OFDM = {%u, %u, %u, %u, %u, %u, %u, %u}\n",
610 : 0 : last_cnt->num_qry_pkt[DESC_RATE6M],
611 : 0 : last_cnt->num_qry_pkt[DESC_RATE9M],
612 : 0 : last_cnt->num_qry_pkt[DESC_RATE12M],
613 : 0 : last_cnt->num_qry_pkt[DESC_RATE18M],
614 : 0 : last_cnt->num_qry_pkt[DESC_RATE24M],
615 : 0 : last_cnt->num_qry_pkt[DESC_RATE36M],
616 : 0 : last_cnt->num_qry_pkt[DESC_RATE48M],
617 : 0 : last_cnt->num_qry_pkt[DESC_RATE54M]);
618 : :
619 [ # # ]: 0 : for (ss = 0; ss < efuse->hw_cap.nss; ss++) {
620 : 0 : rate_id = DESC_RATEMCS0 + ss * 8;
621 : 0 : seq_printf(m, " * HT_MCS[%u:%u] = {%u, %u, %u, %u, %u, %u, %u, %u}\n",
622 : 0 : ss * 8, ss * 8 + 7,
623 : 0 : last_cnt->num_qry_pkt[rate_id],
624 : 0 : last_cnt->num_qry_pkt[rate_id + 1],
625 : 0 : last_cnt->num_qry_pkt[rate_id + 2],
626 : 0 : last_cnt->num_qry_pkt[rate_id + 3],
627 : 0 : last_cnt->num_qry_pkt[rate_id + 4],
628 : 0 : last_cnt->num_qry_pkt[rate_id + 5],
629 : 0 : last_cnt->num_qry_pkt[rate_id + 6],
630 : 0 : last_cnt->num_qry_pkt[rate_id + 7]);
631 : : }
632 : :
633 [ # # ]: 0 : for (ss = 0; ss < efuse->hw_cap.nss; ss++) {
634 : 0 : rate_id = DESC_RATEVHT1SS_MCS0 + ss * 10;
635 : 0 : seq_printf(m, " * VHT_MCS-%uss MCS[0:9] = {%u, %u, %u, %u, %u, %u, %u, %u, %u, %u}\n",
636 : : ss + 1,
637 : 0 : last_cnt->num_qry_pkt[rate_id],
638 : 0 : last_cnt->num_qry_pkt[rate_id + 1],
639 : 0 : last_cnt->num_qry_pkt[rate_id + 2],
640 : 0 : last_cnt->num_qry_pkt[rate_id + 3],
641 : 0 : last_cnt->num_qry_pkt[rate_id + 4],
642 : 0 : last_cnt->num_qry_pkt[rate_id + 5],
643 : 0 : last_cnt->num_qry_pkt[rate_id + 6],
644 : 0 : last_cnt->num_qry_pkt[rate_id + 7],
645 : 0 : last_cnt->num_qry_pkt[rate_id + 8],
646 : 0 : last_cnt->num_qry_pkt[rate_id + 9]);
647 : : }
648 : :
649 : 0 : seq_printf(m, "[RSSI(dBm)] = {%d, %d}\n",
650 : 0 : dm_info->rssi[RF_PATH_A] - 100,
651 : 0 : dm_info->rssi[RF_PATH_B] - 100);
652 : 0 : seq_printf(m, "[Rx EVM(dB)] = {-%d, -%d}\n",
653 : 0 : dm_info->rx_evm_dbm[RF_PATH_A],
654 : 0 : dm_info->rx_evm_dbm[RF_PATH_B]);
655 : 0 : seq_printf(m, "[Rx SNR] = {%d, %d}\n",
656 : 0 : dm_info->rx_snr[RF_PATH_A],
657 : 0 : dm_info->rx_snr[RF_PATH_B]);
658 : 0 : seq_printf(m, "[CFO_tail(KHz)] = {%d, %d}\n",
659 : 0 : dm_info->cfo_tail[RF_PATH_A],
660 : 0 : dm_info->cfo_tail[RF_PATH_B]);
661 : :
662 [ # # ]: 0 : if (dm_info->curr_rx_rate >= DESC_RATE11M) {
663 : 0 : seq_puts(m, "[Rx Average Status]:\n");
664 : 0 : seq_printf(m, " * OFDM, EVM: {-%d}, SNR: {%d}\n",
665 : 0 : (u8)ewma_evm_read(&ewma_evm[RTW_EVM_OFDM]),
666 : 0 : (u8)ewma_snr_read(&ewma_snr[RTW_SNR_OFDM_A]));
667 : 0 : seq_printf(m, " * 1SS, EVM: {-%d}, SNR: {%d}\n",
668 : 0 : (u8)ewma_evm_read(&ewma_evm[RTW_EVM_1SS]),
669 : 0 : (u8)ewma_snr_read(&ewma_snr[RTW_SNR_1SS_A]));
670 : 0 : seq_printf(m, " * 2SS, EVM: {-%d, -%d}, SNR: {%d, %d}\n",
671 : 0 : (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_A]),
672 : 0 : (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_B]),
673 : 0 : (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_A]),
674 : 0 : (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_B]));
675 : : }
676 : :
677 : 0 : seq_puts(m, "[Rx Counter]:\n");
678 : 0 : seq_printf(m, " * CCA (CCK, OFDM, Total) = (%u, %u, %u)\n",
679 : : dm_info->cck_cca_cnt,
680 : : dm_info->ofdm_cca_cnt,
681 : : dm_info->total_cca_cnt);
682 : 0 : seq_printf(m, " * False Alarm (CCK, OFDM, Total) = (%u, %u, %u)\n",
683 : : dm_info->cck_fa_cnt,
684 : : dm_info->ofdm_fa_cnt,
685 : : dm_info->total_fa_cnt);
686 : 0 : seq_printf(m, " * CCK cnt (ok, err) = (%u, %u)\n",
687 : : dm_info->cck_ok_cnt, dm_info->cck_err_cnt);
688 : 0 : seq_printf(m, " * OFDM cnt (ok, err) = (%u, %u)\n",
689 : : dm_info->ofdm_ok_cnt, dm_info->ofdm_err_cnt);
690 : 0 : seq_printf(m, " * HT cnt (ok, err) = (%u, %u)\n",
691 : : dm_info->ht_ok_cnt, dm_info->ht_err_cnt);
692 : 0 : seq_printf(m, " * VHT cnt (ok, err) = (%u, %u)\n",
693 : : dm_info->vht_ok_cnt, dm_info->vht_err_cnt);
694 : 0 : return 0;
695 : : }
696 : :
697 : : #define rtw_debug_impl_mac(page, addr) \
698 : : static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = { \
699 : : .cb_read = rtw_debug_get_mac_page, \
700 : : .cb_data = addr, \
701 : : }
702 : :
703 : : rtw_debug_impl_mac(0, 0x0000);
704 : : rtw_debug_impl_mac(1, 0x0100);
705 : : rtw_debug_impl_mac(2, 0x0200);
706 : : rtw_debug_impl_mac(3, 0x0300);
707 : : rtw_debug_impl_mac(4, 0x0400);
708 : : rtw_debug_impl_mac(5, 0x0500);
709 : : rtw_debug_impl_mac(6, 0x0600);
710 : : rtw_debug_impl_mac(7, 0x0700);
711 : : rtw_debug_impl_mac(10, 0x1000);
712 : : rtw_debug_impl_mac(11, 0x1100);
713 : : rtw_debug_impl_mac(12, 0x1200);
714 : : rtw_debug_impl_mac(13, 0x1300);
715 : : rtw_debug_impl_mac(14, 0x1400);
716 : : rtw_debug_impl_mac(15, 0x1500);
717 : : rtw_debug_impl_mac(16, 0x1600);
718 : : rtw_debug_impl_mac(17, 0x1700);
719 : :
720 : : #define rtw_debug_impl_bb(page, addr) \
721 : : static struct rtw_debugfs_priv rtw_debug_priv_bb_ ##page = { \
722 : : .cb_read = rtw_debug_get_bb_page, \
723 : : .cb_data = addr, \
724 : : }
725 : :
726 : : rtw_debug_impl_bb(8, 0x0800);
727 : : rtw_debug_impl_bb(9, 0x0900);
728 : : rtw_debug_impl_bb(a, 0x0a00);
729 : : rtw_debug_impl_bb(b, 0x0b00);
730 : : rtw_debug_impl_bb(c, 0x0c00);
731 : : rtw_debug_impl_bb(d, 0x0d00);
732 : : rtw_debug_impl_bb(e, 0x0e00);
733 : : rtw_debug_impl_bb(f, 0x0f00);
734 : : rtw_debug_impl_bb(18, 0x1800);
735 : : rtw_debug_impl_bb(19, 0x1900);
736 : : rtw_debug_impl_bb(1a, 0x1a00);
737 : : rtw_debug_impl_bb(1b, 0x1b00);
738 : : rtw_debug_impl_bb(1c, 0x1c00);
739 : : rtw_debug_impl_bb(1d, 0x1d00);
740 : : rtw_debug_impl_bb(1e, 0x1e00);
741 : : rtw_debug_impl_bb(1f, 0x1f00);
742 : : rtw_debug_impl_bb(2c, 0x2c00);
743 : : rtw_debug_impl_bb(2d, 0x2d00);
744 : : rtw_debug_impl_bb(40, 0x4000);
745 : : rtw_debug_impl_bb(41, 0x4100);
746 : :
747 : : static struct rtw_debugfs_priv rtw_debug_priv_rf_dump = {
748 : : .cb_read = rtw_debug_get_rf_dump,
749 : : };
750 : :
751 : : static struct rtw_debugfs_priv rtw_debug_priv_tx_pwr_tbl = {
752 : : .cb_read = rtw_debugfs_get_tx_pwr_tbl,
753 : : };
754 : :
755 : : static struct rtw_debugfs_priv rtw_debug_priv_write_reg = {
756 : : .cb_write = rtw_debugfs_set_write_reg,
757 : : };
758 : :
759 : : static struct rtw_debugfs_priv rtw_debug_priv_rf_write = {
760 : : .cb_write = rtw_debugfs_set_rf_write,
761 : : };
762 : :
763 : : static struct rtw_debugfs_priv rtw_debug_priv_rf_read = {
764 : : .cb_write = rtw_debugfs_set_rf_read,
765 : : .cb_read = rtw_debugfs_get_rf_read,
766 : : };
767 : :
768 : : static struct rtw_debugfs_priv rtw_debug_priv_read_reg = {
769 : : .cb_write = rtw_debugfs_set_read_reg,
770 : : .cb_read = rtw_debugfs_get_read_reg,
771 : : };
772 : :
773 : : static struct rtw_debugfs_priv rtw_debug_priv_dump_cam = {
774 : : .cb_write = rtw_debugfs_set_single_input,
775 : : .cb_read = rtw_debugfs_get_dump_cam,
776 : : };
777 : :
778 : : static struct rtw_debugfs_priv rtw_debug_priv_rsvd_page = {
779 : : .cb_write = rtw_debugfs_set_rsvd_page,
780 : : .cb_read = rtw_debugfs_get_rsvd_page,
781 : : };
782 : :
783 : : static struct rtw_debugfs_priv rtw_debug_priv_phy_info = {
784 : : .cb_read = rtw_debugfs_get_phy_info,
785 : : };
786 : :
787 : : #define rtw_debugfs_add_core(name, mode, fopname, parent) \
788 : : do { \
789 : : rtw_debug_priv_ ##name.rtwdev = rtwdev; \
790 : : if (!debugfs_create_file(#name, mode, \
791 : : parent, &rtw_debug_priv_ ##name,\
792 : : &file_ops_ ##fopname)) \
793 : : pr_debug("Unable to initialize debugfs:%s\n", \
794 : : #name); \
795 : : } while (0)
796 : :
797 : : #define rtw_debugfs_add_w(name) \
798 : : rtw_debugfs_add_core(name, S_IFREG | 0222, common_write, debugfs_topdir)
799 : : #define rtw_debugfs_add_rw(name) \
800 : : rtw_debugfs_add_core(name, S_IFREG | 0666, single_rw, debugfs_topdir)
801 : : #define rtw_debugfs_add_r(name) \
802 : : rtw_debugfs_add_core(name, S_IFREG | 0444, single_r, debugfs_topdir)
803 : :
804 : 0 : void rtw_debugfs_init(struct rtw_dev *rtwdev)
805 : : {
806 : 0 : struct dentry *debugfs_topdir;
807 : :
808 : 0 : debugfs_topdir = debugfs_create_dir("rtw88",
809 : 0 : rtwdev->hw->wiphy->debugfsdir);
810 : 0 : rtw_debugfs_add_w(write_reg);
811 : 0 : rtw_debugfs_add_rw(read_reg);
812 : 0 : rtw_debugfs_add_w(rf_write);
813 : 0 : rtw_debugfs_add_rw(rf_read);
814 : 0 : rtw_debugfs_add_rw(dump_cam);
815 : 0 : rtw_debugfs_add_rw(rsvd_page);
816 : 0 : rtw_debugfs_add_r(phy_info);
817 : 0 : rtw_debugfs_add_r(mac_0);
818 : 0 : rtw_debugfs_add_r(mac_1);
819 : 0 : rtw_debugfs_add_r(mac_2);
820 : 0 : rtw_debugfs_add_r(mac_3);
821 : 0 : rtw_debugfs_add_r(mac_4);
822 : 0 : rtw_debugfs_add_r(mac_5);
823 : 0 : rtw_debugfs_add_r(mac_6);
824 : 0 : rtw_debugfs_add_r(mac_7);
825 : 0 : rtw_debugfs_add_r(bb_8);
826 : 0 : rtw_debugfs_add_r(bb_9);
827 : 0 : rtw_debugfs_add_r(bb_a);
828 : 0 : rtw_debugfs_add_r(bb_b);
829 : 0 : rtw_debugfs_add_r(bb_c);
830 : 0 : rtw_debugfs_add_r(bb_d);
831 : 0 : rtw_debugfs_add_r(bb_e);
832 : 0 : rtw_debugfs_add_r(bb_f);
833 : 0 : rtw_debugfs_add_r(mac_10);
834 : 0 : rtw_debugfs_add_r(mac_11);
835 : 0 : rtw_debugfs_add_r(mac_12);
836 : 0 : rtw_debugfs_add_r(mac_13);
837 : 0 : rtw_debugfs_add_r(mac_14);
838 : 0 : rtw_debugfs_add_r(mac_15);
839 : 0 : rtw_debugfs_add_r(mac_16);
840 : 0 : rtw_debugfs_add_r(mac_17);
841 : 0 : rtw_debugfs_add_r(bb_18);
842 : 0 : rtw_debugfs_add_r(bb_19);
843 : 0 : rtw_debugfs_add_r(bb_1a);
844 : 0 : rtw_debugfs_add_r(bb_1b);
845 : 0 : rtw_debugfs_add_r(bb_1c);
846 : 0 : rtw_debugfs_add_r(bb_1d);
847 : 0 : rtw_debugfs_add_r(bb_1e);
848 : 0 : rtw_debugfs_add_r(bb_1f);
849 [ # # ]: 0 : if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) {
850 : 0 : rtw_debugfs_add_r(bb_2c);
851 : 0 : rtw_debugfs_add_r(bb_2d);
852 : 0 : rtw_debugfs_add_r(bb_40);
853 : 0 : rtw_debugfs_add_r(bb_41);
854 : : }
855 : 0 : rtw_debugfs_add_r(rf_dump);
856 : 0 : rtw_debugfs_add_r(tx_pwr_tbl);
857 : 0 : }
858 : :
859 : : #endif /* CONFIG_RTW88_DEBUGFS */
860 : :
861 : : #ifdef CONFIG_RTW88_DEBUG
862 : :
863 : 29 : void __rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask,
864 : : const char *fmt, ...)
865 : : {
866 : 29 : struct va_format vaf = {
867 : : .fmt = fmt,
868 : : };
869 : 29 : va_list args;
870 : :
871 : 29 : va_start(args, fmt);
872 : 29 : vaf.va = &args;
873 : :
874 [ - + ]: 29 : if (rtw_debug_mask & mask)
875 : 0 : dev_printk(KERN_DEBUG, rtwdev->dev, "%pV", &vaf);
876 : :
877 : 29 : va_end(args);
878 : 29 : }
879 : : EXPORT_SYMBOL(__rtw_dbg);
880 : :
881 : : #endif /* CONFIG_RTW88_DEBUG */
|