Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.25
[linux-2.6] / drivers / net / wireless / rt2x00 / rt2x00debug.c
1 /*
2         Copyright (C) 2004 - 2007 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 PRINT_LINE_LEN_MAX 32
37
38 struct rt2x00debug_intf {
39         /*
40          * Pointer to driver structure where
41          * this debugfs entry belongs to.
42          */
43         struct rt2x00_dev *rt2x00dev;
44
45         /*
46          * Reference to the rt2x00debug structure
47          * which can be used to communicate with
48          * the registers.
49          */
50         const struct rt2x00debug *debug;
51
52         /*
53          * Debugfs entries for:
54          * - driver folder
55          *   - driver file
56          *   - chipset file
57          *   - device flags file
58          *   - register folder
59          *     - csr offset/value files
60          *     - eeprom offset/value files
61          *     - bbp offset/value files
62          *     - rf offset/value files
63          *   - frame dump folder
64          *     - frame dump file
65          */
66         struct dentry *driver_folder;
67         struct dentry *driver_entry;
68         struct dentry *chipset_entry;
69         struct dentry *dev_flags;
70         struct dentry *register_folder;
71         struct dentry *csr_off_entry;
72         struct dentry *csr_val_entry;
73         struct dentry *eeprom_off_entry;
74         struct dentry *eeprom_val_entry;
75         struct dentry *bbp_off_entry;
76         struct dentry *bbp_val_entry;
77         struct dentry *rf_off_entry;
78         struct dentry *rf_val_entry;
79         struct dentry *frame_folder;
80         struct dentry *frame_dump_entry;
81
82         /*
83          * The frame dump file only allows a single reader,
84          * so we need to store the current state here.
85          */
86         unsigned long frame_dump_flags;
87 #define FRAME_DUMP_FILE_OPEN    1
88
89         /*
90          * We queue each frame before dumping it to the user,
91          * per read command we will pass a single skb structure
92          * so we should be prepared to queue multiple sk buffers
93          * before sending it to userspace.
94          */
95         struct sk_buff_head frame_dump_skbqueue;
96         wait_queue_head_t frame_dump_waitqueue;
97
98         /*
99          * Driver and chipset files will use a data buffer
100          * that has been created in advance. This will simplify
101          * the code since we can use the debugfs functions.
102          */
103         struct debugfs_blob_wrapper driver_blob;
104         struct debugfs_blob_wrapper chipset_blob;
105
106         /*
107          * Requested offset for each register type.
108          */
109         unsigned int offset_csr;
110         unsigned int offset_eeprom;
111         unsigned int offset_bbp;
112         unsigned int offset_rf;
113 };
114
115 void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
116                             struct sk_buff *skb)
117 {
118         struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
119         struct skb_desc *desc = get_skb_desc(skb);
120         struct sk_buff *skbcopy;
121         struct rt2x00dump_hdr *dump_hdr;
122         struct timeval timestamp;
123
124         do_gettimeofday(&timestamp);
125
126         if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))
127                 return;
128
129         if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) {
130                 DEBUG(rt2x00dev, "txrx dump queue length exceeded.\n");
131                 return;
132         }
133
134         skbcopy = alloc_skb(sizeof(*dump_hdr) + desc->desc_len + desc->data_len,
135                             GFP_ATOMIC);
136         if (!skbcopy) {
137                 DEBUG(rt2x00dev, "Failed to copy skb for dump.\n");
138                 return;
139         }
140
141         dump_hdr = (struct rt2x00dump_hdr *)skb_put(skbcopy, sizeof(*dump_hdr));
142         dump_hdr->version = cpu_to_le32(DUMP_HEADER_VERSION);
143         dump_hdr->header_length = cpu_to_le32(sizeof(*dump_hdr));
144         dump_hdr->desc_length = cpu_to_le32(desc->desc_len);
145         dump_hdr->data_length = cpu_to_le32(desc->data_len);
146         dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt);
147         dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf);
148         dump_hdr->chip_rev = cpu_to_le32(rt2x00dev->chip.rev);
149         dump_hdr->type = cpu_to_le16(desc->frame_type);
150         dump_hdr->ring_index = desc->ring->queue_idx;
151         dump_hdr->entry_index = desc->entry->entry_idx;
152         dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec);
153         dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec);
154
155         memcpy(skb_put(skbcopy, desc->desc_len), desc->desc, desc->desc_len);
156         memcpy(skb_put(skbcopy, desc->data_len), desc->data, desc->data_len);
157
158         skb_queue_tail(&intf->frame_dump_skbqueue, skbcopy);
159         wake_up_interruptible(&intf->frame_dump_waitqueue);
160
161         /*
162          * Verify that the file has not been closed while we were working.
163          */
164         if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))
165                 skb_queue_purge(&intf->frame_dump_skbqueue);
166 }
167
168 static int rt2x00debug_file_open(struct inode *inode, struct file *file)
169 {
170         struct rt2x00debug_intf *intf = inode->i_private;
171
172         file->private_data = inode->i_private;
173
174         if (!try_module_get(intf->debug->owner))
175                 return -EBUSY;
176
177         return 0;
178 }
179
180 static int rt2x00debug_file_release(struct inode *inode, struct file *file)
181 {
182         struct rt2x00debug_intf *intf = file->private_data;
183
184         module_put(intf->debug->owner);
185
186         return 0;
187 }
188
189 static int rt2x00debug_open_ring_dump(struct inode *inode, struct file *file)
190 {
191         struct rt2x00debug_intf *intf = inode->i_private;
192         int retval;
193
194         retval = rt2x00debug_file_open(inode, file);
195         if (retval)
196                 return retval;
197
198         if (test_and_set_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)) {
199                 rt2x00debug_file_release(inode, file);
200                 return -EBUSY;
201         }
202
203         return 0;
204 }
205
206 static int rt2x00debug_release_ring_dump(struct inode *inode, struct file *file)
207 {
208         struct rt2x00debug_intf *intf = inode->i_private;
209
210         skb_queue_purge(&intf->frame_dump_skbqueue);
211
212         clear_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags);
213
214         return rt2x00debug_file_release(inode, file);
215 }
216
217 static ssize_t rt2x00debug_read_ring_dump(struct file *file,
218                                           char __user *buf,
219                                           size_t length,
220                                           loff_t *offset)
221 {
222         struct rt2x00debug_intf *intf = file->private_data;
223         struct sk_buff *skb;
224         size_t status;
225         int retval;
226
227         if (file->f_flags & O_NONBLOCK)
228                 return -EAGAIN;
229
230         retval =
231             wait_event_interruptible(intf->frame_dump_waitqueue,
232                                      (skb =
233                                      skb_dequeue(&intf->frame_dump_skbqueue)));
234         if (retval)
235                 return retval;
236
237         status = min((size_t)skb->len, length);
238         if (copy_to_user(buf, skb->data, status)) {
239                 status = -EFAULT;
240                 goto exit;
241         }
242
243         *offset += status;
244
245 exit:
246         kfree_skb(skb);
247
248         return status;
249 }
250
251 static unsigned int rt2x00debug_poll_ring_dump(struct file *file,
252                                                poll_table *wait)
253 {
254         struct rt2x00debug_intf *intf = file->private_data;
255
256         poll_wait(file, &intf->frame_dump_waitqueue, wait);
257
258         if (!skb_queue_empty(&intf->frame_dump_skbqueue))
259                 return POLLOUT | POLLWRNORM;
260
261         return 0;
262 }
263
264 static const struct file_operations rt2x00debug_fop_ring_dump = {
265         .owner          = THIS_MODULE,
266         .read           = rt2x00debug_read_ring_dump,
267         .poll           = rt2x00debug_poll_ring_dump,
268         .open           = rt2x00debug_open_ring_dump,
269         .release        = rt2x00debug_release_ring_dump,
270 };
271
272 #define RT2X00DEBUGFS_OPS_READ(__name, __format, __type)        \
273 static ssize_t rt2x00debug_read_##__name(struct file *file,     \
274                                          char __user *buf,      \
275                                          size_t length,         \
276                                          loff_t *offset)        \
277 {                                                               \
278         struct rt2x00debug_intf *intf = file->private_data;     \
279         const struct rt2x00debug *debug = intf->debug;          \
280         char line[16];                                          \
281         size_t size;                                            \
282         __type value;                                           \
283                                                                 \
284         if (*offset)                                            \
285                 return 0;                                       \
286                                                                 \
287         if (intf->offset_##__name >= debug->__name.word_count)  \
288                 return -EINVAL;                                 \
289                                                                 \
290         debug->__name.read(intf->rt2x00dev,                     \
291                            intf->offset_##__name, &value);      \
292                                                                 \
293         size = sprintf(line, __format, value);                  \
294                                                                 \
295         if (copy_to_user(buf, line, size))                      \
296                 return -EFAULT;                                 \
297                                                                 \
298         *offset += size;                                        \
299         return size;                                            \
300 }
301
302 #define RT2X00DEBUGFS_OPS_WRITE(__name, __type)                 \
303 static ssize_t rt2x00debug_write_##__name(struct file *file,    \
304                                           const char __user *buf,\
305                                           size_t length,        \
306                                           loff_t *offset)       \
307 {                                                               \
308         struct rt2x00debug_intf *intf = file->private_data;     \
309         const struct rt2x00debug *debug = intf->debug;          \
310         char line[16];                                          \
311         size_t size;                                            \
312         __type value;                                           \
313                                                                 \
314         if (*offset)                                            \
315                 return 0;                                       \
316                                                                 \
317         if (!capable(CAP_NET_ADMIN))                            \
318                 return -EPERM;                                  \
319                                                                 \
320         if (intf->offset_##__name >= debug->__name.word_count)  \
321                 return -EINVAL;                                 \
322                                                                 \
323         if (copy_from_user(line, buf, length))                  \
324                 return -EFAULT;                                 \
325                                                                 \
326         size = strlen(line);                                    \
327         value = simple_strtoul(line, NULL, 0);                  \
328                                                                 \
329         debug->__name.write(intf->rt2x00dev,                    \
330                             intf->offset_##__name, value);      \
331                                                                 \
332         *offset += size;                                        \
333         return size;                                            \
334 }
335
336 #define RT2X00DEBUGFS_OPS(__name, __format, __type)             \
337 RT2X00DEBUGFS_OPS_READ(__name, __format, __type);               \
338 RT2X00DEBUGFS_OPS_WRITE(__name, __type);                        \
339                                                                 \
340 static const struct file_operations rt2x00debug_fop_##__name = {\
341         .owner          = THIS_MODULE,                          \
342         .read           = rt2x00debug_read_##__name,            \
343         .write          = rt2x00debug_write_##__name,           \
344         .open           = rt2x00debug_file_open,                \
345         .release        = rt2x00debug_file_release,             \
346 };
347
348 RT2X00DEBUGFS_OPS(csr, "0x%.8x\n", u32);
349 RT2X00DEBUGFS_OPS(eeprom, "0x%.4x\n", u16);
350 RT2X00DEBUGFS_OPS(bbp, "0x%.2x\n", u8);
351 RT2X00DEBUGFS_OPS(rf, "0x%.8x\n", u32);
352
353 static ssize_t rt2x00debug_read_dev_flags(struct file *file,
354                                           char __user *buf,
355                                           size_t length,
356                                           loff_t *offset)
357 {
358         struct rt2x00debug_intf *intf = file->private_data;
359         char line[16];
360         size_t size;
361
362         if (*offset)
363                 return 0;
364
365         size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->flags);
366
367         if (copy_to_user(buf, line, size))
368                 return -EFAULT;
369
370         *offset += size;
371         return size;
372 }
373
374 static const struct file_operations rt2x00debug_fop_dev_flags = {
375         .owner          = THIS_MODULE,
376         .read           = rt2x00debug_read_dev_flags,
377         .open           = rt2x00debug_file_open,
378         .release        = rt2x00debug_file_release,
379 };
380
381 static struct dentry *rt2x00debug_create_file_driver(const char *name,
382                                                      struct rt2x00debug_intf
383                                                      *intf,
384                                                      struct debugfs_blob_wrapper
385                                                      *blob)
386 {
387         char *data;
388
389         data = kzalloc(3 * PRINT_LINE_LEN_MAX, GFP_KERNEL);
390         if (!data)
391                 return NULL;
392
393         blob->data = data;
394         data += sprintf(data, "driver: %s\n", intf->rt2x00dev->ops->name);
395         data += sprintf(data, "version: %s\n", DRV_VERSION);
396         data += sprintf(data, "compiled: %s %s\n", __DATE__, __TIME__);
397         blob->size = strlen(blob->data);
398
399         return debugfs_create_blob(name, S_IRUGO, intf->driver_folder, blob);
400 }
401
402 static struct dentry *rt2x00debug_create_file_chipset(const char *name,
403                                                       struct rt2x00debug_intf
404                                                       *intf,
405                                                       struct
406                                                       debugfs_blob_wrapper
407                                                       *blob)
408 {
409         const struct rt2x00debug *debug = intf->debug;
410         char *data;
411
412         data = kzalloc(8 * PRINT_LINE_LEN_MAX, GFP_KERNEL);
413         if (!data)
414                 return NULL;
415
416         blob->data = data;
417         data += sprintf(data, "rt chip: %04x\n", intf->rt2x00dev->chip.rt);
418         data += sprintf(data, "rf chip: %04x\n", intf->rt2x00dev->chip.rf);
419         data += sprintf(data, "revision:%08x\n", intf->rt2x00dev->chip.rev);
420         data += sprintf(data, "\n");
421         data += sprintf(data, "csr length: %d\n", debug->csr.word_count);
422         data += sprintf(data, "eeprom length: %d\n", debug->eeprom.word_count);
423         data += sprintf(data, "bbp length: %d\n", debug->bbp.word_count);
424         data += sprintf(data, "rf length: %d\n", debug->rf.word_count);
425         blob->size = strlen(blob->data);
426
427         return debugfs_create_blob(name, S_IRUGO, intf->driver_folder, blob);
428 }
429
430 void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
431 {
432         const struct rt2x00debug *debug = rt2x00dev->ops->debugfs;
433         struct rt2x00debug_intf *intf;
434
435         intf = kzalloc(sizeof(struct rt2x00debug_intf), GFP_KERNEL);
436         if (!intf) {
437                 ERROR(rt2x00dev, "Failed to allocate debug handler.\n");
438                 return;
439         }
440
441         intf->debug = debug;
442         intf->rt2x00dev = rt2x00dev;
443         rt2x00dev->debugfs_intf = intf;
444
445         intf->driver_folder =
446             debugfs_create_dir(intf->rt2x00dev->ops->name,
447                                rt2x00dev->hw->wiphy->debugfsdir);
448         if (IS_ERR(intf->driver_folder))
449                 goto exit;
450
451         intf->driver_entry =
452             rt2x00debug_create_file_driver("driver", intf, &intf->driver_blob);
453         if (IS_ERR(intf->driver_entry))
454                 goto exit;
455
456         intf->chipset_entry =
457             rt2x00debug_create_file_chipset("chipset",
458                                             intf, &intf->chipset_blob);
459         if (IS_ERR(intf->chipset_entry))
460                 goto exit;
461
462         intf->dev_flags = debugfs_create_file("dev_flags", S_IRUGO,
463                                               intf->driver_folder, intf,
464                                               &rt2x00debug_fop_dev_flags);
465         if (IS_ERR(intf->dev_flags))
466                 goto exit;
467
468         intf->register_folder =
469             debugfs_create_dir("register", intf->driver_folder);
470         if (IS_ERR(intf->register_folder))
471                 goto exit;
472
473 #define RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(__intf, __name)     \
474 ({                                                              \
475         (__intf)->__name##_off_entry =                          \
476             debugfs_create_u32(__stringify(__name) "_offset",   \
477                                S_IRUGO | S_IWUSR,               \
478                                (__intf)->register_folder,       \
479                                &(__intf)->offset_##__name);     \
480         if (IS_ERR((__intf)->__name##_off_entry))               \
481                 goto exit;                                      \
482                                                                 \
483         (__intf)->__name##_val_entry =                          \
484             debugfs_create_file(__stringify(__name) "_value",   \
485                                 S_IRUGO | S_IWUSR,              \
486                                 (__intf)->register_folder,      \
487                                 (__intf), &rt2x00debug_fop_##__name);\
488         if (IS_ERR((__intf)->__name##_val_entry))               \
489                 goto exit;                                      \
490 })
491
492         RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, csr);
493         RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, eeprom);
494         RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, bbp);
495         RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, rf);
496
497 #undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY
498
499         intf->frame_folder =
500             debugfs_create_dir("frame", intf->driver_folder);
501         if (IS_ERR(intf->frame_folder))
502                 goto exit;
503
504         intf->frame_dump_entry =
505             debugfs_create_file("dump", S_IRUGO, intf->frame_folder,
506                                 intf, &rt2x00debug_fop_ring_dump);
507         if (IS_ERR(intf->frame_dump_entry))
508                 goto exit;
509
510         skb_queue_head_init(&intf->frame_dump_skbqueue);
511         init_waitqueue_head(&intf->frame_dump_waitqueue);
512
513         return;
514
515 exit:
516         rt2x00debug_deregister(rt2x00dev);
517         ERROR(rt2x00dev, "Failed to register debug handler.\n");
518
519         return;
520 }
521
522 void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
523 {
524         struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
525
526         if (unlikely(!intf))
527                 return;
528
529         skb_queue_purge(&intf->frame_dump_skbqueue);
530
531         debugfs_remove(intf->frame_dump_entry);
532         debugfs_remove(intf->frame_folder);
533         debugfs_remove(intf->rf_val_entry);
534         debugfs_remove(intf->rf_off_entry);
535         debugfs_remove(intf->bbp_val_entry);
536         debugfs_remove(intf->bbp_off_entry);
537         debugfs_remove(intf->eeprom_val_entry);
538         debugfs_remove(intf->eeprom_off_entry);
539         debugfs_remove(intf->csr_val_entry);
540         debugfs_remove(intf->csr_off_entry);
541         debugfs_remove(intf->register_folder);
542         debugfs_remove(intf->dev_flags);
543         debugfs_remove(intf->chipset_entry);
544         debugfs_remove(intf->driver_entry);
545         debugfs_remove(intf->driver_folder);
546         kfree(intf->chipset_blob.data);
547         kfree(intf->driver_blob.data);
548         kfree(intf);
549
550         rt2x00dev->debugfs_intf = NULL;
551 }