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