1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2018-2019 Realtek Corporation
5 #include <linux/debugfs.h>
6 #include <linux/seq_file.h>
12 #ifdef CONFIG_RTW88_DEBUGFS
14 struct rtw_debugfs_priv {
15 struct rtw_dev *rtwdev;
16 int (*cb_read)(struct seq_file *m, void *v);
17 ssize_t (*cb_write)(struct file *filp, const char __user *buffer,
18 size_t count, loff_t *loff);
38 static int rtw_debugfs_single_show(struct seq_file *m, void *v)
40 struct rtw_debugfs_priv *debugfs_priv = m->private;
42 return debugfs_priv->cb_read(m, v);
45 static ssize_t rtw_debugfs_common_write(struct file *filp,
46 const char __user *buffer,
47 size_t count, loff_t *loff)
49 struct rtw_debugfs_priv *debugfs_priv = filp->private_data;
51 return debugfs_priv->cb_write(filp, buffer, count, loff);
54 static ssize_t rtw_debugfs_single_write(struct file *filp,
55 const char __user *buffer,
56 size_t count, loff_t *loff)
58 struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
59 struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
61 return debugfs_priv->cb_write(filp, buffer, count, loff);
64 static int rtw_debugfs_single_open_rw(struct inode *inode, struct file *filp)
66 return single_open(filp, rtw_debugfs_single_show, inode->i_private);
69 static int rtw_debugfs_close(struct inode *inode, struct file *filp)
74 static const struct file_operations file_ops_single_r = {
76 .open = rtw_debugfs_single_open_rw,
79 .release = seq_release,
82 static const struct file_operations file_ops_single_rw = {
84 .open = rtw_debugfs_single_open_rw,
85 .release = single_release,
88 .write = rtw_debugfs_single_write,
91 static const struct file_operations file_ops_common_write = {
93 .write = rtw_debugfs_common_write,
95 .release = rtw_debugfs_close,
98 static int rtw_debugfs_get_read_reg(struct seq_file *m, void *v)
100 struct rtw_debugfs_priv *debugfs_priv = m->private;
101 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
104 len = debugfs_priv->read_reg.len;
105 addr = debugfs_priv->read_reg.addr;
108 val = rtw_read8(rtwdev, addr);
109 seq_printf(m, "reg 0x%03x: 0x%02x\n", addr, val);
112 val = rtw_read16(rtwdev, addr);
113 seq_printf(m, "reg 0x%03x: 0x%04x\n", addr, val);
116 val = rtw_read32(rtwdev, addr);
117 seq_printf(m, "reg 0x%03x: 0x%08x\n", addr, val);
123 static int rtw_debugfs_get_rf_read(struct seq_file *m, void *v)
125 struct rtw_debugfs_priv *debugfs_priv = m->private;
126 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
130 path = debugfs_priv->rf_path;
131 addr = debugfs_priv->rf_addr;
132 mask = debugfs_priv->rf_mask;
134 val = rtw_read_rf(rtwdev, path, addr, mask);
136 seq_printf(m, "rf_read path:%d addr:0x%08x mask:0x%08x val=0x%08x\n",
137 path, addr, mask, val);
142 static int rtw_debugfs_copy_from_user(char tmp[], int size,
143 const char __user *buffer, size_t count,
151 tmp_len = (count > size - 1 ? size - 1 : count);
153 if (!buffer || copy_from_user(tmp, buffer, tmp_len))
161 static ssize_t rtw_debugfs_set_read_reg(struct file *filp,
162 const char __user *buffer,
163 size_t count, loff_t *loff)
165 struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
166 struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
167 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
172 rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2);
174 num = sscanf(tmp, "%x %x", &addr, &len);
179 if (len != 1 && len != 2 && len != 4) {
180 rtw_warn(rtwdev, "read reg setting wrong len\n");
183 debugfs_priv->read_reg.addr = addr;
184 debugfs_priv->read_reg.len = len;
189 static int rtw_debugfs_get_dump_cam(struct seq_file *m, void *v)
191 struct rtw_debugfs_priv *debugfs_priv = m->private;
192 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
194 u32 hw_key_idx = debugfs_priv->cb_data << RTW_SEC_CAM_ENTRY_SHIFT;
195 u32 read_cmd = RTW_SEC_CMD_POLLING;
198 seq_printf(m, "cam entry%d\n", debugfs_priv->cb_data);
199 seq_puts(m, "0x0 0x1 0x2 0x3 ");
200 seq_puts(m, "0x4 0x5\n");
201 mutex_lock(&rtwdev->mutex);
202 for (i = 0; i <= 5; i++) {
203 command = read_cmd | (hw_key_idx + i);
204 rtw_write32(rtwdev, RTW_SEC_CMD_REG, command);
205 val = rtw_read32(rtwdev, RTW_SEC_READ_REG);
206 seq_printf(m, "%8.8x", val);
211 mutex_unlock(&rtwdev->mutex);
215 static int rtw_debugfs_get_rsvd_page(struct seq_file *m, void *v)
217 struct rtw_debugfs_priv *debugfs_priv = m->private;
218 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
219 u8 page_size = rtwdev->chip->page_size;
220 u32 buf_size = debugfs_priv->rsvd_page.page_num * page_size;
221 u32 offset = debugfs_priv->rsvd_page.page_offset * page_size;
226 buf = vzalloc(buf_size);
230 ret = rtw_dump_drv_rsvd_page(rtwdev, offset, buf_size, (u32 *)buf);
232 rtw_err(rtwdev, "failed to dump rsvd page\n");
237 for (i = 0 ; i < buf_size ; i += 8) {
238 if (i % page_size == 0)
239 seq_printf(m, "PAGE %d\n", (i + offset) / page_size);
240 seq_printf(m, "%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
241 *(buf + i), *(buf + i + 1),
242 *(buf + i + 2), *(buf + i + 3),
243 *(buf + i + 4), *(buf + i + 5),
244 *(buf + i + 6), *(buf + i + 7));
251 static ssize_t rtw_debugfs_set_rsvd_page(struct file *filp,
252 const char __user *buffer,
253 size_t count, loff_t *loff)
255 struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
256 struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
257 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
259 u32 offset, page_num;
262 rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 2);
264 num = sscanf(tmp, "%d %d", &offset, &page_num);
267 rtw_warn(rtwdev, "invalid arguments\n");
271 debugfs_priv->rsvd_page.page_offset = offset;
272 debugfs_priv->rsvd_page.page_num = page_num;
277 static ssize_t rtw_debugfs_set_single_input(struct file *filp,
278 const char __user *buffer,
279 size_t count, loff_t *loff)
281 struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
282 struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
283 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
288 rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1);
290 num = kstrtoint(tmp, 0, &input);
293 rtw_warn(rtwdev, "kstrtoint failed\n");
297 debugfs_priv->cb_data = input;
302 static ssize_t rtw_debugfs_set_write_reg(struct file *filp,
303 const char __user *buffer,
304 size_t count, loff_t *loff)
306 struct rtw_debugfs_priv *debugfs_priv = filp->private_data;
307 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
312 rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3);
314 /* write BB/MAC register */
315 num = sscanf(tmp, "%x %x %x", &addr, &val, &len);
322 rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,
323 "reg write8 0x%03x: 0x%08x\n", addr, val);
324 rtw_write8(rtwdev, addr, (u8)val);
327 rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,
328 "reg write16 0x%03x: 0x%08x\n", addr, val);
329 rtw_write16(rtwdev, addr, (u16)val);
332 rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,
333 "reg write32 0x%03x: 0x%08x\n", addr, val);
334 rtw_write32(rtwdev, addr, (u32)val);
337 rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,
338 "error write length = %d\n", len);
345 static ssize_t rtw_debugfs_set_rf_write(struct file *filp,
346 const char __user *buffer,
347 size_t count, loff_t *loff)
349 struct rtw_debugfs_priv *debugfs_priv = filp->private_data;
350 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
352 u32 path, addr, mask, val;
355 rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 4);
357 num = sscanf(tmp, "%x %x %x %x", &path, &addr, &mask, &val);
360 rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n");
364 rtw_write_rf(rtwdev, path, addr, mask, val);
365 rtw_dbg(rtwdev, RTW_DBG_DEBUGFS,
366 "write_rf path:%d addr:0x%08x mask:0x%08x, val:0x%08x\n",
367 path, addr, mask, val);
372 static ssize_t rtw_debugfs_set_rf_read(struct file *filp,
373 const char __user *buffer,
374 size_t count, loff_t *loff)
376 struct seq_file *seqpriv = (struct seq_file *)filp->private_data;
377 struct rtw_debugfs_priv *debugfs_priv = seqpriv->private;
378 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
380 u32 path, addr, mask;
383 rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 3);
385 num = sscanf(tmp, "%x %x %x", &path, &addr, &mask);
388 rtw_warn(rtwdev, "invalid args, [path] [addr] [mask] [val]\n");
392 debugfs_priv->rf_path = path;
393 debugfs_priv->rf_addr = addr;
394 debugfs_priv->rf_mask = mask;
399 static int rtw_debug_get_mac_page(struct seq_file *m, void *v)
401 struct rtw_debugfs_priv *debugfs_priv = m->private;
402 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
404 u32 page = debugfs_priv->cb_data;
408 val = rtw_read32(rtwdev, debugfs_priv->cb_data);
409 for (n = 0; n <= max; ) {
410 seq_printf(m, "\n%8.8x ", n + page);
411 for (i = 0; i < 4 && n <= max; i++, n += 4)
412 seq_printf(m, "%8.8x ",
413 rtw_read32(rtwdev, (page | n)));
419 static int rtw_debug_get_bb_page(struct seq_file *m, void *v)
421 struct rtw_debugfs_priv *debugfs_priv = m->private;
422 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
424 u32 page = debugfs_priv->cb_data;
428 val = rtw_read32(rtwdev, debugfs_priv->cb_data);
429 for (n = 0; n <= max; ) {
430 seq_printf(m, "\n%8.8x ", n + page);
431 for (i = 0; i < 4 && n <= max; i++, n += 4)
432 seq_printf(m, "%8.8x ",
433 rtw_read32(rtwdev, (page | n)));
439 static int rtw_debug_get_rf_dump(struct seq_file *m, void *v)
441 struct rtw_debugfs_priv *debugfs_priv = m->private;
442 struct rtw_dev *rtwdev = debugfs_priv->rtwdev;
443 u32 addr, offset, data;
446 for (path = 0; path < rtwdev->hal.rf_path_num; path++) {
447 seq_printf(m, "RF path:%d\n", path);
448 for (addr = 0; addr < 0x100; addr += 4) {
449 seq_printf(m, "%8.8x ", addr);
450 for (offset = 0; offset < 4; offset++) {
451 data = rtw_read_rf(rtwdev, path, addr + offset,
453 seq_printf(m, "%8.8x ", data);
463 #define rtw_debug_impl_mac(page, addr) \
464 static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = { \
465 .cb_read = rtw_debug_get_mac_page, \
469 rtw_debug_impl_mac(0, 0x0000);
470 rtw_debug_impl_mac(1, 0x0100);
471 rtw_debug_impl_mac(2, 0x0200);
472 rtw_debug_impl_mac(3, 0x0300);
473 rtw_debug_impl_mac(4, 0x0400);
474 rtw_debug_impl_mac(5, 0x0500);
475 rtw_debug_impl_mac(6, 0x0600);
476 rtw_debug_impl_mac(7, 0x0700);
477 rtw_debug_impl_mac(10, 0x1000);
478 rtw_debug_impl_mac(11, 0x1100);
479 rtw_debug_impl_mac(12, 0x1200);
480 rtw_debug_impl_mac(13, 0x1300);
481 rtw_debug_impl_mac(14, 0x1400);
482 rtw_debug_impl_mac(15, 0x1500);
483 rtw_debug_impl_mac(16, 0x1600);
484 rtw_debug_impl_mac(17, 0x1700);
486 #define rtw_debug_impl_bb(page, addr) \
487 static struct rtw_debugfs_priv rtw_debug_priv_bb_ ##page = { \
488 .cb_read = rtw_debug_get_bb_page, \
492 rtw_debug_impl_bb(8, 0x0800);
493 rtw_debug_impl_bb(9, 0x0900);
494 rtw_debug_impl_bb(a, 0x0a00);
495 rtw_debug_impl_bb(b, 0x0b00);
496 rtw_debug_impl_bb(c, 0x0c00);
497 rtw_debug_impl_bb(d, 0x0d00);
498 rtw_debug_impl_bb(e, 0x0e00);
499 rtw_debug_impl_bb(f, 0x0f00);
500 rtw_debug_impl_bb(18, 0x1800);
501 rtw_debug_impl_bb(19, 0x1900);
502 rtw_debug_impl_bb(1a, 0x1a00);
503 rtw_debug_impl_bb(1b, 0x1b00);
504 rtw_debug_impl_bb(1c, 0x1c00);
505 rtw_debug_impl_bb(1d, 0x1d00);
506 rtw_debug_impl_bb(1e, 0x1e00);
507 rtw_debug_impl_bb(1f, 0x1f00);
508 rtw_debug_impl_bb(2c, 0x2c00);
509 rtw_debug_impl_bb(2d, 0x2d00);
510 rtw_debug_impl_bb(40, 0x4000);
511 rtw_debug_impl_bb(41, 0x4100);
513 static struct rtw_debugfs_priv rtw_debug_priv_rf_dump = {
514 .cb_read = rtw_debug_get_rf_dump,
517 static struct rtw_debugfs_priv rtw_debug_priv_write_reg = {
518 .cb_write = rtw_debugfs_set_write_reg,
521 static struct rtw_debugfs_priv rtw_debug_priv_rf_write = {
522 .cb_write = rtw_debugfs_set_rf_write,
525 static struct rtw_debugfs_priv rtw_debug_priv_rf_read = {
526 .cb_write = rtw_debugfs_set_rf_read,
527 .cb_read = rtw_debugfs_get_rf_read,
530 static struct rtw_debugfs_priv rtw_debug_priv_read_reg = {
531 .cb_write = rtw_debugfs_set_read_reg,
532 .cb_read = rtw_debugfs_get_read_reg,
535 static struct rtw_debugfs_priv rtw_debug_priv_dump_cam = {
536 .cb_write = rtw_debugfs_set_single_input,
537 .cb_read = rtw_debugfs_get_dump_cam,
540 static struct rtw_debugfs_priv rtw_debug_priv_rsvd_page = {
541 .cb_write = rtw_debugfs_set_rsvd_page,
542 .cb_read = rtw_debugfs_get_rsvd_page,
545 #define rtw_debugfs_add_core(name, mode, fopname, parent) \
547 rtw_debug_priv_ ##name.rtwdev = rtwdev; \
548 if (!debugfs_create_file(#name, mode, \
549 parent, &rtw_debug_priv_ ##name,\
550 &file_ops_ ##fopname)) \
551 pr_debug("Unable to initialize debugfs:%s\n", \
555 #define rtw_debugfs_add_w(name) \
556 rtw_debugfs_add_core(name, S_IFREG | 0222, common_write, debugfs_topdir)
557 #define rtw_debugfs_add_rw(name) \
558 rtw_debugfs_add_core(name, S_IFREG | 0666, single_rw, debugfs_topdir)
559 #define rtw_debugfs_add_r(name) \
560 rtw_debugfs_add_core(name, S_IFREG | 0444, single_r, debugfs_topdir)
562 void rtw_debugfs_init(struct rtw_dev *rtwdev)
564 struct dentry *debugfs_topdir = rtwdev->debugfs;
566 debugfs_topdir = debugfs_create_dir("rtw88",
567 rtwdev->hw->wiphy->debugfsdir);
568 rtw_debugfs_add_w(write_reg);
569 rtw_debugfs_add_rw(read_reg);
570 rtw_debugfs_add_w(rf_write);
571 rtw_debugfs_add_rw(rf_read);
572 rtw_debugfs_add_rw(dump_cam);
573 rtw_debugfs_add_rw(rsvd_page);
574 rtw_debugfs_add_r(mac_0);
575 rtw_debugfs_add_r(mac_1);
576 rtw_debugfs_add_r(mac_2);
577 rtw_debugfs_add_r(mac_3);
578 rtw_debugfs_add_r(mac_4);
579 rtw_debugfs_add_r(mac_5);
580 rtw_debugfs_add_r(mac_6);
581 rtw_debugfs_add_r(mac_7);
582 rtw_debugfs_add_r(bb_8);
583 rtw_debugfs_add_r(bb_9);
584 rtw_debugfs_add_r(bb_a);
585 rtw_debugfs_add_r(bb_b);
586 rtw_debugfs_add_r(bb_c);
587 rtw_debugfs_add_r(bb_d);
588 rtw_debugfs_add_r(bb_e);
589 rtw_debugfs_add_r(bb_f);
590 rtw_debugfs_add_r(mac_10);
591 rtw_debugfs_add_r(mac_11);
592 rtw_debugfs_add_r(mac_12);
593 rtw_debugfs_add_r(mac_13);
594 rtw_debugfs_add_r(mac_14);
595 rtw_debugfs_add_r(mac_15);
596 rtw_debugfs_add_r(mac_16);
597 rtw_debugfs_add_r(mac_17);
598 rtw_debugfs_add_r(bb_18);
599 rtw_debugfs_add_r(bb_19);
600 rtw_debugfs_add_r(bb_1a);
601 rtw_debugfs_add_r(bb_1b);
602 rtw_debugfs_add_r(bb_1c);
603 rtw_debugfs_add_r(bb_1d);
604 rtw_debugfs_add_r(bb_1e);
605 rtw_debugfs_add_r(bb_1f);
606 if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) {
607 rtw_debugfs_add_r(bb_2c);
608 rtw_debugfs_add_r(bb_2d);
609 rtw_debugfs_add_r(bb_40);
610 rtw_debugfs_add_r(bb_41);
612 rtw_debugfs_add_r(rf_dump);
615 #endif /* CONFIG_RTW88_DEBUGFS */
617 #ifdef CONFIG_RTW88_DEBUG
619 void __rtw_dbg(struct rtw_dev *rtwdev, enum rtw_debug_mask mask,
620 const char *fmt, ...)
622 struct va_format vaf = {
630 if (rtw_debug_mask & mask)
631 dev_printk(KERN_DEBUG, rtwdev->dev, "%pV", &vaf);
635 EXPORT_SYMBOL(__rtw_dbg);
637 #endif /* CONFIG_RTW88_DEBUG */