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