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