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