1 #include <linux/module.h>
2 #include <linux/dcache.h>
3 #include <linux/debugfs.h>
4 #include <linux/delay.h>
6 #include <linux/string.h>
7 #include <net/iw_handler.h>
14 static struct dentry
*lbs_dir
;
15 static char *szStates
[] = {
21 static void lbs_debug_init(struct lbs_private
*priv
, struct net_device
*dev
);
24 static int open_file_generic(struct inode
*inode
, struct file
*file
)
26 file
->private_data
= inode
->i_private
;
30 static ssize_t
write_file_dummy(struct file
*file
, const char __user
*buf
,
31 size_t count
, loff_t
*ppos
)
36 static const size_t len
= PAGE_SIZE
;
38 static ssize_t
lbs_dev_info(struct file
*file
, char __user
*userbuf
,
39 size_t count
, loff_t
*ppos
)
41 struct lbs_private
*priv
= file
->private_data
;
43 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
44 char *buf
= (char *)addr
;
47 pos
+= snprintf(buf
+pos
, len
-pos
, "state = %s\n",
48 szStates
[priv
->adapter
->connect_status
]);
49 pos
+= snprintf(buf
+pos
, len
-pos
, "region_code = %02x\n",
50 (u32
) priv
->adapter
->regioncode
);
52 res
= simple_read_from_buffer(userbuf
, count
, ppos
, buf
, pos
);
59 static ssize_t
lbs_getscantable(struct file
*file
, char __user
*userbuf
,
60 size_t count
, loff_t
*ppos
)
62 struct lbs_private
*priv
= file
->private_data
;
64 int numscansdone
= 0, res
;
65 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
66 char *buf
= (char *)addr
;
68 struct bss_descriptor
* iter_bss
;
70 pos
+= snprintf(buf
+pos
, len
-pos
,
71 "# | ch | rssi | bssid | cap | Qual | SSID \n");
73 mutex_lock(&priv
->adapter
->lock
);
74 list_for_each_entry (iter_bss
, &priv
->adapter
->network_list
, list
) {
75 u16 ibss
= (iter_bss
->capability
& WLAN_CAPABILITY_IBSS
);
76 u16 privacy
= (iter_bss
->capability
& WLAN_CAPABILITY_PRIVACY
);
77 u16 spectrum_mgmt
= (iter_bss
->capability
& WLAN_CAPABILITY_SPECTRUM_MGMT
);
79 pos
+= snprintf(buf
+pos
, len
-pos
,
80 "%02u| %03d | %04ld | %s |",
81 numscansdone
, iter_bss
->channel
, iter_bss
->rssi
,
82 print_mac(mac
, iter_bss
->bssid
));
83 pos
+= snprintf(buf
+pos
, len
-pos
, " %04x-", iter_bss
->capability
);
84 pos
+= snprintf(buf
+pos
, len
-pos
, "%c%c%c |",
85 ibss
? 'A' : 'I', privacy
? 'P' : ' ',
86 spectrum_mgmt
? 'S' : ' ');
87 pos
+= snprintf(buf
+pos
, len
-pos
, " %04d |", SCAN_RSSI(iter_bss
->rssi
));
88 pos
+= snprintf(buf
+pos
, len
-pos
, " %s\n",
89 escape_essid(iter_bss
->ssid
, iter_bss
->ssid_len
));
93 mutex_unlock(&priv
->adapter
->lock
);
95 res
= simple_read_from_buffer(userbuf
, count
, ppos
, buf
, pos
);
101 static ssize_t
lbs_sleepparams_write(struct file
*file
,
102 const char __user
*user_buf
, size_t count
,
105 struct lbs_private
*priv
= file
->private_data
;
106 ssize_t buf_size
, res
;
107 int p1
, p2
, p3
, p4
, p5
, p6
;
108 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
109 char *buf
= (char *)addr
;
111 buf_size
= min(count
, len
- 1);
112 if (copy_from_user(buf
, user_buf
, buf_size
)) {
116 res
= sscanf(buf
, "%d %d %d %d %d %d", &p1
, &p2
, &p3
, &p4
, &p5
, &p6
);
121 priv
->adapter
->sp
.sp_error
= p1
;
122 priv
->adapter
->sp
.sp_offset
= p2
;
123 priv
->adapter
->sp
.sp_stabletime
= p3
;
124 priv
->adapter
->sp
.sp_calcontrol
= p4
;
125 priv
->adapter
->sp
.sp_extsleepclk
= p5
;
126 priv
->adapter
->sp
.sp_reserved
= p6
;
128 res
= lbs_prepare_and_send_command(priv
,
129 CMD_802_11_SLEEP_PARAMS
,
131 CMD_OPTION_WAITFORRSP
, 0, NULL
);
143 static ssize_t
lbs_sleepparams_read(struct file
*file
, char __user
*userbuf
,
144 size_t count
, loff_t
*ppos
)
146 struct lbs_private
*priv
= file
->private_data
;
147 struct lbs_adapter
*adapter
= priv
->adapter
;
150 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
151 char *buf
= (char *)addr
;
153 res
= lbs_prepare_and_send_command(priv
,
154 CMD_802_11_SLEEP_PARAMS
,
156 CMD_OPTION_WAITFORRSP
, 0, NULL
);
162 pos
+= snprintf(buf
, len
, "%d %d %d %d %d %d\n", adapter
->sp
.sp_error
,
163 adapter
->sp
.sp_offset
, adapter
->sp
.sp_stabletime
,
164 adapter
->sp
.sp_calcontrol
, adapter
->sp
.sp_extsleepclk
,
165 adapter
->sp
.sp_reserved
);
167 res
= simple_read_from_buffer(userbuf
, count
, ppos
, buf
, pos
);
174 static ssize_t
lbs_extscan(struct file
*file
, const char __user
*userbuf
,
175 size_t count
, loff_t
*ppos
)
177 struct lbs_private
*priv
= file
->private_data
;
178 ssize_t res
, buf_size
;
179 union iwreq_data wrqu
;
180 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
181 char *buf
= (char *)addr
;
183 buf_size
= min(count
, len
- 1);
184 if (copy_from_user(buf
, userbuf
, buf_size
)) {
189 lbs_send_specific_ssid_scan(priv
, buf
, strlen(buf
)-1, 0);
191 memset(&wrqu
, 0, sizeof(union iwreq_data
));
192 wireless_send_event(priv
->dev
, SIOCGIWSCAN
, &wrqu
, NULL
);
199 static int lbs_parse_chan(char *buf
, size_t count
,
200 struct lbs_ioctl_user_scan_cfg
*scan_cfg
, int dur
)
202 char *start
, *end
, *hold
, *str
;
205 start
= strstr(buf
, "chan=");
209 end
= strchr(start
, ' ');
212 hold
= kzalloc((end
- start
)+1, GFP_KERNEL
);
215 strncpy(hold
, start
, end
- start
);
216 hold
[(end
-start
)+1] = '\0';
217 while(hold
&& (str
= strsep(&hold
, ","))) {
219 char band
, passive
= 0;
220 sscanf(str
, "%d%c%c", &chan
, &band
, &passive
);
221 scan_cfg
->chanlist
[i
].channumber
= chan
;
222 scan_cfg
->chanlist
[i
].scantype
= passive
? 1 : 0;
223 if (band
== 'b' || band
== 'g')
224 scan_cfg
->chanlist
[i
].radiotype
= 0;
225 else if (band
== 'a')
226 scan_cfg
->chanlist
[i
].radiotype
= 1;
228 scan_cfg
->chanlist
[i
].scantime
= dur
;
236 static void lbs_parse_bssid(char *buf
, size_t count
,
237 struct lbs_ioctl_user_scan_cfg
*scan_cfg
)
240 unsigned int mac
[ETH_ALEN
];
242 hold
= strstr(buf
, "bssid=");
246 sscanf(hold
, "%02x:%02x:%02x:%02x:%02x:%02x",
247 mac
, mac
+1, mac
+2, mac
+3, mac
+4, mac
+5);
248 memcpy(scan_cfg
->bssid
, mac
, ETH_ALEN
);
251 static void lbs_parse_ssid(char *buf
, size_t count
,
252 struct lbs_ioctl_user_scan_cfg
*scan_cfg
)
257 hold
= strstr(buf
, "ssid=");
261 end
= strchr(hold
, ' ');
263 end
= buf
+ count
- 1;
265 size
= min((size_t)IW_ESSID_MAX_SIZE
, (size_t) (end
- hold
));
266 strncpy(scan_cfg
->ssid
, hold
, size
);
271 static int lbs_parse_clear(char *buf
, size_t count
, const char *tag
)
276 hold
= strstr(buf
, tag
);
280 sscanf(hold
, "%d", &val
);
288 static int lbs_parse_dur(char *buf
, size_t count
,
289 struct lbs_ioctl_user_scan_cfg
*scan_cfg
)
294 hold
= strstr(buf
, "dur=");
298 sscanf(hold
, "%d", &val
);
303 static void lbs_parse_probes(char *buf
, size_t count
,
304 struct lbs_ioctl_user_scan_cfg
*scan_cfg
)
309 hold
= strstr(buf
, "probes=");
313 sscanf(hold
, "%d", &val
);
315 scan_cfg
->numprobes
= val
;
320 static void lbs_parse_type(char *buf
, size_t count
,
321 struct lbs_ioctl_user_scan_cfg
*scan_cfg
)
326 hold
= strstr(buf
, "type=");
330 sscanf(hold
, "%d", &val
);
333 if (val
< 1 || val
> 3)
336 scan_cfg
->bsstype
= val
;
341 static ssize_t
lbs_setuserscan(struct file
*file
,
342 const char __user
*userbuf
,
343 size_t count
, loff_t
*ppos
)
345 struct lbs_private
*priv
= file
->private_data
;
346 ssize_t res
, buf_size
;
347 struct lbs_ioctl_user_scan_cfg
*scan_cfg
;
348 union iwreq_data wrqu
;
350 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
351 char *buf
= (char *)addr
;
353 scan_cfg
= kzalloc(sizeof(struct lbs_ioctl_user_scan_cfg
), GFP_KERNEL
);
357 buf_size
= min(count
, len
- 1);
358 if (copy_from_user(buf
, userbuf
, buf_size
)) {
363 scan_cfg
->bsstype
= LBS_SCAN_BSS_TYPE_ANY
;
365 dur
= lbs_parse_dur(buf
, count
, scan_cfg
);
366 lbs_parse_chan(buf
, count
, scan_cfg
, dur
);
367 lbs_parse_bssid(buf
, count
, scan_cfg
);
368 scan_cfg
->clear_bssid
= lbs_parse_clear(buf
, count
, "clear_bssid=");
369 lbs_parse_ssid(buf
, count
, scan_cfg
);
370 scan_cfg
->clear_ssid
= lbs_parse_clear(buf
, count
, "clear_ssid=");
371 lbs_parse_probes(buf
, count
, scan_cfg
);
372 lbs_parse_type(buf
, count
, scan_cfg
);
374 lbs_scan_networks(priv
, scan_cfg
, 1);
375 wait_event_interruptible(priv
->adapter
->cmd_pending
,
376 !priv
->adapter
->nr_cmd_pending
);
378 memset(&wrqu
, 0x00, sizeof(union iwreq_data
));
379 wireless_send_event(priv
->dev
, SIOCGIWSCAN
, &wrqu
, NULL
);
387 static int lbs_event_initcmd(struct lbs_private
*priv
, void **response_buf
,
388 struct cmd_ctrl_node
**cmdnode
,
389 struct cmd_ds_command
**cmd
)
391 u16 wait_option
= CMD_OPTION_WAITFORRSP
;
393 if (!(*cmdnode
= lbs_get_free_cmd_ctrl_node(priv
))) {
394 lbs_deb_debugfs("failed lbs_get_free_cmd_ctrl_node\n");
397 if (!(*response_buf
= kmalloc(3000, GFP_KERNEL
))) {
398 lbs_deb_debugfs("failed to allocate response buffer!\n");
401 lbs_set_cmd_ctrl_node(priv
, *cmdnode
, 0, wait_option
, NULL
);
402 init_waitqueue_head(&(*cmdnode
)->cmdwait_q
);
403 (*cmdnode
)->pdata_buf
= *response_buf
;
404 (*cmdnode
)->cmdflags
|= CMD_F_HOSTCMD
;
405 (*cmdnode
)->cmdwaitqwoken
= 0;
406 *cmd
= (struct cmd_ds_command
*)(*cmdnode
)->bufvirtualaddr
;
407 (*cmd
)->command
= cpu_to_le16(CMD_802_11_SUBSCRIBE_EVENT
);
408 (*cmd
)->seqnum
= cpu_to_le16(++priv
->adapter
->seqnum
);
413 static ssize_t
lbs_lowrssi_read(struct file
*file
, char __user
*userbuf
,
414 size_t count
, loff_t
*ppos
)
416 struct lbs_private
*priv
= file
->private_data
;
417 struct lbs_adapter
*adapter
= priv
->adapter
;
418 struct cmd_ctrl_node
*pcmdnode
;
419 struct cmd_ds_command
*pcmdptr
;
420 struct cmd_ds_802_11_subscribe_event
*event
;
424 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
425 char *buf
= (char *)addr
;
427 res
= lbs_event_initcmd(priv
, &response_buf
, &pcmdnode
, &pcmdptr
);
433 event
= &pcmdptr
->params
.subscribe_event
;
434 event
->action
= cpu_to_le16(CMD_ACT_GET
);
435 pcmdptr
->size
= cpu_to_le16(sizeof(*event
) + S_DS_GEN
);
436 lbs_queue_cmd(adapter
, pcmdnode
, 1);
437 wake_up_interruptible(&priv
->waitq
);
439 /* Sleep until response is generated by FW */
440 wait_event_interruptible(pcmdnode
->cmdwait_q
,
441 pcmdnode
->cmdwaitqwoken
);
443 pcmdptr
= response_buf
;
444 if (pcmdptr
->result
) {
445 lbs_pr_err("%s: fail, result=%d\n", __func__
,
446 le16_to_cpu(pcmdptr
->result
));
452 if (pcmdptr
->command
!= cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT
))) {
453 lbs_pr_err("command response incorrect!\n");
459 cmd_len
= S_DS_GEN
+ sizeof(struct cmd_ds_802_11_subscribe_event
);
460 event
= (void *)(response_buf
+ S_DS_GEN
);
461 while (cmd_len
< le16_to_cpu(pcmdptr
->size
)) {
462 struct mrvlietypesheader
*header
= (void *)(response_buf
+ cmd_len
);
463 switch (header
->type
) {
464 struct mrvlietypes_rssithreshold
*Lowrssi
;
465 case __constant_cpu_to_le16(TLV_TYPE_RSSI_LOW
):
466 Lowrssi
= (void *)(response_buf
+ cmd_len
);
467 pos
+= snprintf(buf
+pos
, len
-pos
, "%d %d %d\n",
470 (event
->events
& cpu_to_le16(0x0001))?1:0);
472 cmd_len
+= sizeof(struct mrvlietypes_snrthreshold
);
478 res
= simple_read_from_buffer(userbuf
, count
, ppos
, buf
, pos
);
483 static u16
lbs_get_events_bitmap(struct lbs_private
*priv
)
485 struct lbs_adapter
*adapter
= priv
->adapter
;
486 struct cmd_ctrl_node
*pcmdnode
;
487 struct cmd_ds_command
*pcmdptr
;
488 struct cmd_ds_802_11_subscribe_event
*event
;
493 res
= lbs_event_initcmd(priv
, &response_buf
, &pcmdnode
, &pcmdptr
);
497 event
= &pcmdptr
->params
.subscribe_event
;
498 event
->action
= cpu_to_le16(CMD_ACT_GET
);
499 pcmdptr
->size
= cpu_to_le16(sizeof(*event
) + S_DS_GEN
);
500 lbs_queue_cmd(adapter
, pcmdnode
, 1);
501 wake_up_interruptible(&priv
->waitq
);
503 /* Sleep until response is generated by FW */
504 wait_event_interruptible(pcmdnode
->cmdwait_q
,
505 pcmdnode
->cmdwaitqwoken
);
507 pcmdptr
= response_buf
;
509 if (pcmdptr
->result
) {
510 lbs_pr_err("%s: fail, result=%d\n", __func__
,
511 le16_to_cpu(pcmdptr
->result
));
516 if (le16_to_cpu(pcmdptr
->command
) != CMD_RET(CMD_802_11_SUBSCRIBE_EVENT
)) {
517 lbs_pr_err("command response incorrect!\n");
522 event
= (struct cmd_ds_802_11_subscribe_event
*)(response_buf
+ S_DS_GEN
);
523 event_bitmap
= le16_to_cpu(event
->events
);
528 static ssize_t
lbs_lowrssi_write(struct file
*file
,
529 const char __user
*userbuf
,
530 size_t count
, loff_t
*ppos
)
532 struct lbs_private
*priv
= file
->private_data
;
533 struct lbs_adapter
*adapter
= priv
->adapter
;
534 ssize_t res
, buf_size
;
535 int value
, freq
, subscribed
, cmd_len
;
536 struct cmd_ctrl_node
*pcmdnode
;
537 struct cmd_ds_command
*pcmdptr
;
538 struct cmd_ds_802_11_subscribe_event
*event
;
539 struct mrvlietypes_rssithreshold
*rssi_threshold
;
543 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
544 char *buf
= (char *)addr
;
546 buf_size
= min(count
, len
- 1);
547 if (copy_from_user(buf
, userbuf
, buf_size
)) {
551 res
= sscanf(buf
, "%d %d %d", &value
, &freq
, &subscribed
);
557 event_bitmap
= lbs_get_events_bitmap(priv
);
559 res
= lbs_event_initcmd(priv
, &response_buf
, &pcmdnode
, &pcmdptr
);
563 event
= &pcmdptr
->params
.subscribe_event
;
564 event
->action
= cpu_to_le16(CMD_ACT_SET
);
565 pcmdptr
->size
= cpu_to_le16(S_DS_GEN
+
566 sizeof(struct cmd_ds_802_11_subscribe_event
) +
567 sizeof(struct mrvlietypes_rssithreshold
));
569 cmd_len
= S_DS_GEN
+ sizeof(struct cmd_ds_802_11_subscribe_event
);
570 ptr
= (u8
*) pcmdptr
+cmd_len
;
571 rssi_threshold
= (struct mrvlietypes_rssithreshold
*)(ptr
);
572 rssi_threshold
->header
.type
= cpu_to_le16(0x0104);
573 rssi_threshold
->header
.len
= cpu_to_le16(2);
574 rssi_threshold
->rssivalue
= value
;
575 rssi_threshold
->rssifreq
= freq
;
576 event_bitmap
|= subscribed
? 0x0001 : 0x0;
577 event
->events
= cpu_to_le16(event_bitmap
);
579 lbs_queue_cmd(adapter
, pcmdnode
, 1);
580 wake_up_interruptible(&priv
->waitq
);
582 /* Sleep until response is generated by FW */
583 wait_event_interruptible(pcmdnode
->cmdwait_q
,
584 pcmdnode
->cmdwaitqwoken
);
586 pcmdptr
= response_buf
;
588 if (pcmdptr
->result
) {
589 lbs_pr_err("%s: fail, result=%d\n", __func__
,
590 le16_to_cpu(pcmdptr
->result
));
596 if (pcmdptr
->command
!= cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT
))) {
597 lbs_pr_err("command response incorrect!\n");
609 static ssize_t
lbs_lowsnr_read(struct file
*file
, char __user
*userbuf
,
610 size_t count
, loff_t
*ppos
)
612 struct lbs_private
*priv
= file
->private_data
;
613 struct lbs_adapter
*adapter
= priv
->adapter
;
614 struct cmd_ctrl_node
*pcmdnode
;
615 struct cmd_ds_command
*pcmdptr
;
616 struct cmd_ds_802_11_subscribe_event
*event
;
620 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
621 char *buf
= (char *)addr
;
623 res
= lbs_event_initcmd(priv
, &response_buf
, &pcmdnode
, &pcmdptr
);
629 event
= &pcmdptr
->params
.subscribe_event
;
630 event
->action
= cpu_to_le16(CMD_ACT_GET
);
631 pcmdptr
->size
= cpu_to_le16(sizeof(*event
) + S_DS_GEN
);
632 lbs_queue_cmd(adapter
, pcmdnode
, 1);
633 wake_up_interruptible(&priv
->waitq
);
635 /* Sleep until response is generated by FW */
636 wait_event_interruptible(pcmdnode
->cmdwait_q
,
637 pcmdnode
->cmdwaitqwoken
);
639 pcmdptr
= response_buf
;
641 if (pcmdptr
->result
) {
642 lbs_pr_err("%s: fail, result=%d\n", __func__
,
643 le16_to_cpu(pcmdptr
->result
));
649 if (pcmdptr
->command
!= cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT
))) {
650 lbs_pr_err("command response incorrect!\n");
656 cmd_len
= S_DS_GEN
+ sizeof(struct cmd_ds_802_11_subscribe_event
);
657 event
= (void *)(response_buf
+ S_DS_GEN
);
658 while (cmd_len
< le16_to_cpu(pcmdptr
->size
)) {
659 struct mrvlietypesheader
*header
= (void *)(response_buf
+ cmd_len
);
660 switch (header
->type
) {
661 struct mrvlietypes_snrthreshold
*LowSnr
;
662 case __constant_cpu_to_le16(TLV_TYPE_SNR_LOW
):
663 LowSnr
= (void *)(response_buf
+ cmd_len
);
664 pos
+= snprintf(buf
+pos
, len
-pos
, "%d %d %d\n",
667 (event
->events
& cpu_to_le16(0x0002))?1:0);
669 cmd_len
+= sizeof(struct mrvlietypes_snrthreshold
);
676 res
= simple_read_from_buffer(userbuf
, count
, ppos
, buf
, pos
);
681 static ssize_t
lbs_lowsnr_write(struct file
*file
,
682 const char __user
*userbuf
,
683 size_t count
, loff_t
*ppos
)
685 struct lbs_private
*priv
= file
->private_data
;
686 struct lbs_adapter
*adapter
= priv
->adapter
;
687 ssize_t res
, buf_size
;
688 int value
, freq
, subscribed
, cmd_len
;
689 struct cmd_ctrl_node
*pcmdnode
;
690 struct cmd_ds_command
*pcmdptr
;
691 struct cmd_ds_802_11_subscribe_event
*event
;
692 struct mrvlietypes_snrthreshold
*snr_threshold
;
696 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
697 char *buf
= (char *)addr
;
699 buf_size
= min(count
, len
- 1);
700 if (copy_from_user(buf
, userbuf
, buf_size
)) {
704 res
= sscanf(buf
, "%d %d %d", &value
, &freq
, &subscribed
);
710 event_bitmap
= lbs_get_events_bitmap(priv
);
712 res
= lbs_event_initcmd(priv
, &response_buf
, &pcmdnode
, &pcmdptr
);
716 event
= &pcmdptr
->params
.subscribe_event
;
717 event
->action
= cpu_to_le16(CMD_ACT_SET
);
718 pcmdptr
->size
= cpu_to_le16(S_DS_GEN
+
719 sizeof(struct cmd_ds_802_11_subscribe_event
) +
720 sizeof(struct mrvlietypes_snrthreshold
));
721 cmd_len
= S_DS_GEN
+ sizeof(struct cmd_ds_802_11_subscribe_event
);
722 ptr
= (u8
*) pcmdptr
+cmd_len
;
723 snr_threshold
= (struct mrvlietypes_snrthreshold
*)(ptr
);
724 snr_threshold
->header
.type
= cpu_to_le16(TLV_TYPE_SNR_LOW
);
725 snr_threshold
->header
.len
= cpu_to_le16(2);
726 snr_threshold
->snrvalue
= value
;
727 snr_threshold
->snrfreq
= freq
;
728 event_bitmap
|= subscribed
? 0x0002 : 0x0;
729 event
->events
= cpu_to_le16(event_bitmap
);
731 lbs_queue_cmd(adapter
, pcmdnode
, 1);
732 wake_up_interruptible(&priv
->waitq
);
734 /* Sleep until response is generated by FW */
735 wait_event_interruptible(pcmdnode
->cmdwait_q
,
736 pcmdnode
->cmdwaitqwoken
);
738 pcmdptr
= response_buf
;
740 if (pcmdptr
->result
) {
741 lbs_pr_err("%s: fail, result=%d\n", __func__
,
742 le16_to_cpu(pcmdptr
->result
));
748 if (pcmdptr
->command
!= cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT
))) {
749 lbs_pr_err("command response incorrect!\n");
762 static ssize_t
lbs_failcount_read(struct file
*file
, char __user
*userbuf
,
763 size_t count
, loff_t
*ppos
)
765 struct lbs_private
*priv
= file
->private_data
;
766 struct lbs_adapter
*adapter
= priv
->adapter
;
767 struct cmd_ctrl_node
*pcmdnode
;
768 struct cmd_ds_command
*pcmdptr
;
769 struct cmd_ds_802_11_subscribe_event
*event
;
773 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
774 char *buf
= (char *)addr
;
776 res
= lbs_event_initcmd(priv
, &response_buf
, &pcmdnode
, &pcmdptr
);
782 event
= &pcmdptr
->params
.subscribe_event
;
783 event
->action
= cpu_to_le16(CMD_ACT_GET
);
784 pcmdptr
->size
= cpu_to_le16(sizeof(*event
) + S_DS_GEN
);
785 lbs_queue_cmd(adapter
, pcmdnode
, 1);
786 wake_up_interruptible(&priv
->waitq
);
788 /* Sleep until response is generated by FW */
789 wait_event_interruptible(pcmdnode
->cmdwait_q
,
790 pcmdnode
->cmdwaitqwoken
);
792 pcmdptr
= response_buf
;
794 if (pcmdptr
->result
) {
795 lbs_pr_err("%s: fail, result=%d\n", __func__
,
796 le16_to_cpu(pcmdptr
->result
));
802 if (pcmdptr
->command
!= cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT
))) {
803 lbs_pr_err("command response incorrect!\n");
809 cmd_len
= S_DS_GEN
+ sizeof(struct cmd_ds_802_11_subscribe_event
);
810 event
= (void *)(response_buf
+ S_DS_GEN
);
811 while (cmd_len
< le16_to_cpu(pcmdptr
->size
)) {
812 struct mrvlietypesheader
*header
= (void *)(response_buf
+ cmd_len
);
813 switch (header
->type
) {
814 struct mrvlietypes_failurecount
*failcount
;
815 case __constant_cpu_to_le16(TLV_TYPE_FAILCOUNT
):
816 failcount
= (void *)(response_buf
+ cmd_len
);
817 pos
+= snprintf(buf
+pos
, len
-pos
, "%d %d %d\n",
818 failcount
->failvalue
,
820 (event
->events
& cpu_to_le16(0x0004))?1:0);
822 cmd_len
+= sizeof(struct mrvlietypes_failurecount
);
828 res
= simple_read_from_buffer(userbuf
, count
, ppos
, buf
, pos
);
833 static ssize_t
lbs_failcount_write(struct file
*file
,
834 const char __user
*userbuf
,
835 size_t count
, loff_t
*ppos
)
837 struct lbs_private
*priv
= file
->private_data
;
838 struct lbs_adapter
*adapter
= priv
->adapter
;
839 ssize_t res
, buf_size
;
840 int value
, freq
, subscribed
, cmd_len
;
841 struct cmd_ctrl_node
*pcmdnode
;
842 struct cmd_ds_command
*pcmdptr
;
843 struct cmd_ds_802_11_subscribe_event
*event
;
844 struct mrvlietypes_failurecount
*failcount
;
848 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
849 char *buf
= (char *)addr
;
851 buf_size
= min(count
, len
- 1);
852 if (copy_from_user(buf
, userbuf
, buf_size
)) {
856 res
= sscanf(buf
, "%d %d %d", &value
, &freq
, &subscribed
);
862 event_bitmap
= lbs_get_events_bitmap(priv
);
864 res
= lbs_event_initcmd(priv
, &response_buf
, &pcmdnode
, &pcmdptr
);
868 event
= &pcmdptr
->params
.subscribe_event
;
869 event
->action
= cpu_to_le16(CMD_ACT_SET
);
870 pcmdptr
->size
= cpu_to_le16(S_DS_GEN
+
871 sizeof(struct cmd_ds_802_11_subscribe_event
) +
872 sizeof(struct mrvlietypes_failurecount
));
873 cmd_len
= S_DS_GEN
+ sizeof(struct cmd_ds_802_11_subscribe_event
);
874 ptr
= (u8
*) pcmdptr
+cmd_len
;
875 failcount
= (struct mrvlietypes_failurecount
*)(ptr
);
876 failcount
->header
.type
= cpu_to_le16(TLV_TYPE_FAILCOUNT
);
877 failcount
->header
.len
= cpu_to_le16(2);
878 failcount
->failvalue
= value
;
879 failcount
->Failfreq
= freq
;
880 event_bitmap
|= subscribed
? 0x0004 : 0x0;
881 event
->events
= cpu_to_le16(event_bitmap
);
883 lbs_queue_cmd(adapter
, pcmdnode
, 1);
884 wake_up_interruptible(&priv
->waitq
);
886 /* Sleep until response is generated by FW */
887 wait_event_interruptible(pcmdnode
->cmdwait_q
,
888 pcmdnode
->cmdwaitqwoken
);
890 pcmdptr
= (struct cmd_ds_command
*)response_buf
;
892 if (pcmdptr
->result
) {
893 lbs_pr_err("%s: fail, result=%d\n", __func__
,
894 le16_to_cpu(pcmdptr
->result
));
900 if (pcmdptr
->command
!= cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT
))) {
901 lbs_pr_err("command response incorrect!\n");
913 static ssize_t
lbs_bcnmiss_read(struct file
*file
, char __user
*userbuf
,
914 size_t count
, loff_t
*ppos
)
916 struct lbs_private
*priv
= file
->private_data
;
917 struct lbs_adapter
*adapter
= priv
->adapter
;
918 struct cmd_ctrl_node
*pcmdnode
;
919 struct cmd_ds_command
*pcmdptr
;
920 struct cmd_ds_802_11_subscribe_event
*event
;
924 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
925 char *buf
= (char *)addr
;
927 res
= lbs_event_initcmd(priv
, &response_buf
, &pcmdnode
, &pcmdptr
);
933 event
= &pcmdptr
->params
.subscribe_event
;
934 event
->action
= cpu_to_le16(CMD_ACT_GET
);
935 pcmdptr
->size
= cpu_to_le16(sizeof(*event
) + S_DS_GEN
);
936 lbs_queue_cmd(adapter
, pcmdnode
, 1);
937 wake_up_interruptible(&priv
->waitq
);
939 /* Sleep until response is generated by FW */
940 wait_event_interruptible(pcmdnode
->cmdwait_q
,
941 pcmdnode
->cmdwaitqwoken
);
943 pcmdptr
= response_buf
;
945 if (pcmdptr
->result
) {
946 lbs_pr_err("%s: fail, result=%d\n", __func__
,
947 le16_to_cpu(pcmdptr
->result
));
953 if (pcmdptr
->command
!= cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT
))) {
954 lbs_pr_err("command response incorrect!\n");
960 cmd_len
= S_DS_GEN
+ sizeof(struct cmd_ds_802_11_subscribe_event
);
961 event
= (void *)(response_buf
+ S_DS_GEN
);
962 while (cmd_len
< le16_to_cpu(pcmdptr
->size
)) {
963 struct mrvlietypesheader
*header
= (void *)(response_buf
+ cmd_len
);
964 switch (header
->type
) {
965 struct mrvlietypes_beaconsmissed
*bcnmiss
;
966 case __constant_cpu_to_le16(TLV_TYPE_BCNMISS
):
967 bcnmiss
= (void *)(response_buf
+ cmd_len
);
968 pos
+= snprintf(buf
+pos
, len
-pos
, "%d N/A %d\n",
969 bcnmiss
->beaconmissed
,
970 (event
->events
& cpu_to_le16(0x0008))?1:0);
972 cmd_len
+= sizeof(struct mrvlietypes_beaconsmissed
);
979 res
= simple_read_from_buffer(userbuf
, count
, ppos
, buf
, pos
);
984 static ssize_t
lbs_bcnmiss_write(struct file
*file
,
985 const char __user
*userbuf
,
986 size_t count
, loff_t
*ppos
)
988 struct lbs_private
*priv
= file
->private_data
;
989 struct lbs_adapter
*adapter
= priv
->adapter
;
990 ssize_t res
, buf_size
;
991 int value
, freq
, subscribed
, cmd_len
;
992 struct cmd_ctrl_node
*pcmdnode
;
993 struct cmd_ds_command
*pcmdptr
;
994 struct cmd_ds_802_11_subscribe_event
*event
;
995 struct mrvlietypes_beaconsmissed
*bcnmiss
;
999 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
1000 char *buf
= (char *)addr
;
1002 buf_size
= min(count
, len
- 1);
1003 if (copy_from_user(buf
, userbuf
, buf_size
)) {
1007 res
= sscanf(buf
, "%d %d %d", &value
, &freq
, &subscribed
);
1013 event_bitmap
= lbs_get_events_bitmap(priv
);
1015 res
= lbs_event_initcmd(priv
, &response_buf
, &pcmdnode
, &pcmdptr
);
1019 event
= &pcmdptr
->params
.subscribe_event
;
1020 event
->action
= cpu_to_le16(CMD_ACT_SET
);
1021 pcmdptr
->size
= cpu_to_le16(S_DS_GEN
+
1022 sizeof(struct cmd_ds_802_11_subscribe_event
) +
1023 sizeof(struct mrvlietypes_beaconsmissed
));
1024 cmd_len
= S_DS_GEN
+ sizeof(struct cmd_ds_802_11_subscribe_event
);
1025 ptr
= (u8
*) pcmdptr
+cmd_len
;
1026 bcnmiss
= (struct mrvlietypes_beaconsmissed
*)(ptr
);
1027 bcnmiss
->header
.type
= cpu_to_le16(TLV_TYPE_BCNMISS
);
1028 bcnmiss
->header
.len
= cpu_to_le16(2);
1029 bcnmiss
->beaconmissed
= value
;
1030 event_bitmap
|= subscribed
? 0x0008 : 0x0;
1031 event
->events
= cpu_to_le16(event_bitmap
);
1033 lbs_queue_cmd(adapter
, pcmdnode
, 1);
1034 wake_up_interruptible(&priv
->waitq
);
1036 /* Sleep until response is generated by FW */
1037 wait_event_interruptible(pcmdnode
->cmdwait_q
,
1038 pcmdnode
->cmdwaitqwoken
);
1040 pcmdptr
= response_buf
;
1042 if (pcmdptr
->result
) {
1043 lbs_pr_err("%s: fail, result=%d\n", __func__
,
1044 le16_to_cpu(pcmdptr
->result
));
1045 kfree(response_buf
);
1050 if (pcmdptr
->command
!= cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT
))) {
1051 lbs_pr_err("command response incorrect!\n");
1053 kfree(response_buf
);
1063 static ssize_t
lbs_highrssi_read(struct file
*file
, char __user
*userbuf
,
1064 size_t count
, loff_t
*ppos
)
1066 struct lbs_private
*priv
= file
->private_data
;
1067 struct lbs_adapter
*adapter
= priv
->adapter
;
1068 struct cmd_ctrl_node
*pcmdnode
;
1069 struct cmd_ds_command
*pcmdptr
;
1070 struct cmd_ds_802_11_subscribe_event
*event
;
1074 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
1075 char *buf
= (char *)addr
;
1077 res
= lbs_event_initcmd(priv
, &response_buf
, &pcmdnode
, &pcmdptr
);
1083 event
= &pcmdptr
->params
.subscribe_event
;
1084 event
->action
= cpu_to_le16(CMD_ACT_GET
);
1085 pcmdptr
->size
= cpu_to_le16(sizeof(*event
) + S_DS_GEN
);
1086 lbs_queue_cmd(adapter
, pcmdnode
, 1);
1087 wake_up_interruptible(&priv
->waitq
);
1089 /* Sleep until response is generated by FW */
1090 wait_event_interruptible(pcmdnode
->cmdwait_q
,
1091 pcmdnode
->cmdwaitqwoken
);
1093 pcmdptr
= response_buf
;
1095 if (pcmdptr
->result
) {
1096 lbs_pr_err("%s: fail, result=%d\n", __func__
,
1097 le16_to_cpu(pcmdptr
->result
));
1098 kfree(response_buf
);
1103 if (pcmdptr
->command
!= cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT
))) {
1104 lbs_pr_err("command response incorrect!\n");
1105 kfree(response_buf
);
1110 cmd_len
= S_DS_GEN
+ sizeof(struct cmd_ds_802_11_subscribe_event
);
1111 event
= (void *)(response_buf
+ S_DS_GEN
);
1112 while (cmd_len
< le16_to_cpu(pcmdptr
->size
)) {
1113 struct mrvlietypesheader
*header
= (void *)(response_buf
+ cmd_len
);
1114 switch (header
->type
) {
1115 struct mrvlietypes_rssithreshold
*Highrssi
;
1116 case __constant_cpu_to_le16(TLV_TYPE_RSSI_HIGH
):
1117 Highrssi
= (void *)(response_buf
+ cmd_len
);
1118 pos
+= snprintf(buf
+pos
, len
-pos
, "%d %d %d\n",
1119 Highrssi
->rssivalue
,
1121 (event
->events
& cpu_to_le16(0x0010))?1:0);
1123 cmd_len
+= sizeof(struct mrvlietypes_snrthreshold
);
1128 kfree(response_buf
);
1130 res
= simple_read_from_buffer(userbuf
, count
, ppos
, buf
, pos
);
1135 static ssize_t
lbs_highrssi_write(struct file
*file
,
1136 const char __user
*userbuf
,
1137 size_t count
, loff_t
*ppos
)
1139 struct lbs_private
*priv
= file
->private_data
;
1140 struct lbs_adapter
*adapter
= priv
->adapter
;
1141 ssize_t res
, buf_size
;
1142 int value
, freq
, subscribed
, cmd_len
;
1143 struct cmd_ctrl_node
*pcmdnode
;
1144 struct cmd_ds_command
*pcmdptr
;
1145 struct cmd_ds_802_11_subscribe_event
*event
;
1146 struct mrvlietypes_rssithreshold
*rssi_threshold
;
1150 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
1151 char *buf
= (char *)addr
;
1153 buf_size
= min(count
, len
- 1);
1154 if (copy_from_user(buf
, userbuf
, buf_size
)) {
1158 res
= sscanf(buf
, "%d %d %d", &value
, &freq
, &subscribed
);
1164 event_bitmap
= lbs_get_events_bitmap(priv
);
1166 res
= lbs_event_initcmd(priv
, &response_buf
, &pcmdnode
, &pcmdptr
);
1170 event
= &pcmdptr
->params
.subscribe_event
;
1171 event
->action
= cpu_to_le16(CMD_ACT_SET
);
1172 pcmdptr
->size
= cpu_to_le16(S_DS_GEN
+
1173 sizeof(struct cmd_ds_802_11_subscribe_event
) +
1174 sizeof(struct mrvlietypes_rssithreshold
));
1175 cmd_len
= S_DS_GEN
+ sizeof(struct cmd_ds_802_11_subscribe_event
);
1176 ptr
= (u8
*) pcmdptr
+cmd_len
;
1177 rssi_threshold
= (struct mrvlietypes_rssithreshold
*)(ptr
);
1178 rssi_threshold
->header
.type
= cpu_to_le16(TLV_TYPE_RSSI_HIGH
);
1179 rssi_threshold
->header
.len
= cpu_to_le16(2);
1180 rssi_threshold
->rssivalue
= value
;
1181 rssi_threshold
->rssifreq
= freq
;
1182 event_bitmap
|= subscribed
? 0x0010 : 0x0;
1183 event
->events
= cpu_to_le16(event_bitmap
);
1185 lbs_queue_cmd(adapter
, pcmdnode
, 1);
1186 wake_up_interruptible(&priv
->waitq
);
1188 /* Sleep until response is generated by FW */
1189 wait_event_interruptible(pcmdnode
->cmdwait_q
,
1190 pcmdnode
->cmdwaitqwoken
);
1192 pcmdptr
= response_buf
;
1194 if (pcmdptr
->result
) {
1195 lbs_pr_err("%s: fail, result=%d\n", __func__
,
1196 le16_to_cpu(pcmdptr
->result
));
1197 kfree(response_buf
);
1201 if (pcmdptr
->command
!= cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT
))) {
1202 lbs_pr_err("command response incorrect!\n");
1203 kfree(response_buf
);
1213 static ssize_t
lbs_highsnr_read(struct file
*file
, char __user
*userbuf
,
1214 size_t count
, loff_t
*ppos
)
1216 struct lbs_private
*priv
= file
->private_data
;
1217 struct lbs_adapter
*adapter
= priv
->adapter
;
1218 struct cmd_ctrl_node
*pcmdnode
;
1219 struct cmd_ds_command
*pcmdptr
;
1220 struct cmd_ds_802_11_subscribe_event
*event
;
1224 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
1225 char *buf
= (char *)addr
;
1227 res
= lbs_event_initcmd(priv
, &response_buf
, &pcmdnode
, &pcmdptr
);
1233 event
= &pcmdptr
->params
.subscribe_event
;
1234 event
->action
= cpu_to_le16(CMD_ACT_GET
);
1235 pcmdptr
->size
= cpu_to_le16(sizeof(*event
) + S_DS_GEN
);
1236 lbs_queue_cmd(adapter
, pcmdnode
, 1);
1237 wake_up_interruptible(&priv
->waitq
);
1239 /* Sleep until response is generated by FW */
1240 wait_event_interruptible(pcmdnode
->cmdwait_q
,
1241 pcmdnode
->cmdwaitqwoken
);
1243 pcmdptr
= response_buf
;
1245 if (pcmdptr
->result
) {
1246 lbs_pr_err("%s: fail, result=%d\n", __func__
,
1247 le16_to_cpu(pcmdptr
->result
));
1248 kfree(response_buf
);
1253 if (pcmdptr
->command
!= cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT
))) {
1254 lbs_pr_err("command response incorrect!\n");
1255 kfree(response_buf
);
1260 cmd_len
= S_DS_GEN
+ sizeof(struct cmd_ds_802_11_subscribe_event
);
1261 event
= (void *)(response_buf
+ S_DS_GEN
);
1262 while (cmd_len
< le16_to_cpu(pcmdptr
->size
)) {
1263 struct mrvlietypesheader
*header
= (void *)(response_buf
+ cmd_len
);
1264 switch (header
->type
) {
1265 struct mrvlietypes_snrthreshold
*HighSnr
;
1266 case __constant_cpu_to_le16(TLV_TYPE_SNR_HIGH
):
1267 HighSnr
= (void *)(response_buf
+ cmd_len
);
1268 pos
+= snprintf(buf
+pos
, len
-pos
, "%d %d %d\n",
1271 (event
->events
& cpu_to_le16(0x0020))?1:0);
1273 cmd_len
+= sizeof(struct mrvlietypes_snrthreshold
);
1278 kfree(response_buf
);
1280 res
= simple_read_from_buffer(userbuf
, count
, ppos
, buf
, pos
);
1285 static ssize_t
lbs_highsnr_write(struct file
*file
,
1286 const char __user
*userbuf
,
1287 size_t count
, loff_t
*ppos
)
1289 struct lbs_private
*priv
= file
->private_data
;
1290 struct lbs_adapter
*adapter
= priv
->adapter
;
1291 ssize_t res
, buf_size
;
1292 int value
, freq
, subscribed
, cmd_len
;
1293 struct cmd_ctrl_node
*pcmdnode
;
1294 struct cmd_ds_command
*pcmdptr
;
1295 struct cmd_ds_802_11_subscribe_event
*event
;
1296 struct mrvlietypes_snrthreshold
*snr_threshold
;
1300 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
1301 char *buf
= (char *)addr
;
1303 buf_size
= min(count
, len
- 1);
1304 if (copy_from_user(buf
, userbuf
, buf_size
)) {
1308 res
= sscanf(buf
, "%d %d %d", &value
, &freq
, &subscribed
);
1314 event_bitmap
= lbs_get_events_bitmap(priv
);
1316 res
= lbs_event_initcmd(priv
, &response_buf
, &pcmdnode
, &pcmdptr
);
1320 event
= &pcmdptr
->params
.subscribe_event
;
1321 event
->action
= cpu_to_le16(CMD_ACT_SET
);
1322 pcmdptr
->size
= cpu_to_le16(S_DS_GEN
+
1323 sizeof(struct cmd_ds_802_11_subscribe_event
) +
1324 sizeof(struct mrvlietypes_snrthreshold
));
1325 cmd_len
= S_DS_GEN
+ sizeof(struct cmd_ds_802_11_subscribe_event
);
1326 ptr
= (u8
*) pcmdptr
+cmd_len
;
1327 snr_threshold
= (struct mrvlietypes_snrthreshold
*)(ptr
);
1328 snr_threshold
->header
.type
= cpu_to_le16(TLV_TYPE_SNR_HIGH
);
1329 snr_threshold
->header
.len
= cpu_to_le16(2);
1330 snr_threshold
->snrvalue
= value
;
1331 snr_threshold
->snrfreq
= freq
;
1332 event_bitmap
|= subscribed
? 0x0020 : 0x0;
1333 event
->events
= cpu_to_le16(event_bitmap
);
1335 lbs_queue_cmd(adapter
, pcmdnode
, 1);
1336 wake_up_interruptible(&priv
->waitq
);
1338 /* Sleep until response is generated by FW */
1339 wait_event_interruptible(pcmdnode
->cmdwait_q
,
1340 pcmdnode
->cmdwaitqwoken
);
1342 pcmdptr
= response_buf
;
1344 if (pcmdptr
->result
) {
1345 lbs_pr_err("%s: fail, result=%d\n", __func__
,
1346 le16_to_cpu(pcmdptr
->result
));
1347 kfree(response_buf
);
1352 if (pcmdptr
->command
!= cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT
))) {
1353 lbs_pr_err("command response incorrect!\n");
1354 kfree(response_buf
);
1365 static ssize_t
lbs_rdmac_read(struct file
*file
, char __user
*userbuf
,
1366 size_t count
, loff_t
*ppos
)
1368 struct lbs_private
*priv
= file
->private_data
;
1369 struct lbs_adapter
*adapter
= priv
->adapter
;
1370 struct lbs_offset_value offval
;
1373 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
1374 char *buf
= (char *)addr
;
1376 offval
.offset
= priv
->mac_offset
;
1379 ret
= lbs_prepare_and_send_command(priv
,
1380 CMD_MAC_REG_ACCESS
, 0,
1381 CMD_OPTION_WAITFORRSP
, 0, &offval
);
1383 pos
+= snprintf(buf
+pos
, len
-pos
, "MAC[0x%x] = 0x%08x\n",
1384 priv
->mac_offset
, adapter
->offsetvalue
.value
);
1386 ret
= simple_read_from_buffer(userbuf
, count
, ppos
, buf
, pos
);
1391 static ssize_t
lbs_rdmac_write(struct file
*file
,
1392 const char __user
*userbuf
,
1393 size_t count
, loff_t
*ppos
)
1395 struct lbs_private
*priv
= file
->private_data
;
1396 ssize_t res
, buf_size
;
1397 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
1398 char *buf
= (char *)addr
;
1400 buf_size
= min(count
, len
- 1);
1401 if (copy_from_user(buf
, userbuf
, buf_size
)) {
1405 priv
->mac_offset
= simple_strtoul((char *)buf
, NULL
, 16);
1412 static ssize_t
lbs_wrmac_write(struct file
*file
,
1413 const char __user
*userbuf
,
1414 size_t count
, loff_t
*ppos
)
1417 struct lbs_private
*priv
= file
->private_data
;
1418 ssize_t res
, buf_size
;
1420 struct lbs_offset_value offval
;
1421 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
1422 char *buf
= (char *)addr
;
1424 buf_size
= min(count
, len
- 1);
1425 if (copy_from_user(buf
, userbuf
, buf_size
)) {
1429 res
= sscanf(buf
, "%x %x", &offset
, &value
);
1435 offval
.offset
= offset
;
1436 offval
.value
= value
;
1437 res
= lbs_prepare_and_send_command(priv
,
1438 CMD_MAC_REG_ACCESS
, 1,
1439 CMD_OPTION_WAITFORRSP
, 0, &offval
);
1448 static ssize_t
lbs_rdbbp_read(struct file
*file
, char __user
*userbuf
,
1449 size_t count
, loff_t
*ppos
)
1451 struct lbs_private
*priv
= file
->private_data
;
1452 struct lbs_adapter
*adapter
= priv
->adapter
;
1453 struct lbs_offset_value offval
;
1456 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
1457 char *buf
= (char *)addr
;
1459 offval
.offset
= priv
->bbp_offset
;
1462 ret
= lbs_prepare_and_send_command(priv
,
1463 CMD_BBP_REG_ACCESS
, 0,
1464 CMD_OPTION_WAITFORRSP
, 0, &offval
);
1466 pos
+= snprintf(buf
+pos
, len
-pos
, "BBP[0x%x] = 0x%08x\n",
1467 priv
->bbp_offset
, adapter
->offsetvalue
.value
);
1469 ret
= simple_read_from_buffer(userbuf
, count
, ppos
, buf
, pos
);
1475 static ssize_t
lbs_rdbbp_write(struct file
*file
,
1476 const char __user
*userbuf
,
1477 size_t count
, loff_t
*ppos
)
1479 struct lbs_private
*priv
= file
->private_data
;
1480 ssize_t res
, buf_size
;
1481 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
1482 char *buf
= (char *)addr
;
1484 buf_size
= min(count
, len
- 1);
1485 if (copy_from_user(buf
, userbuf
, buf_size
)) {
1489 priv
->bbp_offset
= simple_strtoul((char *)buf
, NULL
, 16);
1496 static ssize_t
lbs_wrbbp_write(struct file
*file
,
1497 const char __user
*userbuf
,
1498 size_t count
, loff_t
*ppos
)
1501 struct lbs_private
*priv
= file
->private_data
;
1502 ssize_t res
, buf_size
;
1504 struct lbs_offset_value offval
;
1505 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
1506 char *buf
= (char *)addr
;
1508 buf_size
= min(count
, len
- 1);
1509 if (copy_from_user(buf
, userbuf
, buf_size
)) {
1513 res
= sscanf(buf
, "%x %x", &offset
, &value
);
1519 offval
.offset
= offset
;
1520 offval
.value
= value
;
1521 res
= lbs_prepare_and_send_command(priv
,
1522 CMD_BBP_REG_ACCESS
, 1,
1523 CMD_OPTION_WAITFORRSP
, 0, &offval
);
1532 static ssize_t
lbs_rdrf_read(struct file
*file
, char __user
*userbuf
,
1533 size_t count
, loff_t
*ppos
)
1535 struct lbs_private
*priv
= file
->private_data
;
1536 struct lbs_adapter
*adapter
= priv
->adapter
;
1537 struct lbs_offset_value offval
;
1540 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
1541 char *buf
= (char *)addr
;
1543 offval
.offset
= priv
->rf_offset
;
1546 ret
= lbs_prepare_and_send_command(priv
,
1547 CMD_RF_REG_ACCESS
, 0,
1548 CMD_OPTION_WAITFORRSP
, 0, &offval
);
1550 pos
+= snprintf(buf
+pos
, len
-pos
, "RF[0x%x] = 0x%08x\n",
1551 priv
->rf_offset
, adapter
->offsetvalue
.value
);
1553 ret
= simple_read_from_buffer(userbuf
, count
, ppos
, buf
, pos
);
1559 static ssize_t
lbs_rdrf_write(struct file
*file
,
1560 const char __user
*userbuf
,
1561 size_t count
, loff_t
*ppos
)
1563 struct lbs_private
*priv
= file
->private_data
;
1564 ssize_t res
, buf_size
;
1565 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
1566 char *buf
= (char *)addr
;
1568 buf_size
= min(count
, len
- 1);
1569 if (copy_from_user(buf
, userbuf
, buf_size
)) {
1573 priv
->rf_offset
= simple_strtoul((char *)buf
, NULL
, 16);
1580 static ssize_t
lbs_wrrf_write(struct file
*file
,
1581 const char __user
*userbuf
,
1582 size_t count
, loff_t
*ppos
)
1585 struct lbs_private
*priv
= file
->private_data
;
1586 ssize_t res
, buf_size
;
1588 struct lbs_offset_value offval
;
1589 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
1590 char *buf
= (char *)addr
;
1592 buf_size
= min(count
, len
- 1);
1593 if (copy_from_user(buf
, userbuf
, buf_size
)) {
1597 res
= sscanf(buf
, "%x %x", &offset
, &value
);
1603 offval
.offset
= offset
;
1604 offval
.value
= value
;
1605 res
= lbs_prepare_and_send_command(priv
,
1606 CMD_RF_REG_ACCESS
, 1,
1607 CMD_OPTION_WAITFORRSP
, 0, &offval
);
1616 #define FOPS(fread, fwrite) { \
1617 .owner = THIS_MODULE, \
1618 .open = open_file_generic, \
1620 .write = (fwrite), \
1623 struct lbs_debugfs_files
{
1626 struct file_operations fops
;
1629 static struct lbs_debugfs_files debugfs_files
[] = {
1630 { "info", 0444, FOPS(lbs_dev_info
, write_file_dummy
), },
1631 { "getscantable", 0444, FOPS(lbs_getscantable
,
1632 write_file_dummy
), },
1633 { "sleepparams", 0644, FOPS(lbs_sleepparams_read
,
1634 lbs_sleepparams_write
), },
1635 { "extscan", 0600, FOPS(NULL
, lbs_extscan
), },
1636 { "setuserscan", 0600, FOPS(NULL
, lbs_setuserscan
), },
1639 static struct lbs_debugfs_files debugfs_events_files
[] = {
1640 {"low_rssi", 0644, FOPS(lbs_lowrssi_read
,
1641 lbs_lowrssi_write
), },
1642 {"low_snr", 0644, FOPS(lbs_lowsnr_read
,
1643 lbs_lowsnr_write
), },
1644 {"failure_count", 0644, FOPS(lbs_failcount_read
,
1645 lbs_failcount_write
), },
1646 {"beacon_missed", 0644, FOPS(lbs_bcnmiss_read
,
1647 lbs_bcnmiss_write
), },
1648 {"high_rssi", 0644, FOPS(lbs_highrssi_read
,
1649 lbs_highrssi_write
), },
1650 {"high_snr", 0644, FOPS(lbs_highsnr_read
,
1651 lbs_highsnr_write
), },
1654 static struct lbs_debugfs_files debugfs_regs_files
[] = {
1655 {"rdmac", 0644, FOPS(lbs_rdmac_read
, lbs_rdmac_write
), },
1656 {"wrmac", 0600, FOPS(NULL
, lbs_wrmac_write
), },
1657 {"rdbbp", 0644, FOPS(lbs_rdbbp_read
, lbs_rdbbp_write
), },
1658 {"wrbbp", 0600, FOPS(NULL
, lbs_wrbbp_write
), },
1659 {"rdrf", 0644, FOPS(lbs_rdrf_read
, lbs_rdrf_write
), },
1660 {"wrrf", 0600, FOPS(NULL
, lbs_wrrf_write
), },
1663 void lbs_debugfs_init(void)
1666 lbs_dir
= debugfs_create_dir("lbs_wireless", NULL
);
1671 void lbs_debugfs_remove(void)
1674 debugfs_remove(lbs_dir
);
1678 void lbs_debugfs_init_one(struct lbs_private
*priv
, struct net_device
*dev
)
1681 struct lbs_debugfs_files
*files
;
1685 priv
->debugfs_dir
= debugfs_create_dir(dev
->name
, lbs_dir
);
1686 if (!priv
->debugfs_dir
)
1689 for (i
=0; i
<ARRAY_SIZE(debugfs_files
); i
++) {
1690 files
= &debugfs_files
[i
];
1691 priv
->debugfs_files
[i
] = debugfs_create_file(files
->name
,
1698 priv
->events_dir
= debugfs_create_dir("subscribed_events", priv
->debugfs_dir
);
1699 if (!priv
->events_dir
)
1702 for (i
=0; i
<ARRAY_SIZE(debugfs_events_files
); i
++) {
1703 files
= &debugfs_events_files
[i
];
1704 priv
->debugfs_events_files
[i
] = debugfs_create_file(files
->name
,
1711 priv
->regs_dir
= debugfs_create_dir("registers", priv
->debugfs_dir
);
1712 if (!priv
->regs_dir
)
1715 for (i
=0; i
<ARRAY_SIZE(debugfs_regs_files
); i
++) {
1716 files
= &debugfs_regs_files
[i
];
1717 priv
->debugfs_regs_files
[i
] = debugfs_create_file(files
->name
,
1725 lbs_debug_init(priv
, dev
);
1731 void lbs_debugfs_remove_one(struct lbs_private
*priv
)
1735 for(i
=0; i
<ARRAY_SIZE(debugfs_regs_files
); i
++)
1736 debugfs_remove(priv
->debugfs_regs_files
[i
]);
1738 debugfs_remove(priv
->regs_dir
);
1740 for(i
=0; i
<ARRAY_SIZE(debugfs_events_files
); i
++)
1741 debugfs_remove(priv
->debugfs_events_files
[i
]);
1743 debugfs_remove(priv
->events_dir
);
1745 debugfs_remove(priv
->debugfs_debug
);
1747 for(i
=0; i
<ARRAY_SIZE(debugfs_files
); i
++)
1748 debugfs_remove(priv
->debugfs_files
[i
]);
1749 debugfs_remove(priv
->debugfs_dir
);
1758 #define item_size(n) (FIELD_SIZEOF(struct lbs_adapter, n))
1759 #define item_addr(n) (offsetof(struct lbs_adapter, n))
1768 /* To debug any member of struct lbs_adapter, simply add one line here.
1770 static struct debug_data items
[] = {
1771 {"intcounter", item_size(intcounter
), item_addr(intcounter
)},
1772 {"psmode", item_size(psmode
), item_addr(psmode
)},
1773 {"psstate", item_size(psstate
), item_addr(psstate
)},
1776 static int num_of_items
= ARRAY_SIZE(items
);
1779 * @brief proc read function
1781 * @param page pointer to buffer
1782 * @param s read data starting position
1784 * @param cnt counter
1785 * @param eof end of file flag
1786 * @param data data to output
1787 * @return number of output data
1789 static ssize_t
lbs_debugfs_read(struct file
*file
, char __user
*userbuf
,
1790 size_t count
, loff_t
*ppos
)
1797 struct debug_data
*d
;
1798 unsigned long addr
= get_zeroed_page(GFP_KERNEL
);
1799 char *buf
= (char *)addr
;
1803 d
= (struct debug_data
*)file
->private_data
;
1805 for (i
= 0; i
< num_of_items
; i
++) {
1807 val
= *((u8
*) d
[i
].addr
);
1808 else if (d
[i
].size
== 2)
1809 val
= *((u16
*) d
[i
].addr
);
1810 else if (d
[i
].size
== 4)
1811 val
= *((u32
*) d
[i
].addr
);
1812 else if (d
[i
].size
== 8)
1813 val
= *((u64
*) d
[i
].addr
);
1815 pos
+= sprintf(p
+ pos
, "%s=%d\n", d
[i
].name
, val
);
1818 res
= simple_read_from_buffer(userbuf
, count
, ppos
, p
, pos
);
1825 * @brief proc write function
1827 * @param f file pointer
1828 * @param buf pointer to data buffer
1829 * @param cnt data number to write
1830 * @param data data to write
1831 * @return number of data
1833 static ssize_t
lbs_debugfs_write(struct file
*f
, const char __user
*buf
,
1834 size_t cnt
, loff_t
*ppos
)
1842 struct debug_data
*d
= (struct debug_data
*)f
->private_data
;
1844 pdata
= kmalloc(cnt
, GFP_KERNEL
);
1848 if (copy_from_user(pdata
, buf
, cnt
)) {
1849 lbs_deb_debugfs("Copy from user failed\n");
1855 for (i
= 0; i
< num_of_items
; i
++) {
1857 p
= strstr(p0
, d
[i
].name
);
1860 p1
= strchr(p
, '\n');
1864 p2
= strchr(p
, '=');
1868 r
= simple_strtoul(p2
, NULL
, 0);
1870 *((u8
*) d
[i
].addr
) = (u8
) r
;
1871 else if (d
[i
].size
== 2)
1872 *((u16
*) d
[i
].addr
) = (u16
) r
;
1873 else if (d
[i
].size
== 4)
1874 *((u32
*) d
[i
].addr
) = (u32
) r
;
1875 else if (d
[i
].size
== 8)
1876 *((u64
*) d
[i
].addr
) = (u64
) r
;
1882 return (ssize_t
)cnt
;
1885 static struct file_operations lbs_debug_fops
= {
1886 .owner
= THIS_MODULE
,
1887 .open
= open_file_generic
,
1888 .write
= lbs_debugfs_write
,
1889 .read
= lbs_debugfs_read
,
1893 * @brief create debug proc file
1895 * @param priv pointer struct lbs_private
1896 * @param dev pointer net_device
1899 static void lbs_debug_init(struct lbs_private
*priv
, struct net_device
*dev
)
1903 if (!priv
->debugfs_dir
)
1906 for (i
= 0; i
< num_of_items
; i
++)
1907 items
[i
].addr
+= (size_t) priv
->adapter
;
1909 priv
->debugfs_debug
= debugfs_create_file("debug", 0644,
1910 priv
->debugfs_dir
, &items
[0],