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