debug.c 14 KB

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