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