at v5.0-rc3 624 lines 16 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/****************************************************************************** 3 * 4 * Copyright(c) 2009-2012 Realtek Corporation. 5 * 6 * Contact Information: 7 * wlanfae <wlanfae@realtek.com> 8 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, 9 * Hsinchu 300, Taiwan. 10 * 11 * Larry Finger <Larry.Finger@lwfinger.net> 12 *****************************************************************************/ 13 14#include "wifi.h" 15#include "cam.h" 16 17#include <linux/moduleparam.h> 18#include <linux/vmalloc.h> 19 20#ifdef CONFIG_RTLWIFI_DEBUG_ST 21void _rtl_dbg_trace(struct rtl_priv *rtlpriv, u64 comp, int level, 22 const char *fmt, ...) 23{ 24 if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) && 25 level <= rtlpriv->cfg->mod_params->debug_level)) { 26 struct va_format vaf; 27 va_list args; 28 29 va_start(args, fmt); 30 31 vaf.fmt = fmt; 32 vaf.va = &args; 33 34 pr_info(":<%lx> %pV", in_interrupt(), &vaf); 35 36 va_end(args); 37 } 38} 39 40void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level, 41 const char *fmt, ...) 42{ 43 if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) && 44 level <= rtlpriv->cfg->mod_params->debug_level)) { 45 struct va_format vaf; 46 va_list args; 47 48 va_start(args, fmt); 49 50 vaf.fmt = fmt; 51 vaf.va = &args; 52 53 pr_info("%pV", &vaf); 54 55 va_end(args); 56 } 57} 58 59void _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 72struct 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 80static struct dentry *debugfs_topdir; 81 82static int rtl_debug_get_common(struct seq_file *m, void *v) 83{ 84 struct rtl_debugfs_priv *debugfs_priv = m->private; 85 86 return debugfs_priv->cb_read(m, v); 87} 88 89static int dl_debug_open_common(struct inode *inode, struct file *file) 90{ 91 return single_open(file, rtl_debug_get_common, inode->i_private); 92} 93 94static const struct file_operations file_ops_common = { 95 .open = dl_debug_open_common, 96 .read = seq_read, 97 .llseek = seq_lseek, 98 .release = single_release, 99}; 100 101static int rtl_debug_get_mac_page(struct seq_file *m, void *v) 102{ 103 struct rtl_debugfs_priv *debugfs_priv = m->private; 104 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; 105 u32 page = debugfs_priv->cb_data; 106 int i, n; 107 int max = 0xff; 108 109 for (n = 0; n <= max; ) { 110 seq_printf(m, "\n%8.8x ", n + page); 111 for (i = 0; i < 4 && n <= max; i++, n += 4) 112 seq_printf(m, "%8.8x ", 113 rtl_read_dword(rtlpriv, (page | n))); 114 } 115 seq_puts(m, "\n"); 116 return 0; 117} 118 119#define RTL_DEBUG_IMPL_MAC_SERIES(page, addr) \ 120static struct rtl_debugfs_priv rtl_debug_priv_mac_ ##page = { \ 121 .cb_read = rtl_debug_get_mac_page, \ 122 .cb_data = addr, \ 123} 124 125RTL_DEBUG_IMPL_MAC_SERIES(0, 0x0000); 126RTL_DEBUG_IMPL_MAC_SERIES(1, 0x0100); 127RTL_DEBUG_IMPL_MAC_SERIES(2, 0x0200); 128RTL_DEBUG_IMPL_MAC_SERIES(3, 0x0300); 129RTL_DEBUG_IMPL_MAC_SERIES(4, 0x0400); 130RTL_DEBUG_IMPL_MAC_SERIES(5, 0x0500); 131RTL_DEBUG_IMPL_MAC_SERIES(6, 0x0600); 132RTL_DEBUG_IMPL_MAC_SERIES(7, 0x0700); 133RTL_DEBUG_IMPL_MAC_SERIES(10, 0x1000); 134RTL_DEBUG_IMPL_MAC_SERIES(11, 0x1100); 135RTL_DEBUG_IMPL_MAC_SERIES(12, 0x1200); 136RTL_DEBUG_IMPL_MAC_SERIES(13, 0x1300); 137RTL_DEBUG_IMPL_MAC_SERIES(14, 0x1400); 138RTL_DEBUG_IMPL_MAC_SERIES(15, 0x1500); 139RTL_DEBUG_IMPL_MAC_SERIES(16, 0x1600); 140RTL_DEBUG_IMPL_MAC_SERIES(17, 0x1700); 141 142static int rtl_debug_get_bb_page(struct seq_file *m, void *v) 143{ 144 struct rtl_debugfs_priv *debugfs_priv = m->private; 145 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; 146 struct ieee80211_hw *hw = rtlpriv->hw; 147 u32 page = debugfs_priv->cb_data; 148 int i, n; 149 int max = 0xff; 150 151 for (n = 0; n <= max; ) { 152 seq_printf(m, "\n%8.8x ", n + page); 153 for (i = 0; i < 4 && n <= max; i++, n += 4) 154 seq_printf(m, "%8.8x ", 155 rtl_get_bbreg(hw, (page | n), 0xffffffff)); 156 } 157 seq_puts(m, "\n"); 158 return 0; 159} 160 161#define RTL_DEBUG_IMPL_BB_SERIES(page, addr) \ 162static struct rtl_debugfs_priv rtl_debug_priv_bb_ ##page = { \ 163 .cb_read = rtl_debug_get_bb_page, \ 164 .cb_data = addr, \ 165} 166 167RTL_DEBUG_IMPL_BB_SERIES(8, 0x0800); 168RTL_DEBUG_IMPL_BB_SERIES(9, 0x0900); 169RTL_DEBUG_IMPL_BB_SERIES(a, 0x0a00); 170RTL_DEBUG_IMPL_BB_SERIES(b, 0x0b00); 171RTL_DEBUG_IMPL_BB_SERIES(c, 0x0c00); 172RTL_DEBUG_IMPL_BB_SERIES(d, 0x0d00); 173RTL_DEBUG_IMPL_BB_SERIES(e, 0x0e00); 174RTL_DEBUG_IMPL_BB_SERIES(f, 0x0f00); 175RTL_DEBUG_IMPL_BB_SERIES(18, 0x1800); 176RTL_DEBUG_IMPL_BB_SERIES(19, 0x1900); 177RTL_DEBUG_IMPL_BB_SERIES(1a, 0x1a00); 178RTL_DEBUG_IMPL_BB_SERIES(1b, 0x1b00); 179RTL_DEBUG_IMPL_BB_SERIES(1c, 0x1c00); 180RTL_DEBUG_IMPL_BB_SERIES(1d, 0x1d00); 181RTL_DEBUG_IMPL_BB_SERIES(1e, 0x1e00); 182RTL_DEBUG_IMPL_BB_SERIES(1f, 0x1f00); 183 184static int rtl_debug_get_reg_rf(struct seq_file *m, void *v) 185{ 186 struct rtl_debugfs_priv *debugfs_priv = m->private; 187 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; 188 struct ieee80211_hw *hw = rtlpriv->hw; 189 enum radio_path rfpath = debugfs_priv->cb_data; 190 int i, n; 191 int max = 0x40; 192 193 if (IS_HARDWARE_TYPE_8822B(rtlpriv)) 194 max = 0xff; 195 196 seq_printf(m, "\nPATH(%d)", rfpath); 197 198 for (n = 0; n <= max; ) { 199 seq_printf(m, "\n%8.8x ", n); 200 for (i = 0; i < 4 && n <= max; n += 1, i++) 201 seq_printf(m, "%8.8x ", 202 rtl_get_rfreg(hw, rfpath, n, 0xffffffff)); 203 } 204 seq_puts(m, "\n"); 205 return 0; 206} 207 208#define RTL_DEBUG_IMPL_RF_SERIES(page, addr) \ 209static struct rtl_debugfs_priv rtl_debug_priv_rf_ ##page = { \ 210 .cb_read = rtl_debug_get_reg_rf, \ 211 .cb_data = addr, \ 212} 213 214RTL_DEBUG_IMPL_RF_SERIES(a, RF90_PATH_A); 215RTL_DEBUG_IMPL_RF_SERIES(b, RF90_PATH_B); 216 217static int rtl_debug_get_cam_register(struct seq_file *m, void *v) 218{ 219 struct rtl_debugfs_priv *debugfs_priv = m->private; 220 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; 221 int start = debugfs_priv->cb_data; 222 u32 target_cmd = 0; 223 u32 target_val = 0; 224 u8 entry_i = 0; 225 u32 ulstatus; 226 int i = 100, j = 0; 227 int end = (start + 11 > TOTAL_CAM_ENTRY ? TOTAL_CAM_ENTRY : start + 11); 228 229 /* This dump the current register page */ 230 seq_printf(m, 231 "\n#################### SECURITY CAM (%d-%d) ##################\n", 232 start, end - 1); 233 234 for (j = start; j < end; j++) { 235 seq_printf(m, "\nD: %2x > ", j); 236 for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { 237 /* polling bit, and No Write enable, and address */ 238 target_cmd = entry_i + CAM_CONTENT_COUNT * j; 239 target_cmd = target_cmd | BIT(31); 240 241 /* Check polling bit is clear */ 242 while ((i--) >= 0) { 243 ulstatus = rtl_read_dword( 244 rtlpriv, 245 rtlpriv->cfg->maps[RWCAM]); 246 if (ulstatus & BIT(31)) 247 continue; 248 else 249 break; 250 } 251 252 rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], 253 target_cmd); 254 target_val = rtl_read_dword(rtlpriv, 255 rtlpriv->cfg->maps[RCAMO]); 256 seq_printf(m, "%8.8x ", target_val); 257 } 258 } 259 seq_puts(m, "\n"); 260 return 0; 261} 262 263#define RTL_DEBUG_IMPL_CAM_SERIES(page, addr) \ 264static struct rtl_debugfs_priv rtl_debug_priv_cam_ ##page = { \ 265 .cb_read = rtl_debug_get_cam_register, \ 266 .cb_data = addr, \ 267} 268 269RTL_DEBUG_IMPL_CAM_SERIES(1, 0); 270RTL_DEBUG_IMPL_CAM_SERIES(2, 11); 271RTL_DEBUG_IMPL_CAM_SERIES(3, 22); 272 273static int rtl_debug_get_btcoex(struct seq_file *m, void *v) 274{ 275 struct rtl_debugfs_priv *debugfs_priv = m->private; 276 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; 277 278 if (rtlpriv->cfg->ops->get_btc_status()) 279 rtlpriv->btcoexist.btc_ops->btc_display_bt_coex_info(rtlpriv, 280 m); 281 282 seq_puts(m, "\n"); 283 284 return 0; 285} 286 287static struct rtl_debugfs_priv rtl_debug_priv_btcoex = { 288 .cb_read = rtl_debug_get_btcoex, 289 .cb_data = 0, 290}; 291 292static ssize_t rtl_debugfs_set_write_reg(struct file *filp, 293 const char __user *buffer, 294 size_t count, loff_t *loff) 295{ 296 struct rtl_debugfs_priv *debugfs_priv = filp->private_data; 297 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; 298 char tmp[32 + 1]; 299 int tmp_len; 300 u32 addr, val, len; 301 int num; 302 303 if (count < 3) 304 return -EFAULT; 305 306 tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count); 307 308 if (!buffer || copy_from_user(tmp, buffer, tmp_len)) 309 return count; 310 311 tmp[tmp_len] = '\0'; 312 313 /* write BB/MAC register */ 314 num = sscanf(tmp, "%x %x %x", &addr, &val, &len); 315 316 if (num != 3) 317 return count; 318 319 switch (len) { 320 case 1: 321 rtl_write_byte(rtlpriv, addr, (u8)val); 322 break; 323 case 2: 324 rtl_write_word(rtlpriv, addr, (u16)val); 325 break; 326 case 4: 327 rtl_write_dword(rtlpriv, addr, val); 328 break; 329 default: 330 /*printk("error write length=%d", len);*/ 331 break; 332 } 333 334 return count; 335} 336 337static struct rtl_debugfs_priv rtl_debug_priv_write_reg = { 338 .cb_write = rtl_debugfs_set_write_reg, 339}; 340 341static ssize_t rtl_debugfs_set_write_h2c(struct file *filp, 342 const char __user *buffer, 343 size_t count, loff_t *loff) 344{ 345 struct rtl_debugfs_priv *debugfs_priv = filp->private_data; 346 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; 347 struct ieee80211_hw *hw = rtlpriv->hw; 348 char tmp[32 + 1]; 349 int tmp_len; 350 u8 h2c_len, h2c_data_packed[8]; 351 int h2c_data[8]; /* idx 0: cmd */ 352 int i; 353 354 if (count < 3) 355 return -EFAULT; 356 357 tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count); 358 359 if (!buffer || copy_from_user(tmp, buffer, tmp_len)) 360 return count; 361 362 tmp[tmp_len] = '\0'; 363 364 h2c_len = sscanf(tmp, "%X %X %X %X %X %X %X %X", 365 &h2c_data[0], &h2c_data[1], 366 &h2c_data[2], &h2c_data[3], 367 &h2c_data[4], &h2c_data[5], 368 &h2c_data[6], &h2c_data[7]); 369 370 if (h2c_len <= 0) 371 return count; 372 373 for (i = 0; i < h2c_len; i++) 374 h2c_data_packed[i] = (u8)h2c_data[i]; 375 376 rtlpriv->cfg->ops->fill_h2c_cmd(hw, h2c_data_packed[0], 377 h2c_len - 1, 378 &h2c_data_packed[1]); 379 380 return count; 381} 382 383static struct rtl_debugfs_priv rtl_debug_priv_write_h2c = { 384 .cb_write = rtl_debugfs_set_write_h2c, 385}; 386 387static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp, 388 const char __user *buffer, 389 size_t count, loff_t *loff) 390{ 391 struct rtl_debugfs_priv *debugfs_priv = filp->private_data; 392 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; 393 struct ieee80211_hw *hw = rtlpriv->hw; 394 char tmp[32 + 1]; 395 int tmp_len; 396 int num; 397 int path; 398 u32 addr, bitmask, data; 399 400 if (count < 3) 401 return -EFAULT; 402 403 tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count); 404 405 if (!buffer || copy_from_user(tmp, buffer, tmp_len)) 406 return count; 407 408 tmp[tmp_len] = '\0'; 409 410 num = sscanf(tmp, "%X %X %X %X", 411 &path, &addr, &bitmask, &data); 412 413 if (num != 4) { 414 RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, 415 "Format is <path> <addr> <mask> <data>\n"); 416 return count; 417 } 418 419 rtl_set_rfreg(hw, path, addr, bitmask, data); 420 421 return count; 422} 423 424static struct rtl_debugfs_priv rtl_debug_priv_write_rfreg = { 425 .cb_write = rtl_debugfs_set_write_rfreg, 426}; 427 428static int rtl_debugfs_close(struct inode *inode, struct file *filp) 429{ 430 return 0; 431} 432 433static ssize_t rtl_debugfs_common_write(struct file *filp, 434 const char __user *buffer, 435 size_t count, loff_t *loff) 436{ 437 struct rtl_debugfs_priv *debugfs_priv = filp->private_data; 438 439 return debugfs_priv->cb_write(filp, buffer, count, loff); 440} 441 442static const struct file_operations file_ops_common_write = { 443 .owner = THIS_MODULE, 444 .write = rtl_debugfs_common_write, 445 .open = simple_open, 446 .release = rtl_debugfs_close, 447}; 448 449static ssize_t rtl_debugfs_phydm_cmd(struct file *filp, 450 const char __user *buffer, 451 size_t count, loff_t *loff) 452{ 453 struct rtl_debugfs_priv *debugfs_priv = filp->private_data; 454 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; 455 456 char tmp[64]; 457 458 if (!rtlpriv->dbg.msg_buf) 459 return -ENOMEM; 460 461 if (!rtlpriv->phydm.ops) 462 return -EFAULT; 463 464 if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { 465 tmp[count] = '\0'; 466 467 rtlpriv->phydm.ops->phydm_debug_cmd(rtlpriv, tmp, count, 468 rtlpriv->dbg.msg_buf, 469 80 * 25); 470 } 471 472 return count; 473} 474 475static int rtl_debug_get_phydm_cmd(struct seq_file *m, void *v) 476{ 477 struct rtl_debugfs_priv *debugfs_priv = m->private; 478 struct rtl_priv *rtlpriv = debugfs_priv->rtlpriv; 479 480 if (rtlpriv->dbg.msg_buf) 481 seq_puts(m, rtlpriv->dbg.msg_buf); 482 483 return 0; 484} 485 486static int rtl_debugfs_open_rw(struct inode *inode, struct file *filp) 487{ 488 int ret = 0; 489 490 if (filp->f_mode & FMODE_READ) 491 ret = single_open(filp, rtl_debug_get_common, inode->i_private); 492 else 493 filp->private_data = inode->i_private; 494 495 return ret; 496} 497 498static int rtl_debugfs_close_rw(struct inode *inode, struct file *filp) 499{ 500 if (filp->f_mode == FMODE_READ) 501 single_release(inode, filp); 502 503 return 0; 504} 505 506static struct rtl_debugfs_priv rtl_debug_priv_phydm_cmd = { 507 .cb_read = rtl_debug_get_phydm_cmd, 508 .cb_write = rtl_debugfs_phydm_cmd, 509 .cb_data = 0, 510}; 511 512static const struct file_operations file_ops_common_rw = { 513 .owner = THIS_MODULE, 514 .open = rtl_debugfs_open_rw, 515 .release = rtl_debugfs_close_rw, 516 .read = seq_read, 517 .llseek = seq_lseek, 518 .write = rtl_debugfs_common_write, 519}; 520 521#define RTL_DEBUGFS_ADD_CORE(name, mode, fopname) \ 522 do { \ 523 rtl_debug_priv_ ##name.rtlpriv = rtlpriv; \ 524 debugfs_create_file(#name, mode, parent, \ 525 &rtl_debug_priv_ ##name, \ 526 &file_ops_ ##fopname); \ 527 } while (0) 528 529#define RTL_DEBUGFS_ADD(name) \ 530 RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0444, common) 531#define RTL_DEBUGFS_ADD_W(name) \ 532 RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0222, common_write) 533#define RTL_DEBUGFS_ADD_RW(name) \ 534 RTL_DEBUGFS_ADD_CORE(name, S_IFREG | 0666, common_rw) 535 536void rtl_debug_add_one(struct ieee80211_hw *hw) 537{ 538 struct rtl_priv *rtlpriv = rtl_priv(hw); 539 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 540 struct dentry *parent; 541 542 rtlpriv->dbg.msg_buf = vzalloc(80 * 25); 543 544 snprintf(rtlpriv->dbg.debugfs_name, 18, "%pMF", rtlefuse->dev_addr); 545 546 rtlpriv->dbg.debugfs_dir = 547 debugfs_create_dir(rtlpriv->dbg.debugfs_name, debugfs_topdir); 548 if (!rtlpriv->dbg.debugfs_dir) { 549 pr_err("Unable to init debugfs:/%s/%s\n", rtlpriv->cfg->name, 550 rtlpriv->dbg.debugfs_name); 551 return; 552 } 553 554 parent = rtlpriv->dbg.debugfs_dir; 555 556 RTL_DEBUGFS_ADD(mac_0); 557 RTL_DEBUGFS_ADD(mac_1); 558 RTL_DEBUGFS_ADD(mac_2); 559 RTL_DEBUGFS_ADD(mac_3); 560 RTL_DEBUGFS_ADD(mac_4); 561 RTL_DEBUGFS_ADD(mac_5); 562 RTL_DEBUGFS_ADD(mac_6); 563 RTL_DEBUGFS_ADD(mac_7); 564 RTL_DEBUGFS_ADD(bb_8); 565 RTL_DEBUGFS_ADD(bb_9); 566 RTL_DEBUGFS_ADD(bb_a); 567 RTL_DEBUGFS_ADD(bb_b); 568 RTL_DEBUGFS_ADD(bb_c); 569 RTL_DEBUGFS_ADD(bb_d); 570 RTL_DEBUGFS_ADD(bb_e); 571 RTL_DEBUGFS_ADD(bb_f); 572 RTL_DEBUGFS_ADD(mac_10); 573 RTL_DEBUGFS_ADD(mac_11); 574 RTL_DEBUGFS_ADD(mac_12); 575 RTL_DEBUGFS_ADD(mac_13); 576 RTL_DEBUGFS_ADD(mac_14); 577 RTL_DEBUGFS_ADD(mac_15); 578 RTL_DEBUGFS_ADD(mac_16); 579 RTL_DEBUGFS_ADD(mac_17); 580 RTL_DEBUGFS_ADD(bb_18); 581 RTL_DEBUGFS_ADD(bb_19); 582 RTL_DEBUGFS_ADD(bb_1a); 583 RTL_DEBUGFS_ADD(bb_1b); 584 RTL_DEBUGFS_ADD(bb_1c); 585 RTL_DEBUGFS_ADD(bb_1d); 586 RTL_DEBUGFS_ADD(bb_1e); 587 RTL_DEBUGFS_ADD(bb_1f); 588 RTL_DEBUGFS_ADD(rf_a); 589 RTL_DEBUGFS_ADD(rf_b); 590 591 RTL_DEBUGFS_ADD(cam_1); 592 RTL_DEBUGFS_ADD(cam_2); 593 RTL_DEBUGFS_ADD(cam_3); 594 595 RTL_DEBUGFS_ADD(btcoex); 596 597 RTL_DEBUGFS_ADD_W(write_reg); 598 RTL_DEBUGFS_ADD_W(write_h2c); 599 RTL_DEBUGFS_ADD_W(write_rfreg); 600 601 RTL_DEBUGFS_ADD_RW(phydm_cmd); 602} 603 604void rtl_debug_remove_one(struct ieee80211_hw *hw) 605{ 606 struct rtl_priv *rtlpriv = rtl_priv(hw); 607 608 debugfs_remove_recursive(rtlpriv->dbg.debugfs_dir); 609 rtlpriv->dbg.debugfs_dir = NULL; 610 611 vfree(rtlpriv->dbg.msg_buf); 612} 613 614void rtl_debugfs_add_topdir(void) 615{ 616 debugfs_topdir = debugfs_create_dir("rtlwifi", NULL); 617} 618 619void rtl_debugfs_remove_topdir(void) 620{ 621 debugfs_remove_recursive(debugfs_topdir); 622} 623 624#endif