xref: /linux/drivers/net/wireless/realtek/rtlwifi/debug.c (revision e7d759f31ca295d589f7420719c311870bb3166f)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2009-2012  Realtek Corporation.*/
3 
4 #include "wifi.h"
5 #include "cam.h"
6 
7 #include <linux/moduleparam.h>
8 #include <linux/vmalloc.h>
9 
10 #ifdef CONFIG_RTLWIFI_DEBUG
11 void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level,
12 		    const char *fmt, ...)
13 {
14 	if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) &&
15 		     level <= rtlpriv->cfg->mod_params->debug_level)) {
16 		struct va_format vaf;
17 		va_list args;
18 
19 		va_start(args, fmt);
20 
21 		vaf.fmt = fmt;
22 		vaf.va = &args;
23 
24 		pr_info("%pV", &vaf);
25 
26 		va_end(args);
27 	}
28 }
29 EXPORT_SYMBOL_GPL(_rtl_dbg_print);
30 
31 void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level,
32 			 const char *titlestring,
33 			 const void *hexdata, int hexdatalen)
34 {
35 	if (unlikely(((comp) & rtlpriv->cfg->mod_params->debug_mask) &&
36 		     ((level) <= rtlpriv->cfg->mod_params->debug_level))) {
37 		pr_info("In process \"%s\" (pid %i): %s\n",
38 			current->comm, current->pid, titlestring);
39 		print_hex_dump_bytes("", DUMP_PREFIX_NONE,
40 				     hexdata, hexdatalen);
41 	}
42 }
43 EXPORT_SYMBOL_GPL(_rtl_dbg_print_data);
44 
45 struct rtl_debugfs_priv {
46 	struct rtl_priv *rtlpriv;
47 	int (*cb_read)(struct seq_file *m, void *v);
48 	ssize_t (*cb_write)(struct file *filp, const char __user *buffer,
49 			    size_t count, loff_t *loff);
50 	u32 cb_data;
51 };
52 
53 static struct dentry *debugfs_topdir;
54 
55 static int rtl_debug_get_common(struct seq_file *m, void *v)
56 {
57 	struct rtl_debugfs_priv *debugfs_priv = m->private;
58 
59 	return debugfs_priv->cb_read(m, v);
60 }
61 
62 static int dl_debug_open_common(struct inode *inode, struct file *file)
63 {
64 	return single_open(file, rtl_debug_get_common, inode->i_private);
65 }
66 
67 static const struct file_operations file_ops_common = {
68 	.open = dl_debug_open_common,
69 	.read = seq_read,
70 	.llseek = seq_lseek,
71 	.release = single_release,
72 };
73 
74 static int rtl_debug_get_mac_page(struct seq_file *m, void *v)
75 {
76 	struct rtl_debugfs_priv *debugfs_priv = m->private;
77 	struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
78 	u32 page = debugfs_priv->cb_data;
79 	int i, n;
80 	int max = 0xff;
81 
82 	for (n = 0; n <= max; ) {
83 		seq_printf(m, "\n%8.8x  ", n + page);
84 		for (i = 0; i < 4 && n <= max; i++, n += 4)
85 			seq_printf(m, "%8.8x    ",
86 				   rtl_read_dword(rtlpriv, (page | n)));
87 	}
88 	seq_puts(m, "\n");
89 	return 0;
90 }
91 
92 #define RTL_DEBUG_IMPL_MAC_SERIES(page, addr)			\
93 static struct rtl_debugfs_priv rtl_debug_priv_mac_ ##page = {	\
94 	.cb_read = rtl_debug_get_mac_page,			\
95 	.cb_data = addr,					\
96 }
97 
98 RTL_DEBUG_IMPL_MAC_SERIES(0, 0x0000);
99 RTL_DEBUG_IMPL_MAC_SERIES(1, 0x0100);
100 RTL_DEBUG_IMPL_MAC_SERIES(2, 0x0200);
101 RTL_DEBUG_IMPL_MAC_SERIES(3, 0x0300);
102 RTL_DEBUG_IMPL_MAC_SERIES(4, 0x0400);
103 RTL_DEBUG_IMPL_MAC_SERIES(5, 0x0500);
104 RTL_DEBUG_IMPL_MAC_SERIES(6, 0x0600);
105 RTL_DEBUG_IMPL_MAC_SERIES(7, 0x0700);
106 RTL_DEBUG_IMPL_MAC_SERIES(10, 0x1000);
107 RTL_DEBUG_IMPL_MAC_SERIES(11, 0x1100);
108 RTL_DEBUG_IMPL_MAC_SERIES(12, 0x1200);
109 RTL_DEBUG_IMPL_MAC_SERIES(13, 0x1300);
110 RTL_DEBUG_IMPL_MAC_SERIES(14, 0x1400);
111 RTL_DEBUG_IMPL_MAC_SERIES(15, 0x1500);
112 RTL_DEBUG_IMPL_MAC_SERIES(16, 0x1600);
113 RTL_DEBUG_IMPL_MAC_SERIES(17, 0x1700);
114 
115 static int rtl_debug_get_bb_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 	struct ieee80211_hw *hw = rtlpriv->hw;
120 	u32 page = debugfs_priv->cb_data;
121 	int i, n;
122 	int max = 0xff;
123 
124 	for (n = 0; n <= max; ) {
125 		seq_printf(m, "\n%8.8x  ", n + page);
126 		for (i = 0; i < 4 && n <= max; i++, n += 4)
127 			seq_printf(m, "%8.8x    ",
128 				   rtl_get_bbreg(hw, (page | n), 0xffffffff));
129 	}
130 	seq_puts(m, "\n");
131 	return 0;
132 }
133 
134 #define RTL_DEBUG_IMPL_BB_SERIES(page, addr)			\
135 static struct rtl_debugfs_priv rtl_debug_priv_bb_ ##page = {	\
136 	.cb_read = rtl_debug_get_bb_page,			\
137 	.cb_data = addr,					\
138 }
139 
140 RTL_DEBUG_IMPL_BB_SERIES(8, 0x0800);
141 RTL_DEBUG_IMPL_BB_SERIES(9, 0x0900);
142 RTL_DEBUG_IMPL_BB_SERIES(a, 0x0a00);
143 RTL_DEBUG_IMPL_BB_SERIES(b, 0x0b00);
144 RTL_DEBUG_IMPL_BB_SERIES(c, 0x0c00);
145 RTL_DEBUG_IMPL_BB_SERIES(d, 0x0d00);
146 RTL_DEBUG_IMPL_BB_SERIES(e, 0x0e00);
147 RTL_DEBUG_IMPL_BB_SERIES(f, 0x0f00);
148 RTL_DEBUG_IMPL_BB_SERIES(18, 0x1800);
149 RTL_DEBUG_IMPL_BB_SERIES(19, 0x1900);
150 RTL_DEBUG_IMPL_BB_SERIES(1a, 0x1a00);
151 RTL_DEBUG_IMPL_BB_SERIES(1b, 0x1b00);
152 RTL_DEBUG_IMPL_BB_SERIES(1c, 0x1c00);
153 RTL_DEBUG_IMPL_BB_SERIES(1d, 0x1d00);
154 RTL_DEBUG_IMPL_BB_SERIES(1e, 0x1e00);
155 RTL_DEBUG_IMPL_BB_SERIES(1f, 0x1f00);
156 
157 static int rtl_debug_get_reg_rf(struct seq_file *m, void *v)
158 {
159 	struct rtl_debugfs_priv *debugfs_priv = m->private;
160 	struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
161 	struct ieee80211_hw *hw = rtlpriv->hw;
162 	enum radio_path rfpath = debugfs_priv->cb_data;
163 	int i, n;
164 	int max = 0x40;
165 
166 	if (IS_HARDWARE_TYPE_8822B(rtlpriv))
167 		max = 0xff;
168 
169 	seq_printf(m, "\nPATH(%d)", rfpath);
170 
171 	for (n = 0; n <= max; ) {
172 		seq_printf(m, "\n%8.8x  ", n);
173 		for (i = 0; i < 4 && n <= max; n += 1, i++)
174 			seq_printf(m, "%8.8x    ",
175 				   rtl_get_rfreg(hw, rfpath, n, 0xffffffff));
176 	}
177 	seq_puts(m, "\n");
178 	return 0;
179 }
180 
181 #define RTL_DEBUG_IMPL_RF_SERIES(page, addr)			\
182 static struct rtl_debugfs_priv rtl_debug_priv_rf_ ##page = {	\
183 	.cb_read = rtl_debug_get_reg_rf,			\
184 	.cb_data = addr,					\
185 }
186 
187 RTL_DEBUG_IMPL_RF_SERIES(a, RF90_PATH_A);
188 RTL_DEBUG_IMPL_RF_SERIES(b, RF90_PATH_B);
189 
190 static int rtl_debug_get_cam_register(struct seq_file *m, void *v)
191 {
192 	struct rtl_debugfs_priv *debugfs_priv = m->private;
193 	struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
194 	int start = debugfs_priv->cb_data;
195 	u32 target_cmd = 0;
196 	u32 target_val = 0;
197 	u8 entry_i = 0;
198 	u32 ulstatus;
199 	int i = 100, j = 0;
200 	int end = (start + 11 > TOTAL_CAM_ENTRY ? TOTAL_CAM_ENTRY : start + 11);
201 
202 	/* This dump the current register page */
203 	seq_printf(m,
204 		   "\n#################### SECURITY CAM (%d-%d) ##################\n",
205 		   start, end - 1);
206 
207 	for (j = start; j < end; j++) {
208 		seq_printf(m, "\nD:  %2x > ", j);
209 		for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
210 			/* polling bit, and No Write enable, and address  */
211 			target_cmd = entry_i + CAM_CONTENT_COUNT * j;
212 			target_cmd = target_cmd | BIT(31);
213 
214 			/* Check polling bit is clear */
215 			while ((i--) >= 0) {
216 				ulstatus =
217 				    rtl_read_dword(rtlpriv,
218 						   rtlpriv->cfg->maps[RWCAM]);
219 				if (ulstatus & BIT(31))
220 					continue;
221 				else
222 					break;
223 			}
224 
225 			rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
226 					target_cmd);
227 			target_val = rtl_read_dword(rtlpriv,
228 						    rtlpriv->cfg->maps[RCAMO]);
229 			seq_printf(m, "%8.8x ", target_val);
230 		}
231 	}
232 	seq_puts(m, "\n");
233 	return 0;
234 }
235 
236 #define RTL_DEBUG_IMPL_CAM_SERIES(page, addr)			\
237 static struct rtl_debugfs_priv rtl_debug_priv_cam_ ##page = {	\
238 	.cb_read = rtl_debug_get_cam_register,			\
239 	.cb_data = addr,					\
240 }
241 
242 RTL_DEBUG_IMPL_CAM_SERIES(1, 0);
243 RTL_DEBUG_IMPL_CAM_SERIES(2, 11);
244 RTL_DEBUG_IMPL_CAM_SERIES(3, 22);
245 
246 static int rtl_debug_get_btcoex(struct seq_file *m, void *v)
247 {
248 	struct rtl_debugfs_priv *debugfs_priv = m->private;
249 	struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
250 
251 	if (rtlpriv->cfg->ops->get_btc_status())
252 		rtlpriv->btcoexist.btc_ops->btc_display_bt_coex_info(rtlpriv,
253 								     m);
254 
255 	seq_puts(m, "\n");
256 
257 	return 0;
258 }
259 
260 static struct rtl_debugfs_priv rtl_debug_priv_btcoex = {
261 	.cb_read = rtl_debug_get_btcoex,
262 	.cb_data = 0,
263 };
264 
265 static ssize_t rtl_debugfs_set_write_reg(struct file *filp,
266 					 const char __user *buffer,
267 					 size_t count, loff_t *loff)
268 {
269 	struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
270 	struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
271 	char tmp[32 + 1];
272 	int tmp_len;
273 	u32 addr, val, len;
274 	int num;
275 
276 	if (count < 3)
277 		return -EFAULT;
278 
279 	tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
280 
281 	if (copy_from_user(tmp, buffer, tmp_len))
282 		return -EFAULT;
283 
284 	tmp[tmp_len] = '\0';
285 
286 	/* write BB/MAC register */
287 	num = sscanf(tmp, "%x %x %x", &addr, &val, &len);
288 
289 	if (num !=  3)
290 		return -EINVAL;
291 
292 	switch (len) {
293 	case 1:
294 		rtl_write_byte(rtlpriv, addr, (u8)val);
295 		break;
296 	case 2:
297 		rtl_write_word(rtlpriv, addr, (u16)val);
298 		break;
299 	case 4:
300 		rtl_write_dword(rtlpriv, addr, val);
301 		break;
302 	default:
303 		/*printk("error write length=%d", len);*/
304 		break;
305 	}
306 
307 	return count;
308 }
309 
310 static struct rtl_debugfs_priv rtl_debug_priv_write_reg = {
311 	.cb_write = rtl_debugfs_set_write_reg,
312 };
313 
314 static ssize_t rtl_debugfs_set_write_h2c(struct file *filp,
315 					 const char __user *buffer,
316 					 size_t count, loff_t *loff)
317 {
318 	struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
319 	struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
320 	struct ieee80211_hw *hw = rtlpriv->hw;
321 	char tmp[32 + 1];
322 	int tmp_len;
323 	u8 h2c_len, h2c_data_packed[8];
324 	int h2c_data[8];	/* idx 0: cmd */
325 	int i;
326 
327 	if (count < 3)
328 		return -EFAULT;
329 
330 	tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
331 
332 	if (copy_from_user(tmp, buffer, tmp_len))
333 		return -EFAULT;
334 
335 	tmp[tmp_len] = '\0';
336 
337 	h2c_len = sscanf(tmp, "%X %X %X %X %X %X %X %X",
338 			 &h2c_data[0], &h2c_data[1],
339 			 &h2c_data[2], &h2c_data[3],
340 			 &h2c_data[4], &h2c_data[5],
341 			 &h2c_data[6], &h2c_data[7]);
342 
343 	if (h2c_len == 0)
344 		return -EINVAL;
345 
346 	for (i = 0; i < h2c_len; i++)
347 		h2c_data_packed[i] = (u8)h2c_data[i];
348 
349 	rtlpriv->cfg->ops->fill_h2c_cmd(hw, h2c_data_packed[0],
350 					h2c_len - 1,
351 					&h2c_data_packed[1]);
352 
353 	return count;
354 }
355 
356 static struct rtl_debugfs_priv rtl_debug_priv_write_h2c = {
357 	.cb_write = rtl_debugfs_set_write_h2c,
358 };
359 
360 static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp,
361 					   const char __user *buffer,
362 					    size_t count, loff_t *loff)
363 {
364 	struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
365 	struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
366 	struct ieee80211_hw *hw = rtlpriv->hw;
367 	char tmp[32 + 1];
368 	int tmp_len;
369 	int num;
370 	int path;
371 	u32 addr, bitmask, data;
372 
373 	if (count < 3)
374 		return -EFAULT;
375 
376 	tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
377 
378 	if (copy_from_user(tmp, buffer, tmp_len))
379 		return -EFAULT;
380 
381 	tmp[tmp_len] = '\0';
382 
383 	num = sscanf(tmp, "%X %X %X %X",
384 		     &path, &addr, &bitmask, &data);
385 
386 	if (num != 4) {
387 		rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG,
388 			"Format is <path> <addr> <mask> <data>\n");
389 		return -EINVAL;
390 	}
391 
392 	rtl_set_rfreg(hw, path, addr, bitmask, data);
393 
394 	return count;
395 }
396 
397 static struct rtl_debugfs_priv rtl_debug_priv_write_rfreg = {
398 	.cb_write = rtl_debugfs_set_write_rfreg,
399 };
400 
401 static int rtl_debugfs_close(struct inode *inode, struct file *filp)
402 {
403 	return 0;
404 }
405 
406 static ssize_t rtl_debugfs_common_write(struct file *filp,
407 					const char __user *buffer,
408 					size_t count, loff_t *loff)
409 {
410 	struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
411 
412 	return debugfs_priv->cb_write(filp, buffer, count, loff);
413 }
414 
415 static const struct file_operations file_ops_common_write = {
416 	.owner = THIS_MODULE,
417 	.write = rtl_debugfs_common_write,
418 	.open = simple_open,
419 	.release = rtl_debugfs_close,
420 };
421 
422 #define RTL_DEBUGFS_ADD_CORE(name, mode, fopname)			   \
423 	do {								   \
424 		rtl_debug_priv_ ##name.rtlpriv = rtlpriv;		   \
425 		debugfs_create_file(#name, mode, parent,		   \
426 				    &rtl_debug_priv_ ##name,		   \
427 				    &file_ops_ ##fopname);		   \
428 	} while (0)
429 
430 #define RTL_DEBUGFS_ADD(name)						   \
431 		RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0444, common)
432 #define RTL_DEBUGFS_ADD_W(name)						   \
433 		RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0222, common_write)
434 
435 void rtl_debug_add_one(struct ieee80211_hw *hw)
436 {
437 	struct rtl_priv *rtlpriv = rtl_priv(hw);
438 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
439 	struct dentry *parent;
440 
441 	snprintf(rtlpriv->dbg.debugfs_name, 18, "%pMF", rtlefuse->dev_addr);
442 
443 	rtlpriv->dbg.debugfs_dir =
444 		debugfs_create_dir(rtlpriv->dbg.debugfs_name, debugfs_topdir);
445 
446 	parent = rtlpriv->dbg.debugfs_dir;
447 
448 	RTL_DEBUGFS_ADD(mac_0);
449 	RTL_DEBUGFS_ADD(mac_1);
450 	RTL_DEBUGFS_ADD(mac_2);
451 	RTL_DEBUGFS_ADD(mac_3);
452 	RTL_DEBUGFS_ADD(mac_4);
453 	RTL_DEBUGFS_ADD(mac_5);
454 	RTL_DEBUGFS_ADD(mac_6);
455 	RTL_DEBUGFS_ADD(mac_7);
456 	RTL_DEBUGFS_ADD(bb_8);
457 	RTL_DEBUGFS_ADD(bb_9);
458 	RTL_DEBUGFS_ADD(bb_a);
459 	RTL_DEBUGFS_ADD(bb_b);
460 	RTL_DEBUGFS_ADD(bb_c);
461 	RTL_DEBUGFS_ADD(bb_d);
462 	RTL_DEBUGFS_ADD(bb_e);
463 	RTL_DEBUGFS_ADD(bb_f);
464 	RTL_DEBUGFS_ADD(mac_10);
465 	RTL_DEBUGFS_ADD(mac_11);
466 	RTL_DEBUGFS_ADD(mac_12);
467 	RTL_DEBUGFS_ADD(mac_13);
468 	RTL_DEBUGFS_ADD(mac_14);
469 	RTL_DEBUGFS_ADD(mac_15);
470 	RTL_DEBUGFS_ADD(mac_16);
471 	RTL_DEBUGFS_ADD(mac_17);
472 	RTL_DEBUGFS_ADD(bb_18);
473 	RTL_DEBUGFS_ADD(bb_19);
474 	RTL_DEBUGFS_ADD(bb_1a);
475 	RTL_DEBUGFS_ADD(bb_1b);
476 	RTL_DEBUGFS_ADD(bb_1c);
477 	RTL_DEBUGFS_ADD(bb_1d);
478 	RTL_DEBUGFS_ADD(bb_1e);
479 	RTL_DEBUGFS_ADD(bb_1f);
480 	RTL_DEBUGFS_ADD(rf_a);
481 	RTL_DEBUGFS_ADD(rf_b);
482 
483 	RTL_DEBUGFS_ADD(cam_1);
484 	RTL_DEBUGFS_ADD(cam_2);
485 	RTL_DEBUGFS_ADD(cam_3);
486 
487 	RTL_DEBUGFS_ADD(btcoex);
488 
489 	RTL_DEBUGFS_ADD_W(write_reg);
490 	RTL_DEBUGFS_ADD_W(write_h2c);
491 	RTL_DEBUGFS_ADD_W(write_rfreg);
492 }
493 EXPORT_SYMBOL_GPL(rtl_debug_add_one);
494 
495 void rtl_debug_remove_one(struct ieee80211_hw *hw)
496 {
497 	struct rtl_priv *rtlpriv = rtl_priv(hw);
498 
499 	debugfs_remove_recursive(rtlpriv->dbg.debugfs_dir);
500 	rtlpriv->dbg.debugfs_dir = NULL;
501 }
502 EXPORT_SYMBOL_GPL(rtl_debug_remove_one);
503 
504 void rtl_debugfs_add_topdir(void)
505 {
506 	debugfs_topdir = debugfs_create_dir("rtlwifi", NULL);
507 }
508 
509 void rtl_debugfs_remove_topdir(void)
510 {
511 	debugfs_remove_recursive(debugfs_topdir);
512 }
513 
514 #endif
515