linux/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c
<<
>>
Prefs
   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
  27struct rt2x00debug_crypto {
  28        unsigned long success;
  29        unsigned long icv_error;
  30        unsigned long mic_error;
  31        unsigned long key_error;
  32};
  33
  34struct 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
 109void 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
 130void 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(&timestamp);
 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}
 190EXPORT_SYMBOL_GPL(rt2x00debug_dump_frame);
 191
 192static 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
 204static 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
 213static 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
 230static 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
 241static 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
 269exit:
 270        kfree_skb(skb);
 271
 272        return status;
 273}
 274
 275static __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
 288static 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
 297static 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
 347static 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
 356static 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
 400static 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)        \
 410static 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)                 \
 442static 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)             \
 483RT2X00DEBUGFS_OPS_READ(__name, __format, __type);               \
 484RT2X00DEBUGFS_OPS_WRITE(__name, __type);                        \
 485                                                                \
 486static 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
 495RT2X00DEBUGFS_OPS(csr, "0x%.8x\n", u32);
 496RT2X00DEBUGFS_OPS(eeprom, "0x%.4x\n", u16);
 497RT2X00DEBUGFS_OPS(bbp, "0x%.2x\n", u8);
 498RT2X00DEBUGFS_OPS(rf, "0x%.8x\n", u32);
 499RT2X00DEBUGFS_OPS(rfcsr, "0x%.2x\n", u8);
 500
 501static 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
 518static 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
 526static 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
 543static 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
 551static 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 = INITIAL_JIFFIES;
 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
 572static 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
 579static 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
 597static 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
 635void 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
 708void 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