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