1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2009-2012 Realtek Corporation.*/
7 #include <linux/moduleparam.h>
8 #include <linux/vmalloc.h>
10 #ifdef CONFIG_RTLWIFI_DEBUG
11 void _rtl_dbg_trace(struct rtl_priv
*rtlpriv
, u64 comp
, int level
,
14 if (unlikely((comp
& rtlpriv
->cfg
->mod_params
->debug_mask
) &&
15 level
<= rtlpriv
->cfg
->mod_params
->debug_level
)) {
24 pr_info(":<%lx> %pV", in_interrupt(), &vaf
);
29 EXPORT_SYMBOL_GPL(_rtl_dbg_trace
);
31 void _rtl_dbg_print(struct rtl_priv
*rtlpriv
, u64 comp
, int level
,
34 if (unlikely((comp
& rtlpriv
->cfg
->mod_params
->debug_mask
) &&
35 level
<= rtlpriv
->cfg
->mod_params
->debug_level
)) {
49 EXPORT_SYMBOL_GPL(_rtl_dbg_print
);
51 void _rtl_dbg_print_data(struct rtl_priv
*rtlpriv
, u64 comp
, int level
,
52 const char *titlestring
,
53 const void *hexdata
, int hexdatalen
)
55 if (unlikely(((comp
) & rtlpriv
->cfg
->mod_params
->debug_mask
) &&
56 ((level
) <= rtlpriv
->cfg
->mod_params
->debug_level
))) {
57 pr_info("In process \"%s\" (pid %i): %s\n",
58 current
->comm
, current
->pid
, titlestring
);
59 print_hex_dump_bytes("", DUMP_PREFIX_NONE
,
63 EXPORT_SYMBOL_GPL(_rtl_dbg_print_data
);
65 struct rtl_debugfs_priv
{
66 struct rtl_priv
*rtlpriv
;
67 int (*cb_read
)(struct seq_file
*m
, void *v
);
68 ssize_t (*cb_write
)(struct file
*filp
, const char __user
*buffer
,
69 size_t count
, loff_t
*loff
);
73 static struct dentry
*debugfs_topdir
;
75 static int rtl_debug_get_common(struct seq_file
*m
, void *v
)
77 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
79 return debugfs_priv
->cb_read(m
, v
);
82 static int dl_debug_open_common(struct inode
*inode
, struct file
*file
)
84 return single_open(file
, rtl_debug_get_common
, inode
->i_private
);
87 static const struct file_operations file_ops_common
= {
88 .open
= dl_debug_open_common
,
91 .release
= single_release
,
94 static int rtl_debug_get_mac_page(struct seq_file
*m
, void *v
)
96 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
97 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
98 u32 page
= debugfs_priv
->cb_data
;
102 for (n
= 0; n
<= max
; ) {
103 seq_printf(m
, "\n%8.8x ", n
+ page
);
104 for (i
= 0; i
< 4 && n
<= max
; i
++, n
+= 4)
105 seq_printf(m
, "%8.8x ",
106 rtl_read_dword(rtlpriv
, (page
| n
)));
112 #define RTL_DEBUG_IMPL_MAC_SERIES(page, addr) \
113 static struct rtl_debugfs_priv rtl_debug_priv_mac_ ##page = { \
114 .cb_read = rtl_debug_get_mac_page, \
118 RTL_DEBUG_IMPL_MAC_SERIES(0, 0x0000);
119 RTL_DEBUG_IMPL_MAC_SERIES(1, 0x0100);
120 RTL_DEBUG_IMPL_MAC_SERIES(2, 0x0200);
121 RTL_DEBUG_IMPL_MAC_SERIES(3, 0x0300);
122 RTL_DEBUG_IMPL_MAC_SERIES(4, 0x0400);
123 RTL_DEBUG_IMPL_MAC_SERIES(5, 0x0500);
124 RTL_DEBUG_IMPL_MAC_SERIES(6, 0x0600);
125 RTL_DEBUG_IMPL_MAC_SERIES(7, 0x0700);
126 RTL_DEBUG_IMPL_MAC_SERIES(10, 0x1000);
127 RTL_DEBUG_IMPL_MAC_SERIES(11, 0x1100);
128 RTL_DEBUG_IMPL_MAC_SERIES(12, 0x1200);
129 RTL_DEBUG_IMPL_MAC_SERIES(13, 0x1300);
130 RTL_DEBUG_IMPL_MAC_SERIES(14, 0x1400);
131 RTL_DEBUG_IMPL_MAC_SERIES(15, 0x1500);
132 RTL_DEBUG_IMPL_MAC_SERIES(16, 0x1600);
133 RTL_DEBUG_IMPL_MAC_SERIES(17, 0x1700);
135 static int rtl_debug_get_bb_page(struct seq_file
*m
, void *v
)
137 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
138 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
139 struct ieee80211_hw
*hw
= rtlpriv
->hw
;
140 u32 page
= debugfs_priv
->cb_data
;
144 for (n
= 0; n
<= max
; ) {
145 seq_printf(m
, "\n%8.8x ", n
+ page
);
146 for (i
= 0; i
< 4 && n
<= max
; i
++, n
+= 4)
147 seq_printf(m
, "%8.8x ",
148 rtl_get_bbreg(hw
, (page
| n
), 0xffffffff));
154 #define RTL_DEBUG_IMPL_BB_SERIES(page, addr) \
155 static struct rtl_debugfs_priv rtl_debug_priv_bb_ ##page = { \
156 .cb_read = rtl_debug_get_bb_page, \
160 RTL_DEBUG_IMPL_BB_SERIES(8, 0x0800);
161 RTL_DEBUG_IMPL_BB_SERIES(9, 0x0900);
162 RTL_DEBUG_IMPL_BB_SERIES(a
, 0x0a00);
163 RTL_DEBUG_IMPL_BB_SERIES(b
, 0x0b00);
164 RTL_DEBUG_IMPL_BB_SERIES(c
, 0x0c00);
165 RTL_DEBUG_IMPL_BB_SERIES(d
, 0x0d00);
166 RTL_DEBUG_IMPL_BB_SERIES(e
, 0x0e00);
167 RTL_DEBUG_IMPL_BB_SERIES(f
, 0x0f00);
168 RTL_DEBUG_IMPL_BB_SERIES(18, 0x1800);
169 RTL_DEBUG_IMPL_BB_SERIES(19, 0x1900);
170 RTL_DEBUG_IMPL_BB_SERIES(1a
, 0x1a00);
171 RTL_DEBUG_IMPL_BB_SERIES(1b
, 0x1b00);
172 RTL_DEBUG_IMPL_BB_SERIES(1c
, 0x1c00);
173 RTL_DEBUG_IMPL_BB_SERIES(1d
, 0x1d00);
174 RTL_DEBUG_IMPL_BB_SERIES(1e
, 0x1e00);
175 RTL_DEBUG_IMPL_BB_SERIES(1f
, 0x1f00);
177 static int rtl_debug_get_reg_rf(struct seq_file
*m
, void *v
)
179 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
180 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
181 struct ieee80211_hw
*hw
= rtlpriv
->hw
;
182 enum radio_path rfpath
= debugfs_priv
->cb_data
;
186 if (IS_HARDWARE_TYPE_8822B(rtlpriv
))
189 seq_printf(m
, "\nPATH(%d)", rfpath
);
191 for (n
= 0; n
<= max
; ) {
192 seq_printf(m
, "\n%8.8x ", n
);
193 for (i
= 0; i
< 4 && n
<= max
; n
+= 1, i
++)
194 seq_printf(m
, "%8.8x ",
195 rtl_get_rfreg(hw
, rfpath
, n
, 0xffffffff));
201 #define RTL_DEBUG_IMPL_RF_SERIES(page, addr) \
202 static struct rtl_debugfs_priv rtl_debug_priv_rf_ ##page = { \
203 .cb_read = rtl_debug_get_reg_rf, \
207 RTL_DEBUG_IMPL_RF_SERIES(a
, RF90_PATH_A
);
208 RTL_DEBUG_IMPL_RF_SERIES(b
, RF90_PATH_B
);
210 static int rtl_debug_get_cam_register(struct seq_file
*m
, void *v
)
212 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
213 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
214 int start
= debugfs_priv
->cb_data
;
220 int end
= (start
+ 11 > TOTAL_CAM_ENTRY
? TOTAL_CAM_ENTRY
: start
+ 11);
222 /* This dump the current register page */
224 "\n#################### SECURITY CAM (%d-%d) ##################\n",
227 for (j
= start
; j
< end
; j
++) {
228 seq_printf(m
, "\nD: %2x > ", j
);
229 for (entry_i
= 0; entry_i
< CAM_CONTENT_COUNT
; entry_i
++) {
230 /* polling bit, and No Write enable, and address */
231 target_cmd
= entry_i
+ CAM_CONTENT_COUNT
* j
;
232 target_cmd
= target_cmd
| BIT(31);
234 /* Check polling bit is clear */
237 rtl_read_dword(rtlpriv
,
238 rtlpriv
->cfg
->maps
[RWCAM
]);
239 if (ulstatus
& BIT(31))
245 rtl_write_dword(rtlpriv
, rtlpriv
->cfg
->maps
[RWCAM
],
247 target_val
= rtl_read_dword(rtlpriv
,
248 rtlpriv
->cfg
->maps
[RCAMO
]);
249 seq_printf(m
, "%8.8x ", target_val
);
256 #define RTL_DEBUG_IMPL_CAM_SERIES(page, addr) \
257 static struct rtl_debugfs_priv rtl_debug_priv_cam_ ##page = { \
258 .cb_read = rtl_debug_get_cam_register, \
262 RTL_DEBUG_IMPL_CAM_SERIES(1, 0);
263 RTL_DEBUG_IMPL_CAM_SERIES(2, 11);
264 RTL_DEBUG_IMPL_CAM_SERIES(3, 22);
266 static int rtl_debug_get_btcoex(struct seq_file
*m
, void *v
)
268 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
269 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
271 if (rtlpriv
->cfg
->ops
->get_btc_status())
272 rtlpriv
->btcoexist
.btc_ops
->btc_display_bt_coex_info(rtlpriv
,
280 static struct rtl_debugfs_priv rtl_debug_priv_btcoex
= {
281 .cb_read
= rtl_debug_get_btcoex
,
285 static ssize_t
rtl_debugfs_set_write_reg(struct file
*filp
,
286 const char __user
*buffer
,
287 size_t count
, loff_t
*loff
)
289 struct rtl_debugfs_priv
*debugfs_priv
= filp
->private_data
;
290 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
299 tmp_len
= (count
> sizeof(tmp
) - 1 ? sizeof(tmp
) - 1 : count
);
301 if (!buffer
|| copy_from_user(tmp
, buffer
, tmp_len
))
306 /* write BB/MAC register */
307 num
= sscanf(tmp
, "%x %x %x", &addr
, &val
, &len
);
314 rtl_write_byte(rtlpriv
, addr
, (u8
)val
);
317 rtl_write_word(rtlpriv
, addr
, (u16
)val
);
320 rtl_write_dword(rtlpriv
, addr
, val
);
323 /*printk("error write length=%d", len);*/
330 static struct rtl_debugfs_priv rtl_debug_priv_write_reg
= {
331 .cb_write
= rtl_debugfs_set_write_reg
,
334 static ssize_t
rtl_debugfs_set_write_h2c(struct file
*filp
,
335 const char __user
*buffer
,
336 size_t count
, loff_t
*loff
)
338 struct rtl_debugfs_priv
*debugfs_priv
= filp
->private_data
;
339 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
340 struct ieee80211_hw
*hw
= rtlpriv
->hw
;
343 u8 h2c_len
, h2c_data_packed
[8];
344 int h2c_data
[8]; /* idx 0: cmd */
350 tmp_len
= (count
> sizeof(tmp
) - 1 ? sizeof(tmp
) - 1 : count
);
352 if (!buffer
|| copy_from_user(tmp
, buffer
, tmp_len
))
357 h2c_len
= sscanf(tmp
, "%X %X %X %X %X %X %X %X",
358 &h2c_data
[0], &h2c_data
[1],
359 &h2c_data
[2], &h2c_data
[3],
360 &h2c_data
[4], &h2c_data
[5],
361 &h2c_data
[6], &h2c_data
[7]);
366 for (i
= 0; i
< h2c_len
; i
++)
367 h2c_data_packed
[i
] = (u8
)h2c_data
[i
];
369 rtlpriv
->cfg
->ops
->fill_h2c_cmd(hw
, h2c_data_packed
[0],
371 &h2c_data_packed
[1]);
376 static struct rtl_debugfs_priv rtl_debug_priv_write_h2c
= {
377 .cb_write
= rtl_debugfs_set_write_h2c
,
380 static ssize_t
rtl_debugfs_set_write_rfreg(struct file
*filp
,
381 const char __user
*buffer
,
382 size_t count
, loff_t
*loff
)
384 struct rtl_debugfs_priv
*debugfs_priv
= filp
->private_data
;
385 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
386 struct ieee80211_hw
*hw
= rtlpriv
->hw
;
391 u32 addr
, bitmask
, data
;
396 tmp_len
= (count
> sizeof(tmp
) - 1 ? sizeof(tmp
) - 1 : count
);
398 if (!buffer
|| copy_from_user(tmp
, buffer
, tmp_len
))
403 num
= sscanf(tmp
, "%X %X %X %X",
404 &path
, &addr
, &bitmask
, &data
);
407 RT_TRACE(rtlpriv
, COMP_ERR
, DBG_DMESG
,
408 "Format is <path> <addr> <mask> <data>\n");
412 rtl_set_rfreg(hw
, path
, addr
, bitmask
, data
);
417 static struct rtl_debugfs_priv rtl_debug_priv_write_rfreg
= {
418 .cb_write
= rtl_debugfs_set_write_rfreg
,
421 static int rtl_debugfs_close(struct inode
*inode
, struct file
*filp
)
426 static ssize_t
rtl_debugfs_common_write(struct file
*filp
,
427 const char __user
*buffer
,
428 size_t count
, loff_t
*loff
)
430 struct rtl_debugfs_priv
*debugfs_priv
= filp
->private_data
;
432 return debugfs_priv
->cb_write(filp
, buffer
, count
, loff
);
435 static const struct file_operations file_ops_common_write
= {
436 .owner
= THIS_MODULE
,
437 .write
= rtl_debugfs_common_write
,
439 .release
= rtl_debugfs_close
,
442 #define RTL_DEBUGFS_ADD_CORE(name, mode, fopname) \
444 rtl_debug_priv_ ##name.rtlpriv = rtlpriv; \
445 debugfs_create_file(#name, mode, parent, \
446 &rtl_debug_priv_ ##name, \
447 &file_ops_ ##fopname); \
450 #define RTL_DEBUGFS_ADD(name) \
451 RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0444, common)
452 #define RTL_DEBUGFS_ADD_W(name) \
453 RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0222, common_write)
455 void rtl_debug_add_one(struct ieee80211_hw
*hw
)
457 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
458 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
459 struct dentry
*parent
;
461 snprintf(rtlpriv
->dbg
.debugfs_name
, 18, "%pMF", rtlefuse
->dev_addr
);
463 rtlpriv
->dbg
.debugfs_dir
=
464 debugfs_create_dir(rtlpriv
->dbg
.debugfs_name
, debugfs_topdir
);
466 parent
= rtlpriv
->dbg
.debugfs_dir
;
468 RTL_DEBUGFS_ADD(mac_0
);
469 RTL_DEBUGFS_ADD(mac_1
);
470 RTL_DEBUGFS_ADD(mac_2
);
471 RTL_DEBUGFS_ADD(mac_3
);
472 RTL_DEBUGFS_ADD(mac_4
);
473 RTL_DEBUGFS_ADD(mac_5
);
474 RTL_DEBUGFS_ADD(mac_6
);
475 RTL_DEBUGFS_ADD(mac_7
);
476 RTL_DEBUGFS_ADD(bb_8
);
477 RTL_DEBUGFS_ADD(bb_9
);
478 RTL_DEBUGFS_ADD(bb_a
);
479 RTL_DEBUGFS_ADD(bb_b
);
480 RTL_DEBUGFS_ADD(bb_c
);
481 RTL_DEBUGFS_ADD(bb_d
);
482 RTL_DEBUGFS_ADD(bb_e
);
483 RTL_DEBUGFS_ADD(bb_f
);
484 RTL_DEBUGFS_ADD(mac_10
);
485 RTL_DEBUGFS_ADD(mac_11
);
486 RTL_DEBUGFS_ADD(mac_12
);
487 RTL_DEBUGFS_ADD(mac_13
);
488 RTL_DEBUGFS_ADD(mac_14
);
489 RTL_DEBUGFS_ADD(mac_15
);
490 RTL_DEBUGFS_ADD(mac_16
);
491 RTL_DEBUGFS_ADD(mac_17
);
492 RTL_DEBUGFS_ADD(bb_18
);
493 RTL_DEBUGFS_ADD(bb_19
);
494 RTL_DEBUGFS_ADD(bb_1a
);
495 RTL_DEBUGFS_ADD(bb_1b
);
496 RTL_DEBUGFS_ADD(bb_1c
);
497 RTL_DEBUGFS_ADD(bb_1d
);
498 RTL_DEBUGFS_ADD(bb_1e
);
499 RTL_DEBUGFS_ADD(bb_1f
);
500 RTL_DEBUGFS_ADD(rf_a
);
501 RTL_DEBUGFS_ADD(rf_b
);
503 RTL_DEBUGFS_ADD(cam_1
);
504 RTL_DEBUGFS_ADD(cam_2
);
505 RTL_DEBUGFS_ADD(cam_3
);
507 RTL_DEBUGFS_ADD(btcoex
);
509 RTL_DEBUGFS_ADD_W(write_reg
);
510 RTL_DEBUGFS_ADD_W(write_h2c
);
511 RTL_DEBUGFS_ADD_W(write_rfreg
);
513 EXPORT_SYMBOL_GPL(rtl_debug_add_one
);
515 void rtl_debug_remove_one(struct ieee80211_hw
*hw
)
517 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
519 debugfs_remove_recursive(rtlpriv
->dbg
.debugfs_dir
);
520 rtlpriv
->dbg
.debugfs_dir
= NULL
;
522 EXPORT_SYMBOL_GPL(rtl_debug_remove_one
);
524 void rtl_debugfs_add_topdir(void)
526 debugfs_topdir
= debugfs_create_dir("rtlwifi", NULL
);
529 void rtl_debugfs_remove_topdir(void)
531 debugfs_remove_recursive(debugfs_topdir
);