Linux 4.16.11
[linux/fpc-iii.git] / drivers / staging / rtlwifi / debug.c
blobbe8d72cb63db5ea00583185b65dcc3cd9890b323
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
12 * more details.
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 *****************************************************************************/
25 #include "wifi.h"
26 #include "cam.h"
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,
33 const char *fmt, ...)
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;
40 va_start(args, fmt);
42 vaf.fmt = fmt;
43 vaf.va = &args;
45 pr_info(":<%lx> %pV", in_interrupt(), &vaf);
47 va_end(args);
51 void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level,
52 const char *fmt, ...)
54 if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) &&
55 level <= rtlpriv->cfg->mod_params->debug_level)) {
56 struct va_format vaf;
57 va_list args;
59 va_start(args, fmt);
61 vaf.fmt = fmt;
62 vaf.va = &args;
64 pr_info("%pV", &vaf);
66 va_end(args);
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,
79 hexdata, hexdatalen);
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);
88 u32 cb_data;
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,
107 .read = seq_read,
108 .llseek = seq_lseek,
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;
117 int i, n;
118 int max = 0xff;
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)));
126 seq_puts(m, "\n");
127 return 0;
130 #define RTL_DEBUG_IMPL_MAC_SERIES(page, addr) \
131 static struct rtl_debugfs_priv rtl_debug_priv_mac_ ##page = { \
132 .cb_read = rtl_debug_get_mac_page, \
133 .cb_data = addr, \
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;
159 int i, n;
160 int max = 0xff;
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));
168 seq_puts(m, "\n");
169 return 0;
172 #define RTL_DEBUG_IMPL_BB_SERIES(page, addr) \
173 static struct rtl_debugfs_priv rtl_debug_priv_bb_ ##page = { \
174 .cb_read = rtl_debug_get_bb_page, \
175 .cb_data = addr, \
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;
201 int i, n;
202 int max = 0x40;
204 if (IS_HARDWARE_TYPE_8822B(rtlpriv))
205 max = 0xff;
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));
215 seq_puts(m, "\n");
216 return 0;
219 #define RTL_DEBUG_IMPL_RF_SERIES(page, addr) \
220 static struct rtl_debugfs_priv rtl_debug_priv_rf_ ##page = { \
221 .cb_read = rtl_debug_get_reg_rf, \
222 .cb_data = addr, \
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;
233 u32 target_cmd = 0;
234 u32 target_val = 0;
235 u8 entry_i = 0;
236 u32 ulstatus;
237 int i = 100, j = 0;
238 int end = (start + 11 > TOTAL_CAM_ENTRY ? TOTAL_CAM_ENTRY : start + 11);
240 /* This dump the current register page */
241 seq_printf(m,
242 "\n#################### SECURITY CAM (%d-%d) ##################\n",
243 start, end - 1);
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 */
253 while ((i--) >= 0) {
254 ulstatus = rtl_read_dword(
255 rtlpriv,
256 rtlpriv->cfg->maps[RWCAM]);
257 if (ulstatus & BIT(31))
258 continue;
259 else
260 break;
263 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
264 target_cmd);
265 target_val = rtl_read_dword(rtlpriv,
266 rtlpriv->cfg->maps[RCAMO]);
267 seq_printf(m, "%8.8x ", target_val);
270 seq_puts(m, "\n");
271 return 0;
274 #define RTL_DEBUG_IMPL_CAM_SERIES(page, addr) \
275 static struct rtl_debugfs_priv rtl_debug_priv_cam_ ##page = { \
276 .cb_read = rtl_debug_get_cam_register, \
277 .cb_data = addr, \
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,
293 seq_puts(m, "\n");
295 return 0;
298 static struct rtl_debugfs_priv rtl_debug_priv_btcoex = {
299 .cb_read = rtl_debug_get_btcoex,
300 .cb_data = 0,
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;
309 char tmp[32 + 1];
310 int tmp_len;
311 u32 addr, val, len;
312 int num;
314 if (count < 3)
315 return -EFAULT;
317 tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
319 if (!buffer || copy_from_user(tmp, buffer, tmp_len))
320 return count;
322 tmp[tmp_len] = '\0';
324 /* write BB/MAC register */
325 num = sscanf(tmp, "%x %x %x", &addr, &val, &len);
327 if (num != 3)
328 return count;
330 switch (len) {
331 case 1:
332 rtl_write_byte(rtlpriv, addr, (u8)val);
333 break;
334 case 2:
335 rtl_write_word(rtlpriv, addr, (u16)val);
336 break;
337 case 4:
338 rtl_write_dword(rtlpriv, addr, val);
339 break;
340 default:
341 /*printk("error write length=%d", len);*/
342 break;
345 return count;
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;
359 char tmp[32 + 1];
360 int tmp_len;
361 u8 h2c_len, h2c_data_packed[8];
362 int h2c_data[8]; /* idx 0: cmd */
363 int i;
365 if (count < 3)
366 return -EFAULT;
368 tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
370 if (!buffer || copy_from_user(tmp, buffer, tmp_len))
371 return count;
373 tmp[tmp_len] = '\0';
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]);
381 if (h2c_len <= 0)
382 return count;
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],
388 h2c_len - 1,
389 &h2c_data_packed[1]);
391 return count;
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;
405 char tmp[32 + 1];
406 int tmp_len;
407 int num;
408 int path;
409 u32 addr, bitmask, data;
411 if (count < 3)
412 return -EFAULT;
414 tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
416 if (!buffer || copy_from_user(tmp, buffer, tmp_len))
417 return count;
419 tmp[tmp_len] = '\0';
421 num = sscanf(tmp, "%X %X %X %X",
422 &path, &addr, &bitmask, &data);
424 if (num != 4) {
425 RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
426 "Format is <path> <addr> <mask> <data>\n");
427 return count;
430 rtl_set_rfreg(hw, path, addr, bitmask, data);
432 return count;
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)
441 return 0;
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,
456 .open = simple_open,
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;
467 char tmp[64];
469 if (!rtlpriv->dbg.msg_buf)
470 return -ENOMEM;
472 if (!rtlpriv->phydm.ops)
473 return -EFAULT;
475 if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
476 tmp[count] = '\0';
478 rtlpriv->phydm.ops->phydm_debug_cmd(rtlpriv, tmp, count,
479 rtlpriv->dbg.msg_buf,
480 80 * 25);
483 return count;
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);
494 return 0;
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);
501 else
502 filp->private_data = inode->i_private;
504 return 0;
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);
512 return 0;
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,
518 .cb_data = 0,
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,
525 .read = seq_read,
526 .llseek = seq_lseek,
527 .write = rtl_debugfs_common_write,
530 #define RTL_DEBUGFS_ADD_CORE(name, mode, fopname) \
531 do { \
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, \
538 #name); \
539 } while (0)
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);
563 return;
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);
636 #endif