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