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_ST
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
);
51 void _rtl_dbg_print(struct rtl_priv
*rtlpriv
, u64 comp
, int level
,
54 if (unlikely((comp
& rtlpriv
->cfg
->mod_params
->debug_mask
) &&
55 (level
<= rtlpriv
->cfg
->mod_params
->debug_level
))) {
70 void _rtl_dbg_print_data(struct rtl_priv
*rtlpriv
, u64 comp
, int level
,
71 const char *titlestring
,
72 const void *hexdata
, int hexdatalen
)
74 if (unlikely(((comp
) & rtlpriv
->cfg
->mod_params
->debug_mask
) &&
75 ((level
) <= rtlpriv
->cfg
->mod_params
->debug_level
))) {
76 pr_info("In process \"%s\" (pid %i): %s\n",
77 current
->comm
, current
->pid
, titlestring
);
78 print_hex_dump_bytes("", DUMP_PREFIX_NONE
,
83 struct rtl_debugfs_priv
{
84 struct rtl_priv
*rtlpriv
;
85 int (*cb_read
)(struct seq_file
*m
, void *v
);
86 ssize_t (*cb_write
)(struct file
*filp
, const char __user
*buffer
,
87 size_t count
, loff_t
*loff
);
91 static struct dentry
*debugfs_topdir
;
93 static int rtl_debug_get_common(struct seq_file
*m
, void *v
)
95 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
97 return debugfs_priv
->cb_read(m
, v
);
100 static int dl_debug_open_common(struct inode
*inode
, struct file
*file
)
102 return single_open(file
, rtl_debug_get_common
, inode
->i_private
);
105 static const struct file_operations file_ops_common
= {
106 .open
= dl_debug_open_common
,
109 .release
= seq_release
,
112 static int rtl_debug_get_mac_page(struct seq_file
*m
, void *v
)
114 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
115 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
116 u32 page
= debugfs_priv
->cb_data
;
120 for (n
= 0; n
<= max
; ) {
121 seq_printf(m
, "\n%8.8x ", n
+ page
);
122 for (i
= 0; i
< 4 && n
<= max
; i
++, n
+= 4)
123 seq_printf(m
, "%8.8x ",
124 rtl_read_dword(rtlpriv
, (page
| n
)));
130 #define RTL_DEBUG_IMPL_MAC_SERIES(page, addr) \
131 struct rtl_debugfs_priv rtl_debug_priv_mac_ ##page = { \
132 .cb_read = rtl_debug_get_mac_page, \
136 RTL_DEBUG_IMPL_MAC_SERIES(0, 0x0000);
137 RTL_DEBUG_IMPL_MAC_SERIES(1, 0x0100);
138 RTL_DEBUG_IMPL_MAC_SERIES(2, 0x0200);
139 RTL_DEBUG_IMPL_MAC_SERIES(3, 0x0300);
140 RTL_DEBUG_IMPL_MAC_SERIES(4, 0x0400);
141 RTL_DEBUG_IMPL_MAC_SERIES(5, 0x0500);
142 RTL_DEBUG_IMPL_MAC_SERIES(6, 0x0600);
143 RTL_DEBUG_IMPL_MAC_SERIES(7, 0x0700);
144 RTL_DEBUG_IMPL_MAC_SERIES(10, 0x1000);
145 RTL_DEBUG_IMPL_MAC_SERIES(11, 0x1100);
146 RTL_DEBUG_IMPL_MAC_SERIES(12, 0x1200);
147 RTL_DEBUG_IMPL_MAC_SERIES(13, 0x1300);
148 RTL_DEBUG_IMPL_MAC_SERIES(14, 0x1400);
149 RTL_DEBUG_IMPL_MAC_SERIES(15, 0x1500);
150 RTL_DEBUG_IMPL_MAC_SERIES(16, 0x1600);
151 RTL_DEBUG_IMPL_MAC_SERIES(17, 0x1700);
153 static int rtl_debug_get_bb_page(struct seq_file
*m
, void *v
)
155 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
156 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
157 struct ieee80211_hw
*hw
= rtlpriv
->hw
;
158 u32 page
= debugfs_priv
->cb_data
;
162 for (n
= 0; n
<= max
; ) {
163 seq_printf(m
, "\n%8.8x ", n
+ page
);
164 for (i
= 0; i
< 4 && n
<= max
; i
++, n
+= 4)
165 seq_printf(m
, "%8.8x ",
166 rtl_get_bbreg(hw
, (page
| n
), 0xffffffff));
172 #define RTL_DEBUG_IMPL_BB_SERIES(page, addr) \
173 struct rtl_debugfs_priv rtl_debug_priv_bb_ ##page = { \
174 .cb_read = rtl_debug_get_bb_page, \
178 RTL_DEBUG_IMPL_BB_SERIES(8, 0x0800);
179 RTL_DEBUG_IMPL_BB_SERIES(9, 0x0900);
180 RTL_DEBUG_IMPL_BB_SERIES(a
, 0x0a00);
181 RTL_DEBUG_IMPL_BB_SERIES(b
, 0x0b00);
182 RTL_DEBUG_IMPL_BB_SERIES(c
, 0x0c00);
183 RTL_DEBUG_IMPL_BB_SERIES(d
, 0x0d00);
184 RTL_DEBUG_IMPL_BB_SERIES(e
, 0x0e00);
185 RTL_DEBUG_IMPL_BB_SERIES(f
, 0x0f00);
186 RTL_DEBUG_IMPL_BB_SERIES(18, 0x1800);
187 RTL_DEBUG_IMPL_BB_SERIES(19, 0x1900);
188 RTL_DEBUG_IMPL_BB_SERIES(1a
, 0x1a00);
189 RTL_DEBUG_IMPL_BB_SERIES(1b
, 0x1b00);
190 RTL_DEBUG_IMPL_BB_SERIES(1c
, 0x1c00);
191 RTL_DEBUG_IMPL_BB_SERIES(1d
, 0x1d00);
192 RTL_DEBUG_IMPL_BB_SERIES(1e
, 0x1e00);
193 RTL_DEBUG_IMPL_BB_SERIES(1f
, 0x1f00);
195 static int rtl_debug_get_reg_rf(struct seq_file
*m
, void *v
)
197 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
198 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
199 struct ieee80211_hw
*hw
= rtlpriv
->hw
;
200 enum radio_path rfpath
= debugfs_priv
->cb_data
;
204 if (IS_HARDWARE_TYPE_8822B(rtlpriv
))
207 seq_printf(m
, "\nPATH(%d)", rfpath
);
209 for (n
= 0; n
<= max
; ) {
210 seq_printf(m
, "\n%8.8x ", n
);
211 for (i
= 0; i
< 4 && n
<= max
; n
+= 1, i
++)
212 seq_printf(m
, "%8.8x ",
213 rtl_get_rfreg(hw
, rfpath
, n
, 0xffffffff));
219 #define RTL_DEBUG_IMPL_RF_SERIES(page, addr) \
220 struct rtl_debugfs_priv rtl_debug_priv_rf_ ##page = { \
221 .cb_read = rtl_debug_get_reg_rf, \
225 RTL_DEBUG_IMPL_RF_SERIES(a
, RF90_PATH_A
);
226 RTL_DEBUG_IMPL_RF_SERIES(b
, RF90_PATH_B
);
228 static int rtl_debug_get_cam_register(struct seq_file
*m
, void *v
)
230 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
231 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
232 int start
= debugfs_priv
->cb_data
;
238 int end
= (start
+ 11 > TOTAL_CAM_ENTRY
? TOTAL_CAM_ENTRY
: start
+ 11);
240 /* This dump the current register page */
242 "\n#################### SECURITY CAM (%d-%d) ##################\n",
245 for (j
= start
; j
< end
; j
++) {
246 seq_printf(m
, "\nD: %2x > ", j
);
247 for (entry_i
= 0; entry_i
< CAM_CONTENT_COUNT
; entry_i
++) {
248 /* polling bit, and No Write enable, and address */
249 target_cmd
= entry_i
+ CAM_CONTENT_COUNT
* j
;
250 target_cmd
= target_cmd
| BIT(31);
252 /* Check polling bit is clear */
254 ulstatus
= rtl_read_dword(
256 rtlpriv
->cfg
->maps
[RWCAM
]);
257 if (ulstatus
& BIT(31))
263 rtl_write_dword(rtlpriv
, rtlpriv
->cfg
->maps
[RWCAM
],
265 target_val
= rtl_read_dword(rtlpriv
,
266 rtlpriv
->cfg
->maps
[RCAMO
]);
267 seq_printf(m
, "%8.8x ", target_val
);
274 #define RTL_DEBUG_IMPL_CAM_SERIES(page, addr) \
275 struct rtl_debugfs_priv rtl_debug_priv_cam_ ##page = { \
276 .cb_read = rtl_debug_get_cam_register, \
280 RTL_DEBUG_IMPL_CAM_SERIES(1, 0);
281 RTL_DEBUG_IMPL_CAM_SERIES(2, 11);
282 RTL_DEBUG_IMPL_CAM_SERIES(3, 22);
284 static int rtl_debug_get_btcoex(struct seq_file
*m
, void *v
)
286 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
287 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
289 if (rtlpriv
->cfg
->ops
->get_btc_status())
290 rtlpriv
->btcoexist
.btc_ops
->btc_display_bt_coex_info(rtlpriv
,
298 static struct rtl_debugfs_priv rtl_debug_priv_btcoex
= {
299 .cb_read
= rtl_debug_get_btcoex
,
303 static ssize_t
rtl_debugfs_set_write_reg(struct file
*filp
,
304 const char __user
*buffer
,
305 size_t count
, loff_t
*loff
)
307 struct rtl_debugfs_priv
*debugfs_priv
= filp
->private_data
;
308 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
317 tmp_len
= (count
> sizeof(tmp
) - 1 ? sizeof(tmp
) - 1 : count
);
319 if (!buffer
|| copy_from_user(tmp
, buffer
, tmp_len
))
324 /* write BB/MAC register */
325 num
= sscanf(tmp
, "%x %x %x", &addr
, &val
, &len
);
332 rtl_write_byte(rtlpriv
, addr
, (u8
)val
);
335 rtl_write_word(rtlpriv
, addr
, (u16
)val
);
338 rtl_write_dword(rtlpriv
, addr
, val
);
341 /*printk("error write length=%d", len);*/
348 static struct rtl_debugfs_priv rtl_debug_priv_write_reg
= {
349 .cb_write
= rtl_debugfs_set_write_reg
,
352 static ssize_t
rtl_debugfs_set_write_h2c(struct file
*filp
,
353 const char __user
*buffer
,
354 size_t count
, loff_t
*loff
)
356 struct rtl_debugfs_priv
*debugfs_priv
= filp
->private_data
;
357 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
358 struct ieee80211_hw
*hw
= rtlpriv
->hw
;
361 u8 h2c_len
, h2c_data_packed
[8];
362 int h2c_data
[8]; /* idx 0: cmd */
368 tmp_len
= (count
> sizeof(tmp
) - 1 ? sizeof(tmp
) - 1 : count
);
370 if (!buffer
|| copy_from_user(tmp
, buffer
, tmp_len
))
375 h2c_len
= sscanf(tmp
, "%X %X %X %X %X %X %X %X",
376 &h2c_data
[0], &h2c_data
[1],
377 &h2c_data
[2], &h2c_data
[3],
378 &h2c_data
[4], &h2c_data
[5],
379 &h2c_data
[6], &h2c_data
[7]);
384 for (i
= 0; i
< h2c_len
; i
++)
385 h2c_data_packed
[i
] = (u8
)h2c_data
[i
];
387 rtlpriv
->cfg
->ops
->fill_h2c_cmd(hw
, h2c_data_packed
[0],
389 &h2c_data_packed
[1]);
394 static struct rtl_debugfs_priv rtl_debug_priv_write_h2c
= {
395 .cb_write
= rtl_debugfs_set_write_h2c
,
398 static ssize_t
rtl_debugfs_set_write_rfreg(struct file
*filp
,
399 const char __user
*buffer
,
400 size_t count
, loff_t
*loff
)
402 struct rtl_debugfs_priv
*debugfs_priv
= filp
->private_data
;
403 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
404 struct ieee80211_hw
*hw
= rtlpriv
->hw
;
409 u32 addr
, bitmask
, data
;
414 tmp_len
= (count
> sizeof(tmp
) - 1 ? sizeof(tmp
) - 1 : count
);
416 if (!buffer
|| copy_from_user(tmp
, buffer
, tmp_len
))
421 num
= sscanf(tmp
, "%X %X %X %X",
422 &path
, &addr
, &bitmask
, &data
);
425 RT_TRACE(rtlpriv
, COMP_ERR
, DBG_DMESG
,
426 "Format is <path> <addr> <mask> <data>\n");
430 rtl_set_rfreg(hw
, path
, addr
, bitmask
, data
);
435 static struct rtl_debugfs_priv rtl_debug_priv_write_rfreg
= {
436 .cb_write
= rtl_debugfs_set_write_rfreg
,
439 static int rtl_debugfs_close(struct inode
*inode
, struct file
*filp
)
444 static ssize_t
rtl_debugfs_common_write(struct file
*filp
,
445 const char __user
*buffer
,
446 size_t count
, loff_t
*loff
)
448 struct rtl_debugfs_priv
*debugfs_priv
= filp
->private_data
;
450 return debugfs_priv
->cb_write(filp
, buffer
, count
, loff
);
453 static const struct file_operations file_ops_common_write
= {
454 .owner
= THIS_MODULE
,
455 .write
= rtl_debugfs_common_write
,
457 .release
= rtl_debugfs_close
,
460 static ssize_t
rtl_debugfs_phydm_cmd(struct file
*filp
,
461 const char __user
*buffer
,
462 size_t count
, loff_t
*loff
)
464 struct rtl_debugfs_priv
*debugfs_priv
= filp
->private_data
;
465 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
469 if (!rtlpriv
->dbg
.msg_buf
)
472 if (!rtlpriv
->phydm
.ops
)
475 if (buffer
&& !copy_from_user(tmp
, buffer
, sizeof(tmp
))) {
478 rtlpriv
->phydm
.ops
->phydm_debug_cmd(rtlpriv
, tmp
, count
,
479 rtlpriv
->dbg
.msg_buf
,
486 static int rtl_debug_get_phydm_cmd(struct seq_file
*m
, void *v
)
488 struct rtl_debugfs_priv
*debugfs_priv
= m
->private;
489 struct rtl_priv
*rtlpriv
= debugfs_priv
->rtlpriv
;
491 if (rtlpriv
->dbg
.msg_buf
)
492 seq_puts(m
, rtlpriv
->dbg
.msg_buf
);
497 static int rtl_debugfs_open_rw(struct inode
*inode
, struct file
*filp
)
499 if (filp
->f_mode
& FMODE_READ
)
500 single_open(filp
, rtl_debug_get_common
, inode
->i_private
);
502 filp
->private_data
= inode
->i_private
;
507 static int rtl_debugfs_close_rw(struct inode
*inode
, struct file
*filp
)
509 if (filp
->f_mode
== FMODE_READ
)
510 seq_release(inode
, filp
);
515 static struct rtl_debugfs_priv rtl_debug_priv_phydm_cmd
= {
516 .cb_read
= rtl_debug_get_phydm_cmd
,
517 .cb_write
= rtl_debugfs_phydm_cmd
,
521 static const struct file_operations file_ops_common_rw
= {
522 .owner
= THIS_MODULE
,
523 .open
= rtl_debugfs_open_rw
,
524 .release
= rtl_debugfs_close_rw
,
527 .write
= rtl_debugfs_common_write
,
530 #define RTL_DEBUGFS_ADD_CORE(name, mode, fopname) \
532 rtl_debug_priv_ ##name.rtlpriv = rtlpriv; \
533 if (!debugfs_create_file(#name, mode, \
534 parent, &rtl_debug_priv_ ##name, \
535 &file_ops_ ##fopname)) \
536 pr_err("Unable to initialize debugfs:%s/%s\n", \
537 rtlpriv->dbg.debugfs_name, \
541 #define RTL_DEBUGFS_ADD(name) \
542 RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0444, common)
543 #define RTL_DEBUGFS_ADD_W(name) \
544 RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0222, common_write)
545 #define RTL_DEBUGFS_ADD_RW(name) \
546 RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0666, common_rw)
548 void rtl_debug_add_one(struct ieee80211_hw
*hw
)
550 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
551 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
552 struct dentry
*parent
;
554 rtlpriv
->dbg
.msg_buf
= vzalloc(80 * 25);
556 snprintf(rtlpriv
->dbg
.debugfs_name
, 18, "%pMF", rtlefuse
->dev_addr
);
558 rtlpriv
->dbg
.debugfs_dir
=
559 debugfs_create_dir(rtlpriv
->dbg
.debugfs_name
, debugfs_topdir
);
560 if (!rtlpriv
->dbg
.debugfs_dir
) {
561 pr_err("Unable to init debugfs:/%s/%s\n", rtlpriv
->cfg
->name
,
562 rtlpriv
->dbg
.debugfs_name
);
566 parent
= rtlpriv
->dbg
.debugfs_dir
;
568 RTL_DEBUGFS_ADD(mac_0
);
569 RTL_DEBUGFS_ADD(mac_1
);
570 RTL_DEBUGFS_ADD(mac_2
);
571 RTL_DEBUGFS_ADD(mac_3
);
572 RTL_DEBUGFS_ADD(mac_4
);
573 RTL_DEBUGFS_ADD(mac_5
);
574 RTL_DEBUGFS_ADD(mac_6
);
575 RTL_DEBUGFS_ADD(mac_7
);
576 RTL_DEBUGFS_ADD(bb_8
);
577 RTL_DEBUGFS_ADD(bb_9
);
578 RTL_DEBUGFS_ADD(bb_a
);
579 RTL_DEBUGFS_ADD(bb_b
);
580 RTL_DEBUGFS_ADD(bb_c
);
581 RTL_DEBUGFS_ADD(bb_d
);
582 RTL_DEBUGFS_ADD(bb_e
);
583 RTL_DEBUGFS_ADD(bb_f
);
584 RTL_DEBUGFS_ADD(mac_10
);
585 RTL_DEBUGFS_ADD(mac_11
);
586 RTL_DEBUGFS_ADD(mac_12
);
587 RTL_DEBUGFS_ADD(mac_13
);
588 RTL_DEBUGFS_ADD(mac_14
);
589 RTL_DEBUGFS_ADD(mac_15
);
590 RTL_DEBUGFS_ADD(mac_16
);
591 RTL_DEBUGFS_ADD(mac_17
);
592 RTL_DEBUGFS_ADD(bb_18
);
593 RTL_DEBUGFS_ADD(bb_19
);
594 RTL_DEBUGFS_ADD(bb_1a
);
595 RTL_DEBUGFS_ADD(bb_1b
);
596 RTL_DEBUGFS_ADD(bb_1c
);
597 RTL_DEBUGFS_ADD(bb_1d
);
598 RTL_DEBUGFS_ADD(bb_1e
);
599 RTL_DEBUGFS_ADD(bb_1f
);
600 RTL_DEBUGFS_ADD(rf_a
);
601 RTL_DEBUGFS_ADD(rf_b
);
603 RTL_DEBUGFS_ADD(cam_1
);
604 RTL_DEBUGFS_ADD(cam_2
);
605 RTL_DEBUGFS_ADD(cam_3
);
607 RTL_DEBUGFS_ADD(btcoex
);
609 RTL_DEBUGFS_ADD_W(write_reg
);
610 RTL_DEBUGFS_ADD_W(write_h2c
);
611 RTL_DEBUGFS_ADD_W(write_rfreg
);
613 RTL_DEBUGFS_ADD_RW(phydm_cmd
);
616 void rtl_debug_remove_one(struct ieee80211_hw
*hw
)
618 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
620 debugfs_remove_recursive(rtlpriv
->dbg
.debugfs_dir
);
621 rtlpriv
->dbg
.debugfs_dir
= NULL
;
623 vfree(rtlpriv
->dbg
.msg_buf
);
626 void rtl_debugfs_add_topdir(void)
628 debugfs_topdir
= debugfs_create_dir("rtlwifi", NULL
);
631 void rtl_debugfs_remove_topdir(void)
633 debugfs_remove_recursive(debugfs_topdir
);