1 /******************************************************************************
3 * Copyright(c) 2009-2012 Realtek Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *****************************************************************************/
28 #include <linux/moduleparam.h>
29 #include <linux/vmalloc.h>
31 #ifdef CONFIG_RTLWIFI_DEBUG
32 void _rtl_dbg_trace(struct rtl_priv
*rtlpriv
, u64 comp
, int level
,
35 if (unlikely((comp
& rtlpriv
->cfg
->mod_params
->debug_mask
) &&
36 level
<= rtlpriv
->cfg
->mod_params
->debug_level
)) {
45 pr_info(":<%lx> %pV", in_interrupt(), &vaf
);
50 EXPORT_SYMBOL_GPL(_rtl_dbg_trace
);
52 void _rtl_dbg_print(struct rtl_priv
*rtlpriv
, u64 comp
, int level
,
55 if (unlikely((comp
& rtlpriv
->cfg
->mod_params
->debug_mask
) &&
56 level
<= rtlpriv
->cfg
->mod_params
->debug_level
)) {
70 EXPORT_SYMBOL_GPL(_rtl_dbg_print
);
72 void _rtl_dbg_print_data(struct rtl_priv
*rtlpriv
, u64 comp
, int level
,
73 const char *titlestring
,
74 const void *hexdata
, int hexdatalen
)
76 if (unlikely(((comp
) & rtlpriv
->cfg
->mod_params
->debug_mask
) &&
77 ((level
) <= rtlpriv
->cfg
->mod_params
->debug_level
))) {
78 pr_info("In process \"%s\" (pid %i): %s\n",
79 current
->comm
, current
->pid
, titlestring
);
80 print_hex_dump_bytes("", DUMP_PREFIX_NONE
,
84 EXPORT_SYMBOL_GPL(_rtl_dbg_print_data
);
86 struct rtl_debugfs_priv
{
87 struct rtl_priv
*rtlpriv
;
88 int (*cb_read
)(struct seq_file
*m
, void *v
);
89 ssize_t (*cb_write
)(struct file
*filp
, const char __user
*buffer
,
90 size_t count
, loff_t
*loff
);
94 static struct dentry
*debugfs_topdir
;
96 static int rtl_debug_get_common(struct seq_file
*m
, void *v
)
98 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
100 return debugfs_priv
->cb_read(m
, v
);
103 static int dl_debug_open_common(struct inode
*inode
, struct file
*file
)
105 return single_open(file
, rtl_debug_get_common
, inode
->i_private
);
108 static const struct file_operations file_ops_common
= {
109 .open
= dl_debug_open_common
,
112 .release
= seq_release
,
115 static int rtl_debug_get_mac_page(struct seq_file
*m
, void *v
)
117 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
118 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
119 u32 page
= debugfs_priv
->cb_data
;
123 for (n
= 0; n
<= max
; ) {
124 seq_printf(m
, "\n%8.8x ", n
+ page
);
125 for (i
= 0; i
< 4 && n
<= max
; i
++, n
+= 4)
126 seq_printf(m
, "%8.8x ",
127 rtl_read_dword(rtlpriv
, (page
| n
)));
133 #define RTL_DEBUG_IMPL_MAC_SERIES(page, addr) \
134 static struct rtl_debugfs_priv rtl_debug_priv_mac_ ##page = { \
135 .cb_read = rtl_debug_get_mac_page, \
139 RTL_DEBUG_IMPL_MAC_SERIES(0, 0x0000);
140 RTL_DEBUG_IMPL_MAC_SERIES(1, 0x0100);
141 RTL_DEBUG_IMPL_MAC_SERIES(2, 0x0200);
142 RTL_DEBUG_IMPL_MAC_SERIES(3, 0x0300);
143 RTL_DEBUG_IMPL_MAC_SERIES(4, 0x0400);
144 RTL_DEBUG_IMPL_MAC_SERIES(5, 0x0500);
145 RTL_DEBUG_IMPL_MAC_SERIES(6, 0x0600);
146 RTL_DEBUG_IMPL_MAC_SERIES(7, 0x0700);
147 RTL_DEBUG_IMPL_MAC_SERIES(10, 0x1000);
148 RTL_DEBUG_IMPL_MAC_SERIES(11, 0x1100);
149 RTL_DEBUG_IMPL_MAC_SERIES(12, 0x1200);
150 RTL_DEBUG_IMPL_MAC_SERIES(13, 0x1300);
151 RTL_DEBUG_IMPL_MAC_SERIES(14, 0x1400);
152 RTL_DEBUG_IMPL_MAC_SERIES(15, 0x1500);
153 RTL_DEBUG_IMPL_MAC_SERIES(16, 0x1600);
154 RTL_DEBUG_IMPL_MAC_SERIES(17, 0x1700);
156 static int rtl_debug_get_bb_page(struct seq_file
*m
, void *v
)
158 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
159 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
160 struct ieee80211_hw
*hw
= rtlpriv
->hw
;
161 u32 page
= debugfs_priv
->cb_data
;
165 for (n
= 0; n
<= max
; ) {
166 seq_printf(m
, "\n%8.8x ", n
+ page
);
167 for (i
= 0; i
< 4 && n
<= max
; i
++, n
+= 4)
168 seq_printf(m
, "%8.8x ",
169 rtl_get_bbreg(hw
, (page
| n
), 0xffffffff));
175 #define RTL_DEBUG_IMPL_BB_SERIES(page, addr) \
176 static struct rtl_debugfs_priv rtl_debug_priv_bb_ ##page = { \
177 .cb_read = rtl_debug_get_bb_page, \
181 RTL_DEBUG_IMPL_BB_SERIES(8, 0x0800);
182 RTL_DEBUG_IMPL_BB_SERIES(9, 0x0900);
183 RTL_DEBUG_IMPL_BB_SERIES(a
, 0x0a00);
184 RTL_DEBUG_IMPL_BB_SERIES(b
, 0x0b00);
185 RTL_DEBUG_IMPL_BB_SERIES(c
, 0x0c00);
186 RTL_DEBUG_IMPL_BB_SERIES(d
, 0x0d00);
187 RTL_DEBUG_IMPL_BB_SERIES(e
, 0x0e00);
188 RTL_DEBUG_IMPL_BB_SERIES(f
, 0x0f00);
189 RTL_DEBUG_IMPL_BB_SERIES(18, 0x1800);
190 RTL_DEBUG_IMPL_BB_SERIES(19, 0x1900);
191 RTL_DEBUG_IMPL_BB_SERIES(1a
, 0x1a00);
192 RTL_DEBUG_IMPL_BB_SERIES(1b
, 0x1b00);
193 RTL_DEBUG_IMPL_BB_SERIES(1c
, 0x1c00);
194 RTL_DEBUG_IMPL_BB_SERIES(1d
, 0x1d00);
195 RTL_DEBUG_IMPL_BB_SERIES(1e
, 0x1e00);
196 RTL_DEBUG_IMPL_BB_SERIES(1f
, 0x1f00);
198 static int rtl_debug_get_reg_rf(struct seq_file
*m
, void *v
)
200 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
201 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
202 struct ieee80211_hw
*hw
= rtlpriv
->hw
;
203 enum radio_path rfpath
= debugfs_priv
->cb_data
;
207 if (IS_HARDWARE_TYPE_8822B(rtlpriv
))
210 seq_printf(m
, "\nPATH(%d)", rfpath
);
212 for (n
= 0; n
<= max
; ) {
213 seq_printf(m
, "\n%8.8x ", n
);
214 for (i
= 0; i
< 4 && n
<= max
; n
+= 1, i
++)
215 seq_printf(m
, "%8.8x ",
216 rtl_get_rfreg(hw
, rfpath
, n
, 0xffffffff));
222 #define RTL_DEBUG_IMPL_RF_SERIES(page, addr) \
223 static struct rtl_debugfs_priv rtl_debug_priv_rf_ ##page = { \
224 .cb_read = rtl_debug_get_reg_rf, \
228 RTL_DEBUG_IMPL_RF_SERIES(a
, RF90_PATH_A
);
229 RTL_DEBUG_IMPL_RF_SERIES(b
, RF90_PATH_B
);
231 static int rtl_debug_get_cam_register(struct seq_file
*m
, void *v
)
233 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
234 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
235 int start
= debugfs_priv
->cb_data
;
241 int end
= (start
+ 11 > TOTAL_CAM_ENTRY
? TOTAL_CAM_ENTRY
: start
+ 11);
243 /* This dump the current register page */
245 "\n#################### SECURITY CAM (%d-%d) ##################\n",
248 for (j
= start
; j
< end
; j
++) {
249 seq_printf(m
, "\nD: %2x > ", j
);
250 for (entry_i
= 0; entry_i
< CAM_CONTENT_COUNT
; entry_i
++) {
251 /* polling bit, and No Write enable, and address */
252 target_cmd
= entry_i
+ CAM_CONTENT_COUNT
* j
;
253 target_cmd
= target_cmd
| BIT(31);
255 /* Check polling bit is clear */
258 rtl_read_dword(rtlpriv
,
259 rtlpriv
->cfg
->maps
[RWCAM
]);
260 if (ulstatus
& BIT(31))
266 rtl_write_dword(rtlpriv
, rtlpriv
->cfg
->maps
[RWCAM
],
268 target_val
= rtl_read_dword(rtlpriv
,
269 rtlpriv
->cfg
->maps
[RCAMO
]);
270 seq_printf(m
, "%8.8x ", target_val
);
277 #define RTL_DEBUG_IMPL_CAM_SERIES(page, addr) \
278 static struct rtl_debugfs_priv rtl_debug_priv_cam_ ##page = { \
279 .cb_read = rtl_debug_get_cam_register, \
283 RTL_DEBUG_IMPL_CAM_SERIES(1, 0);
284 RTL_DEBUG_IMPL_CAM_SERIES(2, 11);
285 RTL_DEBUG_IMPL_CAM_SERIES(3, 22);
287 static int rtl_debug_get_btcoex(struct seq_file
*m
, void *v
)
289 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
290 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
292 if (rtlpriv
->cfg
->ops
->get_btc_status())
293 rtlpriv
->btcoexist
.btc_ops
->btc_display_bt_coex_info(rtlpriv
,
301 static struct rtl_debugfs_priv rtl_debug_priv_btcoex
= {
302 .cb_read
= rtl_debug_get_btcoex
,
306 static ssize_t
rtl_debugfs_set_write_reg(struct file
*filp
,
307 const char __user
*buffer
,
308 size_t count
, loff_t
*loff
)
310 struct rtl_debugfs_priv
*debugfs_priv
= filp
->private_data
;
311 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
320 tmp_len
= (count
> sizeof(tmp
) - 1 ? sizeof(tmp
) - 1 : count
);
322 if (!buffer
|| copy_from_user(tmp
, buffer
, tmp_len
))
327 /* write BB/MAC register */
328 num
= sscanf(tmp
, "%x %x %x", &addr
, &val
, &len
);
335 rtl_write_byte(rtlpriv
, addr
, (u8
)val
);
338 rtl_write_word(rtlpriv
, addr
, (u16
)val
);
341 rtl_write_dword(rtlpriv
, addr
, val
);
344 /*printk("error write length=%d", len);*/
351 static struct rtl_debugfs_priv rtl_debug_priv_write_reg
= {
352 .cb_write
= rtl_debugfs_set_write_reg
,
355 static ssize_t
rtl_debugfs_set_write_h2c(struct file
*filp
,
356 const char __user
*buffer
,
357 size_t count
, loff_t
*loff
)
359 struct rtl_debugfs_priv
*debugfs_priv
= filp
->private_data
;
360 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
361 struct ieee80211_hw
*hw
= rtlpriv
->hw
;
364 u8 h2c_len
, h2c_data_packed
[8];
365 int h2c_data
[8]; /* idx 0: cmd */
371 tmp_len
= (count
> sizeof(tmp
) - 1 ? sizeof(tmp
) - 1 : count
);
373 if (!buffer
|| copy_from_user(tmp
, buffer
, tmp_len
))
378 h2c_len
= sscanf(tmp
, "%X %X %X %X %X %X %X %X",
379 &h2c_data
[0], &h2c_data
[1],
380 &h2c_data
[2], &h2c_data
[3],
381 &h2c_data
[4], &h2c_data
[5],
382 &h2c_data
[6], &h2c_data
[7]);
387 for (i
= 0; i
< h2c_len
; i
++)
388 h2c_data_packed
[i
] = (u8
)h2c_data
[i
];
390 rtlpriv
->cfg
->ops
->fill_h2c_cmd(hw
, h2c_data_packed
[0],
392 &h2c_data_packed
[1]);
397 static struct rtl_debugfs_priv rtl_debug_priv_write_h2c
= {
398 .cb_write
= rtl_debugfs_set_write_h2c
,
401 static ssize_t
rtl_debugfs_set_write_rfreg(struct file
*filp
,
402 const char __user
*buffer
,
403 size_t count
, loff_t
*loff
)
405 struct rtl_debugfs_priv
*debugfs_priv
= filp
->private_data
;
406 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
407 struct ieee80211_hw
*hw
= rtlpriv
->hw
;
412 u32 addr
, bitmask
, data
;
417 tmp_len
= (count
> sizeof(tmp
) - 1 ? sizeof(tmp
) - 1 : count
);
419 if (!buffer
|| copy_from_user(tmp
, buffer
, tmp_len
))
424 num
= sscanf(tmp
, "%X %X %X %X",
425 &path
, &addr
, &bitmask
, &data
);
428 RT_TRACE(rtlpriv
, COMP_ERR
, DBG_DMESG
,
429 "Format is <path> <addr> <mask> <data>\n");
433 rtl_set_rfreg(hw
, path
, addr
, bitmask
, data
);
438 static struct rtl_debugfs_priv rtl_debug_priv_write_rfreg
= {
439 .cb_write
= rtl_debugfs_set_write_rfreg
,
442 static int rtl_debugfs_close(struct inode
*inode
, struct file
*filp
)
447 static ssize_t
rtl_debugfs_common_write(struct file
*filp
,
448 const char __user
*buffer
,
449 size_t count
, loff_t
*loff
)
451 struct rtl_debugfs_priv
*debugfs_priv
= filp
->private_data
;
453 return debugfs_priv
->cb_write(filp
, buffer
, count
, loff
);
456 static const struct file_operations file_ops_common_write
= {
457 .owner
= THIS_MODULE
,
458 .write
= rtl_debugfs_common_write
,
460 .release
= rtl_debugfs_close
,
463 #define RTL_DEBUGFS_ADD_CORE(name, mode, fopname) \
465 rtl_debug_priv_ ##name.rtlpriv = rtlpriv; \
466 if (!debugfs_create_file(#name, mode, \
467 parent, &rtl_debug_priv_ ##name, \
468 &file_ops_ ##fopname)) \
469 pr_err("Unable to initialize debugfs:%s/%s\n", \
470 rtlpriv->dbg.debugfs_name, \
474 #define RTL_DEBUGFS_ADD(name) \
475 RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0444, common)
476 #define RTL_DEBUGFS_ADD_W(name) \
477 RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0222, common_write)
479 void rtl_debug_add_one(struct ieee80211_hw
*hw
)
481 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
482 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
483 struct dentry
*parent
;
485 snprintf(rtlpriv
->dbg
.debugfs_name
, 18, "%pMF", rtlefuse
->dev_addr
);
487 rtlpriv
->dbg
.debugfs_dir
=
488 debugfs_create_dir(rtlpriv
->dbg
.debugfs_name
, debugfs_topdir
);
489 if (!rtlpriv
->dbg
.debugfs_dir
) {
490 pr_err("Unable to init debugfs:/%s/%s\n", rtlpriv
->cfg
->name
,
491 rtlpriv
->dbg
.debugfs_name
);
495 parent
= rtlpriv
->dbg
.debugfs_dir
;
497 RTL_DEBUGFS_ADD(mac_0
);
498 RTL_DEBUGFS_ADD(mac_1
);
499 RTL_DEBUGFS_ADD(mac_2
);
500 RTL_DEBUGFS_ADD(mac_3
);
501 RTL_DEBUGFS_ADD(mac_4
);
502 RTL_DEBUGFS_ADD(mac_5
);
503 RTL_DEBUGFS_ADD(mac_6
);
504 RTL_DEBUGFS_ADD(mac_7
);
505 RTL_DEBUGFS_ADD(bb_8
);
506 RTL_DEBUGFS_ADD(bb_9
);
507 RTL_DEBUGFS_ADD(bb_a
);
508 RTL_DEBUGFS_ADD(bb_b
);
509 RTL_DEBUGFS_ADD(bb_c
);
510 RTL_DEBUGFS_ADD(bb_d
);
511 RTL_DEBUGFS_ADD(bb_e
);
512 RTL_DEBUGFS_ADD(bb_f
);
513 RTL_DEBUGFS_ADD(mac_10
);
514 RTL_DEBUGFS_ADD(mac_11
);
515 RTL_DEBUGFS_ADD(mac_12
);
516 RTL_DEBUGFS_ADD(mac_13
);
517 RTL_DEBUGFS_ADD(mac_14
);
518 RTL_DEBUGFS_ADD(mac_15
);
519 RTL_DEBUGFS_ADD(mac_16
);
520 RTL_DEBUGFS_ADD(mac_17
);
521 RTL_DEBUGFS_ADD(bb_18
);
522 RTL_DEBUGFS_ADD(bb_19
);
523 RTL_DEBUGFS_ADD(bb_1a
);
524 RTL_DEBUGFS_ADD(bb_1b
);
525 RTL_DEBUGFS_ADD(bb_1c
);
526 RTL_DEBUGFS_ADD(bb_1d
);
527 RTL_DEBUGFS_ADD(bb_1e
);
528 RTL_DEBUGFS_ADD(bb_1f
);
529 RTL_DEBUGFS_ADD(rf_a
);
530 RTL_DEBUGFS_ADD(rf_b
);
532 RTL_DEBUGFS_ADD(cam_1
);
533 RTL_DEBUGFS_ADD(cam_2
);
534 RTL_DEBUGFS_ADD(cam_3
);
536 RTL_DEBUGFS_ADD(btcoex
);
538 RTL_DEBUGFS_ADD_W(write_reg
);
539 RTL_DEBUGFS_ADD_W(write_h2c
);
540 RTL_DEBUGFS_ADD_W(write_rfreg
);
542 EXPORT_SYMBOL_GPL(rtl_debug_add_one
);
544 void rtl_debug_remove_one(struct ieee80211_hw
*hw
)
546 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
548 debugfs_remove_recursive(rtlpriv
->dbg
.debugfs_dir
);
549 rtlpriv
->dbg
.debugfs_dir
= NULL
;
551 EXPORT_SYMBOL_GPL(rtl_debug_remove_one
);
553 void rtl_debugfs_add_topdir(void)
555 debugfs_topdir
= debugfs_create_dir("rtlwifi", NULL
);
558 void rtl_debugfs_remove_topdir(void)
560 debugfs_remove_recursive(debugfs_topdir
);