linux/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c
<<
>>
Prefs
   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 queue_entry *entry)
 161{
 162        struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
 163        struct sk_buff *skb = entry->skb;
 164        struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
 165        struct sk_buff *skbcopy;
 166        struct rt2x00dump_hdr *dump_hdr;
 167        struct timeval timestamp;
 168        u32 data_len;
 169
 170        if (likely(!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)))
 171                return;
 172
 173        do_gettimeofday(&timestamp);
 174
 175        if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) {
 176                rt2x00_dbg(rt2x00dev, "txrx dump queue length exceeded\n");
 177                return;
 178        }
 179
 180        data_len = skb->len;
 181        if (skbdesc->flags & SKBDESC_DESC_IN_SKB)
 182                data_len -= skbdesc->desc_len;
 183
 184        skbcopy = alloc_skb(sizeof(*dump_hdr) + skbdesc->desc_len + data_len,
 185                            GFP_ATOMIC);
 186        if (!skbcopy) {
 187                rt2x00_dbg(rt2x00dev, "Failed to copy skb for dump\n");
 188                return;
 189        }
 190
 191        dump_hdr = skb_put(skbcopy, sizeof(*dump_hdr));
 192        dump_hdr->version = cpu_to_le32(DUMP_HEADER_VERSION);
 193        dump_hdr->header_length = cpu_to_le32(sizeof(*dump_hdr));
 194        dump_hdr->desc_length = cpu_to_le32(skbdesc->desc_len);
 195        dump_hdr->data_length = cpu_to_le32(data_len);
 196        dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt);
 197        dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf);
 198        dump_hdr->chip_rev = cpu_to_le16(rt2x00dev->chip.rev);
 199        dump_hdr->type = cpu_to_le16(type);
 200        dump_hdr->queue_index = entry->queue->qid;
 201        dump_hdr->entry_index = entry->entry_idx;
 202        dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec);
 203        dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec);
 204
 205        if (!(skbdesc->flags & SKBDESC_DESC_IN_SKB))
 206                skb_put_data(skbcopy, skbdesc->desc, skbdesc->desc_len);
 207        skb_put_data(skbcopy, 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        value = debug->__name.read(intf->rt2x00dev, index);     \
 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[17];                                          \
 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        line[16] = 0;                                           \
 498                                                \
 499        size = strlen(line);                                    \
 500        value = simple_strtoul(line, NULL, 0);                  \
 501                                                                \
 502        index += (debug->__name.word_base /                     \
 503                  debug->__name.word_size);                     \
 504                                                                \
 505        if (debug->__name.flags & RT2X00DEBUGFS_OFFSET)         \
 506                index *= debug->__name.word_size;               \
 507                                                                \
 508        debug->__name.write(intf->rt2x00dev, index, value);     \
 509                                                                \
 510        *offset += size;                                        \
 511        return size;                                            \
 512}
 513
 514#define RT2X00DEBUGFS_OPS(__name, __format, __type)             \
 515RT2X00DEBUGFS_OPS_READ(__name, __format, __type);               \
 516RT2X00DEBUGFS_OPS_WRITE(__name, __type);                        \
 517                                                                \
 518static const struct file_operations rt2x00debug_fop_##__name = {\
 519        .owner          = THIS_MODULE,                          \
 520        .read           = rt2x00debug_read_##__name,            \
 521        .write          = rt2x00debug_write_##__name,           \
 522        .open           = rt2x00debug_file_open,                \
 523        .release        = rt2x00debug_file_release,             \
 524        .llseek         = generic_file_llseek,                  \
 525};
 526
 527RT2X00DEBUGFS_OPS(csr, "0x%.8x\n", u32);
 528RT2X00DEBUGFS_OPS(eeprom, "0x%.4x\n", u16);
 529RT2X00DEBUGFS_OPS(bbp, "0x%.2x\n", u8);
 530RT2X00DEBUGFS_OPS(rf, "0x%.8x\n", u32);
 531RT2X00DEBUGFS_OPS(rfcsr, "0x%.2x\n", u8);
 532
 533static ssize_t rt2x00debug_read_dev_flags(struct file *file,
 534                                          char __user *buf,
 535                                          size_t length,
 536                                          loff_t *offset)
 537{
 538        struct rt2x00debug_intf *intf = file->private_data;
 539        char line[16];
 540        size_t size;
 541
 542        if (*offset)
 543                return 0;
 544
 545        size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->flags);
 546
 547        if (copy_to_user(buf, line, size))
 548                return -EFAULT;
 549
 550        *offset += size;
 551        return size;
 552}
 553
 554static const struct file_operations rt2x00debug_fop_dev_flags = {
 555        .owner          = THIS_MODULE,
 556        .read           = rt2x00debug_read_dev_flags,
 557        .open           = rt2x00debug_file_open,
 558        .release        = rt2x00debug_file_release,
 559        .llseek         = default_llseek,
 560};
 561
 562static ssize_t rt2x00debug_read_cap_flags(struct file *file,
 563                                          char __user *buf,
 564                                          size_t length,
 565                                          loff_t *offset)
 566{
 567        struct rt2x00debug_intf *intf = file->private_data;
 568        char line[16];
 569        size_t size;
 570
 571        if (*offset)
 572                return 0;
 573
 574        size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->cap_flags);
 575
 576        if (copy_to_user(buf, line, size))
 577                return -EFAULT;
 578
 579        *offset += size;
 580        return size;
 581}
 582
 583static const struct file_operations rt2x00debug_fop_cap_flags = {
 584        .owner          = THIS_MODULE,
 585        .read           = rt2x00debug_read_cap_flags,
 586        .open           = rt2x00debug_file_open,
 587        .release        = rt2x00debug_file_release,
 588        .llseek         = default_llseek,
 589};
 590
 591static struct dentry *rt2x00debug_create_file_driver(const char *name,
 592                                                     struct rt2x00debug_intf
 593                                                     *intf,
 594                                                     struct debugfs_blob_wrapper
 595                                                     *blob)
 596{
 597        char *data;
 598
 599        data = kzalloc(3 * MAX_LINE_LENGTH, GFP_KERNEL);
 600        if (!data)
 601                return NULL;
 602
 603        blob->data = data;
 604        data += sprintf(data, "driver:\t%s\n", intf->rt2x00dev->ops->name);
 605        data += sprintf(data, "version:\t%s\n", DRV_VERSION);
 606        blob->size = strlen(blob->data);
 607
 608        return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
 609}
 610
 611static struct dentry *rt2x00debug_create_file_chipset(const char *name,
 612                                                      struct rt2x00debug_intf
 613                                                      *intf,
 614                                                      struct
 615                                                      debugfs_blob_wrapper
 616                                                      *blob)
 617{
 618        const struct rt2x00debug *debug = intf->debug;
 619        char *data;
 620
 621        data = kzalloc(9 * MAX_LINE_LENGTH, GFP_KERNEL);
 622        if (!data)
 623                return NULL;
 624
 625        blob->data = data;
 626        data += sprintf(data, "rt chip:\t%04x\n", intf->rt2x00dev->chip.rt);
 627        data += sprintf(data, "rf chip:\t%04x\n", intf->rt2x00dev->chip.rf);
 628        data += sprintf(data, "revision:\t%04x\n", intf->rt2x00dev->chip.rev);
 629        data += sprintf(data, "\n");
 630        data += sprintf(data, "register\tbase\twords\twordsize\n");
 631#define RT2X00DEBUGFS_SPRINTF_REGISTER(__name)                  \
 632{                                                               \
 633        if (debug->__name.read)                                 \
 634                data += sprintf(data, __stringify(__name)       \
 635                                "\t%d\t%d\t%d\n",               \
 636                                debug->__name.word_base,        \
 637                                debug->__name.word_count,       \
 638                                debug->__name.word_size);       \
 639}
 640        RT2X00DEBUGFS_SPRINTF_REGISTER(csr);
 641        RT2X00DEBUGFS_SPRINTF_REGISTER(eeprom);
 642        RT2X00DEBUGFS_SPRINTF_REGISTER(bbp);
 643        RT2X00DEBUGFS_SPRINTF_REGISTER(rf);
 644        RT2X00DEBUGFS_SPRINTF_REGISTER(rfcsr);
 645#undef RT2X00DEBUGFS_SPRINTF_REGISTER
 646
 647        blob->size = strlen(blob->data);
 648
 649        return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
 650}
 651
 652void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
 653{
 654        const struct rt2x00debug *debug = rt2x00dev->ops->debugfs;
 655        struct rt2x00debug_intf *intf;
 656
 657        intf = kzalloc(sizeof(struct rt2x00debug_intf), GFP_KERNEL);
 658        if (!intf) {
 659                rt2x00_err(rt2x00dev, "Failed to allocate debug handler\n");
 660                return;
 661        }
 662
 663        intf->debug = debug;
 664        intf->rt2x00dev = rt2x00dev;
 665        rt2x00dev->debugfs_intf = intf;
 666
 667        intf->driver_folder =
 668            debugfs_create_dir(intf->rt2x00dev->ops->name,
 669                               rt2x00dev->hw->wiphy->debugfsdir);
 670        if (IS_ERR(intf->driver_folder) || !intf->driver_folder)
 671                goto exit;
 672
 673        intf->driver_entry =
 674            rt2x00debug_create_file_driver("driver", intf, &intf->driver_blob);
 675        if (IS_ERR(intf->driver_entry) || !intf->driver_entry)
 676                goto exit;
 677
 678        intf->chipset_entry =
 679            rt2x00debug_create_file_chipset("chipset",
 680                                            intf, &intf->chipset_blob);
 681        if (IS_ERR(intf->chipset_entry) || !intf->chipset_entry)
 682                goto exit;
 683
 684        intf->dev_flags = debugfs_create_file("dev_flags", S_IRUSR,
 685                                              intf->driver_folder, intf,
 686                                              &rt2x00debug_fop_dev_flags);
 687        if (IS_ERR(intf->dev_flags) || !intf->dev_flags)
 688                goto exit;
 689
 690        intf->cap_flags = debugfs_create_file("cap_flags", S_IRUSR,
 691                                              intf->driver_folder, intf,
 692                                              &rt2x00debug_fop_cap_flags);
 693        if (IS_ERR(intf->cap_flags) || !intf->cap_flags)
 694                goto exit;
 695
 696        intf->register_folder =
 697            debugfs_create_dir("register", intf->driver_folder);
 698        if (IS_ERR(intf->register_folder) || !intf->register_folder)
 699                goto exit;
 700
 701#define RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(__intf, __name)                     \
 702({                                                                              \
 703        if (debug->__name.read) {                                               \
 704                (__intf)->__name##_off_entry =                                  \
 705                debugfs_create_u32(__stringify(__name) "_offset",               \
 706                                       S_IRUSR | S_IWUSR,                       \
 707                                       (__intf)->register_folder,               \
 708                                       &(__intf)->offset_##__name);             \
 709                if (IS_ERR((__intf)->__name##_off_entry)                        \
 710                                || !(__intf)->__name##_off_entry)               \
 711                        goto exit;                                              \
 712                                                                                \
 713                (__intf)->__name##_val_entry =                                  \
 714                debugfs_create_file(__stringify(__name) "_value",               \
 715                                        S_IRUSR | S_IWUSR,                      \
 716                                        (__intf)->register_folder,              \
 717                                        (__intf), &rt2x00debug_fop_##__name);   \
 718                if (IS_ERR((__intf)->__name##_val_entry)                        \
 719                                || !(__intf)->__name##_val_entry)               \
 720                        goto exit;                                              \
 721        }                                                                       \
 722})
 723
 724        RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, csr);
 725        RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, eeprom);
 726        RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, bbp);
 727        RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, rf);
 728        RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, rfcsr);
 729
 730#undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY
 731
 732        intf->queue_folder =
 733            debugfs_create_dir("queue", intf->driver_folder);
 734        if (IS_ERR(intf->queue_folder) || !intf->queue_folder)
 735                goto exit;
 736
 737        intf->queue_frame_dump_entry =
 738            debugfs_create_file("dump", S_IRUSR, intf->queue_folder,
 739                                intf, &rt2x00debug_fop_queue_dump);
 740        if (IS_ERR(intf->queue_frame_dump_entry)
 741                || !intf->queue_frame_dump_entry)
 742                goto exit;
 743
 744        skb_queue_head_init(&intf->frame_dump_skbqueue);
 745        init_waitqueue_head(&intf->frame_dump_waitqueue);
 746
 747        intf->queue_stats_entry =
 748            debugfs_create_file("queue", S_IRUSR, intf->queue_folder,
 749                                intf, &rt2x00debug_fop_queue_stats);
 750
 751#ifdef CONFIG_RT2X00_LIB_CRYPTO
 752        if (rt2x00_has_cap_hw_crypto(rt2x00dev))
 753                intf->crypto_stats_entry =
 754                    debugfs_create_file("crypto", S_IRUGO, intf->queue_folder,
 755                                        intf, &rt2x00debug_fop_crypto_stats);
 756#endif
 757
 758        return;
 759
 760exit:
 761        rt2x00debug_deregister(rt2x00dev);
 762        rt2x00_err(rt2x00dev, "Failed to register debug handler\n");
 763}
 764
 765void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
 766{
 767        struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
 768
 769        if (unlikely(!intf))
 770                return;
 771
 772        skb_queue_purge(&intf->frame_dump_skbqueue);
 773
 774#ifdef CONFIG_RT2X00_LIB_CRYPTO
 775        debugfs_remove(intf->crypto_stats_entry);
 776#endif
 777        debugfs_remove(intf->queue_stats_entry);
 778        debugfs_remove(intf->queue_frame_dump_entry);
 779        debugfs_remove(intf->queue_folder);
 780        debugfs_remove(intf->rfcsr_val_entry);
 781        debugfs_remove(intf->rfcsr_off_entry);
 782        debugfs_remove(intf->rf_val_entry);
 783        debugfs_remove(intf->rf_off_entry);
 784        debugfs_remove(intf->bbp_val_entry);
 785        debugfs_remove(intf->bbp_off_entry);
 786        debugfs_remove(intf->eeprom_val_entry);
 787        debugfs_remove(intf->eeprom_off_entry);
 788        debugfs_remove(intf->csr_val_entry);
 789        debugfs_remove(intf->csr_off_entry);
 790        debugfs_remove(intf->register_folder);
 791        debugfs_remove(intf->dev_flags);
 792        debugfs_remove(intf->cap_flags);
 793        debugfs_remove(intf->chipset_entry);
 794        debugfs_remove(intf->driver_entry);
 795        debugfs_remove(intf->driver_folder);
 796        kfree(intf->chipset_blob.data);
 797        kfree(intf->driver_blob.data);
 798        kfree(intf);
 799
 800        rt2x00dev->debugfs_intf = NULL;
 801}
 802