xref: /openbmc/linux/drivers/net/wireless/realtek/rtlwifi/debug.c (revision c62d3cd0ddd629606a3830aa22e9dcc6c2a0d3bf)
1 /******************************************************************************
2  *
3  * Copyright(c) 2009-2012  Realtek Corporation.
4  *
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.
8  *
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
12  * more details.
13  *
14  * The full GNU General Public License is included in this distribution in the
15  * file called LICENSE.
16  *
17  * Contact Information:
18  * wlanfae <wlanfae@realtek.com>
19  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20  * Hsinchu 300, Taiwan.
21  *
22  * Larry Finger <Larry.Finger@lwfinger.net>
23  *****************************************************************************/
24 
25 #include "wifi.h"
26 #include "cam.h"
27 
28 #include <linux/moduleparam.h>
29 #include <linux/vmalloc.h>
30 
31 #ifdef CONFIG_RTLWIFI_DEBUG
32 void _rtl_dbg_trace(struct rtl_priv *rtlpriv, u64 comp, int level,
33 		    const char *fmt, ...)
34 {
35 	if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) &&
36 		     level <= rtlpriv->cfg->mod_params->debug_level)) {
37 		struct va_format vaf;
38 		va_list args;
39 
40 		va_start(args, fmt);
41 
42 		vaf.fmt = fmt;
43 		vaf.va = &args;
44 
45 		pr_info(":<%lx> %pV", in_interrupt(), &vaf);
46 
47 		va_end(args);
48 	}
49 }
50 EXPORT_SYMBOL_GPL(_rtl_dbg_trace);
51 
52 void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level,
53 		    const char *fmt, ...)
54 {
55 	if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) &&
56 		     level <= rtlpriv->cfg->mod_params->debug_level)) {
57 		struct va_format vaf;
58 		va_list args;
59 
60 		va_start(args, fmt);
61 
62 		vaf.fmt = fmt;
63 		vaf.va = &args;
64 
65 		pr_info("%pV", &vaf);
66 
67 		va_end(args);
68 	}
69 }
70 EXPORT_SYMBOL_GPL(_rtl_dbg_print);
71 
72 void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level,
73 			 const char *titlestring,
74 			 const void *hexdata, int hexdatalen)
75 {
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,
81 				     hexdata, hexdatalen);
82 	}
83 }
84 EXPORT_SYMBOL_GPL(_rtl_dbg_print_data);
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 
563 #endif
564