Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003     Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
0004     <http://rt2x00.serialmonkey.com>
0005 
0006  */
0007 
0008 /*
0009     Module: rt2x00lib
0010     Abstract: rt2x00 debugfs specific routines.
0011  */
0012 
0013 #include <linux/debugfs.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/poll.h>
0017 #include <linux/sched.h>
0018 #include <linux/slab.h>
0019 #include <linux/uaccess.h>
0020 
0021 #include "rt2x00.h"
0022 #include "rt2x00lib.h"
0023 #include "rt2x00dump.h"
0024 
0025 #define MAX_LINE_LENGTH 64
0026 
0027 struct rt2x00debug_crypto {
0028     unsigned long success;
0029     unsigned long icv_error;
0030     unsigned long mic_error;
0031     unsigned long key_error;
0032 };
0033 
0034 struct rt2x00debug_intf {
0035     /*
0036      * Pointer to driver structure where
0037      * this debugfs entry belongs to.
0038      */
0039     struct rt2x00_dev *rt2x00dev;
0040 
0041     /*
0042      * Reference to the rt2x00debug structure
0043      * which can be used to communicate with
0044      * the registers.
0045      */
0046     const struct rt2x00debug *debug;
0047 
0048     /*
0049      * Debugfs entries for:
0050      * - driver folder
0051      *   - driver file
0052      *   - chipset file
0053      *   - device state flags file
0054      *   - device capability flags file
0055      *   - hardware restart file
0056      *   - register folder
0057      *     - csr offset/value files
0058      *     - eeprom offset/value files
0059      *     - bbp offset/value files
0060      *     - rf offset/value files
0061      *     - rfcsr offset/value files
0062      *   - queue folder
0063      *     - frame dump file
0064      *     - queue stats file
0065      *     - crypto stats file
0066      */
0067     struct dentry *driver_folder;
0068 
0069     /*
0070      * The frame dump file only allows a single reader,
0071      * so we need to store the current state here.
0072      */
0073     unsigned long frame_dump_flags;
0074 #define FRAME_DUMP_FILE_OPEN    1
0075 
0076     /*
0077      * We queue each frame before dumping it to the user,
0078      * per read command we will pass a single skb structure
0079      * so we should be prepared to queue multiple sk buffers
0080      * before sending it to userspace.
0081      */
0082     struct sk_buff_head frame_dump_skbqueue;
0083     wait_queue_head_t frame_dump_waitqueue;
0084 
0085     /*
0086      * HW crypto statistics.
0087      * All statistics are stored separately per cipher type.
0088      */
0089     struct rt2x00debug_crypto crypto_stats[CIPHER_MAX];
0090 
0091     /*
0092      * Driver and chipset files will use a data buffer
0093      * that has been created in advance. This will simplify
0094      * the code since we can use the debugfs functions.
0095      */
0096     struct debugfs_blob_wrapper driver_blob;
0097     struct debugfs_blob_wrapper chipset_blob;
0098 
0099     /*
0100      * Requested offset for each register type.
0101      */
0102     unsigned int offset_csr;
0103     unsigned int offset_eeprom;
0104     unsigned int offset_bbp;
0105     unsigned int offset_rf;
0106     unsigned int offset_rfcsr;
0107 };
0108 
0109 void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
0110                    struct rxdone_entry_desc *rxdesc)
0111 {
0112     struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
0113     enum cipher cipher = rxdesc->cipher;
0114     enum rx_crypto status = rxdesc->cipher_status;
0115 
0116     if (cipher == CIPHER_TKIP_NO_MIC)
0117         cipher = CIPHER_TKIP;
0118     if (cipher == CIPHER_NONE || cipher >= CIPHER_MAX)
0119         return;
0120 
0121     /* Remove CIPHER_NONE index */
0122     cipher--;
0123 
0124     intf->crypto_stats[cipher].success += (status == RX_CRYPTO_SUCCESS);
0125     intf->crypto_stats[cipher].icv_error += (status == RX_CRYPTO_FAIL_ICV);
0126     intf->crypto_stats[cipher].mic_error += (status == RX_CRYPTO_FAIL_MIC);
0127     intf->crypto_stats[cipher].key_error += (status == RX_CRYPTO_FAIL_KEY);
0128 }
0129 
0130 void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
0131                 enum rt2x00_dump_type type, struct queue_entry *entry)
0132 {
0133     struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
0134     struct sk_buff *skb = entry->skb;
0135     struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
0136     struct sk_buff *skbcopy;
0137     struct rt2x00dump_hdr *dump_hdr;
0138     struct timespec64 timestamp;
0139     u32 data_len;
0140 
0141     if (likely(!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)))
0142         return;
0143 
0144     ktime_get_ts64(&timestamp);
0145 
0146     if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) {
0147         rt2x00_dbg(rt2x00dev, "txrx dump queue length exceeded\n");
0148         return;
0149     }
0150 
0151     data_len = skb->len;
0152     if (skbdesc->flags & SKBDESC_DESC_IN_SKB)
0153         data_len -= skbdesc->desc_len;
0154 
0155     skbcopy = alloc_skb(sizeof(*dump_hdr) + skbdesc->desc_len + data_len,
0156                 GFP_ATOMIC);
0157     if (!skbcopy) {
0158         rt2x00_dbg(rt2x00dev, "Failed to copy skb for dump\n");
0159         return;
0160     }
0161 
0162     dump_hdr = skb_put(skbcopy, sizeof(*dump_hdr));
0163     dump_hdr->version = cpu_to_le32(DUMP_HEADER_VERSION);
0164     dump_hdr->header_length = cpu_to_le32(sizeof(*dump_hdr));
0165     dump_hdr->desc_length = cpu_to_le32(skbdesc->desc_len);
0166     dump_hdr->data_length = cpu_to_le32(data_len);
0167     dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt);
0168     dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf);
0169     dump_hdr->chip_rev = cpu_to_le16(rt2x00dev->chip.rev);
0170     dump_hdr->type = cpu_to_le16(type);
0171     dump_hdr->queue_index = entry->queue->qid;
0172     dump_hdr->entry_index = entry->entry_idx;
0173     dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec);
0174     dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_nsec /
0175                            NSEC_PER_USEC);
0176 
0177     if (!(skbdesc->flags & SKBDESC_DESC_IN_SKB))
0178         skb_put_data(skbcopy, skbdesc->desc, skbdesc->desc_len);
0179     skb_put_data(skbcopy, skb->data, skb->len);
0180 
0181     skb_queue_tail(&intf->frame_dump_skbqueue, skbcopy);
0182     wake_up_interruptible(&intf->frame_dump_waitqueue);
0183 
0184     /*
0185      * Verify that the file has not been closed while we were working.
0186      */
0187     if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))
0188         skb_queue_purge(&intf->frame_dump_skbqueue);
0189 }
0190 EXPORT_SYMBOL_GPL(rt2x00debug_dump_frame);
0191 
0192 static int rt2x00debug_file_open(struct inode *inode, struct file *file)
0193 {
0194     struct rt2x00debug_intf *intf = inode->i_private;
0195 
0196     file->private_data = inode->i_private;
0197 
0198     if (!try_module_get(intf->debug->owner))
0199         return -EBUSY;
0200 
0201     return 0;
0202 }
0203 
0204 static int rt2x00debug_file_release(struct inode *inode, struct file *file)
0205 {
0206     struct rt2x00debug_intf *intf = file->private_data;
0207 
0208     module_put(intf->debug->owner);
0209 
0210     return 0;
0211 }
0212 
0213 static int rt2x00debug_open_queue_dump(struct inode *inode, struct file *file)
0214 {
0215     struct rt2x00debug_intf *intf = inode->i_private;
0216     int retval;
0217 
0218     retval = rt2x00debug_file_open(inode, file);
0219     if (retval)
0220         return retval;
0221 
0222     if (test_and_set_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)) {
0223         rt2x00debug_file_release(inode, file);
0224         return -EBUSY;
0225     }
0226 
0227     return 0;
0228 }
0229 
0230 static int rt2x00debug_release_queue_dump(struct inode *inode, struct file *file)
0231 {
0232     struct rt2x00debug_intf *intf = inode->i_private;
0233 
0234     skb_queue_purge(&intf->frame_dump_skbqueue);
0235 
0236     clear_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags);
0237 
0238     return rt2x00debug_file_release(inode, file);
0239 }
0240 
0241 static ssize_t rt2x00debug_read_queue_dump(struct file *file,
0242                        char __user *buf,
0243                        size_t length,
0244                        loff_t *offset)
0245 {
0246     struct rt2x00debug_intf *intf = file->private_data;
0247     struct sk_buff *skb;
0248     size_t status;
0249     int retval;
0250 
0251     if (file->f_flags & O_NONBLOCK)
0252         return -EAGAIN;
0253 
0254     retval =
0255         wait_event_interruptible(intf->frame_dump_waitqueue,
0256                      (skb =
0257                      skb_dequeue(&intf->frame_dump_skbqueue)));
0258     if (retval)
0259         return retval;
0260 
0261     status = min_t(size_t, skb->len, length);
0262     if (copy_to_user(buf, skb->data, status)) {
0263         status = -EFAULT;
0264         goto exit;
0265     }
0266 
0267     *offset += status;
0268 
0269 exit:
0270     kfree_skb(skb);
0271 
0272     return status;
0273 }
0274 
0275 static __poll_t rt2x00debug_poll_queue_dump(struct file *file,
0276                         poll_table *wait)
0277 {
0278     struct rt2x00debug_intf *intf = file->private_data;
0279 
0280     poll_wait(file, &intf->frame_dump_waitqueue, wait);
0281 
0282     if (!skb_queue_empty(&intf->frame_dump_skbqueue))
0283         return EPOLLOUT | EPOLLWRNORM;
0284 
0285     return 0;
0286 }
0287 
0288 static const struct file_operations rt2x00debug_fop_queue_dump = {
0289     .owner      = THIS_MODULE,
0290     .read       = rt2x00debug_read_queue_dump,
0291     .poll       = rt2x00debug_poll_queue_dump,
0292     .open       = rt2x00debug_open_queue_dump,
0293     .release    = rt2x00debug_release_queue_dump,
0294     .llseek     = default_llseek,
0295 };
0296 
0297 static ssize_t rt2x00debug_read_queue_stats(struct file *file,
0298                         char __user *buf,
0299                         size_t length,
0300                         loff_t *offset)
0301 {
0302     struct rt2x00debug_intf *intf = file->private_data;
0303     struct data_queue *queue;
0304     unsigned long irqflags;
0305     unsigned int lines = 1 + intf->rt2x00dev->data_queues;
0306     size_t size;
0307     char *data;
0308     char *temp;
0309 
0310     if (*offset)
0311         return 0;
0312 
0313     data = kcalloc(lines, MAX_LINE_LENGTH, GFP_KERNEL);
0314     if (!data)
0315         return -ENOMEM;
0316 
0317     temp = data +
0318         sprintf(data, "qid\tflags\t\tcount\tlimit\tlength\tindex\tdma done\tdone\n");
0319 
0320     queue_for_each(intf->rt2x00dev, queue) {
0321         spin_lock_irqsave(&queue->index_lock, irqflags);
0322 
0323         temp += sprintf(temp, "%d\t0x%.8x\t%d\t%d\t%d\t%d\t%d\t\t%d\n",
0324                 queue->qid, (unsigned int)queue->flags,
0325                 queue->count, queue->limit, queue->length,
0326                 queue->index[Q_INDEX],
0327                 queue->index[Q_INDEX_DMA_DONE],
0328                 queue->index[Q_INDEX_DONE]);
0329 
0330         spin_unlock_irqrestore(&queue->index_lock, irqflags);
0331     }
0332 
0333     size = strlen(data);
0334     size = min(size, length);
0335 
0336     if (copy_to_user(buf, data, size)) {
0337         kfree(data);
0338         return -EFAULT;
0339     }
0340 
0341     kfree(data);
0342 
0343     *offset += size;
0344     return size;
0345 }
0346 
0347 static const struct file_operations rt2x00debug_fop_queue_stats = {
0348     .owner      = THIS_MODULE,
0349     .read       = rt2x00debug_read_queue_stats,
0350     .open       = rt2x00debug_file_open,
0351     .release    = rt2x00debug_file_release,
0352     .llseek     = default_llseek,
0353 };
0354 
0355 #ifdef CONFIG_RT2X00_LIB_CRYPTO
0356 static ssize_t rt2x00debug_read_crypto_stats(struct file *file,
0357                          char __user *buf,
0358                          size_t length,
0359                          loff_t *offset)
0360 {
0361     struct rt2x00debug_intf *intf = file->private_data;
0362     static const char * const name[] = { "WEP64", "WEP128", "TKIP", "AES" };
0363     char *data;
0364     char *temp;
0365     size_t size;
0366     unsigned int i;
0367 
0368     if (*offset)
0369         return 0;
0370 
0371     data = kcalloc(1 + CIPHER_MAX, MAX_LINE_LENGTH, GFP_KERNEL);
0372     if (!data)
0373         return -ENOMEM;
0374 
0375     temp = data;
0376     temp += sprintf(data, "cipher\tsuccess\ticv err\tmic err\tkey err\n");
0377 
0378     for (i = 0; i < CIPHER_MAX; i++) {
0379         temp += sprintf(temp, "%s\t%lu\t%lu\t%lu\t%lu\n", name[i],
0380                 intf->crypto_stats[i].success,
0381                 intf->crypto_stats[i].icv_error,
0382                 intf->crypto_stats[i].mic_error,
0383                 intf->crypto_stats[i].key_error);
0384     }
0385 
0386     size = strlen(data);
0387     size = min(size, length);
0388 
0389     if (copy_to_user(buf, data, size)) {
0390         kfree(data);
0391         return -EFAULT;
0392     }
0393 
0394     kfree(data);
0395 
0396     *offset += size;
0397     return size;
0398 }
0399 
0400 static const struct file_operations rt2x00debug_fop_crypto_stats = {
0401     .owner      = THIS_MODULE,
0402     .read       = rt2x00debug_read_crypto_stats,
0403     .open       = rt2x00debug_file_open,
0404     .release    = rt2x00debug_file_release,
0405     .llseek     = default_llseek,
0406 };
0407 #endif
0408 
0409 #define RT2X00DEBUGFS_OPS_READ(__name, __format, __type)    \
0410 static ssize_t rt2x00debug_read_##__name(struct file *file, \
0411                      char __user *buf,  \
0412                      size_t length,     \
0413                      loff_t *offset)    \
0414 {                               \
0415     struct rt2x00debug_intf *intf = file->private_data; \
0416     const struct rt2x00debug *debug = intf->debug;      \
0417     char line[16];                      \
0418     size_t size;                        \
0419     unsigned int index = intf->offset_##__name;     \
0420     __type value;                       \
0421                                 \
0422     if (*offset)                        \
0423         return 0;                   \
0424                                 \
0425     if (index >= debug->__name.word_count)          \
0426         return -EINVAL;                 \
0427                                 \
0428     index += (debug->__name.word_base /         \
0429           debug->__name.word_size);         \
0430                                 \
0431     if (debug->__name.flags & RT2X00DEBUGFS_OFFSET)     \
0432         index *= debug->__name.word_size;       \
0433                                 \
0434     value = debug->__name.read(intf->rt2x00dev, index); \
0435                                 \
0436     size = sprintf(line, __format, value);          \
0437                                 \
0438     return simple_read_from_buffer(buf, length, offset, line, size); \
0439 }
0440 
0441 #define RT2X00DEBUGFS_OPS_WRITE(__name, __type)         \
0442 static ssize_t rt2x00debug_write_##__name(struct file *file,    \
0443                       const char __user *buf,\
0444                       size_t length,    \
0445                       loff_t *offset)   \
0446 {                               \
0447     struct rt2x00debug_intf *intf = file->private_data; \
0448     const struct rt2x00debug *debug = intf->debug;      \
0449     char line[17];                      \
0450     size_t size;                        \
0451     unsigned int index = intf->offset_##__name;     \
0452     __type value;                       \
0453                                 \
0454     if (*offset)                        \
0455         return 0;                   \
0456                                 \
0457     if (index >= debug->__name.word_count)          \
0458         return -EINVAL;                 \
0459                                 \
0460     if (length > sizeof(line))              \
0461         return -EINVAL;                 \
0462                                 \
0463     if (copy_from_user(line, buf, length))          \
0464         return -EFAULT;                 \
0465     line[16] = 0;                       \
0466                         \
0467     size = strlen(line);                    \
0468     value = simple_strtoul(line, NULL, 0);          \
0469                                 \
0470     index += (debug->__name.word_base /         \
0471           debug->__name.word_size);         \
0472                                 \
0473     if (debug->__name.flags & RT2X00DEBUGFS_OFFSET)     \
0474         index *= debug->__name.word_size;       \
0475                                 \
0476     debug->__name.write(intf->rt2x00dev, index, value); \
0477                                 \
0478     *offset += size;                    \
0479     return size;                        \
0480 }
0481 
0482 #define RT2X00DEBUGFS_OPS(__name, __format, __type)     \
0483 RT2X00DEBUGFS_OPS_READ(__name, __format, __type);       \
0484 RT2X00DEBUGFS_OPS_WRITE(__name, __type);            \
0485                                 \
0486 static const struct file_operations rt2x00debug_fop_##__name = {\
0487     .owner      = THIS_MODULE,              \
0488     .read       = rt2x00debug_read_##__name,        \
0489     .write      = rt2x00debug_write_##__name,       \
0490     .open       = rt2x00debug_file_open,        \
0491     .release    = rt2x00debug_file_release,     \
0492     .llseek     = generic_file_llseek,          \
0493 };
0494 
0495 RT2X00DEBUGFS_OPS(csr, "0x%.8x\n", u32);
0496 RT2X00DEBUGFS_OPS(eeprom, "0x%.4x\n", u16);
0497 RT2X00DEBUGFS_OPS(bbp, "0x%.2x\n", u8);
0498 RT2X00DEBUGFS_OPS(rf, "0x%.8x\n", u32);
0499 RT2X00DEBUGFS_OPS(rfcsr, "0x%.2x\n", u8);
0500 
0501 static ssize_t rt2x00debug_read_dev_flags(struct file *file,
0502                       char __user *buf,
0503                       size_t length,
0504                       loff_t *offset)
0505 {
0506     struct rt2x00debug_intf *intf = file->private_data;
0507     char line[16];
0508     size_t size;
0509 
0510     if (*offset)
0511         return 0;
0512 
0513     size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->flags);
0514 
0515     return simple_read_from_buffer(buf, length, offset, line, size);
0516 }
0517 
0518 static const struct file_operations rt2x00debug_fop_dev_flags = {
0519     .owner      = THIS_MODULE,
0520     .read       = rt2x00debug_read_dev_flags,
0521     .open       = rt2x00debug_file_open,
0522     .release    = rt2x00debug_file_release,
0523     .llseek     = default_llseek,
0524 };
0525 
0526 static ssize_t rt2x00debug_read_cap_flags(struct file *file,
0527                       char __user *buf,
0528                       size_t length,
0529                       loff_t *offset)
0530 {
0531     struct rt2x00debug_intf *intf = file->private_data;
0532     char line[16];
0533     size_t size;
0534 
0535     if (*offset)
0536         return 0;
0537 
0538     size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->cap_flags);
0539 
0540     return simple_read_from_buffer(buf, length, offset, line, size);
0541 }
0542 
0543 static const struct file_operations rt2x00debug_fop_cap_flags = {
0544     .owner      = THIS_MODULE,
0545     .read       = rt2x00debug_read_cap_flags,
0546     .open       = rt2x00debug_file_open,
0547     .release    = rt2x00debug_file_release,
0548     .llseek     = default_llseek,
0549 };
0550 
0551 static ssize_t rt2x00debug_write_restart_hw(struct file *file,
0552                         const char __user *buf,
0553                         size_t length,
0554                         loff_t *offset)
0555 {
0556     struct rt2x00debug_intf *intf = file->private_data;
0557     struct rt2x00_dev *rt2x00dev = intf->rt2x00dev;
0558     static unsigned long last_reset = INITIAL_JIFFIES;
0559 
0560     if (!rt2x00_has_cap_restart_hw(rt2x00dev))
0561         return -EOPNOTSUPP;
0562 
0563     if (time_before(jiffies, last_reset + msecs_to_jiffies(2000)))
0564         return -EBUSY;
0565 
0566     last_reset = jiffies;
0567 
0568     ieee80211_restart_hw(rt2x00dev->hw);
0569     return length;
0570 }
0571 
0572 static const struct file_operations rt2x00debug_restart_hw = {
0573     .owner = THIS_MODULE,
0574     .write = rt2x00debug_write_restart_hw,
0575     .open = simple_open,
0576     .llseek = generic_file_llseek,
0577 };
0578 
0579 static void rt2x00debug_create_file_driver(const char *name,
0580                        struct rt2x00debug_intf *intf,
0581                        struct debugfs_blob_wrapper *blob)
0582 {
0583     char *data;
0584 
0585     data = kzalloc(3 * MAX_LINE_LENGTH, GFP_KERNEL);
0586     if (!data)
0587         return;
0588 
0589     blob->data = data;
0590     data += sprintf(data, "driver:\t%s\n", intf->rt2x00dev->ops->name);
0591     data += sprintf(data, "version:\t%s\n", DRV_VERSION);
0592     blob->size = strlen(blob->data);
0593 
0594     debugfs_create_blob(name, 0400, intf->driver_folder, blob);
0595 }
0596 
0597 static void rt2x00debug_create_file_chipset(const char *name,
0598                         struct rt2x00debug_intf *intf,
0599                         struct debugfs_blob_wrapper *blob)
0600 {
0601     const struct rt2x00debug *debug = intf->debug;
0602     char *data;
0603 
0604     data = kzalloc(9 * MAX_LINE_LENGTH, GFP_KERNEL);
0605     if (!data)
0606         return;
0607 
0608     blob->data = data;
0609     data += sprintf(data, "rt chip:\t%04x\n", intf->rt2x00dev->chip.rt);
0610     data += sprintf(data, "rf chip:\t%04x\n", intf->rt2x00dev->chip.rf);
0611     data += sprintf(data, "revision:\t%04x\n", intf->rt2x00dev->chip.rev);
0612     data += sprintf(data, "\n");
0613     data += sprintf(data, "register\tbase\twords\twordsize\n");
0614 #define RT2X00DEBUGFS_SPRINTF_REGISTER(__name)          \
0615 {                               \
0616     if (debug->__name.read)                 \
0617         data += sprintf(data, __stringify(__name)   \
0618                 "\t%d\t%d\t%d\n",       \
0619                 debug->__name.word_base,    \
0620                 debug->__name.word_count,   \
0621                 debug->__name.word_size);   \
0622 }
0623     RT2X00DEBUGFS_SPRINTF_REGISTER(csr);
0624     RT2X00DEBUGFS_SPRINTF_REGISTER(eeprom);
0625     RT2X00DEBUGFS_SPRINTF_REGISTER(bbp);
0626     RT2X00DEBUGFS_SPRINTF_REGISTER(rf);
0627     RT2X00DEBUGFS_SPRINTF_REGISTER(rfcsr);
0628 #undef RT2X00DEBUGFS_SPRINTF_REGISTER
0629 
0630     blob->size = strlen(blob->data);
0631 
0632     debugfs_create_blob(name, 0400, intf->driver_folder, blob);
0633 }
0634 
0635 void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
0636 {
0637     const struct rt2x00debug *debug = rt2x00dev->ops->debugfs;
0638     struct rt2x00debug_intf *intf;
0639     struct dentry *queue_folder;
0640     struct dentry *register_folder;
0641 
0642     intf = kzalloc(sizeof(struct rt2x00debug_intf), GFP_KERNEL);
0643     if (!intf) {
0644         rt2x00_err(rt2x00dev, "Failed to allocate debug handler\n");
0645         return;
0646     }
0647 
0648     intf->debug = debug;
0649     intf->rt2x00dev = rt2x00dev;
0650     rt2x00dev->debugfs_intf = intf;
0651 
0652     intf->driver_folder =
0653         debugfs_create_dir(intf->rt2x00dev->ops->name,
0654                    rt2x00dev->hw->wiphy->debugfsdir);
0655 
0656     rt2x00debug_create_file_driver("driver", intf, &intf->driver_blob);
0657     rt2x00debug_create_file_chipset("chipset", intf, &intf->chipset_blob);
0658     debugfs_create_file("dev_flags", 0400, intf->driver_folder, intf,
0659                 &rt2x00debug_fop_dev_flags);
0660     debugfs_create_file("cap_flags", 0400, intf->driver_folder, intf,
0661                 &rt2x00debug_fop_cap_flags);
0662     debugfs_create_file("restart_hw", 0200, intf->driver_folder, intf,
0663                 &rt2x00debug_restart_hw);
0664 
0665     register_folder = debugfs_create_dir("register", intf->driver_folder);
0666 
0667 #define RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(__intf, __name)     \
0668 ({                                  \
0669     if (debug->__name.read) {                   \
0670         debugfs_create_u32(__stringify(__name) "_offset", 0600, \
0671                    register_folder,         \
0672                    &(__intf)->offset_##__name);     \
0673                                     \
0674         debugfs_create_file(__stringify(__name) "_value", 0600, \
0675                     register_folder, (__intf),      \
0676                     &rt2x00debug_fop_##__name);     \
0677     }                               \
0678 })
0679 
0680     RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, csr);
0681     RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, eeprom);
0682     RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, bbp);
0683     RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, rf);
0684     RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, rfcsr);
0685 
0686 #undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY
0687 
0688     queue_folder = debugfs_create_dir("queue", intf->driver_folder);
0689 
0690     debugfs_create_file("dump", 0400, queue_folder, intf,
0691                 &rt2x00debug_fop_queue_dump);
0692 
0693     skb_queue_head_init(&intf->frame_dump_skbqueue);
0694     init_waitqueue_head(&intf->frame_dump_waitqueue);
0695 
0696     debugfs_create_file("queue", 0400, queue_folder, intf,
0697                 &rt2x00debug_fop_queue_stats);
0698 
0699 #ifdef CONFIG_RT2X00_LIB_CRYPTO
0700     if (rt2x00_has_cap_hw_crypto(rt2x00dev))
0701         debugfs_create_file("crypto", 0444, queue_folder, intf,
0702                     &rt2x00debug_fop_crypto_stats);
0703 #endif
0704 
0705     return;
0706 }
0707 
0708 void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
0709 {
0710     struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
0711 
0712     if (unlikely(!intf))
0713         return;
0714 
0715     skb_queue_purge(&intf->frame_dump_skbqueue);
0716 
0717     debugfs_remove_recursive(intf->driver_folder);
0718     kfree(intf->chipset_blob.data);
0719     kfree(intf->driver_blob.data);
0720     kfree(intf);
0721 
0722     rt2x00dev->debugfs_intf = NULL;
0723 }