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