aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorPing-Ke Shih <pkshih@realtek.com>2017-12-29 03:31:10 -0500
committerKalle Valo <kvalo@codeaurora.org>2018-01-08 12:07:45 -0500
commit610247f46feb23beda99d0bb44aa8f51a8dc27e1 (patch)
tree1c34f56e3580ad9e18f022ade34ce816610942c6 /drivers/net
parent981a2b6e055bce9a9f780fb074ffdf9a9bab0d47 (diff)
rtlwifi: Improve debugging by using debugfs
Use debugfs to dump register and btcoex status, and also write registers and h2c. We create topdir in /sys/kernel/debug/rtlwifi/, and use the MAC address as subdirectory with several entries to dump mac_reg, bb_reg, rf_reg etc. An example is /sys/kernel/debug/rtlwifi/00-11-22-33-44-55-66/mac_0 This change permits examination of device registers in a dynamic manner, a feature not available with the current debug mechanism. Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/base.c6
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c3
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h3
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c6
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.h1
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/debug.c479
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/debug.h12
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/pci.c6
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/wifi.h9
9 files changed, 523 insertions, 2 deletions
diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c
index 5605fa14aa4c..0ba9c0cc95e1 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.c
+++ b/drivers/net/wireless/realtek/rtlwifi/base.c
@@ -2530,6 +2530,9 @@ static int __init rtl_core_module_init(void)
2530 if (rtl_rate_control_register()) 2530 if (rtl_rate_control_register())
2531 pr_err("rtl: Unable to register rtl_rc, use default RC !!\n"); 2531 pr_err("rtl: Unable to register rtl_rc, use default RC !!\n");
2532 2532
2533 /* add debugfs */
2534 rtl_debugfs_add_topdir();
2535
2533 /* init some global vars */ 2536 /* init some global vars */
2534 INIT_LIST_HEAD(&rtl_global_var.glb_priv_list); 2537 INIT_LIST_HEAD(&rtl_global_var.glb_priv_list);
2535 spin_lock_init(&rtl_global_var.glb_list_lock); 2538 spin_lock_init(&rtl_global_var.glb_list_lock);
@@ -2541,6 +2544,9 @@ static void __exit rtl_core_module_exit(void)
2541{ 2544{
2542 /*RC*/ 2545 /*RC*/
2543 rtl_rate_control_unregister(); 2546 rtl_rate_control_unregister();
2547
2548 /* remove debugfs */
2549 rtl_debugfs_remove_topdir();
2544} 2550}
2545 2551
2546module_init(rtl_core_module_init); 2552module_init(rtl_core_module_init);
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
index b5e9877d935c..b13ee51b2022 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
@@ -1513,7 +1513,8 @@ void exhalbtc_set_single_ant_path(u8 single_ant_path)
1513 gl_bt_coexist.board_info.single_ant_path = single_ant_path; 1513 gl_bt_coexist.board_info.single_ant_path = single_ant_path;
1514} 1514}
1515 1515
1516void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist) 1516void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist,
1517 struct seq_file *m)
1517{ 1518{
1518 if (!halbtc_is_bt_coexist_available(btcoexist)) 1519 if (!halbtc_is_bt_coexist_available(btcoexist))
1519 return; 1520 return;
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
index f9b87c12db09..53aeb669cc63 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
@@ -626,7 +626,8 @@ void exhalbtc_update_min_bt_rssi(s8 bt_rssi);
626void exhalbtc_set_bt_exist(bool bt_exist); 626void exhalbtc_set_bt_exist(bool bt_exist);
627void exhalbtc_set_chip_type(u8 chip_type); 627void exhalbtc_set_chip_type(u8 chip_type);
628void exhalbtc_set_ant_num(struct rtl_priv *rtlpriv, u8 type, u8 ant_num); 628void exhalbtc_set_ant_num(struct rtl_priv *rtlpriv, u8 type, u8 ant_num);
629void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist); 629void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist,
630 struct seq_file *m);
630void exhalbtc_signal_compensation(struct btc_coexist *btcoexist, 631void exhalbtc_signal_compensation(struct btc_coexist *btcoexist,
631 u8 *rssi_wifi, u8 *rssi_bt); 632 u8 *rssi_wifi, u8 *rssi_bt);
632void exhalbtc_lps_leave(struct btc_coexist *btcoexist); 633void exhalbtc_lps_leave(struct btc_coexist *btcoexist);
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c
index 7d296a401b6f..4d9e33078d4f 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c
@@ -52,8 +52,14 @@ static struct rtl_btc_ops rtl_btc_operation = {
52 .btc_is_bt_ctrl_lps = rtl_btc_is_bt_ctrl_lps, 52 .btc_is_bt_ctrl_lps = rtl_btc_is_bt_ctrl_lps,
53 .btc_is_bt_lps_on = rtl_btc_is_bt_lps_on, 53 .btc_is_bt_lps_on = rtl_btc_is_bt_lps_on,
54 .btc_get_ampdu_cfg = rtl_btc_get_ampdu_cfg, 54 .btc_get_ampdu_cfg = rtl_btc_get_ampdu_cfg,
55 .btc_display_bt_coex_info = rtl_btc_display_bt_coex_info,
55}; 56};
56 57
58void rtl_btc_display_bt_coex_info(struct rtl_priv *rtlpriv, struct seq_file *m)
59{
60 exhalbtc_display_bt_coex_info(&gl_bt_coexist, m);
61}
62
57void rtl_btc_record_pwr_mode(struct rtl_priv *rtlpriv, u8 *buf, u8 len) 63void rtl_btc_record_pwr_mode(struct rtl_priv *rtlpriv, u8 *buf, u8 len)
58{ 64{
59 u8 safe_len; 65 u8 safe_len;
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.h
index ac1253c46f44..40f1ce8c8a06 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.h
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.h
@@ -44,6 +44,7 @@ bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv);
44bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv); 44bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv);
45bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv); 45bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv);
46void rtl_btc_special_packet_notify(struct rtl_priv *rtlpriv, u8 pkt_type); 46void rtl_btc_special_packet_notify(struct rtl_priv *rtlpriv, u8 pkt_type);
47void rtl_btc_display_bt_coex_info(struct rtl_priv *rtlpriv, struct seq_file *m);
47void rtl_btc_record_pwr_mode(struct rtl_priv *rtlpriv, u8 *buf, u8 len); 48void rtl_btc_record_pwr_mode(struct rtl_priv *rtlpriv, u8 *buf, u8 len);
48u8 rtl_btc_get_lps_val(struct rtl_priv *rtlpriv); 49u8 rtl_btc_get_lps_val(struct rtl_priv *rtlpriv);
49u8 rtl_btc_get_rpwm_val(struct rtl_priv *rtlpriv); 50u8 rtl_btc_get_rpwm_val(struct rtl_priv *rtlpriv);
diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.c b/drivers/net/wireless/realtek/rtlwifi/debug.c
index c4e1da887941..d70385be9976 100644
--- a/drivers/net/wireless/realtek/rtlwifi/debug.c
+++ b/drivers/net/wireless/realtek/rtlwifi/debug.c
@@ -23,8 +23,10 @@
23 *****************************************************************************/ 23 *****************************************************************************/
24 24
25#include "wifi.h" 25#include "wifi.h"
26#include "cam.h"
26 27
27#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
29#include <linux/vmalloc.h>
28 30
29#ifdef CONFIG_RTLWIFI_DEBUG 31#ifdef CONFIG_RTLWIFI_DEBUG
30void _rtl_dbg_trace(struct rtl_priv *rtlpriv, u64 comp, int level, 32void _rtl_dbg_trace(struct rtl_priv *rtlpriv, u64 comp, int level,
@@ -81,4 +83,481 @@ void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level,
81} 83}
82EXPORT_SYMBOL_GPL(_rtl_dbg_print_data); 84EXPORT_SYMBOL_GPL(_rtl_dbg_print_data);
83 85
86struct 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);
91 u32 cb_data;
92};
93
94static struct dentry *debugfs_topdir;
95
96static int rtl_debug_get_common(struct seq_file *m, void *v)
97{
98 struct rtl_debugfs_priv *debugfs_priv = m->private;
99
100 return debugfs_priv->cb_read(m, v);
101}
102
103static int dl_debug_open_common(struct inode *inode, struct file *file)
104{
105 return single_open(file, rtl_debug_get_common, inode->i_private);
106}
107
108static const struct file_operations file_ops_common = {
109 .open = dl_debug_open_common,
110 .read = seq_read,
111 .llseek = seq_lseek,
112 .release = seq_release,
113};
114
115static int rtl_debug_get_mac_page(struct seq_file *m, void *v)
116{
117 struct rtl_debugfs_priv *debugfs_priv = m->private;
118 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
119 u32 page = debugfs_priv->cb_data;
120 int i, n;
121 int max = 0xff;
122
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)));
128 }
129 seq_puts(m, "\n");
130 return 0;
131}
132
133#define RTL_DEBUG_IMPL_MAC_SERIES(page, addr) \
134static struct rtl_debugfs_priv rtl_debug_priv_mac_ ##page = { \
135 .cb_read = rtl_debug_get_mac_page, \
136 .cb_data = addr, \
137}
138
139RTL_DEBUG_IMPL_MAC_SERIES(0, 0x0000);
140RTL_DEBUG_IMPL_MAC_SERIES(1, 0x0100);
141RTL_DEBUG_IMPL_MAC_SERIES(2, 0x0200);
142RTL_DEBUG_IMPL_MAC_SERIES(3, 0x0300);
143RTL_DEBUG_IMPL_MAC_SERIES(4, 0x0400);
144RTL_DEBUG_IMPL_MAC_SERIES(5, 0x0500);
145RTL_DEBUG_IMPL_MAC_SERIES(6, 0x0600);
146RTL_DEBUG_IMPL_MAC_SERIES(7, 0x0700);
147RTL_DEBUG_IMPL_MAC_SERIES(10, 0x1000);
148RTL_DEBUG_IMPL_MAC_SERIES(11, 0x1100);
149RTL_DEBUG_IMPL_MAC_SERIES(12, 0x1200);
150RTL_DEBUG_IMPL_MAC_SERIES(13, 0x1300);
151RTL_DEBUG_IMPL_MAC_SERIES(14, 0x1400);
152RTL_DEBUG_IMPL_MAC_SERIES(15, 0x1500);
153RTL_DEBUG_IMPL_MAC_SERIES(16, 0x1600);
154RTL_DEBUG_IMPL_MAC_SERIES(17, 0x1700);
155
156static int rtl_debug_get_bb_page(struct seq_file *m, void *v)
157{
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;
162 int i, n;
163 int max = 0xff;
164
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));
170 }
171 seq_puts(m, "\n");
172 return 0;
173}
174
175#define RTL_DEBUG_IMPL_BB_SERIES(page, addr) \
176static struct rtl_debugfs_priv rtl_debug_priv_bb_ ##page = { \
177 .cb_read = rtl_debug_get_bb_page, \
178 .cb_data = addr, \
179}
180
181RTL_DEBUG_IMPL_BB_SERIES(8, 0x0800);
182RTL_DEBUG_IMPL_BB_SERIES(9, 0x0900);
183RTL_DEBUG_IMPL_BB_SERIES(a, 0x0a00);
184RTL_DEBUG_IMPL_BB_SERIES(b, 0x0b00);
185RTL_DEBUG_IMPL_BB_SERIES(c, 0x0c00);
186RTL_DEBUG_IMPL_BB_SERIES(d, 0x0d00);
187RTL_DEBUG_IMPL_BB_SERIES(e, 0x0e00);
188RTL_DEBUG_IMPL_BB_SERIES(f, 0x0f00);
189RTL_DEBUG_IMPL_BB_SERIES(18, 0x1800);
190RTL_DEBUG_IMPL_BB_SERIES(19, 0x1900);
191RTL_DEBUG_IMPL_BB_SERIES(1a, 0x1a00);
192RTL_DEBUG_IMPL_BB_SERIES(1b, 0x1b00);
193RTL_DEBUG_IMPL_BB_SERIES(1c, 0x1c00);
194RTL_DEBUG_IMPL_BB_SERIES(1d, 0x1d00);
195RTL_DEBUG_IMPL_BB_SERIES(1e, 0x1e00);
196RTL_DEBUG_IMPL_BB_SERIES(1f, 0x1f00);
197
198static int rtl_debug_get_reg_rf(struct seq_file *m, void *v)
199{
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;
204 int i, n;
205 int max = 0x40;
206
207 if (IS_HARDWARE_TYPE_8822B(rtlpriv))
208 max = 0xff;
209
210 seq_printf(m, "\nPATH(%d)", rfpath);
211
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));
217 }
218 seq_puts(m, "\n");
219 return 0;
220}
221
222#define RTL_DEBUG_IMPL_RF_SERIES(page, addr) \
223static struct rtl_debugfs_priv rtl_debug_priv_rf_ ##page = { \
224 .cb_read = rtl_debug_get_reg_rf, \
225 .cb_data = addr, \
226}
227
228RTL_DEBUG_IMPL_RF_SERIES(a, RF90_PATH_A);
229RTL_DEBUG_IMPL_RF_SERIES(b, RF90_PATH_B);
230
231static int rtl_debug_get_cam_register(struct seq_file *m, void *v)
232{
233 struct rtl_debugfs_priv *debugfs_priv = m->private;
234 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
235 int start = debugfs_priv->cb_data;
236 u32 target_cmd = 0;
237 u32 target_val = 0;
238 u8 entry_i = 0;
239 u32 ulstatus;
240 int i = 100, j = 0;
241 int end = (start + 11 > TOTAL_CAM_ENTRY ? TOTAL_CAM_ENTRY : start + 11);
242
243 /* This dump the current register page */
244 seq_printf(m,
245 "\n#################### SECURITY CAM (%d-%d) ##################\n",
246 start, end - 1);
247
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);
254
255 /* Check polling bit is clear */
256 while ((i--) >= 0) {
257 ulstatus =
258 rtl_read_dword(rtlpriv,
259 rtlpriv->cfg->maps[RWCAM]);
260 if (ulstatus & BIT(31))
261 continue;
262 else
263 break;
264 }
265
266 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
267 target_cmd);
268 target_val = rtl_read_dword(rtlpriv,
269 rtlpriv->cfg->maps[RCAMO]);
270 seq_printf(m, "%8.8x ", target_val);
271 }
272 }
273 seq_puts(m, "\n");
274 return 0;
275}
276
277#define RTL_DEBUG_IMPL_CAM_SERIES(page, addr) \
278static struct rtl_debugfs_priv rtl_debug_priv_cam_ ##page = { \
279 .cb_read = rtl_debug_get_cam_register, \
280 .cb_data = addr, \
281}
282
283RTL_DEBUG_IMPL_CAM_SERIES(1, 0);
284RTL_DEBUG_IMPL_CAM_SERIES(2, 11);
285RTL_DEBUG_IMPL_CAM_SERIES(3, 22);
286
287static int rtl_debug_get_btcoex(struct seq_file *m, void *v)
288{
289 struct rtl_debugfs_priv *debugfs_priv = m->private;
290 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
291
292 if (rtlpriv->cfg->ops->get_btc_status())
293 rtlpriv->btcoexist.btc_ops->btc_display_bt_coex_info(rtlpriv,
294 m);
295
296 seq_puts(m, "\n");
297
298 return 0;
299}
300
301static struct rtl_debugfs_priv rtl_debug_priv_btcoex = {
302 .cb_read = rtl_debug_get_btcoex,
303 .cb_data = 0,
304};
305
306static ssize_t rtl_debugfs_set_write_reg(struct file *filp,
307 const char __user *buffer,
308 size_t count, loff_t *loff)
309{
310 struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
311 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
312 char tmp[32 + 1];
313 int tmp_len;
314 u32 addr, val, len;
315 int num;
316
317 if (count < 3)
318 return -EFAULT;
319
320 tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
321
322 if (!buffer || copy_from_user(tmp, buffer, tmp_len))
323 return count;
324
325 tmp[tmp_len] = '\0';
326
327 /* write BB/MAC register */
328 num = sscanf(tmp, "%x %x %x", &addr, &val, &len);
329
330 if (num != 3)
331 return count;
332
333 switch (len) {
334 case 1:
335 rtl_write_byte(rtlpriv, addr, (u8)val);
336 break;
337 case 2:
338 rtl_write_word(rtlpriv, addr, (u16)val);
339 break;
340 case 4:
341 rtl_write_dword(rtlpriv, addr, val);
342 break;
343 default:
344 /*printk("error write length=%d", len);*/
345 break;
346 }
347
348 return count;
349}
350
351static struct rtl_debugfs_priv rtl_debug_priv_write_reg = {
352 .cb_write = rtl_debugfs_set_write_reg,
353};
354
355static ssize_t rtl_debugfs_set_write_h2c(struct file *filp,
356 const char __user *buffer,
357 size_t count, loff_t *loff)
358{
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;
362 char tmp[32 + 1];
363 int tmp_len;
364 u8 h2c_len, h2c_data_packed[8];
365 int h2c_data[8]; /* idx 0: cmd */
366 int i;
367
368 if (count < 3)
369 return -EFAULT;
370
371 tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
372
373 if (!buffer || copy_from_user(tmp, buffer, tmp_len))
374 return count;
375
376 tmp[tmp_len] = '\0';
377
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]);
383
384 if (h2c_len <= 0)
385 return count;
386
387 for (i = 0; i < h2c_len; i++)
388 h2c_data_packed[i] = (u8)h2c_data[i];
389
390 rtlpriv->cfg->ops->fill_h2c_cmd(hw, h2c_data_packed[0],
391 h2c_len - 1,
392 &h2c_data_packed[1]);
393
394 return count;
395}
396
397static struct rtl_debugfs_priv rtl_debug_priv_write_h2c = {
398 .cb_write = rtl_debugfs_set_write_h2c,
399};
400
401static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp,
402 const char __user *buffer,
403 size_t count, loff_t *loff)
404{
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;
408 char tmp[32 + 1];
409 int tmp_len;
410 int num;
411 int path;
412 u32 addr, bitmask, data;
413
414 if (count < 3)
415 return -EFAULT;
416
417 tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
418
419 if (!buffer || copy_from_user(tmp, buffer, tmp_len))
420 return count;
421
422 tmp[tmp_len] = '\0';
423
424 num = sscanf(tmp, "%X %X %X %X",
425 &path, &addr, &bitmask, &data);
426
427 if (num != 4) {
428 RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
429 "Format is <path> <addr> <mask> <data>\n");
430 return count;
431 }
432
433 rtl_set_rfreg(hw, path, addr, bitmask, data);
434
435 return count;
436}
437
438static struct rtl_debugfs_priv rtl_debug_priv_write_rfreg = {
439 .cb_write = rtl_debugfs_set_write_rfreg,
440};
441
442static int rtl_debugfs_close(struct inode *inode, struct file *filp)
443{
444 return 0;
445}
446
447static ssize_t rtl_debugfs_common_write(struct file *filp,
448 const char __user *buffer,
449 size_t count, loff_t *loff)
450{
451 struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
452
453 return debugfs_priv->cb_write(filp, buffer, count, loff);
454}
455
456static const struct file_operations file_ops_common_write = {
457 .owner = THIS_MODULE,
458 .write = rtl_debugfs_common_write,
459 .open = simple_open,
460 .release = rtl_debugfs_close,
461};
462
463#define RTL_DEBUGFS_ADD_CORE(name, mode, fopname) \
464 do { \
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, \
471 #name); \
472 } while (0)
473
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)
478
479void rtl_debug_add_one(struct ieee80211_hw *hw)
480{
481 struct rtl_priv *rtlpriv = rtl_priv(hw);
482 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
483 struct dentry *parent;
484
485 snprintf(rtlpriv->dbg.debugfs_name, 18, "%pMF", rtlefuse->dev_addr);
486
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);
492 return;
493 }
494
495 parent = rtlpriv->dbg.debugfs_dir;
496
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);
531
532 RTL_DEBUGFS_ADD(cam_1);
533 RTL_DEBUGFS_ADD(cam_2);
534 RTL_DEBUGFS_ADD(cam_3);
535
536 RTL_DEBUGFS_ADD(btcoex);
537
538 RTL_DEBUGFS_ADD_W(write_reg);
539 RTL_DEBUGFS_ADD_W(write_h2c);
540 RTL_DEBUGFS_ADD_W(write_rfreg);
541}
542EXPORT_SYMBOL_GPL(rtl_debug_add_one);
543
544void rtl_debug_remove_one(struct ieee80211_hw *hw)
545{
546 struct rtl_priv *rtlpriv = rtl_priv(hw);
547
548 debugfs_remove_recursive(rtlpriv->dbg.debugfs_dir);
549 rtlpriv->dbg.debugfs_dir = NULL;
550}
551EXPORT_SYMBOL_GPL(rtl_debug_remove_one);
552
553void rtl_debugfs_add_topdir(void)
554{
555 debugfs_topdir = debugfs_create_dir("rtlwifi", NULL);
556}
557
558void rtl_debugfs_remove_topdir(void)
559{
560 debugfs_remove_recursive(debugfs_topdir);
561}
562
84#endif 563#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.h b/drivers/net/wireless/realtek/rtlwifi/debug.h
index 947718001457..ad6834af618b 100644
--- a/drivers/net/wireless/realtek/rtlwifi/debug.h
+++ b/drivers/net/wireless/realtek/rtlwifi/debug.h
@@ -219,4 +219,16 @@ static inline void RT_PRINT_DATA(struct rtl_priv *rtlpriv,
219} 219}
220 220
221#endif 221#endif
222
223#ifdef CONFIG_RTLWIFI_DEBUG
224void rtl_debug_add_one(struct ieee80211_hw *hw);
225void rtl_debug_remove_one(struct ieee80211_hw *hw);
226void rtl_debugfs_add_topdir(void);
227void rtl_debugfs_remove_topdir(void);
228#else
229#define rtl_debug_add_one(hw)
230#define rtl_debug_remove_one(hw)
231#define rtl_debugfs_add_topdir()
232#define rtl_debugfs_remove_topdir()
233#endif
222#endif 234#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c
index 4013394fac33..c1833a501be4 100644
--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
@@ -2309,6 +2309,9 @@ int rtl_pci_probe(struct pci_dev *pdev,
2309 } 2309 }
2310 rtlpriv->mac80211.mac80211_registered = 1; 2310 rtlpriv->mac80211.mac80211_registered = 1;
2311 2311
2312 /* add for debug */
2313 rtl_debug_add_one(hw);
2314
2312 /*init rfkill */ 2315 /*init rfkill */
2313 rtl_init_rfkill(hw); /* Init PCI sw */ 2316 rtl_init_rfkill(hw); /* Init PCI sw */
2314 2317
@@ -2357,6 +2360,9 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
2357 wait_for_completion(&rtlpriv->firmware_loading_complete); 2360 wait_for_completion(&rtlpriv->firmware_loading_complete);
2358 clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); 2361 clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
2359 2362
2363 /* remove form debug */
2364 rtl_debug_remove_one(hw);
2365
2360 /*ieee80211_unregister_hw will call ops_stop */ 2366 /*ieee80211_unregister_hw will call ops_stop */
2361 if (rtlmac->mac80211_registered == 1) { 2367 if (rtlmac->mac80211_registered == 1) {
2362 ieee80211_unregister_hw(hw); 2368 ieee80211_unregister_hw(hw);
diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h
index e2b14793b705..0b1c54381a2f 100644
--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h
+++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h
@@ -2381,6 +2381,12 @@ struct rtl_works {
2381 struct work_struct fill_h2c_cmd; 2381 struct work_struct fill_h2c_cmd;
2382}; 2382};
2383 2383
2384struct rtl_debug {
2385 /* add for debug */
2386 struct dentry *debugfs_dir;
2387 char debugfs_name[20];
2388};
2389
2384#define MIMO_PS_STATIC 0 2390#define MIMO_PS_STATIC 0
2385#define MIMO_PS_DYNAMIC 1 2391#define MIMO_PS_DYNAMIC 1
2386#define MIMO_PS_NOLIMIT 3 2392#define MIMO_PS_NOLIMIT 3
@@ -2575,6 +2581,8 @@ struct rtl_btc_ops {
2575 bool (*btc_is_bt_disabled) (struct rtl_priv *rtlpriv); 2581 bool (*btc_is_bt_disabled) (struct rtl_priv *rtlpriv);
2576 void (*btc_special_packet_notify)(struct rtl_priv *rtlpriv, 2582 void (*btc_special_packet_notify)(struct rtl_priv *rtlpriv,
2577 u8 pkt_type); 2583 u8 pkt_type);
2584 void (*btc_display_bt_coex_info)(struct rtl_priv *rtlpriv,
2585 struct seq_file *m);
2578 void (*btc_record_pwr_mode)(struct rtl_priv *rtlpriv, u8 *buf, u8 len); 2586 void (*btc_record_pwr_mode)(struct rtl_priv *rtlpriv, u8 *buf, u8 len);
2579 u8 (*btc_get_lps_val)(struct rtl_priv *rtlpriv); 2587 u8 (*btc_get_lps_val)(struct rtl_priv *rtlpriv);
2580 u8 (*btc_get_rpwm_val)(struct rtl_priv *rtlpriv); 2588 u8 (*btc_get_rpwm_val)(struct rtl_priv *rtlpriv);
@@ -2649,6 +2657,7 @@ struct rtl_priv {
2649 /* c2hcmd list for kthread level access */ 2657 /* c2hcmd list for kthread level access */
2650 struct list_head c2hcmd_list; 2658 struct list_head c2hcmd_list;
2651 2659
2660 struct rtl_debug dbg;
2652 int max_fw_size; 2661 int max_fw_size;
2653 2662
2654 /* 2663 /*