[PATCH] libertas: make debug configurable
[safe/jmp/linux-2.6] / drivers / net / wireless / libertas / debugfs.c
1 #include <linux/module.h>
2 #include <linux/dcache.h>
3 #include <linux/debugfs.h>
4 #include <linux/delay.h>
5 #include <linux/mm.h>
6 #include <net/iw_handler.h>
7
8 #include "dev.h"
9 #include "decl.h"
10 #include "host.h"
11 #include "debugfs.h"
12
13 static struct dentry *libertas_dir = NULL;
14 static char *szStates[] = {
15         "Connected",
16         "Disconnected"
17 };
18
19 #ifdef PROC_DEBUG
20 static void libertas_debug_init(wlan_private * priv, struct net_device *dev);
21 #endif
22
23 static int open_file_generic(struct inode *inode, struct file *file)
24 {
25         file->private_data = inode->i_private;
26         return 0;
27 }
28
29 static ssize_t write_file_dummy(struct file *file, const char __user *buf,
30                                 size_t count, loff_t *ppos)
31 {
32         return -EINVAL;
33 }
34
35 static const size_t len = PAGE_SIZE;
36
37 static ssize_t libertas_dev_info(struct file *file, char __user *userbuf,
38                                   size_t count, loff_t *ppos)
39 {
40         wlan_private *priv = file->private_data;
41         size_t pos = 0;
42         unsigned long addr = get_zeroed_page(GFP_KERNEL);
43         char *buf = (char *)addr;
44         ssize_t res;
45
46         pos += snprintf(buf+pos, len-pos, "state = %s\n",
47                                 szStates[priv->adapter->connect_status]);
48         pos += snprintf(buf+pos, len-pos, "region_code = %02x\n",
49                                 (u32) priv->adapter->regioncode);
50
51         res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
52
53         free_page(addr);
54         return res;
55 }
56
57
58 static ssize_t libertas_getscantable(struct file *file, char __user *userbuf,
59                                   size_t count, loff_t *ppos)
60 {
61         wlan_private *priv = file->private_data;
62         size_t pos = 0;
63         int numscansdone = 0, res;
64         unsigned long addr = get_zeroed_page(GFP_KERNEL);
65         char *buf = (char *)addr;
66
67         pos += snprintf(buf+pos, len-pos,
68                 "# | ch  | ss  |       bssid       |   cap    |    TSF   | Qual | SSID \n");
69
70         while (numscansdone < priv->adapter->numinscantable) {
71                 struct bss_descriptor *pbssinfo;
72                 u16 cap;
73
74                 pbssinfo = &priv->adapter->scantable[numscansdone];
75                 memcpy(&cap, &pbssinfo->cap, sizeof(cap));
76                 pos += snprintf(buf+pos, len-pos,
77                         "%02u| %03d | %03ld | %02x:%02x:%02x:%02x:%02x:%02x |",
78                         numscansdone, pbssinfo->channel, pbssinfo->rssi,
79                         pbssinfo->macaddress[0], pbssinfo->macaddress[1],
80                         pbssinfo->macaddress[2], pbssinfo->macaddress[3],
81                         pbssinfo->macaddress[4], pbssinfo->macaddress[5]);
82                 pos += snprintf(buf+pos, len-pos, " %04x-", cap);
83                 pos += snprintf(buf+pos, len-pos, "%c%c%c |",
84                                 pbssinfo->cap.ibss ? 'A' : 'I',
85                                 pbssinfo->cap.privacy ? 'P' : ' ',
86                                 pbssinfo->cap.spectrummgmt ? 'S' : ' ');
87                 pos += snprintf(buf+pos, len-pos, " %08llx |", pbssinfo->networktsf);
88                 pos += snprintf(buf+pos, len-pos, " %d |",
89                         SCAN_RSSI(priv->adapter->scantable[numscansdone].rssi));
90
91                 pos += snprintf(buf+pos, len-pos, " %s\n", pbssinfo->ssid.ssid);
92
93                 numscansdone++;
94         }
95
96         res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
97
98         free_page(addr);
99         return res;
100 }
101
102 static ssize_t libertas_sleepparams_write(struct file *file,
103                                 const char __user *user_buf, size_t count,
104                                 loff_t *ppos)
105 {
106         wlan_private *priv = file->private_data;
107         ssize_t buf_size, res;
108         int p1, p2, p3, p4, p5, p6;
109         struct sleep_params sp;
110         unsigned long addr = get_zeroed_page(GFP_KERNEL);
111         char *buf = (char *)addr;
112
113         buf_size = min(count, len - 1);
114         if (copy_from_user(buf, user_buf, buf_size)) {
115                 res = -EFAULT;
116                 goto out_unlock;
117         }
118         res = sscanf(buf, "%d %d %d %d %d %d", &p1, &p2, &p3, &p4, &p5, &p6);
119         if (res != 6) {
120                 res = -EFAULT;
121                 goto out_unlock;
122         }
123         sp.sp_error = p1;
124         sp.sp_offset = p2;
125         sp.sp_stabletime = p3;
126         sp.sp_calcontrol = p4;
127         sp.sp_extsleepclk = p5;
128         sp.sp_reserved = p6;
129
130         memcpy(&priv->adapter->sp, &sp, sizeof(struct sleep_params));
131
132         res = libertas_prepare_and_send_command(priv,
133                                 cmd_802_11_sleep_params,
134                                 cmd_act_set,
135                                 cmd_option_waitforrsp, 0, NULL);
136
137         if (!res)
138                 res = count;
139         else
140                 res = -EINVAL;
141
142 out_unlock:
143         free_page(addr);
144         return res;
145 }
146
147 static ssize_t libertas_sleepparams_read(struct file *file, char __user *userbuf,
148                                   size_t count, loff_t *ppos)
149 {
150         wlan_private *priv = file->private_data;
151         wlan_adapter *adapter = priv->adapter;
152         ssize_t res;
153         size_t pos = 0;
154         unsigned long addr = get_zeroed_page(GFP_KERNEL);
155         char *buf = (char *)addr;
156
157         res = libertas_prepare_and_send_command(priv,
158                                 cmd_802_11_sleep_params,
159                                 cmd_act_get,
160                                 cmd_option_waitforrsp, 0, NULL);
161         if (res) {
162                 res = -EFAULT;
163                 goto out_unlock;
164         }
165
166         pos += snprintf(buf, len, "%d %d %d %d %d %d\n", adapter->sp.sp_error,
167                         adapter->sp.sp_offset, adapter->sp.sp_stabletime,
168                         adapter->sp.sp_calcontrol, adapter->sp.sp_extsleepclk,
169                         adapter->sp.sp_reserved);
170
171         res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
172
173 out_unlock:
174         free_page(addr);
175         return res;
176 }
177
178 static ssize_t libertas_extscan(struct file *file, const char __user *userbuf,
179                                   size_t count, loff_t *ppos)
180 {
181         wlan_private *priv = file->private_data;
182         ssize_t res, buf_size;
183         struct WLAN_802_11_SSID extscan_ssid;
184         union iwreq_data wrqu;
185         unsigned long addr = get_zeroed_page(GFP_KERNEL);
186         char *buf = (char *)addr;
187
188         buf_size = min(count, len - 1);
189         if (copy_from_user(buf, userbuf, buf_size)) {
190                 res = -EFAULT;
191                 goto out_unlock;
192         }
193
194         memcpy(&extscan_ssid.ssid, buf, strlen(buf)-1);
195         extscan_ssid.ssidlength = strlen(buf)-1;
196
197         libertas_send_specific_SSID_scan(priv, &extscan_ssid, 1);
198
199         memset(&wrqu, 0, sizeof(union iwreq_data));
200         wireless_send_event(priv->wlan_dev.netdev, SIOCGIWSCAN, &wrqu, NULL);
201
202 out_unlock:
203         free_page(addr);
204         return count;
205 }
206
207 static int libertas_parse_chan(char *buf, size_t count,
208                         struct wlan_ioctl_user_scan_cfg *scan_cfg, int dur)
209 {
210         char *start, *end, *hold, *str;
211         int i = 0;
212
213         start = strstr(buf, "chan=");
214         if (!start)
215                 return -EINVAL;
216         start += 5;
217         end = strstr(start, " ");
218         if (!end)
219                 end = buf + count;
220         hold = kzalloc((end - start)+1, GFP_KERNEL);
221         if (!hold)
222                 return -ENOMEM;
223         strncpy(hold, start, end - start);
224         hold[(end-start)+1] = '\0';
225         while(hold && (str = strsep(&hold, ","))) {
226                 int chan;
227                 char band, passive = 0;
228                 sscanf(str, "%d%c%c", &chan, &band, &passive);
229                 scan_cfg->chanlist[i].channumber = chan;
230                 scan_cfg->chanlist[i].scantype = passive ? 1 : 0;
231                 if (band == 'b' || band == 'g')
232                         scan_cfg->chanlist[i].radiotype = 0;
233                 else if (band == 'a')
234                         scan_cfg->chanlist[i].radiotype = 1;
235
236                 scan_cfg->chanlist[i].scantime = dur;
237                 i++;
238         }
239
240         kfree(hold);
241         return i;
242 }
243
244 static void libertas_parse_bssid(char *buf, size_t count,
245                         struct wlan_ioctl_user_scan_cfg *scan_cfg)
246 {
247         char *hold;
248         unsigned int mac[ETH_ALEN];
249         int i;
250
251         hold = strstr(buf, "bssid=");
252         if (!hold)
253                 return;
254         hold += 6;
255         sscanf(hold, "%2x:%2x:%2x:%2x:%2x:%2x", mac, mac+1, mac+2, mac+3,
256                         mac+4, mac+5);
257         for(i=0;i<ETH_ALEN;i++)
258                 scan_cfg->specificBSSID[i] = mac[i];
259 }
260
261 static void libertas_parse_ssid(char *buf, size_t count,
262                         struct wlan_ioctl_user_scan_cfg *scan_cfg)
263 {
264         char *hold, *end;
265         ssize_t size;
266
267         hold = strstr(buf, "ssid=");
268         if (!hold)
269                 return;
270         hold += 5;
271         end = strstr(hold, " ");
272         if (!end)
273                 end = buf + count - 1;
274
275         size = min((size_t)IW_ESSID_MAX_SIZE, (size_t) (end - hold));
276         strncpy(scan_cfg->specificSSID, hold, size);
277
278         return;
279 }
280
281 static void libertas_parse_keep(char *buf, size_t count,
282                         struct wlan_ioctl_user_scan_cfg *scan_cfg)
283 {
284         char *hold;
285         int val;
286
287         hold = strstr(buf, "keep=");
288         if (!hold)
289                 return;
290         hold += 5;
291         sscanf(hold, "%d", &val);
292
293         if (val != 0)
294                 val = 1;
295
296         scan_cfg->keeppreviousscan = val;
297         return;
298 }
299
300 static int libertas_parse_dur(char *buf, size_t count,
301                         struct wlan_ioctl_user_scan_cfg *scan_cfg)
302 {
303         char *hold;
304         int val;
305
306         hold = strstr(buf, "dur=");
307         if (!hold)
308                 return 0;
309         hold += 4;
310         sscanf(hold, "%d", &val);
311
312         return val;
313 }
314
315 static void libertas_parse_probes(char *buf, size_t count,
316                         struct wlan_ioctl_user_scan_cfg *scan_cfg)
317 {
318         char *hold;
319         int val;
320
321         hold = strstr(buf, "probes=");
322         if (!hold)
323                 return;
324         hold += 7;
325         sscanf(hold, "%d", &val);
326
327         scan_cfg->numprobes = val;
328
329         return;
330 }
331
332 static void libertas_parse_type(char *buf, size_t count,
333                         struct wlan_ioctl_user_scan_cfg *scan_cfg)
334 {
335         char *hold;
336         int val;
337
338         hold = strstr(buf, "type=");
339         if (!hold)
340                 return;
341         hold += 5;
342         sscanf(hold, "%d", &val);
343
344         /* type=1,2 or 3 */
345         if (val < 1 || val > 3)
346                 return;
347
348         scan_cfg->bsstype = val;
349
350         return;
351 }
352
353 static ssize_t libertas_setuserscan(struct file *file,
354                                     const char __user *userbuf,
355                                     size_t count, loff_t *ppos)
356 {
357         wlan_private *priv = file->private_data;
358         ssize_t res, buf_size;
359         struct wlan_ioctl_user_scan_cfg *scan_cfg;
360         union iwreq_data wrqu;
361         int dur;
362         unsigned long addr = get_zeroed_page(GFP_KERNEL);
363         char *buf = (char *)addr;
364
365         scan_cfg = kzalloc(sizeof(struct wlan_ioctl_user_scan_cfg), GFP_KERNEL);
366         if (!scan_cfg)
367                 return -ENOMEM;
368
369         buf_size = min(count, len - 1);
370         if (copy_from_user(buf, userbuf, buf_size)) {
371                 res = -EFAULT;
372                 goto out_unlock;
373         }
374
375         scan_cfg->bsstype = WLAN_SCAN_BSS_TYPE_ANY;
376
377         dur = libertas_parse_dur(buf, count, scan_cfg);
378         libertas_parse_chan(buf, count, scan_cfg, dur);
379         libertas_parse_bssid(buf, count, scan_cfg);
380         libertas_parse_ssid(buf, count, scan_cfg);
381         libertas_parse_keep(buf, count, scan_cfg);
382         libertas_parse_probes(buf, count, scan_cfg);
383         libertas_parse_type(buf, count, scan_cfg);
384
385         wlan_scan_networks(priv, scan_cfg, 1);
386         wait_event_interruptible(priv->adapter->cmd_pending,
387                                  !priv->adapter->nr_cmd_pending);
388
389         memset(&wrqu, 0x00, sizeof(union iwreq_data));
390         wireless_send_event(priv->wlan_dev.netdev, SIOCGIWSCAN, &wrqu, NULL);
391
392 out_unlock:
393         free_page(addr);
394         kfree(scan_cfg);
395         return count;
396 }
397
398 static int libertas_event_initcmd(wlan_private *priv, void **response_buf,
399                         struct cmd_ctrl_node **cmdnode,
400                         struct cmd_ds_command **cmd)
401 {
402         u16 wait_option = cmd_option_waitforrsp;
403
404         if (!(*cmdnode = libertas_get_free_cmd_ctrl_node(priv))) {
405                 lbs_deb_debugfs("failed libertas_get_free_cmd_ctrl_node\n");
406                 return -ENOMEM;
407         }
408         if (!(*response_buf = kmalloc(3000, GFP_KERNEL))) {
409                 lbs_deb_debugfs("failed to allocate response buffer!\n");
410                 return -ENOMEM;
411         }
412         libertas_set_cmd_ctrl_node(priv, *cmdnode, 0, wait_option, NULL);
413         init_waitqueue_head(&(*cmdnode)->cmdwait_q);
414         (*cmdnode)->pdata_buf = *response_buf;
415         (*cmdnode)->cmdflags |= CMD_F_HOSTCMD;
416         (*cmdnode)->cmdwaitqwoken = 0;
417         *cmd = (struct cmd_ds_command *)(*cmdnode)->bufvirtualaddr;
418         (*cmd)->command = cmd_802_11_subscribe_event;
419         (*cmd)->seqnum = ++priv->adapter->seqnum;
420         (*cmd)->result = 0;
421         return 0;
422 }
423
424 static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf,
425                                   size_t count, loff_t *ppos)
426 {
427         wlan_private *priv = file->private_data;
428         wlan_adapter *adapter = priv->adapter;
429         struct cmd_ctrl_node *pcmdnode;
430         struct cmd_ds_command *pcmdptr;
431         struct cmd_ds_802_11_subscribe_event *event;
432         void *response_buf;
433         int res, cmd_len;
434         ssize_t pos = 0;
435         unsigned long addr = get_zeroed_page(GFP_KERNEL);
436         char *buf = (char *)addr;
437
438         res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
439         if (res < 0) {
440                 free_page(addr);
441                 return res;
442         }
443
444         event = &pcmdptr->params.subscribe_event;
445         event->action = cmd_act_get;
446         pcmdptr->size =
447         cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
448         libertas_queue_cmd(adapter, pcmdnode, 1);
449         wake_up_interruptible(&priv->mainthread.waitq);
450
451         /* Sleep until response is generated by FW */
452         wait_event_interruptible(pcmdnode->cmdwait_q,
453                                 pcmdnode->cmdwaitqwoken);
454
455         pcmdptr = response_buf;
456         if (pcmdptr->result) {
457                 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
458                         pcmdptr->result);
459                 kfree(response_buf);
460                 free_page(addr);
461                 return 0;
462         }
463
464         if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
465                 lbs_pr_err("command response incorrect!\n");
466                 kfree(response_buf);
467                 free_page(addr);
468                 return 0;
469         }
470
471         cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
472         event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
473         while (cmd_len < pcmdptr->size) {
474                 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
475                 switch(header->type) {
476                 struct mrvlietypes_rssithreshold  *Lowrssi;
477                 case TLV_TYPE_RSSI_LOW:
478                 Lowrssi = (struct mrvlietypes_rssithreshold *)(response_buf + cmd_len);
479                 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
480                                 Lowrssi->rssivalue,
481                                 Lowrssi->rssifreq,
482                                 (event->events & 0x0001)?1:0);
483                 default:
484                         cmd_len += sizeof(struct mrvlietypes_snrthreshold);
485                         break;
486                 }
487         }
488
489         kfree(response_buf);
490         res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
491         free_page(addr);
492         return res;
493 }
494
495 static u16 libertas_get_events_bitmap(wlan_private *priv)
496 {
497         wlan_adapter *adapter = priv->adapter;
498         struct cmd_ctrl_node *pcmdnode;
499         struct cmd_ds_command *pcmdptr;
500         struct cmd_ds_802_11_subscribe_event *event;
501         void *response_buf;
502         int res;
503         u16 event_bitmap;
504
505         res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
506         if (res < 0)
507                 return res;
508
509         event = &pcmdptr->params.subscribe_event;
510         event->action = cmd_act_get;
511         pcmdptr->size =
512         cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
513         libertas_queue_cmd(adapter, pcmdnode, 1);
514         wake_up_interruptible(&priv->mainthread.waitq);
515
516         /* Sleep until response is generated by FW */
517         wait_event_interruptible(pcmdnode->cmdwait_q,
518                                 pcmdnode->cmdwaitqwoken);
519
520         pcmdptr = response_buf;
521
522         if (pcmdptr->result) {
523                 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
524                         pcmdptr->result);
525                 kfree(response_buf);
526                 return 0;
527         }
528
529         if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
530                 lbs_pr_err("command response incorrect!\n");
531                 kfree(response_buf);
532                 return 0;
533         }
534
535         event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
536         event_bitmap = event->events;
537         kfree(response_buf);
538         return event_bitmap;
539 }
540
541 static ssize_t libertas_lowrssi_write(struct file *file,
542                                     const char __user *userbuf,
543                                     size_t count, loff_t *ppos)
544 {
545         wlan_private *priv = file->private_data;
546         wlan_adapter *adapter = priv->adapter;
547         ssize_t res, buf_size;
548         int value, freq, subscribed, cmd_len;
549         struct cmd_ctrl_node *pcmdnode;
550         struct cmd_ds_command *pcmdptr;
551         struct cmd_ds_802_11_subscribe_event *event;
552         struct mrvlietypes_rssithreshold *rssi_threshold;
553         void *response_buf;
554         u16 event_bitmap;
555         u8 *ptr;
556         unsigned long addr = get_zeroed_page(GFP_KERNEL);
557         char *buf = (char *)addr;
558
559         buf_size = min(count, len - 1);
560         if (copy_from_user(buf, userbuf, buf_size)) {
561                 res = -EFAULT;
562                 goto out_unlock;
563         }
564         res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
565         if (res != 3) {
566                 res = -EFAULT;
567                 goto out_unlock;
568         }
569
570         event_bitmap = libertas_get_events_bitmap(priv);
571
572         res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
573         if (res < 0)
574                 goto out_unlock;
575
576         event = &pcmdptr->params.subscribe_event;
577         event->action = cmd_act_set;
578         pcmdptr->size = cpu_to_le16(S_DS_GEN +
579                 sizeof(struct cmd_ds_802_11_subscribe_event) +
580                 sizeof(struct mrvlietypes_rssithreshold));
581
582         cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
583         ptr = (u8*) pcmdptr+cmd_len;
584         rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
585         rssi_threshold->header.type = cpu_to_le16(0x0104);
586         rssi_threshold->header.len = 2;
587         rssi_threshold->rssivalue = cpu_to_le16(value);
588         rssi_threshold->rssifreq = cpu_to_le16(freq);
589         event_bitmap |= subscribed ? 0x0001 : 0x0;
590         event->events = event_bitmap;
591
592         libertas_queue_cmd(adapter, pcmdnode, 1);
593         wake_up_interruptible(&priv->mainthread.waitq);
594
595         /* Sleep until response is generated by FW */
596         wait_event_interruptible(pcmdnode->cmdwait_q,
597                                 pcmdnode->cmdwaitqwoken);
598
599         pcmdptr = response_buf;
600
601         if (pcmdptr->result) {
602                 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
603                         pcmdptr->result);
604                 kfree(response_buf);
605                 free_page(addr);
606                 return 0;
607         }
608
609         if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
610                 lbs_pr_err("command response incorrect!\n");
611                 kfree(response_buf);
612                 free_page(addr);
613                 return 0;
614         }
615
616         res = count;
617 out_unlock:
618         free_page(addr);
619         return res;
620 }
621
622 static ssize_t libertas_lowsnr_read(struct file *file, char __user *userbuf,
623                                   size_t count, loff_t *ppos)
624 {
625         wlan_private *priv = file->private_data;
626         wlan_adapter *adapter = priv->adapter;
627         struct cmd_ctrl_node *pcmdnode;
628         struct cmd_ds_command *pcmdptr;
629         struct cmd_ds_802_11_subscribe_event *event;
630         void *response_buf;
631         int res, cmd_len;
632         ssize_t pos = 0;
633         unsigned long addr = get_zeroed_page(GFP_KERNEL);
634         char *buf = (char *)addr;
635
636         res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
637         if (res < 0) {
638                 free_page(addr);
639                 return res;
640         }
641
642         event = &pcmdptr->params.subscribe_event;
643         event->action = cmd_act_get;
644         pcmdptr->size =
645         cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
646         libertas_queue_cmd(adapter, pcmdnode, 1);
647         wake_up_interruptible(&priv->mainthread.waitq);
648
649         /* Sleep until response is generated by FW */
650         wait_event_interruptible(pcmdnode->cmdwait_q,
651                                 pcmdnode->cmdwaitqwoken);
652
653         pcmdptr = response_buf;
654
655         if (pcmdptr->result) {
656                 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
657                         pcmdptr->result);
658                 kfree(response_buf);
659                 free_page(addr);
660                 return 0;
661         }
662
663         if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
664                 lbs_pr_err("command response incorrect!\n");
665                 kfree(response_buf);
666                 free_page(addr);
667                 return 0;
668         }
669
670         cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
671         event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
672         while (cmd_len < pcmdptr->size) {
673                 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
674                 switch(header->type) {
675                 struct mrvlietypes_snrthreshold *LowSnr;
676                 case TLV_TYPE_SNR_LOW:
677                 LowSnr = (struct mrvlietypes_snrthreshold *)(response_buf + cmd_len);
678                 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
679                                 LowSnr->snrvalue,
680                                 LowSnr->snrfreq,
681                                 (event->events & 0x0002)?1:0);
682                 default:
683                         cmd_len += sizeof(struct mrvlietypes_snrthreshold);
684                         break;
685                 }
686         }
687
688         kfree(response_buf);
689
690         res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
691         free_page(addr);
692         return res;
693 }
694
695 static ssize_t libertas_lowsnr_write(struct file *file,
696                                     const char __user *userbuf,
697                                     size_t count, loff_t *ppos)
698 {
699         wlan_private *priv = file->private_data;
700         wlan_adapter *adapter = priv->adapter;
701         ssize_t res, buf_size;
702         int value, freq, subscribed, cmd_len;
703         struct cmd_ctrl_node *pcmdnode;
704         struct cmd_ds_command *pcmdptr;
705         struct cmd_ds_802_11_subscribe_event *event;
706         struct mrvlietypes_snrthreshold *snr_threshold;
707         void *response_buf;
708         u16 event_bitmap;
709         u8 *ptr;
710         unsigned long addr = get_zeroed_page(GFP_KERNEL);
711         char *buf = (char *)addr;
712
713         buf_size = min(count, len - 1);
714         if (copy_from_user(buf, userbuf, buf_size)) {
715                 res = -EFAULT;
716                 goto out_unlock;
717         }
718         res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
719         if (res != 3) {
720                 res = -EFAULT;
721                 goto out_unlock;
722         }
723
724         event_bitmap = libertas_get_events_bitmap(priv);
725
726         res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
727         if (res < 0)
728                 goto out_unlock;
729
730         event = &pcmdptr->params.subscribe_event;
731         event->action = cmd_act_set;
732         pcmdptr->size = cpu_to_le16(S_DS_GEN +
733                 sizeof(struct cmd_ds_802_11_subscribe_event) +
734                 sizeof(struct mrvlietypes_snrthreshold));
735         cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
736         ptr = (u8*) pcmdptr+cmd_len;
737         snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
738         snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_LOW);
739         snr_threshold->header.len = 2;
740         snr_threshold->snrvalue = cpu_to_le16(value);
741         snr_threshold->snrfreq = cpu_to_le16(freq);
742         event_bitmap |= subscribed ? 0x0002 : 0x0;
743         event->events = event_bitmap;
744
745         libertas_queue_cmd(adapter, pcmdnode, 1);
746         wake_up_interruptible(&priv->mainthread.waitq);
747
748         /* Sleep until response is generated by FW */
749         wait_event_interruptible(pcmdnode->cmdwait_q,
750                                 pcmdnode->cmdwaitqwoken);
751
752         pcmdptr = response_buf;
753
754         if (pcmdptr->result) {
755                 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
756                         pcmdptr->result);
757                 kfree(response_buf);
758                 free_page(addr);
759                 return 0;
760         }
761
762         if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
763                 lbs_pr_err("command response incorrect!\n");
764                 kfree(response_buf);
765                 free_page(addr);
766                 return 0;
767         }
768
769         res = count;
770
771 out_unlock:
772         free_page(addr);
773         return res;
774 }
775
776 static ssize_t libertas_failcount_read(struct file *file, char __user *userbuf,
777                                   size_t count, loff_t *ppos)
778 {
779         wlan_private *priv = file->private_data;
780         wlan_adapter *adapter = priv->adapter;
781         struct cmd_ctrl_node *pcmdnode;
782         struct cmd_ds_command *pcmdptr;
783         struct cmd_ds_802_11_subscribe_event *event;
784         void *response_buf;
785         int res, cmd_len;
786         ssize_t pos = 0;
787         unsigned long addr = get_zeroed_page(GFP_KERNEL);
788         char *buf = (char *)addr;
789
790         res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
791         if (res < 0) {
792                 free_page(addr);
793                 return res;
794         }
795
796         event = &pcmdptr->params.subscribe_event;
797         event->action = cmd_act_get;
798         pcmdptr->size =
799         cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
800         libertas_queue_cmd(adapter, pcmdnode, 1);
801         wake_up_interruptible(&priv->mainthread.waitq);
802
803         /* Sleep until response is generated by FW */
804         wait_event_interruptible(pcmdnode->cmdwait_q,
805                                 pcmdnode->cmdwaitqwoken);
806
807         pcmdptr = response_buf;
808
809         if (pcmdptr->result) {
810                 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
811                         pcmdptr->result);
812                 kfree(response_buf);
813                 free_page(addr);
814                 return 0;
815         }
816
817         if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
818                 lbs_pr_err("command response incorrect!\n");
819                 kfree(response_buf);
820                 free_page(addr);
821                 return 0;
822         }
823
824         cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
825         event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
826         while (cmd_len < pcmdptr->size) {
827                 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
828                 switch(header->type) {
829                 struct mrvlietypes_failurecount *failcount;
830                 case TLV_TYPE_FAILCOUNT:
831                 failcount = (struct mrvlietypes_failurecount *)(response_buf + cmd_len);
832                 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
833                                 failcount->failvalue,
834                                 failcount->Failfreq,
835                                 (event->events & 0x0004)?1:0);
836                 default:
837                         cmd_len += sizeof(struct mrvlietypes_failurecount);
838                         break;
839                 }
840         }
841
842         kfree(response_buf);
843         res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
844         free_page(addr);
845         return res;
846 }
847
848 static ssize_t libertas_failcount_write(struct file *file,
849                                     const char __user *userbuf,
850                                     size_t count, loff_t *ppos)
851 {
852         wlan_private *priv = file->private_data;
853         wlan_adapter *adapter = priv->adapter;
854         ssize_t res, buf_size;
855         int value, freq, subscribed, cmd_len;
856         struct cmd_ctrl_node *pcmdnode;
857         struct cmd_ds_command *pcmdptr;
858         struct cmd_ds_802_11_subscribe_event *event;
859         struct mrvlietypes_failurecount *failcount;
860         void *response_buf;
861         u16 event_bitmap;
862         u8 *ptr;
863         unsigned long addr = get_zeroed_page(GFP_KERNEL);
864         char *buf = (char *)addr;
865
866         buf_size = min(count, len - 1);
867         if (copy_from_user(buf, userbuf, buf_size)) {
868                 res = -EFAULT;
869                 goto out_unlock;
870         }
871         res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
872         if (res != 3) {
873                 res = -EFAULT;
874                 goto out_unlock;
875         }
876
877         event_bitmap = libertas_get_events_bitmap(priv);
878
879         res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
880         if (res < 0)
881                 goto out_unlock;
882
883         event = &pcmdptr->params.subscribe_event;
884         event->action = cmd_act_set;
885         pcmdptr->size = cpu_to_le16(S_DS_GEN +
886                 sizeof(struct cmd_ds_802_11_subscribe_event) +
887                 sizeof(struct mrvlietypes_failurecount));
888         cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
889         ptr = (u8*) pcmdptr+cmd_len;
890         failcount = (struct mrvlietypes_failurecount *)(ptr);
891         failcount->header.type = cpu_to_le16(TLV_TYPE_FAILCOUNT);
892         failcount->header.len = 2;
893         failcount->failvalue = cpu_to_le16(value);
894         failcount->Failfreq = cpu_to_le16(freq);
895         event_bitmap |= subscribed ? 0x0004 : 0x0;
896         event->events = event_bitmap;
897
898         libertas_queue_cmd(adapter, pcmdnode, 1);
899         wake_up_interruptible(&priv->mainthread.waitq);
900
901         /* Sleep until response is generated by FW */
902         wait_event_interruptible(pcmdnode->cmdwait_q,
903                                 pcmdnode->cmdwaitqwoken);
904
905         pcmdptr = (struct cmd_ds_command *)response_buf;
906
907         if (pcmdptr->result) {
908                 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
909                         pcmdptr->result);
910                 kfree(response_buf);
911                 free_page(addr);
912                 return 0;
913         }
914
915         if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
916                 lbs_pr_err("command response incorrect!\n");
917                 kfree(response_buf);
918                 free_page(addr);
919                 return 0;
920         }
921
922         res = count;
923 out_unlock:
924         free_page(addr);
925         return res;
926 }
927
928 static ssize_t libertas_bcnmiss_read(struct file *file, char __user *userbuf,
929                                   size_t count, loff_t *ppos)
930 {
931         wlan_private *priv = file->private_data;
932         wlan_adapter *adapter = priv->adapter;
933         struct cmd_ctrl_node *pcmdnode;
934         struct cmd_ds_command *pcmdptr;
935         struct cmd_ds_802_11_subscribe_event *event;
936         void *response_buf;
937         int res, cmd_len;
938         ssize_t pos = 0;
939         unsigned long addr = get_zeroed_page(GFP_KERNEL);
940         char *buf = (char *)addr;
941
942         res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
943         if (res < 0) {
944                 free_page(addr);
945                 return res;
946         }
947
948         event = &pcmdptr->params.subscribe_event;
949         event->action = cmd_act_get;
950         pcmdptr->size =
951         cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
952         libertas_queue_cmd(adapter, pcmdnode, 1);
953         wake_up_interruptible(&priv->mainthread.waitq);
954
955         /* Sleep until response is generated by FW */
956         wait_event_interruptible(pcmdnode->cmdwait_q,
957                                 pcmdnode->cmdwaitqwoken);
958
959         pcmdptr = response_buf;
960
961         if (pcmdptr->result) {
962                 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
963                         pcmdptr->result);
964                 free_page(addr);
965                 kfree(response_buf);
966                 return 0;
967         }
968
969         if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
970                 lbs_pr_err("command response incorrect!\n");
971                 free_page(addr);
972                 kfree(response_buf);
973                 return 0;
974         }
975
976         cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
977         event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
978         while (cmd_len < pcmdptr->size) {
979                 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
980                 switch(header->type) {
981                 struct mrvlietypes_beaconsmissed *bcnmiss;
982                 case TLV_TYPE_BCNMISS:
983                 bcnmiss = (struct mrvlietypes_beaconsmissed *)(response_buf + cmd_len);
984                 pos += snprintf(buf+pos, len-pos, "%d N/A %d\n",
985                                 bcnmiss->beaconmissed,
986                                 (event->events & 0x0008)?1:0);
987                 default:
988                         cmd_len += sizeof(struct mrvlietypes_beaconsmissed);
989                         break;
990                 }
991         }
992
993         kfree(response_buf);
994
995         res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
996         free_page(addr);
997         return res;
998 }
999
1000 static ssize_t libertas_bcnmiss_write(struct file *file,
1001                                     const char __user *userbuf,
1002                                     size_t count, loff_t *ppos)
1003 {
1004         wlan_private *priv = file->private_data;
1005         wlan_adapter *adapter = priv->adapter;
1006         ssize_t res, buf_size;
1007         int value, freq, subscribed, cmd_len;
1008         struct cmd_ctrl_node *pcmdnode;
1009         struct cmd_ds_command *pcmdptr;
1010         struct cmd_ds_802_11_subscribe_event *event;
1011         struct mrvlietypes_beaconsmissed *bcnmiss;
1012         void *response_buf;
1013         u16 event_bitmap;
1014         u8 *ptr;
1015         unsigned long addr = get_zeroed_page(GFP_KERNEL);
1016         char *buf = (char *)addr;
1017
1018         buf_size = min(count, len - 1);
1019         if (copy_from_user(buf, userbuf, buf_size)) {
1020                 res = -EFAULT;
1021                 goto out_unlock;
1022         }
1023         res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
1024         if (res != 3) {
1025                 res = -EFAULT;
1026                 goto out_unlock;
1027         }
1028
1029         event_bitmap = libertas_get_events_bitmap(priv);
1030
1031         res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1032         if (res < 0)
1033                 goto out_unlock;
1034
1035         event = &pcmdptr->params.subscribe_event;
1036         event->action = cmd_act_set;
1037         pcmdptr->size = cpu_to_le16(S_DS_GEN +
1038                 sizeof(struct cmd_ds_802_11_subscribe_event) +
1039                 sizeof(struct mrvlietypes_beaconsmissed));
1040         cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1041         ptr = (u8*) pcmdptr+cmd_len;
1042         bcnmiss = (struct mrvlietypes_beaconsmissed *)(ptr);
1043         bcnmiss->header.type = cpu_to_le16(TLV_TYPE_BCNMISS);
1044         bcnmiss->header.len = 2;
1045         bcnmiss->beaconmissed = cpu_to_le16(value);
1046         event_bitmap |= subscribed ? 0x0008 : 0x0;
1047         event->events = event_bitmap;
1048
1049         libertas_queue_cmd(adapter, pcmdnode, 1);
1050         wake_up_interruptible(&priv->mainthread.waitq);
1051
1052         /* Sleep until response is generated by FW */
1053         wait_event_interruptible(pcmdnode->cmdwait_q,
1054                                 pcmdnode->cmdwaitqwoken);
1055
1056         pcmdptr = response_buf;
1057
1058         if (pcmdptr->result) {
1059                 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1060                         pcmdptr->result);
1061                 kfree(response_buf);
1062                 free_page(addr);
1063                 return 0;
1064         }
1065
1066         if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1067                 lbs_pr_err("command response incorrect!\n");
1068                 free_page(addr);
1069                 kfree(response_buf);
1070                 return 0;
1071         }
1072
1073         res = count;
1074 out_unlock:
1075         free_page(addr);
1076         return res;
1077 }
1078
1079 static ssize_t libertas_highrssi_read(struct file *file, char __user *userbuf,
1080                                   size_t count, loff_t *ppos)
1081 {
1082         wlan_private *priv = file->private_data;
1083         wlan_adapter *adapter = priv->adapter;
1084         struct cmd_ctrl_node *pcmdnode;
1085         struct cmd_ds_command *pcmdptr;
1086         struct cmd_ds_802_11_subscribe_event *event;
1087         void *response_buf;
1088         int res, cmd_len;
1089         ssize_t pos = 0;
1090         unsigned long addr = get_zeroed_page(GFP_KERNEL);
1091         char *buf = (char *)addr;
1092
1093         res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1094         if (res < 0) {
1095                 free_page(addr);
1096                 return res;
1097         }
1098
1099         event = &pcmdptr->params.subscribe_event;
1100         event->action = cmd_act_get;
1101         pcmdptr->size =
1102         cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
1103         libertas_queue_cmd(adapter, pcmdnode, 1);
1104         wake_up_interruptible(&priv->mainthread.waitq);
1105
1106         /* Sleep until response is generated by FW */
1107         wait_event_interruptible(pcmdnode->cmdwait_q,
1108                                 pcmdnode->cmdwaitqwoken);
1109
1110         pcmdptr = response_buf;
1111
1112         if (pcmdptr->result) {
1113                 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1114                         pcmdptr->result);
1115                 kfree(response_buf);
1116                 free_page(addr);
1117                 return 0;
1118         }
1119
1120         if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1121                 lbs_pr_err("command response incorrect!\n");
1122                 kfree(response_buf);
1123                 free_page(addr);
1124                 return 0;
1125         }
1126
1127         cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1128         event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
1129         while (cmd_len < pcmdptr->size) {
1130                 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
1131                 switch(header->type) {
1132                 struct mrvlietypes_rssithreshold  *Highrssi;
1133                 case TLV_TYPE_RSSI_HIGH:
1134                 Highrssi = (struct mrvlietypes_rssithreshold *)(response_buf + cmd_len);
1135                 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
1136                                 Highrssi->rssivalue,
1137                                 Highrssi->rssifreq,
1138                                 (event->events & 0x0010)?1:0);
1139                 default:
1140                         cmd_len += sizeof(struct mrvlietypes_snrthreshold);
1141                         break;
1142                 }
1143         }
1144
1145         kfree(response_buf);
1146
1147         res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1148         free_page(addr);
1149         return res;
1150 }
1151
1152 static ssize_t libertas_highrssi_write(struct file *file,
1153                                     const char __user *userbuf,
1154                                     size_t count, loff_t *ppos)
1155 {
1156         wlan_private *priv = file->private_data;
1157         wlan_adapter *adapter = priv->adapter;
1158         ssize_t res, buf_size;
1159         int value, freq, subscribed, cmd_len;
1160         struct cmd_ctrl_node *pcmdnode;
1161         struct cmd_ds_command *pcmdptr;
1162         struct cmd_ds_802_11_subscribe_event *event;
1163         struct mrvlietypes_rssithreshold *rssi_threshold;
1164         void *response_buf;
1165         u16 event_bitmap;
1166         u8 *ptr;
1167         unsigned long addr = get_zeroed_page(GFP_KERNEL);
1168         char *buf = (char *)addr;
1169
1170         buf_size = min(count, len - 1);
1171         if (copy_from_user(buf, userbuf, buf_size)) {
1172                 res = -EFAULT;
1173                 goto out_unlock;
1174         }
1175         res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
1176         if (res != 3) {
1177                 res = -EFAULT;
1178                 goto out_unlock;
1179         }
1180
1181         event_bitmap = libertas_get_events_bitmap(priv);
1182
1183         res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1184         if (res < 0)
1185                 goto out_unlock;
1186
1187         event = &pcmdptr->params.subscribe_event;
1188         event->action = cmd_act_set;
1189         pcmdptr->size = cpu_to_le16(S_DS_GEN +
1190                 sizeof(struct cmd_ds_802_11_subscribe_event) +
1191                 sizeof(struct mrvlietypes_rssithreshold));
1192         cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1193         ptr = (u8*) pcmdptr+cmd_len;
1194         rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
1195         rssi_threshold->header.type = cpu_to_le16(TLV_TYPE_RSSI_HIGH);
1196         rssi_threshold->header.len = 2;
1197         rssi_threshold->rssivalue = cpu_to_le16(value);
1198         rssi_threshold->rssifreq = cpu_to_le16(freq);
1199         event_bitmap |= subscribed ? 0x0010 : 0x0;
1200         event->events = event_bitmap;
1201
1202         libertas_queue_cmd(adapter, pcmdnode, 1);
1203         wake_up_interruptible(&priv->mainthread.waitq);
1204
1205         /* Sleep until response is generated by FW */
1206         wait_event_interruptible(pcmdnode->cmdwait_q,
1207                                 pcmdnode->cmdwaitqwoken);
1208
1209         pcmdptr = response_buf;
1210
1211         if (pcmdptr->result) {
1212                 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1213                         pcmdptr->result);
1214                 kfree(response_buf);
1215                 return 0;
1216         }
1217
1218         if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1219                 lbs_pr_err("command response incorrect!\n");
1220                 kfree(response_buf);
1221                 return 0;
1222         }
1223
1224         res = count;
1225 out_unlock:
1226         free_page(addr);
1227         return res;
1228 }
1229
1230 static ssize_t libertas_highsnr_read(struct file *file, char __user *userbuf,
1231                                   size_t count, loff_t *ppos)
1232 {
1233         wlan_private *priv = file->private_data;
1234         wlan_adapter *adapter = priv->adapter;
1235         struct cmd_ctrl_node *pcmdnode;
1236         struct cmd_ds_command *pcmdptr;
1237         struct cmd_ds_802_11_subscribe_event *event;
1238         void *response_buf;
1239         int res, cmd_len;
1240         ssize_t pos = 0;
1241         unsigned long addr = get_zeroed_page(GFP_KERNEL);
1242         char *buf = (char *)addr;
1243
1244         res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1245         if (res < 0) {
1246                 free_page(addr);
1247                 return res;
1248         }
1249
1250         event = &pcmdptr->params.subscribe_event;
1251         event->action = cmd_act_get;
1252         pcmdptr->size =
1253         cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
1254         libertas_queue_cmd(adapter, pcmdnode, 1);
1255         wake_up_interruptible(&priv->mainthread.waitq);
1256
1257         /* Sleep until response is generated by FW */
1258         wait_event_interruptible(pcmdnode->cmdwait_q,
1259                                 pcmdnode->cmdwaitqwoken);
1260
1261         pcmdptr = response_buf;
1262
1263         if (pcmdptr->result) {
1264                 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1265                         pcmdptr->result);
1266                 kfree(response_buf);
1267                 free_page(addr);
1268                 return 0;
1269         }
1270
1271         if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1272                 lbs_pr_err("command response incorrect!\n");
1273                 kfree(response_buf);
1274                 free_page(addr);
1275                 return 0;
1276         }
1277
1278         cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1279         event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
1280         while (cmd_len < pcmdptr->size) {
1281                 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
1282                 switch(header->type) {
1283                 struct mrvlietypes_snrthreshold *HighSnr;
1284                 case TLV_TYPE_SNR_HIGH:
1285                 HighSnr = (struct mrvlietypes_snrthreshold *)(response_buf + cmd_len);
1286                 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
1287                                 HighSnr->snrvalue,
1288                                 HighSnr->snrfreq,
1289                                 (event->events & 0x0020)?1:0);
1290                 default:
1291                         cmd_len += sizeof(struct mrvlietypes_snrthreshold);
1292                         break;
1293                 }
1294         }
1295
1296         kfree(response_buf);
1297
1298         res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1299         free_page(addr);
1300         return res;
1301 }
1302
1303 static ssize_t libertas_highsnr_write(struct file *file,
1304                                     const char __user *userbuf,
1305                                     size_t count, loff_t *ppos)
1306 {
1307         wlan_private *priv = file->private_data;
1308         wlan_adapter *adapter = priv->adapter;
1309         ssize_t res, buf_size;
1310         int value, freq, subscribed, cmd_len;
1311         struct cmd_ctrl_node *pcmdnode;
1312         struct cmd_ds_command *pcmdptr;
1313         struct cmd_ds_802_11_subscribe_event *event;
1314         struct mrvlietypes_snrthreshold *snr_threshold;
1315         void *response_buf;
1316         u16 event_bitmap;
1317         u8 *ptr;
1318         unsigned long addr = get_zeroed_page(GFP_KERNEL);
1319         char *buf = (char *)addr;
1320
1321         buf_size = min(count, len - 1);
1322         if (copy_from_user(buf, userbuf, buf_size)) {
1323                 res = -EFAULT;
1324                 goto out_unlock;
1325         }
1326         res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
1327         if (res != 3) {
1328                 res = -EFAULT;
1329                 goto out_unlock;
1330         }
1331
1332         event_bitmap = libertas_get_events_bitmap(priv);
1333
1334         res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1335         if (res < 0)
1336                 goto out_unlock;
1337
1338         event = &pcmdptr->params.subscribe_event;
1339         event->action = cmd_act_set;
1340         pcmdptr->size = cpu_to_le16(S_DS_GEN +
1341                 sizeof(struct cmd_ds_802_11_subscribe_event) +
1342                 sizeof(struct mrvlietypes_snrthreshold));
1343         cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1344         ptr = (u8*) pcmdptr+cmd_len;
1345         snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
1346         snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_HIGH);
1347         snr_threshold->header.len = 2;
1348         snr_threshold->snrvalue = cpu_to_le16(value);
1349         snr_threshold->snrfreq = cpu_to_le16(freq);
1350         event_bitmap |= subscribed ? 0x0020 : 0x0;
1351         event->events = event_bitmap;
1352
1353         libertas_queue_cmd(adapter, pcmdnode, 1);
1354         wake_up_interruptible(&priv->mainthread.waitq);
1355
1356         /* Sleep until response is generated by FW */
1357         wait_event_interruptible(pcmdnode->cmdwait_q,
1358                                 pcmdnode->cmdwaitqwoken);
1359
1360         pcmdptr = response_buf;
1361
1362         if (pcmdptr->result) {
1363                 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1364                         pcmdptr->result);
1365                 kfree(response_buf);
1366                 free_page(addr);
1367                 return 0;
1368         }
1369
1370         if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1371                 lbs_pr_err("command response incorrect!\n");
1372                 kfree(response_buf);
1373                 free_page(addr);
1374                 return 0;
1375         }
1376
1377         res = count;
1378 out_unlock:
1379         free_page(addr);
1380         return res;
1381 }
1382
1383 static ssize_t libertas_rdmac_read(struct file *file, char __user *userbuf,
1384                                   size_t count, loff_t *ppos)
1385 {
1386         wlan_private *priv = file->private_data;
1387         wlan_adapter *adapter = priv->adapter;
1388         struct wlan_offset_value offval;
1389         ssize_t pos = 0;
1390         int ret;
1391         unsigned long addr = get_zeroed_page(GFP_KERNEL);
1392         char *buf = (char *)addr;
1393
1394         offval.offset = priv->mac_offset;
1395         offval.value = 0;
1396
1397         ret = libertas_prepare_and_send_command(priv,
1398                                 cmd_mac_reg_access, 0,
1399                                 cmd_option_waitforrsp, 0, &offval);
1400         mdelay(10);
1401         pos += snprintf(buf+pos, len-pos, "MAC[0x%x] = 0x%08x\n",
1402                                 priv->mac_offset, adapter->offsetvalue.value);
1403
1404         ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1405         free_page(addr);
1406         return ret;
1407 }
1408
1409 static ssize_t libertas_rdmac_write(struct file *file,
1410                                     const char __user *userbuf,
1411                                     size_t count, loff_t *ppos)
1412 {
1413         wlan_private *priv = file->private_data;
1414         ssize_t res, buf_size;
1415         unsigned long addr = get_zeroed_page(GFP_KERNEL);
1416         char *buf = (char *)addr;
1417
1418         buf_size = min(count, len - 1);
1419         if (copy_from_user(buf, userbuf, buf_size)) {
1420                 res = -EFAULT;
1421                 goto out_unlock;
1422         }
1423         priv->mac_offset = simple_strtoul((char *)buf, NULL, 16);
1424         res = count;
1425 out_unlock:
1426         free_page(addr);
1427         return res;
1428 }
1429
1430 static ssize_t libertas_wrmac_write(struct file *file,
1431                                     const char __user *userbuf,
1432                                     size_t count, loff_t *ppos)
1433 {
1434
1435         wlan_private *priv = file->private_data;
1436         ssize_t res, buf_size;
1437         u32 offset, value;
1438         struct wlan_offset_value offval;
1439         unsigned long addr = get_zeroed_page(GFP_KERNEL);
1440         char *buf = (char *)addr;
1441
1442         buf_size = min(count, len - 1);
1443         if (copy_from_user(buf, userbuf, buf_size)) {
1444                 res = -EFAULT;
1445                 goto out_unlock;
1446         }
1447         res = sscanf(buf, "%x %x", &offset, &value);
1448         if (res != 2) {
1449                 res = -EFAULT;
1450                 goto out_unlock;
1451         }
1452
1453         offval.offset = offset;
1454         offval.value = value;
1455         res = libertas_prepare_and_send_command(priv,
1456                                 cmd_mac_reg_access, 1,
1457                                 cmd_option_waitforrsp, 0, &offval);
1458         mdelay(10);
1459
1460         res = count;
1461 out_unlock:
1462         free_page(addr);
1463         return res;
1464 }
1465
1466 static ssize_t libertas_rdbbp_read(struct file *file, char __user *userbuf,
1467                                   size_t count, loff_t *ppos)
1468 {
1469         wlan_private *priv = file->private_data;
1470         wlan_adapter *adapter = priv->adapter;
1471         struct wlan_offset_value offval;
1472         ssize_t pos = 0;
1473         int ret;
1474         unsigned long addr = get_zeroed_page(GFP_KERNEL);
1475         char *buf = (char *)addr;
1476
1477         offval.offset = priv->bbp_offset;
1478         offval.value = 0;
1479
1480         ret = libertas_prepare_and_send_command(priv,
1481                                 cmd_bbp_reg_access, 0,
1482                                 cmd_option_waitforrsp, 0, &offval);
1483         mdelay(10);
1484         pos += snprintf(buf+pos, len-pos, "BBP[0x%x] = 0x%08x\n",
1485                                 priv->bbp_offset, adapter->offsetvalue.value);
1486
1487         ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1488         free_page(addr);
1489
1490         return ret;
1491 }
1492
1493 static ssize_t libertas_rdbbp_write(struct file *file,
1494                                     const char __user *userbuf,
1495                                     size_t count, loff_t *ppos)
1496 {
1497         wlan_private *priv = file->private_data;
1498         ssize_t res, buf_size;
1499         unsigned long addr = get_zeroed_page(GFP_KERNEL);
1500         char *buf = (char *)addr;
1501
1502         buf_size = min(count, len - 1);
1503         if (copy_from_user(buf, userbuf, buf_size)) {
1504                 res = -EFAULT;
1505                 goto out_unlock;
1506         }
1507         priv->bbp_offset = simple_strtoul((char *)buf, NULL, 16);
1508         res = count;
1509 out_unlock:
1510         free_page(addr);
1511         return res;
1512 }
1513
1514 static ssize_t libertas_wrbbp_write(struct file *file,
1515                                     const char __user *userbuf,
1516                                     size_t count, loff_t *ppos)
1517 {
1518
1519         wlan_private *priv = file->private_data;
1520         ssize_t res, buf_size;
1521         u32 offset, value;
1522         struct wlan_offset_value offval;
1523         unsigned long addr = get_zeroed_page(GFP_KERNEL);
1524         char *buf = (char *)addr;
1525
1526         buf_size = min(count, len - 1);
1527         if (copy_from_user(buf, userbuf, buf_size)) {
1528                 res = -EFAULT;
1529                 goto out_unlock;
1530         }
1531         res = sscanf(buf, "%x %x", &offset, &value);
1532         if (res != 2) {
1533                 res = -EFAULT;
1534                 goto out_unlock;
1535         }
1536
1537         offval.offset = offset;
1538         offval.value = value;
1539         res = libertas_prepare_and_send_command(priv,
1540                                 cmd_bbp_reg_access, 1,
1541                                 cmd_option_waitforrsp, 0, &offval);
1542         mdelay(10);
1543
1544         res = count;
1545 out_unlock:
1546         free_page(addr);
1547         return res;
1548 }
1549
1550 static ssize_t libertas_rdrf_read(struct file *file, char __user *userbuf,
1551                                   size_t count, loff_t *ppos)
1552 {
1553         wlan_private *priv = file->private_data;
1554         wlan_adapter *adapter = priv->adapter;
1555         struct wlan_offset_value offval;
1556         ssize_t pos = 0;
1557         int ret;
1558         unsigned long addr = get_zeroed_page(GFP_KERNEL);
1559         char *buf = (char *)addr;
1560
1561         offval.offset = priv->rf_offset;
1562         offval.value = 0;
1563
1564         ret = libertas_prepare_and_send_command(priv,
1565                                 cmd_rf_reg_access, 0,
1566                                 cmd_option_waitforrsp, 0, &offval);
1567         mdelay(10);
1568         pos += snprintf(buf+pos, len-pos, "RF[0x%x] = 0x%08x\n",
1569                                 priv->rf_offset, adapter->offsetvalue.value);
1570
1571         ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1572         free_page(addr);
1573
1574         return ret;
1575 }
1576
1577 static ssize_t libertas_rdrf_write(struct file *file,
1578                                     const char __user *userbuf,
1579                                     size_t count, loff_t *ppos)
1580 {
1581         wlan_private *priv = file->private_data;
1582         ssize_t res, buf_size;
1583         unsigned long addr = get_zeroed_page(GFP_KERNEL);
1584         char *buf = (char *)addr;
1585
1586         buf_size = min(count, len - 1);
1587         if (copy_from_user(buf, userbuf, buf_size)) {
1588                 res = -EFAULT;
1589                 goto out_unlock;
1590         }
1591         priv->rf_offset = simple_strtoul((char *)buf, NULL, 16);
1592         res = count;
1593 out_unlock:
1594         free_page(addr);
1595         return res;
1596 }
1597
1598 static ssize_t libertas_wrrf_write(struct file *file,
1599                                     const char __user *userbuf,
1600                                     size_t count, loff_t *ppos)
1601 {
1602
1603         wlan_private *priv = file->private_data;
1604         ssize_t res, buf_size;
1605         u32 offset, value;
1606         struct wlan_offset_value offval;
1607         unsigned long addr = get_zeroed_page(GFP_KERNEL);
1608         char *buf = (char *)addr;
1609
1610         buf_size = min(count, len - 1);
1611         if (copy_from_user(buf, userbuf, buf_size)) {
1612                 res = -EFAULT;
1613                 goto out_unlock;
1614         }
1615         res = sscanf(buf, "%x %x", &offset, &value);
1616         if (res != 2) {
1617                 res = -EFAULT;
1618                 goto out_unlock;
1619         }
1620
1621         offval.offset = offset;
1622         offval.value = value;
1623         res = libertas_prepare_and_send_command(priv,
1624                                 cmd_rf_reg_access, 1,
1625                                 cmd_option_waitforrsp, 0, &offval);
1626         mdelay(10);
1627
1628         res = count;
1629 out_unlock:
1630         free_page(addr);
1631         return res;
1632 }
1633
1634 #define FOPS(fread, fwrite) { \
1635         .owner = THIS_MODULE, \
1636         .open = open_file_generic, \
1637         .read = (fread), \
1638         .write = (fwrite), \
1639 }
1640
1641 struct libertas_debugfs_files {
1642         char *name;
1643         int perm;
1644         struct file_operations fops;
1645 };
1646
1647 static struct libertas_debugfs_files debugfs_files[] = {
1648         { "info", 0444, FOPS(libertas_dev_info, write_file_dummy), },
1649         { "getscantable", 0444, FOPS(libertas_getscantable,
1650                                         write_file_dummy), },
1651         { "sleepparams", 0644, FOPS(libertas_sleepparams_read,
1652                                 libertas_sleepparams_write), },
1653         { "extscan", 0600, FOPS(NULL, libertas_extscan), },
1654         { "setuserscan", 0600, FOPS(NULL, libertas_setuserscan), },
1655 };
1656
1657 static struct libertas_debugfs_files debugfs_events_files[] = {
1658         {"low_rssi", 0644, FOPS(libertas_lowrssi_read,
1659                                 libertas_lowrssi_write), },
1660         {"low_snr", 0644, FOPS(libertas_lowsnr_read,
1661                                 libertas_lowsnr_write), },
1662         {"failure_count", 0644, FOPS(libertas_failcount_read,
1663                                 libertas_failcount_write), },
1664         {"beacon_missed", 0644, FOPS(libertas_bcnmiss_read,
1665                                 libertas_bcnmiss_write), },
1666         {"high_rssi", 0644, FOPS(libertas_highrssi_read,
1667                                 libertas_highrssi_write), },
1668         {"high_snr", 0644, FOPS(libertas_highsnr_read,
1669                                 libertas_highsnr_write), },
1670 };
1671
1672 static struct libertas_debugfs_files debugfs_regs_files[] = {
1673         {"rdmac", 0644, FOPS(libertas_rdmac_read, libertas_rdmac_write), },
1674         {"wrmac", 0600, FOPS(NULL, libertas_wrmac_write), },
1675         {"rdbbp", 0644, FOPS(libertas_rdbbp_read, libertas_rdbbp_write), },
1676         {"wrbbp", 0600, FOPS(NULL, libertas_wrbbp_write), },
1677         {"rdrf", 0644, FOPS(libertas_rdrf_read, libertas_rdrf_write), },
1678         {"wrrf", 0600, FOPS(NULL, libertas_wrrf_write), },
1679 };
1680
1681 void libertas_debugfs_init(void)
1682 {
1683         if (!libertas_dir)
1684                 libertas_dir = debugfs_create_dir("libertas_wireless", NULL);
1685
1686         return;
1687 }
1688
1689 void libertas_debugfs_remove(void)
1690 {
1691         if (libertas_dir)
1692                  debugfs_remove(libertas_dir);
1693         return;
1694 }
1695
1696 void libertas_debugfs_init_one(wlan_private *priv, struct net_device *dev)
1697 {
1698         int i;
1699         struct libertas_debugfs_files *files;
1700         if (!libertas_dir)
1701                 goto exit;
1702
1703         priv->debugfs_dir = debugfs_create_dir(dev->name, libertas_dir);
1704         if (!priv->debugfs_dir)
1705                 goto exit;
1706
1707         for (i=0; i<ARRAY_SIZE(debugfs_files); i++) {
1708                 files = &debugfs_files[i];
1709                 priv->debugfs_files[i] = debugfs_create_file(files->name,
1710                                                              files->perm,
1711                                                              priv->debugfs_dir,
1712                                                              priv,
1713                                                              &files->fops);
1714         }
1715
1716         priv->events_dir = debugfs_create_dir("subscribed_events", priv->debugfs_dir);
1717         if (!priv->events_dir)
1718                 goto exit;
1719
1720         for (i=0; i<ARRAY_SIZE(debugfs_events_files); i++) {
1721                 files = &debugfs_events_files[i];
1722                 priv->debugfs_events_files[i] = debugfs_create_file(files->name,
1723                                                              files->perm,
1724                                                              priv->events_dir,
1725                                                              priv,
1726                                                              &files->fops);
1727         }
1728
1729         priv->regs_dir = debugfs_create_dir("registers", priv->debugfs_dir);
1730         if (!priv->regs_dir)
1731                 goto exit;
1732
1733         for (i=0; i<ARRAY_SIZE(debugfs_regs_files); i++) {
1734                 files = &debugfs_regs_files[i];
1735                 priv->debugfs_regs_files[i] = debugfs_create_file(files->name,
1736                                                              files->perm,
1737                                                              priv->regs_dir,
1738                                                              priv,
1739                                                              &files->fops);
1740         }
1741
1742 #ifdef PROC_DEBUG
1743         libertas_debug_init(priv, dev);
1744 #endif
1745 exit:
1746         return;
1747 }
1748
1749 void libertas_debugfs_remove_one(wlan_private *priv)
1750 {
1751         int i;
1752
1753         for(i=0; i<ARRAY_SIZE(debugfs_regs_files); i++)
1754                 debugfs_remove(priv->debugfs_regs_files[i]);
1755
1756         debugfs_remove(priv->regs_dir);
1757
1758         for(i=0; i<ARRAY_SIZE(debugfs_events_files); i++)
1759                 debugfs_remove(priv->debugfs_events_files[i]);
1760
1761         debugfs_remove(priv->events_dir);
1762 #ifdef PROC_DEBUG
1763         debugfs_remove(priv->debugfs_debug);
1764 #endif
1765         for(i=0; i<ARRAY_SIZE(debugfs_files); i++)
1766                 debugfs_remove(priv->debugfs_files[i]);
1767         debugfs_remove(priv->debugfs_dir);
1768 }
1769
1770
1771
1772 /* debug entry */
1773
1774 #ifdef PROC_DEBUG
1775
1776 #define item_size(n)    (FIELD_SIZEOF(wlan_adapter, n))
1777 #define item_addr(n)    (offsetof(wlan_adapter, n))
1778
1779
1780 struct debug_data {
1781         char name[32];
1782         u32 size;
1783         size_t addr;
1784 };
1785
1786 /* To debug any member of wlan_adapter, simply add one line here.
1787  */
1788 static struct debug_data items[] = {
1789         {"intcounter", item_size(intcounter), item_addr(intcounter)},
1790         {"psmode", item_size(psmode), item_addr(psmode)},
1791         {"psstate", item_size(psstate), item_addr(psstate)},
1792 };
1793
1794 static int num_of_items = ARRAY_SIZE(items);
1795
1796 /**
1797  *  @brief proc read function
1798  *
1799  *  @param page    pointer to buffer
1800  *  @param s       read data starting position
1801  *  @param off     offset
1802  *  @param cnt     counter
1803  *  @param eof     end of file flag
1804  *  @param data    data to output
1805  *  @return        number of output data
1806  */
1807 static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf,
1808                         size_t count, loff_t *ppos)
1809 {
1810         int val = 0;
1811         size_t pos = 0;
1812         ssize_t res;
1813         char *p;
1814         int i;
1815         struct debug_data *d;
1816         unsigned long addr = get_zeroed_page(GFP_KERNEL);
1817         char *buf = (char *)addr;
1818
1819         p = buf;
1820
1821         d = (struct debug_data *)file->private_data;
1822
1823         for (i = 0; i < num_of_items; i++) {
1824                 if (d[i].size == 1)
1825                         val = *((u8 *) d[i].addr);
1826                 else if (d[i].size == 2)
1827                         val = *((u16 *) d[i].addr);
1828                 else if (d[i].size == 4)
1829                         val = *((u32 *) d[i].addr);
1830                 else if (d[i].size == 8)
1831                         val = *((u64 *) d[i].addr);
1832
1833                 pos += sprintf(p + pos, "%s=%d\n", d[i].name, val);
1834         }
1835
1836         res = simple_read_from_buffer(userbuf, count, ppos, p, pos);
1837
1838         free_page(addr);
1839         return res;
1840 }
1841
1842 /**
1843  *  @brief proc write function
1844  *
1845  *  @param f       file pointer
1846  *  @param buf     pointer to data buffer
1847  *  @param cnt     data number to write
1848  *  @param data    data to write
1849  *  @return        number of data
1850  */
1851 static ssize_t wlan_debugfs_write(struct file *f, const char __user *buf,
1852                             size_t cnt, loff_t *ppos)
1853 {
1854         int r, i;
1855         char *pdata;
1856         char *p;
1857         char *p0;
1858         char *p1;
1859         char *p2;
1860         struct debug_data *d = (struct debug_data *)f->private_data;
1861
1862         pdata = (char *)kmalloc(cnt, GFP_KERNEL);
1863         if (pdata == NULL)
1864                 return 0;
1865
1866         if (copy_from_user(pdata, buf, cnt)) {
1867                 lbs_deb_debugfs("Copy from user failed\n");
1868                 kfree(pdata);
1869                 return 0;
1870         }
1871
1872         p0 = pdata;
1873         for (i = 0; i < num_of_items; i++) {
1874                 do {
1875                         p = strstr(p0, d[i].name);
1876                         if (p == NULL)
1877                                 break;
1878                         p1 = strchr(p, '\n');
1879                         if (p1 == NULL)
1880                                 break;
1881                         p0 = p1++;
1882                         p2 = strchr(p, '=');
1883                         if (!p2)
1884                                 break;
1885                         p2++;
1886                         r = simple_strtoul(p2, NULL, 0);
1887                         if (d[i].size == 1)
1888                                 *((u8 *) d[i].addr) = (u8) r;
1889                         else if (d[i].size == 2)
1890                                 *((u16 *) d[i].addr) = (u16) r;
1891                         else if (d[i].size == 4)
1892                                 *((u32 *) d[i].addr) = (u32) r;
1893                         else if (d[i].size == 8)
1894                                 *((u64 *) d[i].addr) = (u64) r;
1895                         break;
1896                 } while (1);
1897         }
1898         kfree(pdata);
1899
1900         return (ssize_t)cnt;
1901 }
1902
1903 static struct file_operations libertas_debug_fops = {
1904         .owner = THIS_MODULE,
1905         .open = open_file_generic,
1906         .write = wlan_debugfs_write,
1907         .read = wlan_debugfs_read,
1908 };
1909
1910 /**
1911  *  @brief create debug proc file
1912  *
1913  *  @param priv    pointer wlan_private
1914  *  @param dev     pointer net_device
1915  *  @return        N/A
1916  */
1917 static void libertas_debug_init(wlan_private * priv, struct net_device *dev)
1918 {
1919         int i;
1920
1921         if (!priv->debugfs_dir)
1922                 return;
1923
1924         for (i = 0; i < num_of_items; i++)
1925                 items[i].addr += (size_t) priv->adapter;
1926
1927         priv->debugfs_debug = debugfs_create_file("debug", 0644,
1928                                                   priv->debugfs_dir, &items[0],
1929                                                   &libertas_debug_fops);
1930 }
1931 #endif
1932