GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / net / wireless / realtek / rtlwifi / debug.c
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 = single_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 (copy_from_user(tmp, buffer, tmp_len))
323                 return -EFAULT;
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 -EINVAL;
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 (copy_from_user(tmp, buffer, tmp_len))
374                 return -EFAULT;
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 -EINVAL;
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 (copy_from_user(tmp, buffer, tmp_len))
420                 return -EFAULT;
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                 rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG,
429                         "Format is <path> <addr> <mask> <data>\n");
430                 return -EINVAL;
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