1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> 4 <http://rt2x00.serialmonkey.com> 5 6 */ 7 8 /* 9 Module: rt2x00lib 10 Abstract: rt2x00 debugfs specific routines. 11 */ 12 13 #include <linux/debugfs.h> 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/poll.h> 17 #include <linux/sched.h> 18 #include <linux/slab.h> 19 #include <linux/uaccess.h> 20 21 #include "rt2x00.h" 22 #include "rt2x00lib.h" 23 #include "rt2x00dump.h" 24 25 #define MAX_LINE_LENGTH 64 26 27 struct rt2x00debug_crypto { 28 unsigned long success; 29 unsigned long icv_error; 30 unsigned long mic_error; 31 unsigned long key_error; 32 }; 33 34 struct rt2x00debug_intf { 35 /* 36 * Pointer to driver structure where 37 * this debugfs entry belongs to. 38 */ 39 struct rt2x00_dev *rt2x00dev; 40 41 /* 42 * Reference to the rt2x00debug structure 43 * which can be used to communicate with 44 * the registers. 45 */ 46 const struct rt2x00debug *debug; 47 48 /* 49 * Debugfs entries for: 50 * - driver folder 51 * - driver file 52 * - chipset file 53 * - device state flags file 54 * - device capability flags file 55 * - hardware restart file 56 * - register folder 57 * - csr offset/value files 58 * - eeprom offset/value files 59 * - bbp offset/value files 60 * - rf offset/value files 61 * - rfcsr offset/value files 62 * - queue folder 63 * - frame dump file 64 * - queue stats file 65 * - crypto stats file 66 */ 67 struct dentry *driver_folder; 68 69 /* 70 * The frame dump file only allows a single reader, 71 * so we need to store the current state here. 72 */ 73 unsigned long frame_dump_flags; 74 #define FRAME_DUMP_FILE_OPEN 1 75 76 /* 77 * We queue each frame before dumping it to the user, 78 * per read command we will pass a single skb structure 79 * so we should be prepared to queue multiple sk buffers 80 * before sending it to userspace. 81 */ 82 struct sk_buff_head frame_dump_skbqueue; 83 wait_queue_head_t frame_dump_waitqueue; 84 85 /* 86 * HW crypto statistics. 87 * All statistics are stored separately per cipher type. 88 */ 89 struct rt2x00debug_crypto crypto_stats[CIPHER_MAX]; 90 91 /* 92 * Driver and chipset files will use a data buffer 93 * that has been created in advance. This will simplify 94 * the code since we can use the debugfs functions. 95 */ 96 struct debugfs_blob_wrapper driver_blob; 97 struct debugfs_blob_wrapper chipset_blob; 98 99 /* 100 * Requested offset for each register type. 101 */ 102 unsigned int offset_csr; 103 unsigned int offset_eeprom; 104 unsigned int offset_bbp; 105 unsigned int offset_rf; 106 unsigned int offset_rfcsr; 107 }; 108 109 void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, 110 struct rxdone_entry_desc *rxdesc) 111 { 112 struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf; 113 enum cipher cipher = rxdesc->cipher; 114 enum rx_crypto status = rxdesc->cipher_status; 115 116 if (cipher == CIPHER_TKIP_NO_MIC) 117 cipher = CIPHER_TKIP; 118 if (cipher == CIPHER_NONE || cipher >= CIPHER_MAX) 119 return; 120 121 /* Remove CIPHER_NONE index */ 122 cipher--; 123 124 intf->crypto_stats[cipher].success += (status == RX_CRYPTO_SUCCESS); 125 intf->crypto_stats[cipher].icv_error += (status == RX_CRYPTO_FAIL_ICV); 126 intf->crypto_stats[cipher].mic_error += (status == RX_CRYPTO_FAIL_MIC); 127 intf->crypto_stats[cipher].key_error += (status == RX_CRYPTO_FAIL_KEY); 128 } 129 130 void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, 131 enum rt2x00_dump_type type, struct queue_entry *entry) 132 { 133 struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf; 134 struct sk_buff *skb = entry->skb; 135 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 136 struct sk_buff *skbcopy; 137 struct rt2x00dump_hdr *dump_hdr; 138 struct timespec64 timestamp; 139 u32 data_len; 140 141 if (likely(!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))) 142 return; 143 144 ktime_get_ts64(×tamp); 145 146 if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) { 147 rt2x00_dbg(rt2x00dev, "txrx dump queue length exceeded\n"); 148 return; 149 } 150 151 data_len = skb->len; 152 if (skbdesc->flags & SKBDESC_DESC_IN_SKB) 153 data_len -= skbdesc->desc_len; 154 155 skbcopy = alloc_skb(sizeof(*dump_hdr) + skbdesc->desc_len + data_len, 156 GFP_ATOMIC); 157 if (!skbcopy) { 158 rt2x00_dbg(rt2x00dev, "Failed to copy skb for dump\n"); 159 return; 160 } 161 162 dump_hdr = skb_put(skbcopy, sizeof(*dump_hdr)); 163 dump_hdr->version = cpu_to_le32(DUMP_HEADER_VERSION); 164 dump_hdr->header_length = cpu_to_le32(sizeof(*dump_hdr)); 165 dump_hdr->desc_length = cpu_to_le32(skbdesc->desc_len); 166 dump_hdr->data_length = cpu_to_le32(data_len); 167 dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt); 168 dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf); 169 dump_hdr->chip_rev = cpu_to_le16(rt2x00dev->chip.rev); 170 dump_hdr->type = cpu_to_le16(type); 171 dump_hdr->queue_index = entry->queue->qid; 172 dump_hdr->entry_index = entry->entry_idx; 173 dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec); 174 dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_nsec / 175 NSEC_PER_USEC); 176 177 if (!(skbdesc->flags & SKBDESC_DESC_IN_SKB)) 178 skb_put_data(skbcopy, skbdesc->desc, skbdesc->desc_len); 179 skb_put_data(skbcopy, skb->data, skb->len); 180 181 skb_queue_tail(&intf->frame_dump_skbqueue, skbcopy); 182 wake_up_interruptible(&intf->frame_dump_waitqueue); 183 184 /* 185 * Verify that the file has not been closed while we were working. 186 */ 187 if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)) 188 skb_queue_purge(&intf->frame_dump_skbqueue); 189 } 190 EXPORT_SYMBOL_GPL(rt2x00debug_dump_frame); 191 192 static int rt2x00debug_file_open(struct inode *inode, struct file *file) 193 { 194 struct rt2x00debug_intf *intf = inode->i_private; 195 196 file->private_data = inode->i_private; 197 198 if (!try_module_get(intf->debug->owner)) 199 return -EBUSY; 200 201 return 0; 202 } 203 204 static int rt2x00debug_file_release(struct inode *inode, struct file *file) 205 { 206 struct rt2x00debug_intf *intf = file->private_data; 207 208 module_put(intf->debug->owner); 209 210 return 0; 211 } 212 213 static int rt2x00debug_open_queue_dump(struct inode *inode, struct file *file) 214 { 215 struct rt2x00debug_intf *intf = inode->i_private; 216 int retval; 217 218 retval = rt2x00debug_file_open(inode, file); 219 if (retval) 220 return retval; 221 222 if (test_and_set_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)) { 223 rt2x00debug_file_release(inode, file); 224 return -EBUSY; 225 } 226 227 return 0; 228 } 229 230 static int rt2x00debug_release_queue_dump(struct inode *inode, struct file *file) 231 { 232 struct rt2x00debug_intf *intf = inode->i_private; 233 234 skb_queue_purge(&intf->frame_dump_skbqueue); 235 236 clear_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags); 237 238 return rt2x00debug_file_release(inode, file); 239 } 240 241 static ssize_t rt2x00debug_read_queue_dump(struct file *file, 242 char __user *buf, 243 size_t length, 244 loff_t *offset) 245 { 246 struct rt2x00debug_intf *intf = file->private_data; 247 struct sk_buff *skb; 248 size_t status; 249 int retval; 250 251 if (file->f_flags & O_NONBLOCK) 252 return -EAGAIN; 253 254 retval = 255 wait_event_interruptible(intf->frame_dump_waitqueue, 256 (skb = 257 skb_dequeue(&intf->frame_dump_skbqueue))); 258 if (retval) 259 return retval; 260 261 status = min_t(size_t, skb->len, length); 262 if (copy_to_user(buf, skb->data, status)) { 263 status = -EFAULT; 264 goto exit; 265 } 266 267 *offset += status; 268 269 exit: 270 kfree_skb(skb); 271 272 return status; 273 } 274 275 static __poll_t rt2x00debug_poll_queue_dump(struct file *file, 276 poll_table *wait) 277 { 278 struct rt2x00debug_intf *intf = file->private_data; 279 280 poll_wait(file, &intf->frame_dump_waitqueue, wait); 281 282 if (!skb_queue_empty(&intf->frame_dump_skbqueue)) 283 return EPOLLOUT | EPOLLWRNORM; 284 285 return 0; 286 } 287 288 static const struct file_operations rt2x00debug_fop_queue_dump = { 289 .owner = THIS_MODULE, 290 .read = rt2x00debug_read_queue_dump, 291 .poll = rt2x00debug_poll_queue_dump, 292 .open = rt2x00debug_open_queue_dump, 293 .release = rt2x00debug_release_queue_dump, 294 .llseek = default_llseek, 295 }; 296 297 static ssize_t rt2x00debug_read_queue_stats(struct file *file, 298 char __user *buf, 299 size_t length, 300 loff_t *offset) 301 { 302 struct rt2x00debug_intf *intf = file->private_data; 303 struct data_queue *queue; 304 unsigned long irqflags; 305 unsigned int lines = 1 + intf->rt2x00dev->data_queues; 306 size_t size; 307 char *data; 308 char *temp; 309 310 if (*offset) 311 return 0; 312 313 data = kcalloc(lines, MAX_LINE_LENGTH, GFP_KERNEL); 314 if (!data) 315 return -ENOMEM; 316 317 temp = data + 318 sprintf(data, "qid\tflags\t\tcount\tlimit\tlength\tindex\tdma done\tdone\n"); 319 320 queue_for_each(intf->rt2x00dev, queue) { 321 spin_lock_irqsave(&queue->index_lock, irqflags); 322 323 temp += sprintf(temp, "%d\t0x%.8x\t%d\t%d\t%d\t%d\t%d\t\t%d\n", 324 queue->qid, (unsigned int)queue->flags, 325 queue->count, queue->limit, queue->length, 326 queue->index[Q_INDEX], 327 queue->index[Q_INDEX_DMA_DONE], 328 queue->index[Q_INDEX_DONE]); 329 330 spin_unlock_irqrestore(&queue->index_lock, irqflags); 331 } 332 333 size = strlen(data); 334 size = min(size, length); 335 336 if (copy_to_user(buf, data, size)) { 337 kfree(data); 338 return -EFAULT; 339 } 340 341 kfree(data); 342 343 *offset += size; 344 return size; 345 } 346 347 static const struct file_operations rt2x00debug_fop_queue_stats = { 348 .owner = THIS_MODULE, 349 .read = rt2x00debug_read_queue_stats, 350 .open = rt2x00debug_file_open, 351 .release = rt2x00debug_file_release, 352 .llseek = default_llseek, 353 }; 354 355 #ifdef CONFIG_RT2X00_LIB_CRYPTO 356 static ssize_t rt2x00debug_read_crypto_stats(struct file *file, 357 char __user *buf, 358 size_t length, 359 loff_t *offset) 360 { 361 struct rt2x00debug_intf *intf = file->private_data; 362 static const char * const name[] = { "WEP64", "WEP128", "TKIP", "AES" }; 363 char *data; 364 char *temp; 365 size_t size; 366 unsigned int i; 367 368 if (*offset) 369 return 0; 370 371 data = kcalloc(1 + CIPHER_MAX, MAX_LINE_LENGTH, GFP_KERNEL); 372 if (!data) 373 return -ENOMEM; 374 375 temp = data; 376 temp += sprintf(data, "cipher\tsuccess\ticv err\tmic err\tkey err\n"); 377 378 for (i = 0; i < CIPHER_MAX; i++) { 379 temp += sprintf(temp, "%s\t%lu\t%lu\t%lu\t%lu\n", name[i], 380 intf->crypto_stats[i].success, 381 intf->crypto_stats[i].icv_error, 382 intf->crypto_stats[i].mic_error, 383 intf->crypto_stats[i].key_error); 384 } 385 386 size = strlen(data); 387 size = min(size, length); 388 389 if (copy_to_user(buf, data, size)) { 390 kfree(data); 391 return -EFAULT; 392 } 393 394 kfree(data); 395 396 *offset += size; 397 return size; 398 } 399 400 static const struct file_operations rt2x00debug_fop_crypto_stats = { 401 .owner = THIS_MODULE, 402 .read = rt2x00debug_read_crypto_stats, 403 .open = rt2x00debug_file_open, 404 .release = rt2x00debug_file_release, 405 .llseek = default_llseek, 406 }; 407 #endif 408 409 #define RT2X00DEBUGFS_OPS_READ(__name, __format, __type) \ 410 static ssize_t rt2x00debug_read_##__name(struct file *file, \ 411 char __user *buf, \ 412 size_t length, \ 413 loff_t *offset) \ 414 { \ 415 struct rt2x00debug_intf *intf = file->private_data; \ 416 const struct rt2x00debug *debug = intf->debug; \ 417 char line[16]; \ 418 size_t size; \ 419 unsigned int index = intf->offset_##__name; \ 420 __type value; \ 421 \ 422 if (*offset) \ 423 return 0; \ 424 \ 425 if (index >= debug->__name.word_count) \ 426 return -EINVAL; \ 427 \ 428 index += (debug->__name.word_base / \ 429 debug->__name.word_size); \ 430 \ 431 if (debug->__name.flags & RT2X00DEBUGFS_OFFSET) \ 432 index *= debug->__name.word_size; \ 433 \ 434 value = debug->__name.read(intf->rt2x00dev, index); \ 435 \ 436 size = sprintf(line, __format, value); \ 437 \ 438 return simple_read_from_buffer(buf, length, offset, line, size); \ 439 } 440 441 #define RT2X00DEBUGFS_OPS_WRITE(__name, __type) \ 442 static ssize_t rt2x00debug_write_##__name(struct file *file, \ 443 const char __user *buf,\ 444 size_t length, \ 445 loff_t *offset) \ 446 { \ 447 struct rt2x00debug_intf *intf = file->private_data; \ 448 const struct rt2x00debug *debug = intf->debug; \ 449 char line[17]; \ 450 size_t size; \ 451 unsigned int index = intf->offset_##__name; \ 452 __type value; \ 453 \ 454 if (*offset) \ 455 return 0; \ 456 \ 457 if (index >= debug->__name.word_count) \ 458 return -EINVAL; \ 459 \ 460 if (length > sizeof(line)) \ 461 return -EINVAL; \ 462 \ 463 if (copy_from_user(line, buf, length)) \ 464 return -EFAULT; \ 465 line[16] = 0; \ 466 \ 467 size = strlen(line); \ 468 value = simple_strtoul(line, NULL, 0); \ 469 \ 470 index += (debug->__name.word_base / \ 471 debug->__name.word_size); \ 472 \ 473 if (debug->__name.flags & RT2X00DEBUGFS_OFFSET) \ 474 index *= debug->__name.word_size; \ 475 \ 476 debug->__name.write(intf->rt2x00dev, index, value); \ 477 \ 478 *offset += size; \ 479 return size; \ 480 } 481 482 #define RT2X00DEBUGFS_OPS(__name, __format, __type) \ 483 RT2X00DEBUGFS_OPS_READ(__name, __format, __type); \ 484 RT2X00DEBUGFS_OPS_WRITE(__name, __type); \ 485 \ 486 static const struct file_operations rt2x00debug_fop_##__name = {\ 487 .owner = THIS_MODULE, \ 488 .read = rt2x00debug_read_##__name, \ 489 .write = rt2x00debug_write_##__name, \ 490 .open = rt2x00debug_file_open, \ 491 .release = rt2x00debug_file_release, \ 492 .llseek = generic_file_llseek, \ 493 }; 494 495 RT2X00DEBUGFS_OPS(csr, "0x%.8x\n", u32); 496 RT2X00DEBUGFS_OPS(eeprom, "0x%.4x\n", u16); 497 RT2X00DEBUGFS_OPS(bbp, "0x%.2x\n", u8); 498 RT2X00DEBUGFS_OPS(rf, "0x%.8x\n", u32); 499 RT2X00DEBUGFS_OPS(rfcsr, "0x%.2x\n", u8); 500 501 static ssize_t rt2x00debug_read_dev_flags(struct file *file, 502 char __user *buf, 503 size_t length, 504 loff_t *offset) 505 { 506 struct rt2x00debug_intf *intf = file->private_data; 507 char line[16]; 508 size_t size; 509 510 if (*offset) 511 return 0; 512 513 size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->flags); 514 515 return simple_read_from_buffer(buf, length, offset, line, size); 516 } 517 518 static const struct file_operations rt2x00debug_fop_dev_flags = { 519 .owner = THIS_MODULE, 520 .read = rt2x00debug_read_dev_flags, 521 .open = rt2x00debug_file_open, 522 .release = rt2x00debug_file_release, 523 .llseek = default_llseek, 524 }; 525 526 static ssize_t rt2x00debug_read_cap_flags(struct file *file, 527 char __user *buf, 528 size_t length, 529 loff_t *offset) 530 { 531 struct rt2x00debug_intf *intf = file->private_data; 532 char line[16]; 533 size_t size; 534 535 if (*offset) 536 return 0; 537 538 size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->cap_flags); 539 540 return simple_read_from_buffer(buf, length, offset, line, size); 541 } 542 543 static const struct file_operations rt2x00debug_fop_cap_flags = { 544 .owner = THIS_MODULE, 545 .read = rt2x00debug_read_cap_flags, 546 .open = rt2x00debug_file_open, 547 .release = rt2x00debug_file_release, 548 .llseek = default_llseek, 549 }; 550 551 static ssize_t rt2x00debug_write_restart_hw(struct file *file, 552 const char __user *buf, 553 size_t length, 554 loff_t *offset) 555 { 556 struct rt2x00debug_intf *intf = file->private_data; 557 struct rt2x00_dev *rt2x00dev = intf->rt2x00dev; 558 static unsigned long last_reset; 559 560 if (!rt2x00_has_cap_restart_hw(rt2x00dev)) 561 return -EOPNOTSUPP; 562 563 if (time_before(jiffies, last_reset + msecs_to_jiffies(2000))) 564 return -EBUSY; 565 566 last_reset = jiffies; 567 568 ieee80211_restart_hw(rt2x00dev->hw); 569 return length; 570 } 571 572 static const struct file_operations rt2x00debug_restart_hw = { 573 .owner = THIS_MODULE, 574 .write = rt2x00debug_write_restart_hw, 575 .open = simple_open, 576 .llseek = generic_file_llseek, 577 }; 578 579 static void rt2x00debug_create_file_driver(const char *name, 580 struct rt2x00debug_intf *intf, 581 struct debugfs_blob_wrapper *blob) 582 { 583 char *data; 584 585 data = kzalloc(3 * MAX_LINE_LENGTH, GFP_KERNEL); 586 if (!data) 587 return; 588 589 blob->data = data; 590 data += sprintf(data, "driver:\t%s\n", intf->rt2x00dev->ops->name); 591 data += sprintf(data, "version:\t%s\n", DRV_VERSION); 592 blob->size = strlen(blob->data); 593 594 debugfs_create_blob(name, 0400, intf->driver_folder, blob); 595 } 596 597 static void rt2x00debug_create_file_chipset(const char *name, 598 struct rt2x00debug_intf *intf, 599 struct debugfs_blob_wrapper *blob) 600 { 601 const struct rt2x00debug *debug = intf->debug; 602 char *data; 603 604 data = kzalloc(9 * MAX_LINE_LENGTH, GFP_KERNEL); 605 if (!data) 606 return; 607 608 blob->data = data; 609 data += sprintf(data, "rt chip:\t%04x\n", intf->rt2x00dev->chip.rt); 610 data += sprintf(data, "rf chip:\t%04x\n", intf->rt2x00dev->chip.rf); 611 data += sprintf(data, "revision:\t%04x\n", intf->rt2x00dev->chip.rev); 612 data += sprintf(data, "\n"); 613 data += sprintf(data, "register\tbase\twords\twordsize\n"); 614 #define RT2X00DEBUGFS_SPRINTF_REGISTER(__name) \ 615 { \ 616 if (debug->__name.read) \ 617 data += sprintf(data, __stringify(__name) \ 618 "\t%d\t%d\t%d\n", \ 619 debug->__name.word_base, \ 620 debug->__name.word_count, \ 621 debug->__name.word_size); \ 622 } 623 RT2X00DEBUGFS_SPRINTF_REGISTER(csr); 624 RT2X00DEBUGFS_SPRINTF_REGISTER(eeprom); 625 RT2X00DEBUGFS_SPRINTF_REGISTER(bbp); 626 RT2X00DEBUGFS_SPRINTF_REGISTER(rf); 627 RT2X00DEBUGFS_SPRINTF_REGISTER(rfcsr); 628 #undef RT2X00DEBUGFS_SPRINTF_REGISTER 629 630 blob->size = strlen(blob->data); 631 632 debugfs_create_blob(name, 0400, intf->driver_folder, blob); 633 } 634 635 void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) 636 { 637 const struct rt2x00debug *debug = rt2x00dev->ops->debugfs; 638 struct rt2x00debug_intf *intf; 639 struct dentry *queue_folder; 640 struct dentry *register_folder; 641 642 intf = kzalloc(sizeof(struct rt2x00debug_intf), GFP_KERNEL); 643 if (!intf) { 644 rt2x00_err(rt2x00dev, "Failed to allocate debug handler\n"); 645 return; 646 } 647 648 intf->debug = debug; 649 intf->rt2x00dev = rt2x00dev; 650 rt2x00dev->debugfs_intf = intf; 651 652 intf->driver_folder = 653 debugfs_create_dir(intf->rt2x00dev->ops->name, 654 rt2x00dev->hw->wiphy->debugfsdir); 655 656 rt2x00debug_create_file_driver("driver", intf, &intf->driver_blob); 657 rt2x00debug_create_file_chipset("chipset", intf, &intf->chipset_blob); 658 debugfs_create_file("dev_flags", 0400, intf->driver_folder, intf, 659 &rt2x00debug_fop_dev_flags); 660 debugfs_create_file("cap_flags", 0400, intf->driver_folder, intf, 661 &rt2x00debug_fop_cap_flags); 662 debugfs_create_file("restart_hw", 0200, intf->driver_folder, intf, 663 &rt2x00debug_restart_hw); 664 665 register_folder = debugfs_create_dir("register", intf->driver_folder); 666 667 #define RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(__intf, __name) \ 668 ({ \ 669 if (debug->__name.read) { \ 670 debugfs_create_u32(__stringify(__name) "_offset", 0600, \ 671 register_folder, \ 672 &(__intf)->offset_##__name); \ 673 \ 674 debugfs_create_file(__stringify(__name) "_value", 0600, \ 675 register_folder, (__intf), \ 676 &rt2x00debug_fop_##__name); \ 677 } \ 678 }) 679 680 RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, csr); 681 RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, eeprom); 682 RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, bbp); 683 RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, rf); 684 RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, rfcsr); 685 686 #undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY 687 688 queue_folder = debugfs_create_dir("queue", intf->driver_folder); 689 690 debugfs_create_file("dump", 0400, queue_folder, intf, 691 &rt2x00debug_fop_queue_dump); 692 693 skb_queue_head_init(&intf->frame_dump_skbqueue); 694 init_waitqueue_head(&intf->frame_dump_waitqueue); 695 696 debugfs_create_file("queue", 0400, queue_folder, intf, 697 &rt2x00debug_fop_queue_stats); 698 699 #ifdef CONFIG_RT2X00_LIB_CRYPTO 700 if (rt2x00_has_cap_hw_crypto(rt2x00dev)) 701 debugfs_create_file("crypto", 0444, queue_folder, intf, 702 &rt2x00debug_fop_crypto_stats); 703 #endif 704 705 return; 706 } 707 708 void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) 709 { 710 struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf; 711 712 if (unlikely(!intf)) 713 return; 714 715 skb_queue_purge(&intf->frame_dump_skbqueue); 716 717 debugfs_remove_recursive(intf->driver_folder); 718 kfree(intf->chipset_blob.data); 719 kfree(intf->driver_blob.data); 720 kfree(intf); 721 722 rt2x00dev->debugfs_intf = NULL; 723 } 724