1 #include <linux/module.h>
2 #include <linux/dcache.h>
3 #include <linux/debugfs.h>
4 #include <linux/delay.h>
6 #include <net/iw_handler.h>
13 static struct dentry *libertas_dir = NULL;
14 static char *szStates[] = {
20 static void libertas_debug_init(wlan_private * priv, struct net_device *dev);
23 static int open_file_generic(struct inode *inode, struct file *file)
25 file->private_data = inode->i_private;
29 static ssize_t write_file_dummy(struct file *file, const char __user *buf,
30 size_t count, loff_t *ppos)
35 static const size_t len = PAGE_SIZE;
37 static ssize_t libertas_dev_info(struct file *file, char __user *userbuf,
38 size_t count, loff_t *ppos)
40 wlan_private *priv = file->private_data;
42 unsigned long addr = get_zeroed_page(GFP_KERNEL);
43 char *buf = (char *)addr;
46 pos += snprintf(buf+pos, len-pos, "state = %s\n",
47 szStates[priv->adapter->connect_status]);
48 pos += snprintf(buf+pos, len-pos, "region_code = %02x\n",
49 (u32) priv->adapter->regioncode);
51 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
58 static ssize_t libertas_getscantable(struct file *file, char __user *userbuf,
59 size_t count, loff_t *ppos)
61 wlan_private *priv = file->private_data;
63 int numscansdone = 0, res;
64 unsigned long addr = get_zeroed_page(GFP_KERNEL);
65 char *buf = (char *)addr;
66 struct bss_descriptor * iter_bss;
68 pos += snprintf(buf+pos, len-pos,
69 "# | ch | ss | bssid | cap | TSF | Qual | SSID \n");
71 mutex_lock(&priv->adapter->lock);
72 list_for_each_entry (iter_bss, &priv->adapter->network_list, list) {
75 memcpy(&cap, &iter_bss->cap, sizeof(cap));
76 pos += snprintf(buf+pos, len-pos,
77 "%02u| %03d | %03ld | " MAC_FMT " |",
78 numscansdone, iter_bss->channel, iter_bss->rssi,
79 MAC_ARG(iter_bss->bssid));
80 pos += snprintf(buf+pos, len-pos, " %04x-", cap);
81 pos += snprintf(buf+pos, len-pos, "%c%c%c |",
82 iter_bss->cap.ibss ? 'A' : 'I',
83 iter_bss->cap.privacy ? 'P' : ' ',
84 iter_bss->cap.spectrummgmt ? 'S' : ' ');
85 pos += snprintf(buf+pos, len-pos, " %08llx |", iter_bss->networktsf);
86 pos += snprintf(buf+pos, len-pos, " %d |", SCAN_RSSI(iter_bss->rssi));
87 pos += snprintf(buf+pos, len-pos, " %s\n", iter_bss->ssid.ssid);
91 mutex_unlock(&priv->adapter->lock);
93 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
99 static ssize_t libertas_sleepparams_write(struct file *file,
100 const char __user *user_buf, size_t count,
103 wlan_private *priv = file->private_data;
104 ssize_t buf_size, res;
105 int p1, p2, p3, p4, p5, p6;
106 struct sleep_params sp;
107 unsigned long addr = get_zeroed_page(GFP_KERNEL);
108 char *buf = (char *)addr;
110 buf_size = min(count, len - 1);
111 if (copy_from_user(buf, user_buf, buf_size)) {
115 res = sscanf(buf, "%d %d %d %d %d %d", &p1, &p2, &p3, &p4, &p5, &p6);
122 sp.sp_stabletime = p3;
123 sp.sp_calcontrol = p4;
124 sp.sp_extsleepclk = p5;
127 memcpy(&priv->adapter->sp, &sp, sizeof(struct sleep_params));
129 res = libertas_prepare_and_send_command(priv,
130 cmd_802_11_sleep_params,
132 cmd_option_waitforrsp, 0, NULL);
144 static ssize_t libertas_sleepparams_read(struct file *file, char __user *userbuf,
145 size_t count, loff_t *ppos)
147 wlan_private *priv = file->private_data;
148 wlan_adapter *adapter = priv->adapter;
151 unsigned long addr = get_zeroed_page(GFP_KERNEL);
152 char *buf = (char *)addr;
154 res = libertas_prepare_and_send_command(priv,
155 cmd_802_11_sleep_params,
157 cmd_option_waitforrsp, 0, NULL);
163 pos += snprintf(buf, len, "%d %d %d %d %d %d\n", adapter->sp.sp_error,
164 adapter->sp.sp_offset, adapter->sp.sp_stabletime,
165 adapter->sp.sp_calcontrol, adapter->sp.sp_extsleepclk,
166 adapter->sp.sp_reserved);
168 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
175 static ssize_t libertas_extscan(struct file *file, const char __user *userbuf,
176 size_t count, loff_t *ppos)
178 wlan_private *priv = file->private_data;
179 ssize_t res, buf_size;
180 struct WLAN_802_11_SSID extscan_ssid;
181 union iwreq_data wrqu;
182 unsigned long addr = get_zeroed_page(GFP_KERNEL);
183 char *buf = (char *)addr;
185 buf_size = min(count, len - 1);
186 if (copy_from_user(buf, userbuf, buf_size)) {
191 memcpy(&extscan_ssid.ssid, buf, strlen(buf)-1);
192 extscan_ssid.ssidlength = strlen(buf)-1;
194 libertas_send_specific_SSID_scan(priv, &extscan_ssid, 0);
196 memset(&wrqu, 0, sizeof(union iwreq_data));
197 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
204 static int libertas_parse_chan(char *buf, size_t count,
205 struct wlan_ioctl_user_scan_cfg *scan_cfg, int dur)
207 char *start, *end, *hold, *str;
210 start = strstr(buf, "chan=");
214 end = strstr(start, " ");
217 hold = kzalloc((end - start)+1, GFP_KERNEL);
220 strncpy(hold, start, end - start);
221 hold[(end-start)+1] = '\0';
222 while(hold && (str = strsep(&hold, ","))) {
224 char band, passive = 0;
225 sscanf(str, "%d%c%c", &chan, &band, &passive);
226 scan_cfg->chanlist[i].channumber = chan;
227 scan_cfg->chanlist[i].scantype = passive ? 1 : 0;
228 if (band == 'b' || band == 'g')
229 scan_cfg->chanlist[i].radiotype = 0;
230 else if (band == 'a')
231 scan_cfg->chanlist[i].radiotype = 1;
233 scan_cfg->chanlist[i].scantime = dur;
241 static void libertas_parse_bssid(char *buf, size_t count,
242 struct wlan_ioctl_user_scan_cfg *scan_cfg)
245 unsigned int mac[ETH_ALEN];
247 hold = strstr(buf, "bssid=");
251 sscanf(hold, MAC_FMT, mac, mac+1, mac+2, mac+3, mac+4, mac+5);
252 memcpy(scan_cfg->bssid, mac, ETH_ALEN);
255 static void libertas_parse_ssid(char *buf, size_t count,
256 struct wlan_ioctl_user_scan_cfg *scan_cfg)
261 hold = strstr(buf, "ssid=");
265 end = strstr(hold, " ");
267 end = buf + count - 1;
269 size = min((size_t)IW_ESSID_MAX_SIZE, (size_t) (end - hold));
270 strncpy(scan_cfg->ssid, hold, size);
275 static int libertas_parse_clear(char *buf, size_t count, const char *tag)
280 hold = strstr(buf, tag);
284 sscanf(hold, "%d", &val);
292 static int libertas_parse_dur(char *buf, size_t count,
293 struct wlan_ioctl_user_scan_cfg *scan_cfg)
298 hold = strstr(buf, "dur=");
302 sscanf(hold, "%d", &val);
307 static void libertas_parse_probes(char *buf, size_t count,
308 struct wlan_ioctl_user_scan_cfg *scan_cfg)
313 hold = strstr(buf, "probes=");
317 sscanf(hold, "%d", &val);
319 scan_cfg->numprobes = val;
324 static void libertas_parse_type(char *buf, size_t count,
325 struct wlan_ioctl_user_scan_cfg *scan_cfg)
330 hold = strstr(buf, "type=");
334 sscanf(hold, "%d", &val);
337 if (val < 1 || val > 3)
340 scan_cfg->bsstype = val;
345 static ssize_t libertas_setuserscan(struct file *file,
346 const char __user *userbuf,
347 size_t count, loff_t *ppos)
349 wlan_private *priv = file->private_data;
350 ssize_t res, buf_size;
351 struct wlan_ioctl_user_scan_cfg *scan_cfg;
352 union iwreq_data wrqu;
354 unsigned long addr = get_zeroed_page(GFP_KERNEL);
355 char *buf = (char *)addr;
357 scan_cfg = kzalloc(sizeof(struct wlan_ioctl_user_scan_cfg), GFP_KERNEL);
361 buf_size = min(count, len - 1);
362 if (copy_from_user(buf, userbuf, buf_size)) {
367 scan_cfg->bsstype = WLAN_SCAN_BSS_TYPE_ANY;
369 dur = libertas_parse_dur(buf, count, scan_cfg);
370 libertas_parse_chan(buf, count, scan_cfg, dur);
371 libertas_parse_bssid(buf, count, scan_cfg);
372 scan_cfg->clear_bssid = libertas_parse_clear(buf, count, "clear_bssid=");
373 libertas_parse_ssid(buf, count, scan_cfg);
374 scan_cfg->clear_ssid = libertas_parse_clear(buf, count, "clear_ssid=");
375 libertas_parse_probes(buf, count, scan_cfg);
376 libertas_parse_type(buf, count, scan_cfg);
378 wlan_scan_networks(priv, scan_cfg, 1);
379 wait_event_interruptible(priv->adapter->cmd_pending,
380 !priv->adapter->nr_cmd_pending);
382 memset(&wrqu, 0x00, sizeof(union iwreq_data));
383 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
391 static int libertas_event_initcmd(wlan_private *priv, void **response_buf,
392 struct cmd_ctrl_node **cmdnode,
393 struct cmd_ds_command **cmd)
395 u16 wait_option = cmd_option_waitforrsp;
397 if (!(*cmdnode = libertas_get_free_cmd_ctrl_node(priv))) {
398 lbs_deb_debugfs("failed libertas_get_free_cmd_ctrl_node\n");
401 if (!(*response_buf = kmalloc(3000, GFP_KERNEL))) {
402 lbs_deb_debugfs("failed to allocate response buffer!\n");
405 libertas_set_cmd_ctrl_node(priv, *cmdnode, 0, wait_option, NULL);
406 init_waitqueue_head(&(*cmdnode)->cmdwait_q);
407 (*cmdnode)->pdata_buf = *response_buf;
408 (*cmdnode)->cmdflags |= CMD_F_HOSTCMD;
409 (*cmdnode)->cmdwaitqwoken = 0;
410 *cmd = (struct cmd_ds_command *)(*cmdnode)->bufvirtualaddr;
411 (*cmd)->command = cmd_802_11_subscribe_event;
412 (*cmd)->seqnum = ++priv->adapter->seqnum;
417 static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf,
418 size_t count, loff_t *ppos)
420 wlan_private *priv = file->private_data;
421 wlan_adapter *adapter = priv->adapter;
422 struct cmd_ctrl_node *pcmdnode;
423 struct cmd_ds_command *pcmdptr;
424 struct cmd_ds_802_11_subscribe_event *event;
428 unsigned long addr = get_zeroed_page(GFP_KERNEL);
429 char *buf = (char *)addr;
431 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
437 event = &pcmdptr->params.subscribe_event;
438 event->action = cmd_act_get;
440 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
441 libertas_queue_cmd(adapter, pcmdnode, 1);
442 wake_up_interruptible(&priv->mainthread.waitq);
444 /* Sleep until response is generated by FW */
445 wait_event_interruptible(pcmdnode->cmdwait_q,
446 pcmdnode->cmdwaitqwoken);
448 pcmdptr = response_buf;
449 if (pcmdptr->result) {
450 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
457 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
458 lbs_pr_err("command response incorrect!\n");
464 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
465 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
466 while (cmd_len < pcmdptr->size) {
467 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
468 switch(header->type) {
469 struct mrvlietypes_rssithreshold *Lowrssi;
470 case TLV_TYPE_RSSI_LOW:
471 Lowrssi = (struct mrvlietypes_rssithreshold *)(response_buf + cmd_len);
472 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
475 (event->events & 0x0001)?1:0);
477 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
483 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
488 static u16 libertas_get_events_bitmap(wlan_private *priv)
490 wlan_adapter *adapter = priv->adapter;
491 struct cmd_ctrl_node *pcmdnode;
492 struct cmd_ds_command *pcmdptr;
493 struct cmd_ds_802_11_subscribe_event *event;
498 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
502 event = &pcmdptr->params.subscribe_event;
503 event->action = cmd_act_get;
505 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
506 libertas_queue_cmd(adapter, pcmdnode, 1);
507 wake_up_interruptible(&priv->mainthread.waitq);
509 /* Sleep until response is generated by FW */
510 wait_event_interruptible(pcmdnode->cmdwait_q,
511 pcmdnode->cmdwaitqwoken);
513 pcmdptr = response_buf;
515 if (pcmdptr->result) {
516 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
522 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
523 lbs_pr_err("command response incorrect!\n");
528 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
529 event_bitmap = event->events;
534 static ssize_t libertas_lowrssi_write(struct file *file,
535 const char __user *userbuf,
536 size_t count, loff_t *ppos)
538 wlan_private *priv = file->private_data;
539 wlan_adapter *adapter = priv->adapter;
540 ssize_t res, buf_size;
541 int value, freq, subscribed, cmd_len;
542 struct cmd_ctrl_node *pcmdnode;
543 struct cmd_ds_command *pcmdptr;
544 struct cmd_ds_802_11_subscribe_event *event;
545 struct mrvlietypes_rssithreshold *rssi_threshold;
549 unsigned long addr = get_zeroed_page(GFP_KERNEL);
550 char *buf = (char *)addr;
552 buf_size = min(count, len - 1);
553 if (copy_from_user(buf, userbuf, buf_size)) {
557 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
563 event_bitmap = libertas_get_events_bitmap(priv);
565 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
569 event = &pcmdptr->params.subscribe_event;
570 event->action = cmd_act_set;
571 pcmdptr->size = cpu_to_le16(S_DS_GEN +
572 sizeof(struct cmd_ds_802_11_subscribe_event) +
573 sizeof(struct mrvlietypes_rssithreshold));
575 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
576 ptr = (u8*) pcmdptr+cmd_len;
577 rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
578 rssi_threshold->header.type = cpu_to_le16(0x0104);
579 rssi_threshold->header.len = 2;
580 rssi_threshold->rssivalue = cpu_to_le16(value);
581 rssi_threshold->rssifreq = cpu_to_le16(freq);
582 event_bitmap |= subscribed ? 0x0001 : 0x0;
583 event->events = event_bitmap;
585 libertas_queue_cmd(adapter, pcmdnode, 1);
586 wake_up_interruptible(&priv->mainthread.waitq);
588 /* Sleep until response is generated by FW */
589 wait_event_interruptible(pcmdnode->cmdwait_q,
590 pcmdnode->cmdwaitqwoken);
592 pcmdptr = response_buf;
594 if (pcmdptr->result) {
595 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
602 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
603 lbs_pr_err("command response incorrect!\n");
615 static ssize_t libertas_lowsnr_read(struct file *file, char __user *userbuf,
616 size_t count, loff_t *ppos)
618 wlan_private *priv = file->private_data;
619 wlan_adapter *adapter = priv->adapter;
620 struct cmd_ctrl_node *pcmdnode;
621 struct cmd_ds_command *pcmdptr;
622 struct cmd_ds_802_11_subscribe_event *event;
626 unsigned long addr = get_zeroed_page(GFP_KERNEL);
627 char *buf = (char *)addr;
629 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
635 event = &pcmdptr->params.subscribe_event;
636 event->action = cmd_act_get;
638 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
639 libertas_queue_cmd(adapter, pcmdnode, 1);
640 wake_up_interruptible(&priv->mainthread.waitq);
642 /* Sleep until response is generated by FW */
643 wait_event_interruptible(pcmdnode->cmdwait_q,
644 pcmdnode->cmdwaitqwoken);
646 pcmdptr = response_buf;
648 if (pcmdptr->result) {
649 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
656 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
657 lbs_pr_err("command response incorrect!\n");
663 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
664 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
665 while (cmd_len < pcmdptr->size) {
666 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
667 switch(header->type) {
668 struct mrvlietypes_snrthreshold *LowSnr;
669 case TLV_TYPE_SNR_LOW:
670 LowSnr = (struct mrvlietypes_snrthreshold *)(response_buf + cmd_len);
671 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
674 (event->events & 0x0002)?1:0);
676 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
683 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
688 static ssize_t libertas_lowsnr_write(struct file *file,
689 const char __user *userbuf,
690 size_t count, loff_t *ppos)
692 wlan_private *priv = file->private_data;
693 wlan_adapter *adapter = priv->adapter;
694 ssize_t res, buf_size;
695 int value, freq, subscribed, cmd_len;
696 struct cmd_ctrl_node *pcmdnode;
697 struct cmd_ds_command *pcmdptr;
698 struct cmd_ds_802_11_subscribe_event *event;
699 struct mrvlietypes_snrthreshold *snr_threshold;
703 unsigned long addr = get_zeroed_page(GFP_KERNEL);
704 char *buf = (char *)addr;
706 buf_size = min(count, len - 1);
707 if (copy_from_user(buf, userbuf, buf_size)) {
711 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
717 event_bitmap = libertas_get_events_bitmap(priv);
719 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
723 event = &pcmdptr->params.subscribe_event;
724 event->action = cmd_act_set;
725 pcmdptr->size = cpu_to_le16(S_DS_GEN +
726 sizeof(struct cmd_ds_802_11_subscribe_event) +
727 sizeof(struct mrvlietypes_snrthreshold));
728 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
729 ptr = (u8*) pcmdptr+cmd_len;
730 snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
731 snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_LOW);
732 snr_threshold->header.len = 2;
733 snr_threshold->snrvalue = cpu_to_le16(value);
734 snr_threshold->snrfreq = cpu_to_le16(freq);
735 event_bitmap |= subscribed ? 0x0002 : 0x0;
736 event->events = event_bitmap;
738 libertas_queue_cmd(adapter, pcmdnode, 1);
739 wake_up_interruptible(&priv->mainthread.waitq);
741 /* Sleep until response is generated by FW */
742 wait_event_interruptible(pcmdnode->cmdwait_q,
743 pcmdnode->cmdwaitqwoken);
745 pcmdptr = response_buf;
747 if (pcmdptr->result) {
748 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
755 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
756 lbs_pr_err("command response incorrect!\n");
769 static ssize_t libertas_failcount_read(struct file *file, char __user *userbuf,
770 size_t count, loff_t *ppos)
772 wlan_private *priv = file->private_data;
773 wlan_adapter *adapter = priv->adapter;
774 struct cmd_ctrl_node *pcmdnode;
775 struct cmd_ds_command *pcmdptr;
776 struct cmd_ds_802_11_subscribe_event *event;
780 unsigned long addr = get_zeroed_page(GFP_KERNEL);
781 char *buf = (char *)addr;
783 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
789 event = &pcmdptr->params.subscribe_event;
790 event->action = cmd_act_get;
792 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
793 libertas_queue_cmd(adapter, pcmdnode, 1);
794 wake_up_interruptible(&priv->mainthread.waitq);
796 /* Sleep until response is generated by FW */
797 wait_event_interruptible(pcmdnode->cmdwait_q,
798 pcmdnode->cmdwaitqwoken);
800 pcmdptr = response_buf;
802 if (pcmdptr->result) {
803 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
810 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
811 lbs_pr_err("command response incorrect!\n");
817 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
818 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
819 while (cmd_len < pcmdptr->size) {
820 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
821 switch(header->type) {
822 struct mrvlietypes_failurecount *failcount;
823 case TLV_TYPE_FAILCOUNT:
824 failcount = (struct mrvlietypes_failurecount *)(response_buf + cmd_len);
825 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
826 failcount->failvalue,
828 (event->events & 0x0004)?1:0);
830 cmd_len += sizeof(struct mrvlietypes_failurecount);
836 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
841 static ssize_t libertas_failcount_write(struct file *file,
842 const char __user *userbuf,
843 size_t count, loff_t *ppos)
845 wlan_private *priv = file->private_data;
846 wlan_adapter *adapter = priv->adapter;
847 ssize_t res, buf_size;
848 int value, freq, subscribed, cmd_len;
849 struct cmd_ctrl_node *pcmdnode;
850 struct cmd_ds_command *pcmdptr;
851 struct cmd_ds_802_11_subscribe_event *event;
852 struct mrvlietypes_failurecount *failcount;
856 unsigned long addr = get_zeroed_page(GFP_KERNEL);
857 char *buf = (char *)addr;
859 buf_size = min(count, len - 1);
860 if (copy_from_user(buf, userbuf, buf_size)) {
864 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
870 event_bitmap = libertas_get_events_bitmap(priv);
872 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
876 event = &pcmdptr->params.subscribe_event;
877 event->action = cmd_act_set;
878 pcmdptr->size = cpu_to_le16(S_DS_GEN +
879 sizeof(struct cmd_ds_802_11_subscribe_event) +
880 sizeof(struct mrvlietypes_failurecount));
881 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
882 ptr = (u8*) pcmdptr+cmd_len;
883 failcount = (struct mrvlietypes_failurecount *)(ptr);
884 failcount->header.type = cpu_to_le16(TLV_TYPE_FAILCOUNT);
885 failcount->header.len = 2;
886 failcount->failvalue = cpu_to_le16(value);
887 failcount->Failfreq = cpu_to_le16(freq);
888 event_bitmap |= subscribed ? 0x0004 : 0x0;
889 event->events = event_bitmap;
891 libertas_queue_cmd(adapter, pcmdnode, 1);
892 wake_up_interruptible(&priv->mainthread.waitq);
894 /* Sleep until response is generated by FW */
895 wait_event_interruptible(pcmdnode->cmdwait_q,
896 pcmdnode->cmdwaitqwoken);
898 pcmdptr = (struct cmd_ds_command *)response_buf;
900 if (pcmdptr->result) {
901 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
908 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
909 lbs_pr_err("command response incorrect!\n");
921 static ssize_t libertas_bcnmiss_read(struct file *file, char __user *userbuf,
922 size_t count, loff_t *ppos)
924 wlan_private *priv = file->private_data;
925 wlan_adapter *adapter = priv->adapter;
926 struct cmd_ctrl_node *pcmdnode;
927 struct cmd_ds_command *pcmdptr;
928 struct cmd_ds_802_11_subscribe_event *event;
932 unsigned long addr = get_zeroed_page(GFP_KERNEL);
933 char *buf = (char *)addr;
935 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
941 event = &pcmdptr->params.subscribe_event;
942 event->action = cmd_act_get;
944 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
945 libertas_queue_cmd(adapter, pcmdnode, 1);
946 wake_up_interruptible(&priv->mainthread.waitq);
948 /* Sleep until response is generated by FW */
949 wait_event_interruptible(pcmdnode->cmdwait_q,
950 pcmdnode->cmdwaitqwoken);
952 pcmdptr = response_buf;
954 if (pcmdptr->result) {
955 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
962 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
963 lbs_pr_err("command response incorrect!\n");
969 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
970 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
971 while (cmd_len < pcmdptr->size) {
972 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
973 switch(header->type) {
974 struct mrvlietypes_beaconsmissed *bcnmiss;
975 case TLV_TYPE_BCNMISS:
976 bcnmiss = (struct mrvlietypes_beaconsmissed *)(response_buf + cmd_len);
977 pos += snprintf(buf+pos, len-pos, "%d N/A %d\n",
978 bcnmiss->beaconmissed,
979 (event->events & 0x0008)?1:0);
981 cmd_len += sizeof(struct mrvlietypes_beaconsmissed);
988 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
993 static ssize_t libertas_bcnmiss_write(struct file *file,
994 const char __user *userbuf,
995 size_t count, loff_t *ppos)
997 wlan_private *priv = file->private_data;
998 wlan_adapter *adapter = priv->adapter;
999 ssize_t res, buf_size;
1000 int value, freq, subscribed, cmd_len;
1001 struct cmd_ctrl_node *pcmdnode;
1002 struct cmd_ds_command *pcmdptr;
1003 struct cmd_ds_802_11_subscribe_event *event;
1004 struct mrvlietypes_beaconsmissed *bcnmiss;
1008 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1009 char *buf = (char *)addr;
1011 buf_size = min(count, len - 1);
1012 if (copy_from_user(buf, userbuf, buf_size)) {
1016 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
1022 event_bitmap = libertas_get_events_bitmap(priv);
1024 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1028 event = &pcmdptr->params.subscribe_event;
1029 event->action = cmd_act_set;
1030 pcmdptr->size = cpu_to_le16(S_DS_GEN +
1031 sizeof(struct cmd_ds_802_11_subscribe_event) +
1032 sizeof(struct mrvlietypes_beaconsmissed));
1033 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1034 ptr = (u8*) pcmdptr+cmd_len;
1035 bcnmiss = (struct mrvlietypes_beaconsmissed *)(ptr);
1036 bcnmiss->header.type = cpu_to_le16(TLV_TYPE_BCNMISS);
1037 bcnmiss->header.len = 2;
1038 bcnmiss->beaconmissed = cpu_to_le16(value);
1039 event_bitmap |= subscribed ? 0x0008 : 0x0;
1040 event->events = event_bitmap;
1042 libertas_queue_cmd(adapter, pcmdnode, 1);
1043 wake_up_interruptible(&priv->mainthread.waitq);
1045 /* Sleep until response is generated by FW */
1046 wait_event_interruptible(pcmdnode->cmdwait_q,
1047 pcmdnode->cmdwaitqwoken);
1049 pcmdptr = response_buf;
1051 if (pcmdptr->result) {
1052 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1054 kfree(response_buf);
1059 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1060 lbs_pr_err("command response incorrect!\n");
1062 kfree(response_buf);
1072 static ssize_t libertas_highrssi_read(struct file *file, char __user *userbuf,
1073 size_t count, loff_t *ppos)
1075 wlan_private *priv = file->private_data;
1076 wlan_adapter *adapter = priv->adapter;
1077 struct cmd_ctrl_node *pcmdnode;
1078 struct cmd_ds_command *pcmdptr;
1079 struct cmd_ds_802_11_subscribe_event *event;
1083 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1084 char *buf = (char *)addr;
1086 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1092 event = &pcmdptr->params.subscribe_event;
1093 event->action = cmd_act_get;
1095 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
1096 libertas_queue_cmd(adapter, pcmdnode, 1);
1097 wake_up_interruptible(&priv->mainthread.waitq);
1099 /* Sleep until response is generated by FW */
1100 wait_event_interruptible(pcmdnode->cmdwait_q,
1101 pcmdnode->cmdwaitqwoken);
1103 pcmdptr = response_buf;
1105 if (pcmdptr->result) {
1106 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1108 kfree(response_buf);
1113 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1114 lbs_pr_err("command response incorrect!\n");
1115 kfree(response_buf);
1120 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1121 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
1122 while (cmd_len < pcmdptr->size) {
1123 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
1124 switch(header->type) {
1125 struct mrvlietypes_rssithreshold *Highrssi;
1126 case TLV_TYPE_RSSI_HIGH:
1127 Highrssi = (struct mrvlietypes_rssithreshold *)(response_buf + cmd_len);
1128 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
1129 Highrssi->rssivalue,
1131 (event->events & 0x0010)?1:0);
1133 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
1138 kfree(response_buf);
1140 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1145 static ssize_t libertas_highrssi_write(struct file *file,
1146 const char __user *userbuf,
1147 size_t count, loff_t *ppos)
1149 wlan_private *priv = file->private_data;
1150 wlan_adapter *adapter = priv->adapter;
1151 ssize_t res, buf_size;
1152 int value, freq, subscribed, cmd_len;
1153 struct cmd_ctrl_node *pcmdnode;
1154 struct cmd_ds_command *pcmdptr;
1155 struct cmd_ds_802_11_subscribe_event *event;
1156 struct mrvlietypes_rssithreshold *rssi_threshold;
1160 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1161 char *buf = (char *)addr;
1163 buf_size = min(count, len - 1);
1164 if (copy_from_user(buf, userbuf, buf_size)) {
1168 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
1174 event_bitmap = libertas_get_events_bitmap(priv);
1176 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1180 event = &pcmdptr->params.subscribe_event;
1181 event->action = cmd_act_set;
1182 pcmdptr->size = cpu_to_le16(S_DS_GEN +
1183 sizeof(struct cmd_ds_802_11_subscribe_event) +
1184 sizeof(struct mrvlietypes_rssithreshold));
1185 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1186 ptr = (u8*) pcmdptr+cmd_len;
1187 rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
1188 rssi_threshold->header.type = cpu_to_le16(TLV_TYPE_RSSI_HIGH);
1189 rssi_threshold->header.len = 2;
1190 rssi_threshold->rssivalue = cpu_to_le16(value);
1191 rssi_threshold->rssifreq = cpu_to_le16(freq);
1192 event_bitmap |= subscribed ? 0x0010 : 0x0;
1193 event->events = event_bitmap;
1195 libertas_queue_cmd(adapter, pcmdnode, 1);
1196 wake_up_interruptible(&priv->mainthread.waitq);
1198 /* Sleep until response is generated by FW */
1199 wait_event_interruptible(pcmdnode->cmdwait_q,
1200 pcmdnode->cmdwaitqwoken);
1202 pcmdptr = response_buf;
1204 if (pcmdptr->result) {
1205 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1207 kfree(response_buf);
1211 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1212 lbs_pr_err("command response incorrect!\n");
1213 kfree(response_buf);
1223 static ssize_t libertas_highsnr_read(struct file *file, char __user *userbuf,
1224 size_t count, loff_t *ppos)
1226 wlan_private *priv = file->private_data;
1227 wlan_adapter *adapter = priv->adapter;
1228 struct cmd_ctrl_node *pcmdnode;
1229 struct cmd_ds_command *pcmdptr;
1230 struct cmd_ds_802_11_subscribe_event *event;
1234 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1235 char *buf = (char *)addr;
1237 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1243 event = &pcmdptr->params.subscribe_event;
1244 event->action = cmd_act_get;
1246 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
1247 libertas_queue_cmd(adapter, pcmdnode, 1);
1248 wake_up_interruptible(&priv->mainthread.waitq);
1250 /* Sleep until response is generated by FW */
1251 wait_event_interruptible(pcmdnode->cmdwait_q,
1252 pcmdnode->cmdwaitqwoken);
1254 pcmdptr = response_buf;
1256 if (pcmdptr->result) {
1257 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1259 kfree(response_buf);
1264 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1265 lbs_pr_err("command response incorrect!\n");
1266 kfree(response_buf);
1271 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1272 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
1273 while (cmd_len < pcmdptr->size) {
1274 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
1275 switch(header->type) {
1276 struct mrvlietypes_snrthreshold *HighSnr;
1277 case TLV_TYPE_SNR_HIGH:
1278 HighSnr = (struct mrvlietypes_snrthreshold *)(response_buf + cmd_len);
1279 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
1282 (event->events & 0x0020)?1:0);
1284 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
1289 kfree(response_buf);
1291 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1296 static ssize_t libertas_highsnr_write(struct file *file,
1297 const char __user *userbuf,
1298 size_t count, loff_t *ppos)
1300 wlan_private *priv = file->private_data;
1301 wlan_adapter *adapter = priv->adapter;
1302 ssize_t res, buf_size;
1303 int value, freq, subscribed, cmd_len;
1304 struct cmd_ctrl_node *pcmdnode;
1305 struct cmd_ds_command *pcmdptr;
1306 struct cmd_ds_802_11_subscribe_event *event;
1307 struct mrvlietypes_snrthreshold *snr_threshold;
1311 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1312 char *buf = (char *)addr;
1314 buf_size = min(count, len - 1);
1315 if (copy_from_user(buf, userbuf, buf_size)) {
1319 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
1325 event_bitmap = libertas_get_events_bitmap(priv);
1327 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1331 event = &pcmdptr->params.subscribe_event;
1332 event->action = cmd_act_set;
1333 pcmdptr->size = cpu_to_le16(S_DS_GEN +
1334 sizeof(struct cmd_ds_802_11_subscribe_event) +
1335 sizeof(struct mrvlietypes_snrthreshold));
1336 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1337 ptr = (u8*) pcmdptr+cmd_len;
1338 snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
1339 snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_HIGH);
1340 snr_threshold->header.len = 2;
1341 snr_threshold->snrvalue = cpu_to_le16(value);
1342 snr_threshold->snrfreq = cpu_to_le16(freq);
1343 event_bitmap |= subscribed ? 0x0020 : 0x0;
1344 event->events = event_bitmap;
1346 libertas_queue_cmd(adapter, pcmdnode, 1);
1347 wake_up_interruptible(&priv->mainthread.waitq);
1349 /* Sleep until response is generated by FW */
1350 wait_event_interruptible(pcmdnode->cmdwait_q,
1351 pcmdnode->cmdwaitqwoken);
1353 pcmdptr = response_buf;
1355 if (pcmdptr->result) {
1356 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1358 kfree(response_buf);
1363 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1364 lbs_pr_err("command response incorrect!\n");
1365 kfree(response_buf);
1376 static ssize_t libertas_rdmac_read(struct file *file, char __user *userbuf,
1377 size_t count, loff_t *ppos)
1379 wlan_private *priv = file->private_data;
1380 wlan_adapter *adapter = priv->adapter;
1381 struct wlan_offset_value offval;
1384 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1385 char *buf = (char *)addr;
1387 offval.offset = priv->mac_offset;
1390 ret = libertas_prepare_and_send_command(priv,
1391 cmd_mac_reg_access, 0,
1392 cmd_option_waitforrsp, 0, &offval);
1394 pos += snprintf(buf+pos, len-pos, "MAC[0x%x] = 0x%08x\n",
1395 priv->mac_offset, adapter->offsetvalue.value);
1397 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1402 static ssize_t libertas_rdmac_write(struct file *file,
1403 const char __user *userbuf,
1404 size_t count, loff_t *ppos)
1406 wlan_private *priv = file->private_data;
1407 ssize_t res, buf_size;
1408 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1409 char *buf = (char *)addr;
1411 buf_size = min(count, len - 1);
1412 if (copy_from_user(buf, userbuf, buf_size)) {
1416 priv->mac_offset = simple_strtoul((char *)buf, NULL, 16);
1423 static ssize_t libertas_wrmac_write(struct file *file,
1424 const char __user *userbuf,
1425 size_t count, loff_t *ppos)
1428 wlan_private *priv = file->private_data;
1429 ssize_t res, buf_size;
1431 struct wlan_offset_value offval;
1432 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1433 char *buf = (char *)addr;
1435 buf_size = min(count, len - 1);
1436 if (copy_from_user(buf, userbuf, buf_size)) {
1440 res = sscanf(buf, "%x %x", &offset, &value);
1446 offval.offset = offset;
1447 offval.value = value;
1448 res = libertas_prepare_and_send_command(priv,
1449 cmd_mac_reg_access, 1,
1450 cmd_option_waitforrsp, 0, &offval);
1459 static ssize_t libertas_rdbbp_read(struct file *file, char __user *userbuf,
1460 size_t count, loff_t *ppos)
1462 wlan_private *priv = file->private_data;
1463 wlan_adapter *adapter = priv->adapter;
1464 struct wlan_offset_value offval;
1467 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1468 char *buf = (char *)addr;
1470 offval.offset = priv->bbp_offset;
1473 ret = libertas_prepare_and_send_command(priv,
1474 cmd_bbp_reg_access, 0,
1475 cmd_option_waitforrsp, 0, &offval);
1477 pos += snprintf(buf+pos, len-pos, "BBP[0x%x] = 0x%08x\n",
1478 priv->bbp_offset, adapter->offsetvalue.value);
1480 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1486 static ssize_t libertas_rdbbp_write(struct file *file,
1487 const char __user *userbuf,
1488 size_t count, loff_t *ppos)
1490 wlan_private *priv = file->private_data;
1491 ssize_t res, buf_size;
1492 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1493 char *buf = (char *)addr;
1495 buf_size = min(count, len - 1);
1496 if (copy_from_user(buf, userbuf, buf_size)) {
1500 priv->bbp_offset = simple_strtoul((char *)buf, NULL, 16);
1507 static ssize_t libertas_wrbbp_write(struct file *file,
1508 const char __user *userbuf,
1509 size_t count, loff_t *ppos)
1512 wlan_private *priv = file->private_data;
1513 ssize_t res, buf_size;
1515 struct wlan_offset_value offval;
1516 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1517 char *buf = (char *)addr;
1519 buf_size = min(count, len - 1);
1520 if (copy_from_user(buf, userbuf, buf_size)) {
1524 res = sscanf(buf, "%x %x", &offset, &value);
1530 offval.offset = offset;
1531 offval.value = value;
1532 res = libertas_prepare_and_send_command(priv,
1533 cmd_bbp_reg_access, 1,
1534 cmd_option_waitforrsp, 0, &offval);
1543 static ssize_t libertas_rdrf_read(struct file *file, char __user *userbuf,
1544 size_t count, loff_t *ppos)
1546 wlan_private *priv = file->private_data;
1547 wlan_adapter *adapter = priv->adapter;
1548 struct wlan_offset_value offval;
1551 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1552 char *buf = (char *)addr;
1554 offval.offset = priv->rf_offset;
1557 ret = libertas_prepare_and_send_command(priv,
1558 cmd_rf_reg_access, 0,
1559 cmd_option_waitforrsp, 0, &offval);
1561 pos += snprintf(buf+pos, len-pos, "RF[0x%x] = 0x%08x\n",
1562 priv->rf_offset, adapter->offsetvalue.value);
1564 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1570 static ssize_t libertas_rdrf_write(struct file *file,
1571 const char __user *userbuf,
1572 size_t count, loff_t *ppos)
1574 wlan_private *priv = file->private_data;
1575 ssize_t res, buf_size;
1576 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1577 char *buf = (char *)addr;
1579 buf_size = min(count, len - 1);
1580 if (copy_from_user(buf, userbuf, buf_size)) {
1584 priv->rf_offset = simple_strtoul((char *)buf, NULL, 16);
1591 static ssize_t libertas_wrrf_write(struct file *file,
1592 const char __user *userbuf,
1593 size_t count, loff_t *ppos)
1596 wlan_private *priv = file->private_data;
1597 ssize_t res, buf_size;
1599 struct wlan_offset_value offval;
1600 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1601 char *buf = (char *)addr;
1603 buf_size = min(count, len - 1);
1604 if (copy_from_user(buf, userbuf, buf_size)) {
1608 res = sscanf(buf, "%x %x", &offset, &value);
1614 offval.offset = offset;
1615 offval.value = value;
1616 res = libertas_prepare_and_send_command(priv,
1617 cmd_rf_reg_access, 1,
1618 cmd_option_waitforrsp, 0, &offval);
1627 #define FOPS(fread, fwrite) { \
1628 .owner = THIS_MODULE, \
1629 .open = open_file_generic, \
1631 .write = (fwrite), \
1634 struct libertas_debugfs_files {
1637 struct file_operations fops;
1640 static struct libertas_debugfs_files debugfs_files[] = {
1641 { "info", 0444, FOPS(libertas_dev_info, write_file_dummy), },
1642 { "getscantable", 0444, FOPS(libertas_getscantable,
1643 write_file_dummy), },
1644 { "sleepparams", 0644, FOPS(libertas_sleepparams_read,
1645 libertas_sleepparams_write), },
1646 { "extscan", 0600, FOPS(NULL, libertas_extscan), },
1647 { "setuserscan", 0600, FOPS(NULL, libertas_setuserscan), },
1650 static struct libertas_debugfs_files debugfs_events_files[] = {
1651 {"low_rssi", 0644, FOPS(libertas_lowrssi_read,
1652 libertas_lowrssi_write), },
1653 {"low_snr", 0644, FOPS(libertas_lowsnr_read,
1654 libertas_lowsnr_write), },
1655 {"failure_count", 0644, FOPS(libertas_failcount_read,
1656 libertas_failcount_write), },
1657 {"beacon_missed", 0644, FOPS(libertas_bcnmiss_read,
1658 libertas_bcnmiss_write), },
1659 {"high_rssi", 0644, FOPS(libertas_highrssi_read,
1660 libertas_highrssi_write), },
1661 {"high_snr", 0644, FOPS(libertas_highsnr_read,
1662 libertas_highsnr_write), },
1665 static struct libertas_debugfs_files debugfs_regs_files[] = {
1666 {"rdmac", 0644, FOPS(libertas_rdmac_read, libertas_rdmac_write), },
1667 {"wrmac", 0600, FOPS(NULL, libertas_wrmac_write), },
1668 {"rdbbp", 0644, FOPS(libertas_rdbbp_read, libertas_rdbbp_write), },
1669 {"wrbbp", 0600, FOPS(NULL, libertas_wrbbp_write), },
1670 {"rdrf", 0644, FOPS(libertas_rdrf_read, libertas_rdrf_write), },
1671 {"wrrf", 0600, FOPS(NULL, libertas_wrrf_write), },
1674 void libertas_debugfs_init(void)
1677 libertas_dir = debugfs_create_dir("libertas_wireless", NULL);
1682 void libertas_debugfs_remove(void)
1685 debugfs_remove(libertas_dir);
1689 void libertas_debugfs_init_one(wlan_private *priv, struct net_device *dev)
1692 struct libertas_debugfs_files *files;
1696 priv->debugfs_dir = debugfs_create_dir(dev->name, libertas_dir);
1697 if (!priv->debugfs_dir)
1700 for (i=0; i<ARRAY_SIZE(debugfs_files); i++) {
1701 files = &debugfs_files[i];
1702 priv->debugfs_files[i] = debugfs_create_file(files->name,
1709 priv->events_dir = debugfs_create_dir("subscribed_events", priv->debugfs_dir);
1710 if (!priv->events_dir)
1713 for (i=0; i<ARRAY_SIZE(debugfs_events_files); i++) {
1714 files = &debugfs_events_files[i];
1715 priv->debugfs_events_files[i] = debugfs_create_file(files->name,
1722 priv->regs_dir = debugfs_create_dir("registers", priv->debugfs_dir);
1723 if (!priv->regs_dir)
1726 for (i=0; i<ARRAY_SIZE(debugfs_regs_files); i++) {
1727 files = &debugfs_regs_files[i];
1728 priv->debugfs_regs_files[i] = debugfs_create_file(files->name,
1736 libertas_debug_init(priv, dev);
1742 void libertas_debugfs_remove_one(wlan_private *priv)
1746 for(i=0; i<ARRAY_SIZE(debugfs_regs_files); i++)
1747 debugfs_remove(priv->debugfs_regs_files[i]);
1749 debugfs_remove(priv->regs_dir);
1751 for(i=0; i<ARRAY_SIZE(debugfs_events_files); i++)
1752 debugfs_remove(priv->debugfs_events_files[i]);
1754 debugfs_remove(priv->events_dir);
1756 debugfs_remove(priv->debugfs_debug);
1758 for(i=0; i<ARRAY_SIZE(debugfs_files); i++)
1759 debugfs_remove(priv->debugfs_files[i]);
1760 debugfs_remove(priv->debugfs_dir);
1769 #define item_size(n) (FIELD_SIZEOF(wlan_adapter, n))
1770 #define item_addr(n) (offsetof(wlan_adapter, n))
1779 /* To debug any member of wlan_adapter, simply add one line here.
1781 static struct debug_data items[] = {
1782 {"intcounter", item_size(intcounter), item_addr(intcounter)},
1783 {"psmode", item_size(psmode), item_addr(psmode)},
1784 {"psstate", item_size(psstate), item_addr(psstate)},
1787 static int num_of_items = ARRAY_SIZE(items);
1790 * @brief proc read function
1792 * @param page pointer to buffer
1793 * @param s read data starting position
1795 * @param cnt counter
1796 * @param eof end of file flag
1797 * @param data data to output
1798 * @return number of output data
1800 static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf,
1801 size_t count, loff_t *ppos)
1808 struct debug_data *d;
1809 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1810 char *buf = (char *)addr;
1814 d = (struct debug_data *)file->private_data;
1816 for (i = 0; i < num_of_items; i++) {
1818 val = *((u8 *) d[i].addr);
1819 else if (d[i].size == 2)
1820 val = *((u16 *) d[i].addr);
1821 else if (d[i].size == 4)
1822 val = *((u32 *) d[i].addr);
1823 else if (d[i].size == 8)
1824 val = *((u64 *) d[i].addr);
1826 pos += sprintf(p + pos, "%s=%d\n", d[i].name, val);
1829 res = simple_read_from_buffer(userbuf, count, ppos, p, pos);
1836 * @brief proc write function
1838 * @param f file pointer
1839 * @param buf pointer to data buffer
1840 * @param cnt data number to write
1841 * @param data data to write
1842 * @return number of data
1844 static ssize_t wlan_debugfs_write(struct file *f, const char __user *buf,
1845 size_t cnt, loff_t *ppos)
1853 struct debug_data *d = (struct debug_data *)f->private_data;
1855 pdata = (char *)kmalloc(cnt, GFP_KERNEL);
1859 if (copy_from_user(pdata, buf, cnt)) {
1860 lbs_deb_debugfs("Copy from user failed\n");
1866 for (i = 0; i < num_of_items; i++) {
1868 p = strstr(p0, d[i].name);
1871 p1 = strchr(p, '\n');
1875 p2 = strchr(p, '=');
1879 r = simple_strtoul(p2, NULL, 0);
1881 *((u8 *) d[i].addr) = (u8) r;
1882 else if (d[i].size == 2)
1883 *((u16 *) d[i].addr) = (u16) r;
1884 else if (d[i].size == 4)
1885 *((u32 *) d[i].addr) = (u32) r;
1886 else if (d[i].size == 8)
1887 *((u64 *) d[i].addr) = (u64) r;
1893 return (ssize_t)cnt;
1896 static struct file_operations libertas_debug_fops = {
1897 .owner = THIS_MODULE,
1898 .open = open_file_generic,
1899 .write = wlan_debugfs_write,
1900 .read = wlan_debugfs_read,
1904 * @brief create debug proc file
1906 * @param priv pointer wlan_private
1907 * @param dev pointer net_device
1910 static void libertas_debug_init(wlan_private * priv, struct net_device *dev)
1914 if (!priv->debugfs_dir)
1917 for (i = 0; i < num_of_items; i++)
1918 items[i].addr += (size_t) priv->adapter;
1920 priv->debugfs_debug = debugfs_create_file("debug", 0644,
1921 priv->debugfs_dir, &items[0],
1922 &libertas_debug_fops);