diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00debug.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00debug.c | 74 |
1 files changed, 60 insertions, 14 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index b0498e7e7aae..78787fcc919e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c | |||
@@ -63,7 +63,8 @@ struct rt2x00debug_intf { | |||
63 | * - driver folder | 63 | * - driver folder |
64 | * - driver file | 64 | * - driver file |
65 | * - chipset file | 65 | * - chipset file |
66 | * - device flags file | 66 | * - device state flags file |
67 | * - device capability flags file | ||
67 | * - register folder | 68 | * - register folder |
68 | * - csr offset/value files | 69 | * - csr offset/value files |
69 | * - eeprom offset/value files | 70 | * - eeprom offset/value files |
@@ -78,6 +79,7 @@ struct rt2x00debug_intf { | |||
78 | struct dentry *driver_entry; | 79 | struct dentry *driver_entry; |
79 | struct dentry *chipset_entry; | 80 | struct dentry *chipset_entry; |
80 | struct dentry *dev_flags; | 81 | struct dentry *dev_flags; |
82 | struct dentry *cap_flags; | ||
81 | struct dentry *register_folder; | 83 | struct dentry *register_folder; |
82 | struct dentry *csr_off_entry; | 84 | struct dentry *csr_off_entry; |
83 | struct dentry *csr_val_entry; | 85 | struct dentry *csr_val_entry; |
@@ -162,11 +164,11 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | |||
162 | struct timeval timestamp; | 164 | struct timeval timestamp; |
163 | u32 data_len; | 165 | u32 data_len; |
164 | 166 | ||
165 | do_gettimeofday(×tamp); | 167 | if (likely(!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))) |
166 | |||
167 | if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)) | ||
168 | return; | 168 | return; |
169 | 169 | ||
170 | do_gettimeofday(×tamp); | ||
171 | |||
170 | if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) { | 172 | if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) { |
171 | DEBUG(rt2x00dev, "txrx dump queue length exceeded.\n"); | 173 | DEBUG(rt2x00dev, "txrx dump queue length exceeded.\n"); |
172 | return; | 174 | return; |
@@ -315,6 +317,7 @@ static const struct file_operations rt2x00debug_fop_queue_dump = { | |||
315 | .poll = rt2x00debug_poll_queue_dump, | 317 | .poll = rt2x00debug_poll_queue_dump, |
316 | .open = rt2x00debug_open_queue_dump, | 318 | .open = rt2x00debug_open_queue_dump, |
317 | .release = rt2x00debug_release_queue_dump, | 319 | .release = rt2x00debug_release_queue_dump, |
320 | .llseek = default_llseek, | ||
318 | }; | 321 | }; |
319 | 322 | ||
320 | static ssize_t rt2x00debug_read_queue_stats(struct file *file, | 323 | static ssize_t rt2x00debug_read_queue_stats(struct file *file, |
@@ -333,23 +336,24 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file, | |||
333 | if (*offset) | 336 | if (*offset) |
334 | return 0; | 337 | return 0; |
335 | 338 | ||
336 | data = kzalloc(lines * MAX_LINE_LENGTH, GFP_KERNEL); | 339 | data = kcalloc(lines, MAX_LINE_LENGTH, GFP_KERNEL); |
337 | if (!data) | 340 | if (!data) |
338 | return -ENOMEM; | 341 | return -ENOMEM; |
339 | 342 | ||
340 | temp = data + | 343 | temp = data + |
341 | sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdone\tcrypto\n"); | 344 | sprintf(data, "qid\tflags\t\tcount\tlimit\tlength\tindex\tdma done\tdone\n"); |
342 | 345 | ||
343 | queue_for_each(intf->rt2x00dev, queue) { | 346 | queue_for_each(intf->rt2x00dev, queue) { |
344 | spin_lock_irqsave(&queue->lock, irqflags); | 347 | spin_lock_irqsave(&queue->index_lock, irqflags); |
345 | 348 | ||
346 | temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, | 349 | temp += sprintf(temp, "%d\t0x%.8x\t%d\t%d\t%d\t%d\t%d\t\t%d\n", |
350 | queue->qid, (unsigned int)queue->flags, | ||
347 | queue->count, queue->limit, queue->length, | 351 | queue->count, queue->limit, queue->length, |
348 | queue->index[Q_INDEX], | 352 | queue->index[Q_INDEX], |
349 | queue->index[Q_INDEX_DONE], | 353 | queue->index[Q_INDEX_DMA_DONE], |
350 | queue->index[Q_INDEX_CRYPTO]); | 354 | queue->index[Q_INDEX_DONE]); |
351 | 355 | ||
352 | spin_unlock_irqrestore(&queue->lock, irqflags); | 356 | spin_unlock_irqrestore(&queue->index_lock, irqflags); |
353 | } | 357 | } |
354 | 358 | ||
355 | size = strlen(data); | 359 | size = strlen(data); |
@@ -371,6 +375,7 @@ static const struct file_operations rt2x00debug_fop_queue_stats = { | |||
371 | .read = rt2x00debug_read_queue_stats, | 375 | .read = rt2x00debug_read_queue_stats, |
372 | .open = rt2x00debug_file_open, | 376 | .open = rt2x00debug_file_open, |
373 | .release = rt2x00debug_file_release, | 377 | .release = rt2x00debug_file_release, |
378 | .llseek = default_llseek, | ||
374 | }; | 379 | }; |
375 | 380 | ||
376 | #ifdef CONFIG_RT2X00_LIB_CRYPTO | 381 | #ifdef CONFIG_RT2X00_LIB_CRYPTO |
@@ -380,7 +385,7 @@ static ssize_t rt2x00debug_read_crypto_stats(struct file *file, | |||
380 | loff_t *offset) | 385 | loff_t *offset) |
381 | { | 386 | { |
382 | struct rt2x00debug_intf *intf = file->private_data; | 387 | struct rt2x00debug_intf *intf = file->private_data; |
383 | char *name[] = { "WEP64", "WEP128", "TKIP", "AES" }; | 388 | static const char * const name[] = { "WEP64", "WEP128", "TKIP", "AES" }; |
384 | char *data; | 389 | char *data; |
385 | char *temp; | 390 | char *temp; |
386 | size_t size; | 391 | size_t size; |
@@ -423,6 +428,7 @@ static const struct file_operations rt2x00debug_fop_crypto_stats = { | |||
423 | .read = rt2x00debug_read_crypto_stats, | 428 | .read = rt2x00debug_read_crypto_stats, |
424 | .open = rt2x00debug_file_open, | 429 | .open = rt2x00debug_file_open, |
425 | .release = rt2x00debug_file_release, | 430 | .release = rt2x00debug_file_release, |
431 | .llseek = default_llseek, | ||
426 | }; | 432 | }; |
427 | #endif | 433 | #endif |
428 | 434 | ||
@@ -481,6 +487,9 @@ static ssize_t rt2x00debug_write_##__name(struct file *file, \ | |||
481 | if (index >= debug->__name.word_count) \ | 487 | if (index >= debug->__name.word_count) \ |
482 | return -EINVAL; \ | 488 | return -EINVAL; \ |
483 | \ | 489 | \ |
490 | if (length > sizeof(line)) \ | ||
491 | return -EINVAL; \ | ||
492 | \ | ||
484 | if (copy_from_user(line, buf, length)) \ | 493 | if (copy_from_user(line, buf, length)) \ |
485 | return -EFAULT; \ | 494 | return -EFAULT; \ |
486 | \ | 495 | \ |
@@ -509,6 +518,7 @@ static const struct file_operations rt2x00debug_fop_##__name = {\ | |||
509 | .write = rt2x00debug_write_##__name, \ | 518 | .write = rt2x00debug_write_##__name, \ |
510 | .open = rt2x00debug_file_open, \ | 519 | .open = rt2x00debug_file_open, \ |
511 | .release = rt2x00debug_file_release, \ | 520 | .release = rt2x00debug_file_release, \ |
521 | .llseek = generic_file_llseek, \ | ||
512 | }; | 522 | }; |
513 | 523 | ||
514 | RT2X00DEBUGFS_OPS(csr, "0x%.8x\n", u32); | 524 | RT2X00DEBUGFS_OPS(csr, "0x%.8x\n", u32); |
@@ -542,6 +552,36 @@ static const struct file_operations rt2x00debug_fop_dev_flags = { | |||
542 | .read = rt2x00debug_read_dev_flags, | 552 | .read = rt2x00debug_read_dev_flags, |
543 | .open = rt2x00debug_file_open, | 553 | .open = rt2x00debug_file_open, |
544 | .release = rt2x00debug_file_release, | 554 | .release = rt2x00debug_file_release, |
555 | .llseek = default_llseek, | ||
556 | }; | ||
557 | |||
558 | static ssize_t rt2x00debug_read_cap_flags(struct file *file, | ||
559 | char __user *buf, | ||
560 | size_t length, | ||
561 | loff_t *offset) | ||
562 | { | ||
563 | struct rt2x00debug_intf *intf = file->private_data; | ||
564 | char line[16]; | ||
565 | size_t size; | ||
566 | |||
567 | if (*offset) | ||
568 | return 0; | ||
569 | |||
570 | size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->cap_flags); | ||
571 | |||
572 | if (copy_to_user(buf, line, size)) | ||
573 | return -EFAULT; | ||
574 | |||
575 | *offset += size; | ||
576 | return size; | ||
577 | } | ||
578 | |||
579 | static const struct file_operations rt2x00debug_fop_cap_flags = { | ||
580 | .owner = THIS_MODULE, | ||
581 | .read = rt2x00debug_read_cap_flags, | ||
582 | .open = rt2x00debug_file_open, | ||
583 | .release = rt2x00debug_file_release, | ||
584 | .llseek = default_llseek, | ||
545 | }; | 585 | }; |
546 | 586 | ||
547 | static struct dentry *rt2x00debug_create_file_driver(const char *name, | 587 | static struct dentry *rt2x00debug_create_file_driver(const char *name, |
@@ -559,7 +599,6 @@ static struct dentry *rt2x00debug_create_file_driver(const char *name, | |||
559 | blob->data = data; | 599 | blob->data = data; |
560 | data += sprintf(data, "driver:\t%s\n", intf->rt2x00dev->ops->name); | 600 | data += sprintf(data, "driver:\t%s\n", intf->rt2x00dev->ops->name); |
561 | data += sprintf(data, "version:\t%s\n", DRV_VERSION); | 601 | data += sprintf(data, "version:\t%s\n", DRV_VERSION); |
562 | data += sprintf(data, "compiled:\t%s %s\n", __DATE__, __TIME__); | ||
563 | blob->size = strlen(blob->data); | 602 | blob->size = strlen(blob->data); |
564 | 603 | ||
565 | return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob); | 604 | return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob); |
@@ -644,6 +683,12 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) | |||
644 | if (IS_ERR(intf->dev_flags) || !intf->dev_flags) | 683 | if (IS_ERR(intf->dev_flags) || !intf->dev_flags) |
645 | goto exit; | 684 | goto exit; |
646 | 685 | ||
686 | intf->cap_flags = debugfs_create_file("cap_flags", S_IRUSR, | ||
687 | intf->driver_folder, intf, | ||
688 | &rt2x00debug_fop_cap_flags); | ||
689 | if (IS_ERR(intf->cap_flags) || !intf->cap_flags) | ||
690 | goto exit; | ||
691 | |||
647 | intf->register_folder = | 692 | intf->register_folder = |
648 | debugfs_create_dir("register", intf->driver_folder); | 693 | debugfs_create_dir("register", intf->driver_folder); |
649 | if (IS_ERR(intf->register_folder) || !intf->register_folder) | 694 | if (IS_ERR(intf->register_folder) || !intf->register_folder) |
@@ -697,7 +742,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) | |||
697 | intf, &rt2x00debug_fop_queue_stats); | 742 | intf, &rt2x00debug_fop_queue_stats); |
698 | 743 | ||
699 | #ifdef CONFIG_RT2X00_LIB_CRYPTO | 744 | #ifdef CONFIG_RT2X00_LIB_CRYPTO |
700 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) | 745 | if (test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) |
701 | intf->crypto_stats_entry = | 746 | intf->crypto_stats_entry = |
702 | debugfs_create_file("crypto", S_IRUGO, intf->queue_folder, | 747 | debugfs_create_file("crypto", S_IRUGO, intf->queue_folder, |
703 | intf, &rt2x00debug_fop_crypto_stats); | 748 | intf, &rt2x00debug_fop_crypto_stats); |
@@ -735,6 +780,7 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) | |||
735 | debugfs_remove(intf->csr_off_entry); | 780 | debugfs_remove(intf->csr_off_entry); |
736 | debugfs_remove(intf->register_folder); | 781 | debugfs_remove(intf->register_folder); |
737 | debugfs_remove(intf->dev_flags); | 782 | debugfs_remove(intf->dev_flags); |
783 | debugfs_remove(intf->cap_flags); | ||
738 | debugfs_remove(intf->chipset_entry); | 784 | debugfs_remove(intf->chipset_entry); |
739 | debugfs_remove(intf->driver_entry); | 785 | debugfs_remove(intf->driver_entry); |
740 | debugfs_remove(intf->driver_folder); | 786 | debugfs_remove(intf->driver_folder); |