diff options
author | Ping-Ke Shih <pkshih@realtek.com> | 2017-12-29 03:31:10 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2018-01-08 12:07:45 -0500 |
commit | 610247f46feb23beda99d0bb44aa8f51a8dc27e1 (patch) | |
tree | 1c34f56e3580ad9e18f022ade34ce816610942c6 /drivers/net | |
parent | 981a2b6e055bce9a9f780fb074ffdf9a9bab0d47 (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')
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 | ||
2546 | module_init(rtl_core_module_init); | 2552 | module_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 | ||
1516 | void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist) | 1516 | void 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); | |||
626 | void exhalbtc_set_bt_exist(bool bt_exist); | 626 | void exhalbtc_set_bt_exist(bool bt_exist); |
627 | void exhalbtc_set_chip_type(u8 chip_type); | 627 | void exhalbtc_set_chip_type(u8 chip_type); |
628 | void exhalbtc_set_ant_num(struct rtl_priv *rtlpriv, u8 type, u8 ant_num); | 628 | void exhalbtc_set_ant_num(struct rtl_priv *rtlpriv, u8 type, u8 ant_num); |
629 | void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist); | 629 | void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist, |
630 | struct seq_file *m); | ||
630 | void exhalbtc_signal_compensation(struct btc_coexist *btcoexist, | 631 | void exhalbtc_signal_compensation(struct btc_coexist *btcoexist, |
631 | u8 *rssi_wifi, u8 *rssi_bt); | 632 | u8 *rssi_wifi, u8 *rssi_bt); |
632 | void exhalbtc_lps_leave(struct btc_coexist *btcoexist); | 633 | void 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 | ||
58 | void 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 | |||
57 | void rtl_btc_record_pwr_mode(struct rtl_priv *rtlpriv, u8 *buf, u8 len) | 63 | void 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); | |||
44 | bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv); | 44 | bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv); |
45 | bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv); | 45 | bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv); |
46 | void rtl_btc_special_packet_notify(struct rtl_priv *rtlpriv, u8 pkt_type); | 46 | void rtl_btc_special_packet_notify(struct rtl_priv *rtlpriv, u8 pkt_type); |
47 | void rtl_btc_display_bt_coex_info(struct rtl_priv *rtlpriv, struct seq_file *m); | ||
47 | void rtl_btc_record_pwr_mode(struct rtl_priv *rtlpriv, u8 *buf, u8 len); | 48 | void rtl_btc_record_pwr_mode(struct rtl_priv *rtlpriv, u8 *buf, u8 len); |
48 | u8 rtl_btc_get_lps_val(struct rtl_priv *rtlpriv); | 49 | u8 rtl_btc_get_lps_val(struct rtl_priv *rtlpriv); |
49 | u8 rtl_btc_get_rpwm_val(struct rtl_priv *rtlpriv); | 50 | u8 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 |
30 | void _rtl_dbg_trace(struct rtl_priv *rtlpriv, u64 comp, int level, | 32 | void _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 | } |
82 | EXPORT_SYMBOL_GPL(_rtl_dbg_print_data); | 84 | EXPORT_SYMBOL_GPL(_rtl_dbg_print_data); |
83 | 85 | ||
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); | ||
91 | u32 cb_data; | ||
92 | }; | ||
93 | |||
94 | static struct dentry *debugfs_topdir; | ||
95 | |||
96 | static 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 | |||
103 | static 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 | |||
108 | static 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 | |||
115 | static 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) \ | ||
134 | static struct rtl_debugfs_priv rtl_debug_priv_mac_ ##page = { \ | ||
135 | .cb_read = rtl_debug_get_mac_page, \ | ||
136 | .cb_data = addr, \ | ||
137 | } | ||
138 | |||
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); | ||
155 | |||
156 | static 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) \ | ||
176 | static struct rtl_debugfs_priv rtl_debug_priv_bb_ ##page = { \ | ||
177 | .cb_read = rtl_debug_get_bb_page, \ | ||
178 | .cb_data = addr, \ | ||
179 | } | ||
180 | |||
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); | ||
197 | |||
198 | static 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) \ | ||
223 | static struct rtl_debugfs_priv rtl_debug_priv_rf_ ##page = { \ | ||
224 | .cb_read = rtl_debug_get_reg_rf, \ | ||
225 | .cb_data = addr, \ | ||
226 | } | ||
227 | |||
228 | RTL_DEBUG_IMPL_RF_SERIES(a, RF90_PATH_A); | ||
229 | RTL_DEBUG_IMPL_RF_SERIES(b, RF90_PATH_B); | ||
230 | |||
231 | static 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) \ | ||
278 | static struct rtl_debugfs_priv rtl_debug_priv_cam_ ##page = { \ | ||
279 | .cb_read = rtl_debug_get_cam_register, \ | ||
280 | .cb_data = addr, \ | ||
281 | } | ||
282 | |||
283 | RTL_DEBUG_IMPL_CAM_SERIES(1, 0); | ||
284 | RTL_DEBUG_IMPL_CAM_SERIES(2, 11); | ||
285 | RTL_DEBUG_IMPL_CAM_SERIES(3, 22); | ||
286 | |||
287 | static 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 | |||
301 | static struct rtl_debugfs_priv rtl_debug_priv_btcoex = { | ||
302 | .cb_read = rtl_debug_get_btcoex, | ||
303 | .cb_data = 0, | ||
304 | }; | ||
305 | |||
306 | static 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 | |||
351 | static struct rtl_debugfs_priv rtl_debug_priv_write_reg = { | ||
352 | .cb_write = rtl_debugfs_set_write_reg, | ||
353 | }; | ||
354 | |||
355 | static 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 | |||
397 | static struct rtl_debugfs_priv rtl_debug_priv_write_h2c = { | ||
398 | .cb_write = rtl_debugfs_set_write_h2c, | ||
399 | }; | ||
400 | |||
401 | static 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 | |||
438 | static struct rtl_debugfs_priv rtl_debug_priv_write_rfreg = { | ||
439 | .cb_write = rtl_debugfs_set_write_rfreg, | ||
440 | }; | ||
441 | |||
442 | static int rtl_debugfs_close(struct inode *inode, struct file *filp) | ||
443 | { | ||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | static 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 | |||
456 | static 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 | |||
479 | void 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 | } | ||
542 | EXPORT_SYMBOL_GPL(rtl_debug_add_one); | ||
543 | |||
544 | void 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 | } | ||
551 | EXPORT_SYMBOL_GPL(rtl_debug_remove_one); | ||
552 | |||
553 | void rtl_debugfs_add_topdir(void) | ||
554 | { | ||
555 | debugfs_topdir = debugfs_create_dir("rtlwifi", NULL); | ||
556 | } | ||
557 | |||
558 | void 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 | ||
224 | void rtl_debug_add_one(struct ieee80211_hw *hw); | ||
225 | void rtl_debug_remove_one(struct ieee80211_hw *hw); | ||
226 | void rtl_debugfs_add_topdir(void); | ||
227 | void 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 | ||
2384 | struct 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 | /* |