rt2x00: In debugfs frame dumping allow the TX descriptor to be part of the skb.
[safe/jmp/linux-2.6] / 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 seperately 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 *skbdesc = get_skb_frame_desc(skb);
159         struct sk_buff *skbcopy;
160         struct rt2x00dump_hdr *dump_hdr;
161         struct timeval timestamp;
162         u32 data_len;
163
164         do_gettimeofday(&timestamp);
165
166         if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))
167                 return;
168
169         if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) {
170                 DEBUG(rt2x00dev, "txrx dump queue length exceeded.\n");
171                 return;
172         }
173
174         data_len = skb->len;
175         if (skbdesc->flags & SKBDESC_DESC_IN_SKB)
176                 data_len -= skbdesc->desc_len;
177
178         skbcopy = alloc_skb(sizeof(*dump_hdr) + skbdesc->desc_len + data_len,
179                             GFP_ATOMIC);
180         if (!skbcopy) {
181                 DEBUG(rt2x00dev, "Failed to copy skb for dump.\n");
182                 return;
183         }
184
185         dump_hdr = (struct rt2x00dump_hdr *)skb_put(skbcopy, sizeof(*dump_hdr));
186         dump_hdr->version = cpu_to_le32(DUMP_HEADER_VERSION);
187         dump_hdr->header_length = cpu_to_le32(sizeof(*dump_hdr));
188         dump_hdr->desc_length = cpu_to_le32(skbdesc->desc_len);
189         dump_hdr->data_length = cpu_to_le32(data_len);
190         dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt);
191         dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf);
192         dump_hdr->chip_rev = cpu_to_le16(rt2x00dev->chip.rev);
193         dump_hdr->type = cpu_to_le16(type);
194         dump_hdr->queue_index = skbdesc->entry->queue->qid;
195         dump_hdr->entry_index = skbdesc->entry->entry_idx;
196         dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec);
197         dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec);
198
199         if (!(skbdesc->flags & SKBDESC_DESC_IN_SKB))
200                 memcpy(skb_put(skbcopy, skbdesc->desc_len), skbdesc->desc,
201                        skbdesc->desc_len);
202         memcpy(skb_put(skbcopy, skb->len), skb->data, skb->len);
203
204         skb_queue_tail(&intf->frame_dump_skbqueue, skbcopy);
205         wake_up_interruptible(&intf->frame_dump_waitqueue);
206
207         /*
208          * Verify that the file has not been closed while we were working.
209          */
210         if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))
211                 skb_queue_purge(&intf->frame_dump_skbqueue);
212 }
213
214 static int rt2x00debug_file_open(struct inode *inode, struct file *file)
215 {
216         struct rt2x00debug_intf *intf = inode->i_private;
217
218         file->private_data = inode->i_private;
219
220         if (!try_module_get(intf->debug->owner))
221                 return -EBUSY;
222
223         return 0;
224 }
225
226 static int rt2x00debug_file_release(struct inode *inode, struct file *file)
227 {
228         struct rt2x00debug_intf *intf = file->private_data;
229
230         module_put(intf->debug->owner);
231
232         return 0;
233 }
234
235 static int rt2x00debug_open_queue_dump(struct inode *inode, struct file *file)
236 {
237         struct rt2x00debug_intf *intf = inode->i_private;
238         int retval;
239
240         retval = rt2x00debug_file_open(inode, file);
241         if (retval)
242                 return retval;
243
244         if (test_and_set_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)) {
245                 rt2x00debug_file_release(inode, file);
246                 return -EBUSY;
247         }
248
249         return 0;
250 }
251
252 static int rt2x00debug_release_queue_dump(struct inode *inode, struct file *file)
253 {
254         struct rt2x00debug_intf *intf = inode->i_private;
255
256         skb_queue_purge(&intf->frame_dump_skbqueue);
257
258         clear_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags);
259
260         return rt2x00debug_file_release(inode, file);
261 }
262
263 static ssize_t rt2x00debug_read_queue_dump(struct file *file,
264                                            char __user *buf,
265                                            size_t length,
266                                            loff_t *offset)
267 {
268         struct rt2x00debug_intf *intf = file->private_data;
269         struct sk_buff *skb;
270         size_t status;
271         int retval;
272
273         if (file->f_flags & O_NONBLOCK)
274                 return -EAGAIN;
275
276         retval =
277             wait_event_interruptible(intf->frame_dump_waitqueue,
278                                      (skb =
279                                      skb_dequeue(&intf->frame_dump_skbqueue)));
280         if (retval)
281                 return retval;
282
283         status = min((size_t)skb->len, length);
284         if (copy_to_user(buf, skb->data, status)) {
285                 status = -EFAULT;
286                 goto exit;
287         }
288
289         *offset += status;
290
291 exit:
292         kfree_skb(skb);
293
294         return status;
295 }
296
297 static unsigned int rt2x00debug_poll_queue_dump(struct file *file,
298                                                 poll_table *wait)
299 {
300         struct rt2x00debug_intf *intf = file->private_data;
301
302         poll_wait(file, &intf->frame_dump_waitqueue, wait);
303
304         if (!skb_queue_empty(&intf->frame_dump_skbqueue))
305                 return POLLOUT | POLLWRNORM;
306
307         return 0;
308 }
309
310 static const struct file_operations rt2x00debug_fop_queue_dump = {
311         .owner          = THIS_MODULE,
312         .read           = rt2x00debug_read_queue_dump,
313         .poll           = rt2x00debug_poll_queue_dump,
314         .open           = rt2x00debug_open_queue_dump,
315         .release        = rt2x00debug_release_queue_dump,
316 };
317
318 static ssize_t rt2x00debug_read_queue_stats(struct file *file,
319                                             char __user *buf,
320                                             size_t length,
321                                             loff_t *offset)
322 {
323         struct rt2x00debug_intf *intf = file->private_data;
324         struct data_queue *queue;
325         unsigned long irqflags;
326         unsigned int lines = 1 + intf->rt2x00dev->data_queues;
327         size_t size;
328         char *data;
329         char *temp;
330
331         if (*offset)
332                 return 0;
333
334         data = kzalloc(lines * MAX_LINE_LENGTH, GFP_KERNEL);
335         if (!data)
336                 return -ENOMEM;
337
338         temp = data +
339             sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdone\tcrypto\n");
340
341         queue_for_each(intf->rt2x00dev, queue) {
342                 spin_lock_irqsave(&queue->lock, irqflags);
343
344                 temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid,
345                                 queue->count, queue->limit, queue->length,
346                                 queue->index[Q_INDEX],
347                                 queue->index[Q_INDEX_DONE],
348                                 queue->index[Q_INDEX_CRYPTO]);
349
350                 spin_unlock_irqrestore(&queue->lock, irqflags);
351         }
352
353         size = strlen(data);
354         size = min(size, length);
355
356         if (copy_to_user(buf, data, size)) {
357                 kfree(data);
358                 return -EFAULT;
359         }
360
361         kfree(data);
362
363         *offset += size;
364         return size;
365 }
366
367 static const struct file_operations rt2x00debug_fop_queue_stats = {
368         .owner          = THIS_MODULE,
369         .read           = rt2x00debug_read_queue_stats,
370         .open           = rt2x00debug_file_open,
371         .release        = rt2x00debug_file_release,
372 };
373
374 #ifdef CONFIG_RT2X00_LIB_CRYPTO
375 static ssize_t rt2x00debug_read_crypto_stats(struct file *file,
376                                              char __user *buf,
377                                              size_t length,
378                                              loff_t *offset)
379 {
380         struct rt2x00debug_intf *intf = file->private_data;
381         char *name[] = { "WEP64", "WEP128", "TKIP", "AES" };
382         char *data;
383         char *temp;
384         size_t size;
385         unsigned int i;
386
387         if (*offset)
388                 return 0;
389
390         data = kzalloc((1 + CIPHER_MAX) * MAX_LINE_LENGTH, GFP_KERNEL);
391         if (!data)
392                 return -ENOMEM;
393
394         temp = data;
395         temp += sprintf(data, "cipher\tsuccess\ticv err\tmic err\tkey err\n");
396
397         for (i = 0; i < CIPHER_MAX; i++) {
398                 temp += sprintf(temp, "%s\t%lu\t%lu\t%lu\t%lu\n", name[i],
399                                 intf->crypto_stats[i].success,
400                                 intf->crypto_stats[i].icv_error,
401                                 intf->crypto_stats[i].mic_error,
402                                 intf->crypto_stats[i].key_error);
403         }
404
405         size = strlen(data);
406         size = min(size, length);
407
408         if (copy_to_user(buf, data, size)) {
409                 kfree(data);
410                 return -EFAULT;
411         }
412
413         kfree(data);
414
415         *offset += size;
416         return size;
417 }
418
419 static const struct file_operations rt2x00debug_fop_crypto_stats = {
420         .owner          = THIS_MODULE,
421         .read           = rt2x00debug_read_crypto_stats,
422         .open           = rt2x00debug_file_open,
423         .release        = rt2x00debug_file_release,
424 };
425 #endif
426
427 #define RT2X00DEBUGFS_OPS_READ(__name, __format, __type)        \
428 static ssize_t rt2x00debug_read_##__name(struct file *file,     \
429                                          char __user *buf,      \
430                                          size_t length,         \
431                                          loff_t *offset)        \
432 {                                                               \
433         struct rt2x00debug_intf *intf = file->private_data;     \
434         const struct rt2x00debug *debug = intf->debug;          \
435         char line[16];                                          \
436         size_t size;                                            \
437         unsigned int index = intf->offset_##__name;             \
438         __type value;                                           \
439                                                                 \
440         if (*offset)                                            \
441                 return 0;                                       \
442                                                                 \
443         if (index >= debug->__name.word_count)                  \
444                 return -EINVAL;                                 \
445                                                                 \
446         index += (debug->__name.word_base /                     \
447                   debug->__name.word_size);                     \
448                                                                 \
449         if (debug->__name.flags & RT2X00DEBUGFS_OFFSET)         \
450                 index *= debug->__name.word_size;               \
451                                                                 \
452         debug->__name.read(intf->rt2x00dev, index, &value);     \
453                                                                 \
454         size = sprintf(line, __format, value);                  \
455                                                                 \
456         if (copy_to_user(buf, line, size))                      \
457                 return -EFAULT;                                 \
458                                                                 \
459         *offset += size;                                        \
460         return size;                                            \
461 }
462
463 #define RT2X00DEBUGFS_OPS_WRITE(__name, __type)                 \
464 static ssize_t rt2x00debug_write_##__name(struct file *file,    \
465                                           const char __user *buf,\
466                                           size_t length,        \
467                                           loff_t *offset)       \
468 {                                                               \
469         struct rt2x00debug_intf *intf = file->private_data;     \
470         const struct rt2x00debug *debug = intf->debug;          \
471         char line[16];                                          \
472         size_t size;                                            \
473         unsigned int index = intf->offset_##__name;             \
474         __type value;                                           \
475                                                                 \
476         if (*offset)                                            \
477                 return 0;                                       \
478                                                                 \
479         if (index >= debug->__name.word_count)                  \
480                 return -EINVAL;                                 \
481                                                                 \
482         if (copy_from_user(line, buf, length))                  \
483                 return -EFAULT;                                 \
484                                                                 \
485         size = strlen(line);                                    \
486         value = simple_strtoul(line, NULL, 0);                  \
487                                                                 \
488         index += (debug->__name.word_base /                     \
489                   debug->__name.word_size);                     \
490                                                                 \
491         if (debug->__name.flags & RT2X00DEBUGFS_OFFSET)         \
492                 index *= debug->__name.word_size;               \
493                                                                 \
494         debug->__name.write(intf->rt2x00dev, index, value);     \
495                                                                 \
496         *offset += size;                                        \
497         return size;                                            \
498 }
499
500 #define RT2X00DEBUGFS_OPS(__name, __format, __type)             \
501 RT2X00DEBUGFS_OPS_READ(__name, __format, __type);               \
502 RT2X00DEBUGFS_OPS_WRITE(__name, __type);                        \
503                                                                 \
504 static const struct file_operations rt2x00debug_fop_##__name = {\
505         .owner          = THIS_MODULE,                          \
506         .read           = rt2x00debug_read_##__name,            \
507         .write          = rt2x00debug_write_##__name,           \
508         .open           = rt2x00debug_file_open,                \
509         .release        = rt2x00debug_file_release,             \
510 };
511
512 RT2X00DEBUGFS_OPS(csr, "0x%.8x\n", u32);
513 RT2X00DEBUGFS_OPS(eeprom, "0x%.4x\n", u16);
514 RT2X00DEBUGFS_OPS(bbp, "0x%.2x\n", u8);
515 RT2X00DEBUGFS_OPS(rf, "0x%.8x\n", u32);
516
517 static ssize_t rt2x00debug_read_dev_flags(struct file *file,
518                                           char __user *buf,
519                                           size_t length,
520                                           loff_t *offset)
521 {
522         struct rt2x00debug_intf *intf = file->private_data;
523         char line[16];
524         size_t size;
525
526         if (*offset)
527                 return 0;
528
529         size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->flags);
530
531         if (copy_to_user(buf, line, size))
532                 return -EFAULT;
533
534         *offset += size;
535         return size;
536 }
537
538 static const struct file_operations rt2x00debug_fop_dev_flags = {
539         .owner          = THIS_MODULE,
540         .read           = rt2x00debug_read_dev_flags,
541         .open           = rt2x00debug_file_open,
542         .release        = rt2x00debug_file_release,
543 };
544
545 static struct dentry *rt2x00debug_create_file_driver(const char *name,
546                                                      struct rt2x00debug_intf
547                                                      *intf,
548                                                      struct debugfs_blob_wrapper
549                                                      *blob)
550 {
551         char *data;
552
553         data = kzalloc(3 * MAX_LINE_LENGTH, GFP_KERNEL);
554         if (!data)
555                 return NULL;
556
557         blob->data = data;
558         data += sprintf(data, "driver:\t%s\n", intf->rt2x00dev->ops->name);
559         data += sprintf(data, "version:\t%s\n", DRV_VERSION);
560         data += sprintf(data, "compiled:\t%s %s\n", __DATE__, __TIME__);
561         blob->size = strlen(blob->data);
562
563         return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
564 }
565
566 static struct dentry *rt2x00debug_create_file_chipset(const char *name,
567                                                       struct rt2x00debug_intf
568                                                       *intf,
569                                                       struct
570                                                       debugfs_blob_wrapper
571                                                       *blob)
572 {
573         const struct rt2x00debug *debug = intf->debug;
574         char *data;
575
576         data = kzalloc(8 * MAX_LINE_LENGTH, GFP_KERNEL);
577         if (!data)
578                 return NULL;
579
580         blob->data = data;
581         data += sprintf(data, "rt chip:\t%04x\n", intf->rt2x00dev->chip.rt);
582         data += sprintf(data, "rf chip:\t%04x\n", intf->rt2x00dev->chip.rf);
583         data += sprintf(data, "revision:\t%04x\n", intf->rt2x00dev->chip.rev);
584         data += sprintf(data, "\n");
585         data += sprintf(data, "register\tbase\twords\twordsize\n");
586         data += sprintf(data, "csr\t%d\t%d\t%d\n",
587                         debug->csr.word_base,
588                         debug->csr.word_count,
589                         debug->csr.word_size);
590         data += sprintf(data, "eeprom\t%d\t%d\t%d\n",
591                         debug->eeprom.word_base,
592                         debug->eeprom.word_count,
593                         debug->eeprom.word_size);
594         data += sprintf(data, "bbp\t%d\t%d\t%d\n",
595                         debug->bbp.word_base,
596                         debug->bbp.word_count,
597                         debug->bbp.word_size);
598         data += sprintf(data, "rf\t%d\t%d\t%d\n",
599                         debug->rf.word_base,
600                         debug->rf.word_count,
601                         debug->rf.word_size);
602         blob->size = strlen(blob->data);
603
604         return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
605 }
606
607 void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
608 {
609         const struct rt2x00debug *debug = rt2x00dev->ops->debugfs;
610         struct rt2x00debug_intf *intf;
611
612         intf = kzalloc(sizeof(struct rt2x00debug_intf), GFP_KERNEL);
613         if (!intf) {
614                 ERROR(rt2x00dev, "Failed to allocate debug handler.\n");
615                 return;
616         }
617
618         intf->debug = debug;
619         intf->rt2x00dev = rt2x00dev;
620         rt2x00dev->debugfs_intf = intf;
621
622         intf->driver_folder =
623             debugfs_create_dir(intf->rt2x00dev->ops->name,
624                                rt2x00dev->hw->wiphy->debugfsdir);
625         if (IS_ERR(intf->driver_folder) || !intf->driver_folder)
626                 goto exit;
627
628         intf->driver_entry =
629             rt2x00debug_create_file_driver("driver", intf, &intf->driver_blob);
630         if (IS_ERR(intf->driver_entry) || !intf->driver_entry)
631                 goto exit;
632
633         intf->chipset_entry =
634             rt2x00debug_create_file_chipset("chipset",
635                                             intf, &intf->chipset_blob);
636         if (IS_ERR(intf->chipset_entry) || !intf->chipset_entry)
637                 goto exit;
638
639         intf->dev_flags = debugfs_create_file("dev_flags", S_IRUSR,
640                                               intf->driver_folder, intf,
641                                               &rt2x00debug_fop_dev_flags);
642         if (IS_ERR(intf->dev_flags) || !intf->dev_flags)
643                 goto exit;
644
645         intf->register_folder =
646             debugfs_create_dir("register", intf->driver_folder);
647         if (IS_ERR(intf->register_folder) || !intf->register_folder)
648                 goto exit;
649
650 #define RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(__intf, __name)     \
651 ({                                                              \
652         (__intf)->__name##_off_entry =                          \
653             debugfs_create_u32(__stringify(__name) "_offset",   \
654                                S_IRUSR | S_IWUSR,               \
655                                (__intf)->register_folder,       \
656                                &(__intf)->offset_##__name);     \
657         if (IS_ERR((__intf)->__name##_off_entry)                \
658                         || !(__intf)->__name##_off_entry)       \
659                 goto exit;                                      \
660                                                                 \
661         (__intf)->__name##_val_entry =                          \
662             debugfs_create_file(__stringify(__name) "_value",   \
663                                 S_IRUSR | S_IWUSR,              \
664                                 (__intf)->register_folder,      \
665                                 (__intf), &rt2x00debug_fop_##__name);\
666         if (IS_ERR((__intf)->__name##_val_entry)                \
667                         || !(__intf)->__name##_val_entry)       \
668                 goto exit;                                      \
669 })
670
671         RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, csr);
672         RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, eeprom);
673         RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, bbp);
674         RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, rf);
675
676 #undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY
677
678         intf->queue_folder =
679             debugfs_create_dir("queue", intf->driver_folder);
680         if (IS_ERR(intf->queue_folder) || !intf->queue_folder)
681                 goto exit;
682
683         intf->queue_frame_dump_entry =
684             debugfs_create_file("dump", S_IRUSR, intf->queue_folder,
685                                 intf, &rt2x00debug_fop_queue_dump);
686         if (IS_ERR(intf->queue_frame_dump_entry)
687                 || !intf->queue_frame_dump_entry)
688                 goto exit;
689
690         skb_queue_head_init(&intf->frame_dump_skbqueue);
691         init_waitqueue_head(&intf->frame_dump_waitqueue);
692
693         intf->queue_stats_entry =
694             debugfs_create_file("queue", S_IRUSR, intf->queue_folder,
695                                 intf, &rt2x00debug_fop_queue_stats);
696
697 #ifdef CONFIG_RT2X00_LIB_CRYPTO
698         if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
699                 intf->crypto_stats_entry =
700                     debugfs_create_file("crypto", S_IRUGO, intf->queue_folder,
701                                         intf, &rt2x00debug_fop_crypto_stats);
702 #endif
703
704         return;
705
706 exit:
707         rt2x00debug_deregister(rt2x00dev);
708         ERROR(rt2x00dev, "Failed to register debug handler.\n");
709
710         return;
711 }
712
713 void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
714 {
715         struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
716
717         if (unlikely(!intf))
718                 return;
719
720         skb_queue_purge(&intf->frame_dump_skbqueue);
721
722 #ifdef CONFIG_RT2X00_LIB_CRYPTO
723         debugfs_remove(intf->crypto_stats_entry);
724 #endif
725         debugfs_remove(intf->queue_stats_entry);
726         debugfs_remove(intf->queue_frame_dump_entry);
727         debugfs_remove(intf->queue_folder);
728         debugfs_remove(intf->rf_val_entry);
729         debugfs_remove(intf->rf_off_entry);
730         debugfs_remove(intf->bbp_val_entry);
731         debugfs_remove(intf->bbp_off_entry);
732         debugfs_remove(intf->eeprom_val_entry);
733         debugfs_remove(intf->eeprom_off_entry);
734         debugfs_remove(intf->csr_val_entry);
735         debugfs_remove(intf->csr_off_entry);
736         debugfs_remove(intf->register_folder);
737         debugfs_remove(intf->dev_flags);
738         debugfs_remove(intf->chipset_entry);
739         debugfs_remove(intf->driver_entry);
740         debugfs_remove(intf->driver_folder);
741         kfree(intf->chipset_blob.data);
742         kfree(intf->driver_blob.data);
743         kfree(intf);
744
745         rt2x00dev->debugfs_intf = NULL;
746 }