27 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/poll.h>
30 #include <linux/sched.h>
31 #include <linux/slab.h>
38 #define MAX_LINE_LENGTH 64
105 #define FRAME_DUMP_FILE_OPEN 1
177 DEBUG(rt2x00dev,
"txrx dump queue length exceeded.\n");
185 skbcopy = alloc_skb(
sizeof(*dump_hdr) + skbdesc->
desc_len + data_len,
188 DEBUG(rt2x00dev,
"Failed to copy skb for dump.\n");
228 if (!try_module_get(intf->
debug->owner))
234 static int rt2x00debug_file_release(
struct inode *inode,
struct file *file)
238 module_put(intf->
debug->owner);
243 static int rt2x00debug_open_queue_dump(
struct inode *inode,
struct file *file)
248 retval = rt2x00debug_file_open(inode, file);
253 rt2x00debug_file_release(inode, file);
260 static int rt2x00debug_release_queue_dump(
struct inode *inode,
struct file *file)
268 return rt2x00debug_file_release(inode, file);
271 static ssize_t rt2x00debug_read_queue_dump(
struct file *file,
291 status =
min((
size_t)skb->
len, length);
305 static unsigned int rt2x00debug_poll_queue_dump(
struct file *file,
320 .read = rt2x00debug_read_queue_dump,
321 .poll = rt2x00debug_poll_queue_dump,
322 .open = rt2x00debug_open_queue_dump,
323 .release = rt2x00debug_release_queue_dump,
327 static ssize_t rt2x00debug_read_queue_stats(
struct file *file,
334 unsigned long irqflags;
335 unsigned int lines = 1 + intf->
rt2x00dev->data_queues;
348 sprintf(data,
"qid\tflags\t\tcount\tlimit\tlength\tindex\tdma done\tdone\n");
353 temp +=
sprintf(temp,
"%d\t0x%.8x\t%d\t%d\t%d\t%d\t%d\t\t%d\n",
354 queue->
qid, (
unsigned int)queue->
flags,
360 spin_unlock_irqrestore(&queue->
index_lock, irqflags);
364 size =
min(size, length);
379 .read = rt2x00debug_read_queue_stats,
380 .open = rt2x00debug_file_open,
381 .release = rt2x00debug_file_release,
385 #ifdef CONFIG_RT2X00_LIB_CRYPTO
386 static ssize_t rt2x00debug_read_crypto_stats(
struct file *file,
392 static const char *
const name[] = {
"WEP64",
"WEP128",
"TKIP",
"AES" };
406 temp +=
sprintf(data,
"cipher\tsuccess\ticv err\tmic err\tkey err\n");
409 temp +=
sprintf(temp,
"%s\t%lu\t%lu\t%lu\t%lu\n", name[i],
417 size =
min(size, length);
432 .read = rt2x00debug_read_crypto_stats,
433 .open = rt2x00debug_file_open,
434 .release = rt2x00debug_file_release,
439 #define RT2X00DEBUGFS_OPS_READ(__name, __format, __type) \
440 static ssize_t rt2x00debug_read_##__name(struct file *file, \
445 struct rt2x00debug_intf *intf = file->private_data; \
446 const struct rt2x00debug *debug = intf->debug; \
449 unsigned int index = intf->offset_##__name; \
455 if (index >= debug->__name.word_count) \
458 index += (debug->__name.word_base / \
459 debug->__name.word_size); \
461 if (debug->__name.flags & RT2X00DEBUGFS_OFFSET) \
462 index *= debug->__name.word_size; \
464 debug->__name.read(intf->rt2x00dev, index, &value); \
466 size = sprintf(line, __format, value); \
468 if (copy_to_user(buf, line, size)) \
475 #define RT2X00DEBUGFS_OPS_WRITE(__name, __type) \
476 static ssize_t rt2x00debug_write_##__name(struct file *file, \
477 const char __user *buf,\
481 struct rt2x00debug_intf *intf = file->private_data; \
482 const struct rt2x00debug *debug = intf->debug; \
485 unsigned int index = intf->offset_##__name; \
491 if (index >= debug->__name.word_count) \
494 if (length > sizeof(line)) \
497 if (copy_from_user(line, buf, length)) \
500 size = strlen(line); \
501 value = simple_strtoul(line, NULL, 0); \
503 index += (debug->__name.word_base / \
504 debug->__name.word_size); \
506 if (debug->__name.flags & RT2X00DEBUGFS_OFFSET) \
507 index *= debug->__name.word_size; \
509 debug->__name.write(intf->rt2x00dev, index, value); \
515 #define RT2X00DEBUGFS_OPS(__name, __format, __type) \
516 RT2X00DEBUGFS_OPS_READ(__name, __format, __type); \
517 RT2X00DEBUGFS_OPS_WRITE(__name, __type); \
519 static const struct file_operations rt2x00debug_fop_##__name = {\
520 .owner = THIS_MODULE, \
521 .read = rt2x00debug_read_##__name, \
522 .write = rt2x00debug_write_##__name, \
523 .open = rt2x00debug_file_open, \
524 .release = rt2x00debug_file_release, \
525 .llseek = generic_file_llseek, \
534 static ssize_t rt2x00debug_read_dev_flags(
struct file *file,
557 .read = rt2x00debug_read_dev_flags,
558 .open = rt2x00debug_file_open,
559 .release = rt2x00debug_file_release,
563 static ssize_t rt2x00debug_read_cap_flags(
struct file *file,
586 .read = rt2x00debug_read_cap_flags,
587 .open = rt2x00debug_file_open,
588 .release = rt2x00debug_file_release,
592 static struct dentry *rt2x00debug_create_file_driver(
const char *name,
612 static struct dentry *rt2x00debug_create_file_chipset(
const char *name,
631 data +=
sprintf(data,
"register\tbase\twords\twordsize\n");
632 #define RT2X00DEBUGFS_SPRINTF_REGISTER(__name) \
634 if(debug->__name.read) \
635 data += sprintf(data, __stringify(__name) \
637 debug->__name.word_base, \
638 debug->__name.word_count, \
639 debug->__name.word_size); \
646 #undef RT2X00DEBUGFS_SPRINTF_REGISTER
660 ERROR(rt2x00dev,
"Failed to allocate debug handler.\n");
666 rt2x00dev->debugfs_intf =
intf;
670 rt2x00dev->
hw->wiphy->debugfsdir);
675 rt2x00debug_create_file_driver(
"driver", intf, &intf->
driver_blob);
680 rt2x00debug_create_file_chipset(
"chipset",
687 &rt2x00debug_fop_dev_flags);
693 &rt2x00debug_fop_cap_flags);
702 #define RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(__intf, __name) \
704 if(debug->__name.read) { \
705 (__intf)->__name##_off_entry = \
706 debugfs_create_u32(__stringify(__name) "_offset", \
708 (__intf)->register_folder, \
709 &(__intf)->offset_##__name); \
710 if (IS_ERR((__intf)->__name##_off_entry) \
711 || !(__intf)->__name##_off_entry) \
714 (__intf)->__name##_val_entry = \
715 debugfs_create_file(__stringify(__name) "_value", \
717 (__intf)->register_folder, \
718 (__intf), &rt2x00debug_fop_##__name); \
719 if (IS_ERR((__intf)->__name##_val_entry) \
720 || !(__intf)->__name##_val_entry) \
731 #undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY
740 intf, &rt2x00debug_fop_queue_dump);
750 intf, &rt2x00debug_fop_queue_stats);
752 #ifdef CONFIG_RT2X00_LIB_CRYPTO
756 intf, &rt2x00debug_fop_crypto_stats);
763 ERROR(rt2x00dev,
"Failed to register debug handler.\n");
775 #ifdef CONFIG_RT2X00_LIB_CRYPTO
801 rt2x00dev->debugfs_intf =
NULL;