Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
[cris-mirror.git] / drivers / net / wireless / realtek / rtlwifi / debug.c
blobd70385be99762e97507b998a1711c150182490f5
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
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);
50 EXPORT_SYMBOL_GPL(_rtl_dbg_trace);
52 void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level,
53 const char *fmt, ...)
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;
60 va_start(args, fmt);
62 vaf.fmt = fmt;
63 vaf.va = &args;
65 pr_info("%pV", &vaf);
67 va_end(args);
70 EXPORT_SYMBOL_GPL(_rtl_dbg_print);
72 void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level,
73 const char *titlestring,
74 const void *hexdata, int hexdatalen)
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);
84 EXPORT_SYMBOL_GPL(_rtl_dbg_print_data);
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;
94 static struct dentry *debugfs_topdir;
96 static int rtl_debug_get_common(struct seq_file *m, void *v)
98 struct rtl_debugfs_priv *debugfs_priv = m->private;
100 return debugfs_priv->cb_read(m, v);
103 static int dl_debug_open_common(struct inode *inode, struct file *file)
105 return single_open(file, rtl_debug_get_common, inode->i_private);
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,
115 static int rtl_debug_get_mac_page(struct seq_file *m, void *v)
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;
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)));
129 seq_puts(m, "\n");
130 return 0;
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, \
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);
156 static int rtl_debug_get_bb_page(struct seq_file *m, void *v)
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;
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));
171 seq_puts(m, "\n");
172 return 0;
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, \
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);
198 static int rtl_debug_get_reg_rf(struct seq_file *m, void *v)
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;
207 if (IS_HARDWARE_TYPE_8822B(rtlpriv))
208 max = 0xff;
210 seq_printf(m, "\nPATH(%d)", rfpath);
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));
218 seq_puts(m, "\n");
219 return 0;
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, \
228 RTL_DEBUG_IMPL_RF_SERIES(a, RF90_PATH_A);
229 RTL_DEBUG_IMPL_RF_SERIES(b, RF90_PATH_B);
231 static int rtl_debug_get_cam_register(struct seq_file *m, void *v)
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);
243 /* This dump the current register page */
244 seq_printf(m,
245 "\n#################### SECURITY CAM (%d-%d) ##################\n",
246 start, end - 1);
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);
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;
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);
273 seq_puts(m, "\n");
274 return 0;
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, \
283 RTL_DEBUG_IMPL_CAM_SERIES(1, 0);
284 RTL_DEBUG_IMPL_CAM_SERIES(2, 11);
285 RTL_DEBUG_IMPL_CAM_SERIES(3, 22);
287 static int rtl_debug_get_btcoex(struct seq_file *m, void *v)
289 struct rtl_debugfs_priv *debugfs_priv = m->private;
290 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv;
292 if (rtlpriv->cfg->ops->get_btc_status())
293 rtlpriv->btcoexist.btc_ops->btc_display_bt_coex_info(rtlpriv,
296 seq_puts(m, "\n");
298 return 0;
301 static struct rtl_debugfs_priv rtl_debug_priv_btcoex = {
302 .cb_read = rtl_debug_get_btcoex,
303 .cb_data = 0,
306 static ssize_t rtl_debugfs_set_write_reg(struct file *filp,
307 const char __user *buffer,
308 size_t count, loff_t *loff)
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;
317 if (count < 3)
318 return -EFAULT;
320 tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
322 if (!buffer || copy_from_user(tmp, buffer, tmp_len))
323 return count;
325 tmp[tmp_len] = '\0';
327 /* write BB/MAC register */
328 num = sscanf(tmp, "%x %x %x", &addr, &val, &len);
330 if (num != 3)
331 return count;
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;
348 return count;
351 static struct rtl_debugfs_priv rtl_debug_priv_write_reg = {
352 .cb_write = rtl_debugfs_set_write_reg,
355 static ssize_t rtl_debugfs_set_write_h2c(struct file *filp,
356 const char __user *buffer,
357 size_t count, loff_t *loff)
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;
368 if (count < 3)
369 return -EFAULT;
371 tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
373 if (!buffer || copy_from_user(tmp, buffer, tmp_len))
374 return count;
376 tmp[tmp_len] = '\0';
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]);
384 if (h2c_len <= 0)
385 return count;
387 for (i = 0; i < h2c_len; i++)
388 h2c_data_packed[i] = (u8)h2c_data[i];
390 rtlpriv->cfg->ops->fill_h2c_cmd(hw, h2c_data_packed[0],
391 h2c_len - 1,
392 &h2c_data_packed[1]);
394 return count;
397 static struct rtl_debugfs_priv rtl_debug_priv_write_h2c = {
398 .cb_write = rtl_debugfs_set_write_h2c,
401 static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp,
402 const char __user *buffer,
403 size_t count, loff_t *loff)
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;
414 if (count < 3)
415 return -EFAULT;
417 tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count);
419 if (!buffer || copy_from_user(tmp, buffer, tmp_len))
420 return count;
422 tmp[tmp_len] = '\0';
424 num = sscanf(tmp, "%X %X %X %X",
425 &path, &addr, &bitmask, &data);
427 if (num != 4) {
428 RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
429 "Format is <path> <addr> <mask> <data>\n");
430 return count;
433 rtl_set_rfreg(hw, path, addr, bitmask, data);
435 return count;
438 static struct rtl_debugfs_priv rtl_debug_priv_write_rfreg = {
439 .cb_write = rtl_debugfs_set_write_rfreg,
442 static int rtl_debugfs_close(struct inode *inode, struct file *filp)
444 return 0;
447 static ssize_t rtl_debugfs_common_write(struct file *filp,
448 const char __user *buffer,
449 size_t count, loff_t *loff)
451 struct rtl_debugfs_priv *debugfs_priv = filp->private_data;
453 return debugfs_priv->cb_write(filp, buffer, count, loff);
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,
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)
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)
479 void rtl_debug_add_one(struct ieee80211_hw *hw)
481 struct rtl_priv *rtlpriv = rtl_priv(hw);
482 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
483 struct dentry *parent;
485 snprintf(rtlpriv->dbg.debugfs_name, 18, "%pMF", rtlefuse->dev_addr);
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;
495 parent = rtlpriv->dbg.debugfs_dir;
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);
532 RTL_DEBUGFS_ADD(cam_1);
533 RTL_DEBUGFS_ADD(cam_2);
534 RTL_DEBUGFS_ADD(cam_3);
536 RTL_DEBUGFS_ADD(btcoex);
538 RTL_DEBUGFS_ADD_W(write_reg);
539 RTL_DEBUGFS_ADD_W(write_h2c);
540 RTL_DEBUGFS_ADD_W(write_rfreg);
542 EXPORT_SYMBOL_GPL(rtl_debug_add_one);
544 void rtl_debug_remove_one(struct ieee80211_hw *hw)
546 struct rtl_priv *rtlpriv = rtl_priv(hw);
548 debugfs_remove_recursive(rtlpriv->dbg.debugfs_dir);
549 rtlpriv->dbg.debugfs_dir = NULL;
551 EXPORT_SYMBOL_GPL(rtl_debug_remove_one);
553 void rtl_debugfs_add_topdir(void)
555 debugfs_topdir = debugfs_create_dir("rtlwifi", NULL);
558 void rtl_debugfs_remove_topdir(void)
560 debugfs_remove_recursive(debugfs_topdir);
563 #endif