compat-wireless-2010-03-10
[pandora-wifi.git] / drivers / net / wireless / rt2x00 / rt2x00debug.c
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, write to the
17         Free Software Foundation, Inc.,
18         59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20
21 /*
22         Module: rt2x00lib
23         Abstract: rt2x00 debugfs specific routines.
24  */
25
26 #include <linux/debugfs.h>
27 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/poll.h>
30 #include <linux/sched.h>
31 #include <linux/uaccess.h>
32
33 #include "rt2x00.h"
34 #include "rt2x00lib.h"
35 #include "rt2x00dump.h"
36
37 #define MAX_LINE_LENGTH 64
38
39 struct rt2x00debug_crypto {
40         unsigned long success;
41         unsigned long icv_error;
42         unsigned long mic_error;
43         unsigned long key_error;
44 };
45
46 struct rt2x00debug_intf {
47         /*
48          * Pointer to driver structure where
49          * this debugfs entry belongs to.
50          */
51         struct rt2x00_dev *rt2x00dev;
52
53         /*
54          * Reference to the rt2x00debug structure
55          * which can be used to communicate with
56          * the registers.
57          */
58         const struct rt2x00debug *debug;
59
60         /*
61          * Debugfs entries for:
62          * - driver folder
63          *   - driver file
64          *   - chipset file
65          *   - device 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          *   - queue folder
72          *     - frame dump file
73          *     - queue stats file
74          *     - crypto stats file
75          */
76         struct dentry *driver_folder;
77         struct dentry *driver_entry;
78         struct dentry *chipset_entry;
79         struct dentry *dev_flags;
80         struct dentry *register_folder;
81         struct dentry *csr_off_entry;
82         struct dentry *csr_val_entry;
83         struct dentry *eeprom_off_entry;
84         struct dentry *eeprom_val_entry;
85         struct dentry *bbp_off_entry;
86         struct dentry *bbp_val_entry;
87         struct dentry *rf_off_entry;
88         struct dentry *rf_val_entry;
89         struct dentry *queue_folder;
90         struct dentry *queue_frame_dump_entry;
91         struct dentry *queue_stats_entry;
92         struct dentry *crypto_stats_entry;
93
94         /*
95          * The frame dump file only allows a single reader,
96          * so we need to store the current state here.
97          */
98         unsigned long frame_dump_flags;
99 #define FRAME_DUMP_FILE_OPEN    1
100
101         /*
102          * We queue each frame before dumping it to the user,
103          * per read command we will pass a single skb structure
104          * so we should be prepared to queue multiple sk buffers
105          * before sending it to userspace.
106          */
107         struct sk_buff_head frame_dump_skbqueue;
108         wait_queue_head_t frame_dump_waitqueue;
109
110         /*
111          * HW crypto statistics.
112          * All statistics are stored separately per cipher type.
113          */
114         struct rt2x00debug_crypto crypto_stats[CIPHER_MAX];
115
116         /*
117          * Driver and chipset files will use a data buffer
118          * that has been created in advance. This will simplify
119          * the code since we can use the debugfs functions.
120          */
121         struct debugfs_blob_wrapper driver_blob;
122         struct debugfs_blob_wrapper chipset_blob;
123
124         /*
125          * Requested offset for each register type.
126          */
127         unsigned int offset_csr;
128         unsigned int offset_eeprom;
129         unsigned int offset_bbp;
130         unsigned int offset_rf;
131 };
132
133 void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
134                                struct rxdone_entry_desc *rxdesc)
135 {
136         struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
137         enum cipher cipher = rxdesc->cipher;
138         enum rx_crypto status = rxdesc->cipher_status;
139
140         if (cipher == CIPHER_TKIP_NO_MIC)
141                 cipher = CIPHER_TKIP;
142         if (cipher == CIPHER_NONE || cipher >= CIPHER_MAX)
143                 return;
144
145         /* Remove CIPHER_NONE index */
146         cipher--;
147
148         intf->crypto_stats[cipher].success += (status == RX_CRYPTO_SUCCESS);
149         intf->crypto_stats[cipher].icv_error += (status == RX_CRYPTO_FAIL_ICV);
150         intf->crypto_stats[cipher].mic_error += (status == RX_CRYPTO_FAIL_MIC);
151         intf->crypto_stats[cipher].key_error += (status == RX_CRYPTO_FAIL_KEY);
152 }
153
154 void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
155                             enum rt2x00_dump_type type, struct sk_buff *skb)
156 {
157         struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
158         struct skb_frame_desc *desc = get_skb_frame_desc(skb);
159         struct sk_buff *skbcopy;
160         struct rt2x00dump_hdr *dump_hdr;
161         struct timeval timestamp;
162
163         do_gettimeofday(&timestamp);
164
165         if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))
166                 return;
167
168         if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) {
169                 DEBUG(rt2x00dev, "txrx dump queue length exceeded.\n");
170                 return;
171         }
172
173         skbcopy = alloc_skb(sizeof(*dump_hdr) + desc->desc_len + skb->len,
174                             GFP_ATOMIC);
175         if (!skbcopy) {
176                 DEBUG(rt2x00dev, "Failed to copy skb for dump.\n");
177                 return;
178         }
179
180         dump_hdr = (struct rt2x00dump_hdr *)skb_put(skbcopy, sizeof(*dump_hdr));
181         dump_hdr->version = cpu_to_le32(DUMP_HEADER_VERSION);
182         dump_hdr->header_length = cpu_to_le32(sizeof(*dump_hdr));
183         dump_hdr->desc_length = cpu_to_le32(desc->desc_len);
184         dump_hdr->data_length = cpu_to_le32(skb->len);
185         dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt);
186         dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf);
187         dump_hdr->chip_rev = cpu_to_le16(rt2x00dev->chip.rev);
188         dump_hdr->type = cpu_to_le16(type);
189         dump_hdr->queue_index = desc->entry->queue->qid;
190         dump_hdr->entry_index = desc->entry->entry_idx;
191         dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec);
192         dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec);
193
194         memcpy(skb_put(skbcopy, desc->desc_len), desc->desc, desc->desc_len);
195         memcpy(skb_put(skbcopy, skb->len), skb->data, skb->len);
196
197         skb_queue_tail(&intf->frame_dump_skbqueue, skbcopy);
198         wake_up_interruptible(&intf->frame_dump_waitqueue);
199
200         /*
201          * Verify that the file has not been closed while we were working.
202          */
203         if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))
204                 skb_queue_purge(&intf->frame_dump_skbqueue);
205 }
206
207 static int rt2x00debug_file_open(struct inode *inode, struct file *file)
208 {
209         struct rt2x00debug_intf *intf = inode->i_private;
210
211         file->private_data = inode->i_private;
212
213         if (!try_module_get(intf->debug->owner))
214                 return -EBUSY;
215
216         return 0;
217 }
218
219 static int rt2x00debug_file_release(struct inode *inode, struct file *file)
220 {
221         struct rt2x00debug_intf *intf = file->private_data;
222
223         module_put(intf->debug->owner);
224
225         return 0;
226 }
227
228 static int rt2x00debug_open_queue_dump(struct inode *inode, struct file *file)
229 {
230         struct rt2x00debug_intf *intf = inode->i_private;
231         int retval;
232
233         retval = rt2x00debug_file_open(inode, file);
234         if (retval)
235                 return retval;
236
237         if (test_and_set_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)) {
238                 rt2x00debug_file_release(inode, file);
239                 return -EBUSY;
240         }
241
242         return 0;
243 }
244
245 static int rt2x00debug_release_queue_dump(struct inode *inode, struct file *file)
246 {
247         struct rt2x00debug_intf *intf = inode->i_private;
248
249         skb_queue_purge(&intf->frame_dump_skbqueue);
250
251         clear_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags);
252
253         return rt2x00debug_file_release(inode, file);
254 }
255
256 static ssize_t rt2x00debug_read_queue_dump(struct file *file,
257                                            char __user *buf,
258                                            size_t length,
259                                            loff_t *offset)
260 {
261         struct rt2x00debug_intf *intf = file->private_data;
262         struct sk_buff *skb;
263         size_t status;
264         int retval;
265
266         if (file->f_flags & O_NONBLOCK)
267                 return -EAGAIN;
268
269         retval =
270             wait_event_interruptible(intf->frame_dump_waitqueue,
271                                      (skb =
272                                      skb_dequeue(&intf->frame_dump_skbqueue)));
273         if (retval)
274                 return retval;
275
276         status = min((size_t)skb->len, length);
277         if (copy_to_user(buf, skb->data, status)) {
278                 status = -EFAULT;
279                 goto exit;
280         }
281
282         *offset += status;
283
284 exit:
285         kfree_skb(skb);
286
287         return status;
288 }
289
290 static unsigned int rt2x00debug_poll_queue_dump(struct file *file,
291                                                 poll_table *wait)
292 {
293         struct rt2x00debug_intf *intf = file->private_data;
294
295         poll_wait(file, &intf->frame_dump_waitqueue, wait);
296
297         if (!skb_queue_empty(&intf->frame_dump_skbqueue))
298                 return POLLOUT | POLLWRNORM;
299
300         return 0;
301 }
302
303 static const struct file_operations rt2x00debug_fop_queue_dump = {
304         .owner          = THIS_MODULE,
305         .read           = rt2x00debug_read_queue_dump,
306         .poll           = rt2x00debug_poll_queue_dump,
307         .open           = rt2x00debug_open_queue_dump,
308         .release        = rt2x00debug_release_queue_dump,
309 };
310
311 static ssize_t rt2x00debug_read_queue_stats(struct file *file,
312                                             char __user *buf,
313                                             size_t length,
314                                             loff_t *offset)
315 {
316         struct rt2x00debug_intf *intf = file->private_data;
317         struct data_queue *queue;
318         unsigned long irqflags;
319         unsigned int lines = 1 + intf->rt2x00dev->data_queues;
320         size_t size;
321         char *data;
322         char *temp;
323
324         if (*offset)
325                 return 0;
326
327         data = kzalloc(lines * MAX_LINE_LENGTH, GFP_KERNEL);
328         if (!data)
329                 return -ENOMEM;
330
331         temp = data +
332             sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdone\tcrypto\n");
333
334         queue_for_each(intf->rt2x00dev, queue) {
335                 spin_lock_irqsave(&queue->lock, irqflags);
336
337                 temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid,
338                                 queue->count, queue->limit, queue->length,
339                                 queue->index[Q_INDEX],
340                                 queue->index[Q_INDEX_DONE],
341                                 queue->index[Q_INDEX_CRYPTO]);
342
343                 spin_unlock_irqrestore(&queue->lock, irqflags);
344         }
345
346         size = strlen(data);
347         size = min(size, length);
348
349         if (copy_to_user(buf, data, size)) {
350                 kfree(data);
351                 return -EFAULT;
352         }
353
354         kfree(data);
355
356         *offset += size;
357         return size;
358 }
359
360 static const struct file_operations rt2x00debug_fop_queue_stats = {
361         .owner          = THIS_MODULE,
362         .read           = rt2x00debug_read_queue_stats,
363         .open           = rt2x00debug_file_open,
364         .release        = rt2x00debug_file_release,
365 };
366
367 #ifdef CONFIG_RT2X00_LIB_CRYPTO
368 static ssize_t rt2x00debug_read_crypto_stats(struct file *file,
369                                              char __user *buf,
370                                              size_t length,
371                                              loff_t *offset)
372 {
373         struct rt2x00debug_intf *intf = file->private_data;
374         char *name[] = { "WEP64", "WEP128", "TKIP", "AES" };
375         char *data;
376         char *temp;
377         size_t size;
378         unsigned int i;
379
380         if (*offset)
381                 return 0;
382
383         data = kzalloc((1 + CIPHER_MAX) * MAX_LINE_LENGTH, GFP_KERNEL);
384         if (!data)
385                 return -ENOMEM;
386
387         temp = data;
388         temp += sprintf(data, "cipher\tsuccess\ticv err\tmic err\tkey err\n");
389
390         for (i = 0; i < CIPHER_MAX; i++) {
391                 temp += sprintf(temp, "%s\t%lu\t%lu\t%lu\t%lu\n", name[i],
392                                 intf->crypto_stats[i].success,
393                                 intf->crypto_stats[i].icv_error,
394                                 intf->crypto_stats[i].mic_error,
395                                 intf->crypto_stats[i].key_error);
396         }
397
398         size = strlen(data);
399         size = min(size, length);
400
401         if (copy_to_user(buf, data, size)) {
402                 kfree(data);
403                 return -EFAULT;
404         }
405
406         kfree(data);
407
408         *offset += size;
409         return size;
410 }
411
412 static const struct file_operations rt2x00debug_fop_crypto_stats = {
413         .owner          = THIS_MODULE,
414         .read           = rt2x00debug_read_crypto_stats,
415         .open           = rt2x00debug_file_open,
416         .release        = rt2x00debug_file_release,
417 };
418 #endif
419
420 #define RT2X00DEBUGFS_OPS_READ(__name, __format, __type)        \
421 static ssize_t rt2x00debug_read_##__name(struct file *file,     \
422                                          char __user *buf,      \
423                                          size_t length,         \
424                                          loff_t *offset)        \
425 {                                                               \
426         struct rt2x00debug_intf *intf = file->private_data;     \
427         const struct rt2x00debug *debug = intf->debug;          \
428         char line[16];                                          \
429         size_t size;                                            \
430         unsigned int index = intf->offset_##__name;             \
431         __type value;                                           \
432                                                                 \
433         if (*offset)                                            \
434                 return 0;                                       \
435                                                                 \
436         if (index >= debug->__name.word_count)                  \
437                 return -EINVAL;                                 \
438                                                                 \
439         index += (debug->__name.word_base /                     \
440                   debug->__name.word_size);                     \
441                                                                 \
442         if (debug->__name.flags & RT2X00DEBUGFS_OFFSET)         \
443                 index *= debug->__name.word_size;               \
444                                                                 \
445         debug->__name.read(intf->rt2x00dev, index, &value);     \
446                                                                 \
447         size = sprintf(line, __format, value);                  \
448                                                                 \
449         if (copy_to_user(buf, line, size))                      \
450                 return -EFAULT;                                 \
451                                                                 \
452         *offset += size;                                        \
453         return size;                                            \
454 }
455
456 #define RT2X00DEBUGFS_OPS_WRITE(__name, __type)                 \
457 static ssize_t rt2x00debug_write_##__name(struct file *file,    \
458                                           const char __user *buf,\
459                                           size_t length,        \
460                                           loff_t *offset)       \
461 {                                                               \
462         struct rt2x00debug_intf *intf = file->private_data;     \
463         const struct rt2x00debug *debug = intf->debug;          \
464         char line[16];                                          \
465         size_t size;                                            \
466         unsigned int index = intf->offset_##__name;             \
467         __type value;                                           \
468                                                                 \
469         if (*offset)                                            \
470                 return 0;                                       \
471                                                                 \
472         if (index >= debug->__name.word_count)                  \
473                 return -EINVAL;                                 \
474                                                                 \
475         if (copy_from_user(line, buf, length))                  \
476                 return -EFAULT;                                 \
477                                                                 \
478         size = strlen(line);                                    \
479         value = simple_strtoul(line, NULL, 0);                  \
480                                                                 \
481         index += (debug->__name.word_base /                     \
482                   debug->__name.word_size);                     \
483                                                                 \
484         if (debug->__name.flags & RT2X00DEBUGFS_OFFSET)         \
485                 index *= debug->__name.word_size;               \
486                                                                 \
487         debug->__name.write(intf->rt2x00dev, index, value);     \
488                                                                 \
489         *offset += size;                                        \
490         return size;                                            \
491 }
492
493 #define RT2X00DEBUGFS_OPS(__name, __format, __type)             \
494 RT2X00DEBUGFS_OPS_READ(__name, __format, __type);               \
495 RT2X00DEBUGFS_OPS_WRITE(__name, __type);                        \
496                                                                 \
497 static const struct file_operations rt2x00debug_fop_##__name = {\
498         .owner          = THIS_MODULE,                          \
499         .read           = rt2x00debug_read_##__name,            \
500         .write          = rt2x00debug_write_##__name,           \
501         .open           = rt2x00debug_file_open,                \
502         .release        = rt2x00debug_file_release,             \
503 };
504
505 RT2X00DEBUGFS_OPS(csr, "0x%.8x\n", u32);
506 RT2X00DEBUGFS_OPS(eeprom, "0x%.4x\n", u16);
507 RT2X00DEBUGFS_OPS(bbp, "0x%.2x\n", u8);
508 RT2X00DEBUGFS_OPS(rf, "0x%.8x\n", u32);
509
510 static ssize_t rt2x00debug_read_dev_flags(struct file *file,
511                                           char __user *buf,
512                                           size_t length,
513                                           loff_t *offset)
514 {
515         struct rt2x00debug_intf *intf = file->private_data;
516         char line[16];
517         size_t size;
518
519         if (*offset)
520                 return 0;
521
522         size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->flags);
523
524         if (copy_to_user(buf, line, size))
525                 return -EFAULT;
526
527         *offset += size;
528         return size;
529 }
530
531 static const struct file_operations rt2x00debug_fop_dev_flags = {
532         .owner          = THIS_MODULE,
533         .read           = rt2x00debug_read_dev_flags,
534         .open           = rt2x00debug_file_open,
535         .release        = rt2x00debug_file_release,
536 };
537
538 static struct dentry *rt2x00debug_create_file_driver(const char *name,
539                                                      struct rt2x00debug_intf
540                                                      *intf,
541                                                      struct debugfs_blob_wrapper
542                                                      *blob)
543 {
544         char *data;
545
546         data = kzalloc(3 * MAX_LINE_LENGTH, GFP_KERNEL);
547         if (!data)
548                 return NULL;
549
550         blob->data = data;
551         data += sprintf(data, "driver:\t%s\n", intf->rt2x00dev->ops->name);
552         data += sprintf(data, "version:\t%s\n", DRV_VERSION);
553         data += sprintf(data, "compiled:\t%s %s\n", __DATE__, __TIME__);
554         blob->size = strlen(blob->data);
555
556         return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
557 }
558
559 static struct dentry *rt2x00debug_create_file_chipset(const char *name,
560                                                       struct rt2x00debug_intf
561                                                       *intf,
562                                                       struct
563                                                       debugfs_blob_wrapper
564                                                       *blob)
565 {
566         const struct rt2x00debug *debug = intf->debug;
567         char *data;
568
569         data = kzalloc(8 * MAX_LINE_LENGTH, GFP_KERNEL);
570         if (!data)
571                 return NULL;
572
573         blob->data = data;
574         data += sprintf(data, "rt chip:\t%04x\n", intf->rt2x00dev->chip.rt);
575         data += sprintf(data, "rf chip:\t%04x\n", intf->rt2x00dev->chip.rf);
576         data += sprintf(data, "revision:\t%04x\n", intf->rt2x00dev->chip.rev);
577         data += sprintf(data, "\n");
578         data += sprintf(data, "register\tbase\twords\twordsize\n");
579         data += sprintf(data, "csr\t%d\t%d\t%d\n",
580                         debug->csr.word_base,
581                         debug->csr.word_count,
582                         debug->csr.word_size);
583         data += sprintf(data, "eeprom\t%d\t%d\t%d\n",
584                         debug->eeprom.word_base,
585                         debug->eeprom.word_count,
586                         debug->eeprom.word_size);
587         data += sprintf(data, "bbp\t%d\t%d\t%d\n",
588                         debug->bbp.word_base,
589                         debug->bbp.word_count,
590                         debug->bbp.word_size);
591         data += sprintf(data, "rf\t%d\t%d\t%d\n",
592                         debug->rf.word_base,
593                         debug->rf.word_count,
594                         debug->rf.word_size);
595         blob->size = strlen(blob->data);
596
597         return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
598 }
599
600 void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
601 {
602         const struct rt2x00debug *debug = rt2x00dev->ops->debugfs;
603         struct rt2x00debug_intf *intf;
604
605         intf = kzalloc(sizeof(struct rt2x00debug_intf), GFP_KERNEL);
606         if (!intf) {
607                 ERROR(rt2x00dev, "Failed to allocate debug handler.\n");
608                 return;
609         }
610
611         intf->debug = debug;
612         intf->rt2x00dev = rt2x00dev;
613         rt2x00dev->debugfs_intf = intf;
614
615         intf->driver_folder =
616             debugfs_create_dir(intf->rt2x00dev->ops->name,
617                                rt2x00dev->hw->wiphy->debugfsdir);
618         if (IS_ERR(intf->driver_folder) || !intf->driver_folder)
619                 goto exit;
620
621         intf->driver_entry =
622             rt2x00debug_create_file_driver("driver", intf, &intf->driver_blob);
623         if (IS_ERR(intf->driver_entry) || !intf->driver_entry)
624                 goto exit;
625
626         intf->chipset_entry =
627             rt2x00debug_create_file_chipset("chipset",
628                                             intf, &intf->chipset_blob);
629         if (IS_ERR(intf->chipset_entry) || !intf->chipset_entry)
630                 goto exit;
631
632         intf->dev_flags = debugfs_create_file("dev_flags", S_IRUSR,
633                                               intf->driver_folder, intf,
634                                               &rt2x00debug_fop_dev_flags);
635         if (IS_ERR(intf->dev_flags) || !intf->dev_flags)
636                 goto exit;
637
638         intf->register_folder =
639             debugfs_create_dir("register", intf->driver_folder);
640         if (IS_ERR(intf->register_folder) || !intf->register_folder)
641                 goto exit;
642
643 #define RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(__intf, __name)     \
644 ({                                                              \
645         (__intf)->__name##_off_entry =                          \
646             debugfs_create_u32(__stringify(__name) "_offset",   \
647                                S_IRUSR | S_IWUSR,               \
648                                (__intf)->register_folder,       \
649                                &(__intf)->offset_##__name);     \
650         if (IS_ERR((__intf)->__name##_off_entry)                \
651                         || !(__intf)->__name##_off_entry)       \
652                 goto exit;                                      \
653                                                                 \
654         (__intf)->__name##_val_entry =                          \
655             debugfs_create_file(__stringify(__name) "_value",   \
656                                 S_IRUSR | S_IWUSR,              \
657                                 (__intf)->register_folder,      \
658                                 (__intf), &rt2x00debug_fop_##__name);\
659         if (IS_ERR((__intf)->__name##_val_entry)                \
660                         || !(__intf)->__name##_val_entry)       \
661                 goto exit;                                      \
662 })
663
664         RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, csr);
665         RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, eeprom);
666         RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, bbp);
667         RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, rf);
668
669 #undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY
670
671         intf->queue_folder =
672             debugfs_create_dir("queue", intf->driver_folder);
673         if (IS_ERR(intf->queue_folder) || !intf->queue_folder)
674                 goto exit;
675
676         intf->queue_frame_dump_entry =
677             debugfs_create_file("dump", S_IRUSR, intf->queue_folder,
678                                 intf, &rt2x00debug_fop_queue_dump);
679         if (IS_ERR(intf->queue_frame_dump_entry)
680                 || !intf->queue_frame_dump_entry)
681                 goto exit;
682
683         skb_queue_head_init(&intf->frame_dump_skbqueue);
684         init_waitqueue_head(&intf->frame_dump_waitqueue);
685
686         intf->queue_stats_entry =
687             debugfs_create_file("queue", S_IRUSR, intf->queue_folder,
688                                 intf, &rt2x00debug_fop_queue_stats);
689
690 #ifdef CONFIG_RT2X00_LIB_CRYPTO
691         if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
692                 intf->crypto_stats_entry =
693                     debugfs_create_file("crypto", S_IRUGO, intf->queue_folder,
694                                         intf, &rt2x00debug_fop_crypto_stats);
695 #endif
696
697         return;
698
699 exit:
700         rt2x00debug_deregister(rt2x00dev);
701         ERROR(rt2x00dev, "Failed to register debug handler.\n");
702
703         return;
704 }
705
706 void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
707 {
708         struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
709
710         if (unlikely(!intf))
711                 return;
712
713         skb_queue_purge(&intf->frame_dump_skbqueue);
714
715 #ifdef CONFIG_RT2X00_LIB_CRYPTO
716         debugfs_remove(intf->crypto_stats_entry);
717 #endif
718         debugfs_remove(intf->queue_stats_entry);
719         debugfs_remove(intf->queue_frame_dump_entry);
720         debugfs_remove(intf->queue_folder);
721         debugfs_remove(intf->rf_val_entry);
722         debugfs_remove(intf->rf_off_entry);
723         debugfs_remove(intf->bbp_val_entry);
724         debugfs_remove(intf->bbp_off_entry);
725         debugfs_remove(intf->eeprom_val_entry);
726         debugfs_remove(intf->eeprom_off_entry);
727         debugfs_remove(intf->csr_val_entry);
728         debugfs_remove(intf->csr_off_entry);
729         debugfs_remove(intf->register_folder);
730         debugfs_remove(intf->dev_flags);
731         debugfs_remove(intf->chipset_entry);
732         debugfs_remove(intf->driver_entry);
733         debugfs_remove(intf->driver_folder);
734         kfree(intf->chipset_blob.data);
735         kfree(intf->driver_blob.data);
736         kfree(intf);
737
738         rt2x00dev->debugfs_intf = NULL;
739 }