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 | %02x:%02x:%02x:%02x:%02x:%02x |",
78 numscansdone, iter_bss->channel, iter_bss->rssi,
79 iter_bss->bssid[0], iter_bss->bssid[1],
80 iter_bss->bssid[2], iter_bss->bssid[3],
81 iter_bss->bssid[4], iter_bss->bssid[5]);
82 pos += snprintf(buf+pos, len-pos, " %04x-", cap);
83 pos += snprintf(buf+pos, len-pos, "%c%c%c |",
84 iter_bss->cap.ibss ? 'A' : 'I',
85 iter_bss->cap.privacy ? 'P' : ' ',
86 iter_bss->cap.spectrummgmt ? 'S' : ' ');
87 pos += snprintf(buf+pos, len-pos, " %08llx |", iter_bss->networktsf);
88 pos += snprintf(buf+pos, len-pos, " %d |", SCAN_RSSI(iter_bss->rssi));
89 pos += snprintf(buf+pos, len-pos, " %s\n", iter_bss->ssid.ssid);
93 mutex_unlock(&priv->adapter->lock);
95 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
101 static ssize_t libertas_sleepparams_write(struct file *file,
102 const char __user *user_buf, size_t count,
105 wlan_private *priv = file->private_data;
106 ssize_t buf_size, res;
107 int p1, p2, p3, p4, p5, p6;
108 struct sleep_params sp;
109 unsigned long addr = get_zeroed_page(GFP_KERNEL);
110 char *buf = (char *)addr;
112 buf_size = min(count, len - 1);
113 if (copy_from_user(buf, user_buf, buf_size)) {
117 res = sscanf(buf, "%d %d %d %d %d %d", &p1, &p2, &p3, &p4, &p5, &p6);
124 sp.sp_stabletime = p3;
125 sp.sp_calcontrol = p4;
126 sp.sp_extsleepclk = p5;
129 memcpy(&priv->adapter->sp, &sp, sizeof(struct sleep_params));
131 res = libertas_prepare_and_send_command(priv,
132 cmd_802_11_sleep_params,
134 cmd_option_waitforrsp, 0, NULL);
146 static ssize_t libertas_sleepparams_read(struct file *file, char __user *userbuf,
147 size_t count, loff_t *ppos)
149 wlan_private *priv = file->private_data;
150 wlan_adapter *adapter = priv->adapter;
153 unsigned long addr = get_zeroed_page(GFP_KERNEL);
154 char *buf = (char *)addr;
156 res = libertas_prepare_and_send_command(priv,
157 cmd_802_11_sleep_params,
159 cmd_option_waitforrsp, 0, NULL);
165 pos += snprintf(buf, len, "%d %d %d %d %d %d\n", adapter->sp.sp_error,
166 adapter->sp.sp_offset, adapter->sp.sp_stabletime,
167 adapter->sp.sp_calcontrol, adapter->sp.sp_extsleepclk,
168 adapter->sp.sp_reserved);
170 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
177 static ssize_t libertas_extscan(struct file *file, const char __user *userbuf,
178 size_t count, loff_t *ppos)
180 wlan_private *priv = file->private_data;
181 ssize_t res, buf_size;
182 struct WLAN_802_11_SSID extscan_ssid;
183 union iwreq_data wrqu;
184 unsigned long addr = get_zeroed_page(GFP_KERNEL);
185 char *buf = (char *)addr;
187 buf_size = min(count, len - 1);
188 if (copy_from_user(buf, userbuf, buf_size)) {
193 memcpy(&extscan_ssid.ssid, buf, strlen(buf)-1);
194 extscan_ssid.ssidlength = strlen(buf)-1;
196 libertas_send_specific_SSID_scan(priv, &extscan_ssid, 1);
198 memset(&wrqu, 0, sizeof(union iwreq_data));
199 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
206 static int libertas_parse_chan(char *buf, size_t count,
207 struct wlan_ioctl_user_scan_cfg *scan_cfg, int dur)
209 char *start, *end, *hold, *str;
212 start = strstr(buf, "chan=");
216 end = strstr(start, " ");
219 hold = kzalloc((end - start)+1, GFP_KERNEL);
222 strncpy(hold, start, end - start);
223 hold[(end-start)+1] = '\0';
224 while(hold && (str = strsep(&hold, ","))) {
226 char band, passive = 0;
227 sscanf(str, "%d%c%c", &chan, &band, &passive);
228 scan_cfg->chanlist[i].channumber = chan;
229 scan_cfg->chanlist[i].scantype = passive ? 1 : 0;
230 if (band == 'b' || band == 'g')
231 scan_cfg->chanlist[i].radiotype = 0;
232 else if (band == 'a')
233 scan_cfg->chanlist[i].radiotype = 1;
235 scan_cfg->chanlist[i].scantime = dur;
243 static void libertas_parse_bssid(char *buf, size_t count,
244 struct wlan_ioctl_user_scan_cfg *scan_cfg)
247 unsigned int mac[ETH_ALEN];
250 hold = strstr(buf, "bssid=");
254 sscanf(hold, "%2x:%2x:%2x:%2x:%2x:%2x", mac, mac+1, mac+2, mac+3,
256 for(i=0;i<ETH_ALEN;i++)
257 scan_cfg->specificBSSID[i] = mac[i];
260 static void libertas_parse_ssid(char *buf, size_t count,
261 struct wlan_ioctl_user_scan_cfg *scan_cfg)
266 hold = strstr(buf, "ssid=");
270 end = strstr(hold, " ");
272 end = buf + count - 1;
274 size = min((size_t)IW_ESSID_MAX_SIZE, (size_t) (end - hold));
275 strncpy(scan_cfg->specificSSID, hold, size);
280 static void libertas_parse_keep(char *buf, size_t count,
281 struct wlan_ioctl_user_scan_cfg *scan_cfg)
286 hold = strstr(buf, "keep=");
290 sscanf(hold, "%d", &val);
295 scan_cfg->keeppreviousscan = val;
299 static int libertas_parse_dur(char *buf, size_t count,
300 struct wlan_ioctl_user_scan_cfg *scan_cfg)
305 hold = strstr(buf, "dur=");
309 sscanf(hold, "%d", &val);
314 static void libertas_parse_probes(char *buf, size_t count,
315 struct wlan_ioctl_user_scan_cfg *scan_cfg)
320 hold = strstr(buf, "probes=");
324 sscanf(hold, "%d", &val);
326 scan_cfg->numprobes = val;
331 static void libertas_parse_type(char *buf, size_t count,
332 struct wlan_ioctl_user_scan_cfg *scan_cfg)
337 hold = strstr(buf, "type=");
341 sscanf(hold, "%d", &val);
344 if (val < 1 || val > 3)
347 scan_cfg->bsstype = val;
352 static ssize_t libertas_setuserscan(struct file *file,
353 const char __user *userbuf,
354 size_t count, loff_t *ppos)
356 wlan_private *priv = file->private_data;
357 ssize_t res, buf_size;
358 struct wlan_ioctl_user_scan_cfg *scan_cfg;
359 union iwreq_data wrqu;
361 unsigned long addr = get_zeroed_page(GFP_KERNEL);
362 char *buf = (char *)addr;
364 scan_cfg = kzalloc(sizeof(struct wlan_ioctl_user_scan_cfg), GFP_KERNEL);
368 buf_size = min(count, len - 1);
369 if (copy_from_user(buf, userbuf, buf_size)) {
374 scan_cfg->bsstype = WLAN_SCAN_BSS_TYPE_ANY;
376 dur = libertas_parse_dur(buf, count, scan_cfg);
377 libertas_parse_chan(buf, count, scan_cfg, dur);
378 libertas_parse_bssid(buf, count, scan_cfg);
379 libertas_parse_ssid(buf, count, scan_cfg);
380 libertas_parse_keep(buf, count, scan_cfg);
381 libertas_parse_probes(buf, count, scan_cfg);
382 libertas_parse_type(buf, count, scan_cfg);
384 wlan_scan_networks(priv, scan_cfg, 1);
385 wait_event_interruptible(priv->adapter->cmd_pending,
386 !priv->adapter->nr_cmd_pending);
388 memset(&wrqu, 0x00, sizeof(union iwreq_data));
389 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
397 static int libertas_event_initcmd(wlan_private *priv, void **response_buf,
398 struct cmd_ctrl_node **cmdnode,
399 struct cmd_ds_command **cmd)
401 u16 wait_option = cmd_option_waitforrsp;
403 if (!(*cmdnode = libertas_get_free_cmd_ctrl_node(priv))) {
404 lbs_deb_debugfs("failed libertas_get_free_cmd_ctrl_node\n");
407 if (!(*response_buf = kmalloc(3000, GFP_KERNEL))) {
408 lbs_deb_debugfs("failed to allocate response buffer!\n");
411 libertas_set_cmd_ctrl_node(priv, *cmdnode, 0, wait_option, NULL);
412 init_waitqueue_head(&(*cmdnode)->cmdwait_q);
413 (*cmdnode)->pdata_buf = *response_buf;
414 (*cmdnode)->cmdflags |= CMD_F_HOSTCMD;
415 (*cmdnode)->cmdwaitqwoken = 0;
416 *cmd = (struct cmd_ds_command *)(*cmdnode)->bufvirtualaddr;
417 (*cmd)->command = cmd_802_11_subscribe_event;
418 (*cmd)->seqnum = ++priv->adapter->seqnum;
423 static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf,
424 size_t count, loff_t *ppos)
426 wlan_private *priv = file->private_data;
427 wlan_adapter *adapter = priv->adapter;
428 struct cmd_ctrl_node *pcmdnode;
429 struct cmd_ds_command *pcmdptr;
430 struct cmd_ds_802_11_subscribe_event *event;
434 unsigned long addr = get_zeroed_page(GFP_KERNEL);
435 char *buf = (char *)addr;
437 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
443 event = &pcmdptr->params.subscribe_event;
444 event->action = cmd_act_get;
446 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
447 libertas_queue_cmd(adapter, pcmdnode, 1);
448 wake_up_interruptible(&priv->mainthread.waitq);
450 /* Sleep until response is generated by FW */
451 wait_event_interruptible(pcmdnode->cmdwait_q,
452 pcmdnode->cmdwaitqwoken);
454 pcmdptr = response_buf;
455 if (pcmdptr->result) {
456 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
463 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
464 lbs_pr_err("command response incorrect!\n");
470 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
471 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
472 while (cmd_len < pcmdptr->size) {
473 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
474 switch(header->type) {
475 struct mrvlietypes_rssithreshold *Lowrssi;
476 case TLV_TYPE_RSSI_LOW:
477 Lowrssi = (struct mrvlietypes_rssithreshold *)(response_buf + cmd_len);
478 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
481 (event->events & 0x0001)?1:0);
483 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
489 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
494 static u16 libertas_get_events_bitmap(wlan_private *priv)
496 wlan_adapter *adapter = priv->adapter;
497 struct cmd_ctrl_node *pcmdnode;
498 struct cmd_ds_command *pcmdptr;
499 struct cmd_ds_802_11_subscribe_event *event;
504 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
508 event = &pcmdptr->params.subscribe_event;
509 event->action = cmd_act_get;
511 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
512 libertas_queue_cmd(adapter, pcmdnode, 1);
513 wake_up_interruptible(&priv->mainthread.waitq);
515 /* Sleep until response is generated by FW */
516 wait_event_interruptible(pcmdnode->cmdwait_q,
517 pcmdnode->cmdwaitqwoken);
519 pcmdptr = response_buf;
521 if (pcmdptr->result) {
522 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
528 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
529 lbs_pr_err("command response incorrect!\n");
534 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
535 event_bitmap = event->events;
540 static ssize_t libertas_lowrssi_write(struct file *file,
541 const char __user *userbuf,
542 size_t count, loff_t *ppos)
544 wlan_private *priv = file->private_data;
545 wlan_adapter *adapter = priv->adapter;
546 ssize_t res, buf_size;
547 int value, freq, subscribed, cmd_len;
548 struct cmd_ctrl_node *pcmdnode;
549 struct cmd_ds_command *pcmdptr;
550 struct cmd_ds_802_11_subscribe_event *event;
551 struct mrvlietypes_rssithreshold *rssi_threshold;
555 unsigned long addr = get_zeroed_page(GFP_KERNEL);
556 char *buf = (char *)addr;
558 buf_size = min(count, len - 1);
559 if (copy_from_user(buf, userbuf, buf_size)) {
563 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
569 event_bitmap = libertas_get_events_bitmap(priv);
571 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
575 event = &pcmdptr->params.subscribe_event;
576 event->action = cmd_act_set;
577 pcmdptr->size = cpu_to_le16(S_DS_GEN +
578 sizeof(struct cmd_ds_802_11_subscribe_event) +
579 sizeof(struct mrvlietypes_rssithreshold));
581 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
582 ptr = (u8*) pcmdptr+cmd_len;
583 rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
584 rssi_threshold->header.type = cpu_to_le16(0x0104);
585 rssi_threshold->header.len = 2;
586 rssi_threshold->rssivalue = cpu_to_le16(value);
587 rssi_threshold->rssifreq = cpu_to_le16(freq);
588 event_bitmap |= subscribed ? 0x0001 : 0x0;
589 event->events = event_bitmap;
591 libertas_queue_cmd(adapter, pcmdnode, 1);
592 wake_up_interruptible(&priv->mainthread.waitq);
594 /* Sleep until response is generated by FW */
595 wait_event_interruptible(pcmdnode->cmdwait_q,
596 pcmdnode->cmdwaitqwoken);
598 pcmdptr = response_buf;
600 if (pcmdptr->result) {
601 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
608 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
609 lbs_pr_err("command response incorrect!\n");
621 static ssize_t libertas_lowsnr_read(struct file *file, char __user *userbuf,
622 size_t count, loff_t *ppos)
624 wlan_private *priv = file->private_data;
625 wlan_adapter *adapter = priv->adapter;
626 struct cmd_ctrl_node *pcmdnode;
627 struct cmd_ds_command *pcmdptr;
628 struct cmd_ds_802_11_subscribe_event *event;
632 unsigned long addr = get_zeroed_page(GFP_KERNEL);
633 char *buf = (char *)addr;
635 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
641 event = &pcmdptr->params.subscribe_event;
642 event->action = cmd_act_get;
644 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
645 libertas_queue_cmd(adapter, pcmdnode, 1);
646 wake_up_interruptible(&priv->mainthread.waitq);
648 /* Sleep until response is generated by FW */
649 wait_event_interruptible(pcmdnode->cmdwait_q,
650 pcmdnode->cmdwaitqwoken);
652 pcmdptr = response_buf;
654 if (pcmdptr->result) {
655 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
662 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
663 lbs_pr_err("command response incorrect!\n");
669 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
670 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
671 while (cmd_len < pcmdptr->size) {
672 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
673 switch(header->type) {
674 struct mrvlietypes_snrthreshold *LowSnr;
675 case TLV_TYPE_SNR_LOW:
676 LowSnr = (struct mrvlietypes_snrthreshold *)(response_buf + cmd_len);
677 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
680 (event->events & 0x0002)?1:0);
682 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
689 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
694 static ssize_t libertas_lowsnr_write(struct file *file,
695 const char __user *userbuf,
696 size_t count, loff_t *ppos)
698 wlan_private *priv = file->private_data;
699 wlan_adapter *adapter = priv->adapter;
700 ssize_t res, buf_size;
701 int value, freq, subscribed, cmd_len;
702 struct cmd_ctrl_node *pcmdnode;
703 struct cmd_ds_command *pcmdptr;
704 struct cmd_ds_802_11_subscribe_event *event;
705 struct mrvlietypes_snrthreshold *snr_threshold;
709 unsigned long addr = get_zeroed_page(GFP_KERNEL);
710 char *buf = (char *)addr;
712 buf_size = min(count, len - 1);
713 if (copy_from_user(buf, userbuf, buf_size)) {
717 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
723 event_bitmap = libertas_get_events_bitmap(priv);
725 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
729 event = &pcmdptr->params.subscribe_event;
730 event->action = cmd_act_set;
731 pcmdptr->size = cpu_to_le16(S_DS_GEN +
732 sizeof(struct cmd_ds_802_11_subscribe_event) +
733 sizeof(struct mrvlietypes_snrthreshold));
734 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
735 ptr = (u8*) pcmdptr+cmd_len;
736 snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
737 snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_LOW);
738 snr_threshold->header.len = 2;
739 snr_threshold->snrvalue = cpu_to_le16(value);
740 snr_threshold->snrfreq = cpu_to_le16(freq);
741 event_bitmap |= subscribed ? 0x0002 : 0x0;
742 event->events = event_bitmap;
744 libertas_queue_cmd(adapter, pcmdnode, 1);
745 wake_up_interruptible(&priv->mainthread.waitq);
747 /* Sleep until response is generated by FW */
748 wait_event_interruptible(pcmdnode->cmdwait_q,
749 pcmdnode->cmdwaitqwoken);
751 pcmdptr = response_buf;
753 if (pcmdptr->result) {
754 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
761 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
762 lbs_pr_err("command response incorrect!\n");
775 static ssize_t libertas_failcount_read(struct file *file, char __user *userbuf,
776 size_t count, loff_t *ppos)
778 wlan_private *priv = file->private_data;
779 wlan_adapter *adapter = priv->adapter;
780 struct cmd_ctrl_node *pcmdnode;
781 struct cmd_ds_command *pcmdptr;
782 struct cmd_ds_802_11_subscribe_event *event;
786 unsigned long addr = get_zeroed_page(GFP_KERNEL);
787 char *buf = (char *)addr;
789 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
795 event = &pcmdptr->params.subscribe_event;
796 event->action = cmd_act_get;
798 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
799 libertas_queue_cmd(adapter, pcmdnode, 1);
800 wake_up_interruptible(&priv->mainthread.waitq);
802 /* Sleep until response is generated by FW */
803 wait_event_interruptible(pcmdnode->cmdwait_q,
804 pcmdnode->cmdwaitqwoken);
806 pcmdptr = response_buf;
808 if (pcmdptr->result) {
809 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
816 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
817 lbs_pr_err("command response incorrect!\n");
823 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
824 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
825 while (cmd_len < pcmdptr->size) {
826 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
827 switch(header->type) {
828 struct mrvlietypes_failurecount *failcount;
829 case TLV_TYPE_FAILCOUNT:
830 failcount = (struct mrvlietypes_failurecount *)(response_buf + cmd_len);
831 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
832 failcount->failvalue,
834 (event->events & 0x0004)?1:0);
836 cmd_len += sizeof(struct mrvlietypes_failurecount);
842 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
847 static ssize_t libertas_failcount_write(struct file *file,
848 const char __user *userbuf,
849 size_t count, loff_t *ppos)
851 wlan_private *priv = file->private_data;
852 wlan_adapter *adapter = priv->adapter;
853 ssize_t res, buf_size;
854 int value, freq, subscribed, cmd_len;
855 struct cmd_ctrl_node *pcmdnode;
856 struct cmd_ds_command *pcmdptr;
857 struct cmd_ds_802_11_subscribe_event *event;
858 struct mrvlietypes_failurecount *failcount;
862 unsigned long addr = get_zeroed_page(GFP_KERNEL);
863 char *buf = (char *)addr;
865 buf_size = min(count, len - 1);
866 if (copy_from_user(buf, userbuf, buf_size)) {
870 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
876 event_bitmap = libertas_get_events_bitmap(priv);
878 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
882 event = &pcmdptr->params.subscribe_event;
883 event->action = cmd_act_set;
884 pcmdptr->size = cpu_to_le16(S_DS_GEN +
885 sizeof(struct cmd_ds_802_11_subscribe_event) +
886 sizeof(struct mrvlietypes_failurecount));
887 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
888 ptr = (u8*) pcmdptr+cmd_len;
889 failcount = (struct mrvlietypes_failurecount *)(ptr);
890 failcount->header.type = cpu_to_le16(TLV_TYPE_FAILCOUNT);
891 failcount->header.len = 2;
892 failcount->failvalue = cpu_to_le16(value);
893 failcount->Failfreq = cpu_to_le16(freq);
894 event_bitmap |= subscribed ? 0x0004 : 0x0;
895 event->events = event_bitmap;
897 libertas_queue_cmd(adapter, pcmdnode, 1);
898 wake_up_interruptible(&priv->mainthread.waitq);
900 /* Sleep until response is generated by FW */
901 wait_event_interruptible(pcmdnode->cmdwait_q,
902 pcmdnode->cmdwaitqwoken);
904 pcmdptr = (struct cmd_ds_command *)response_buf;
906 if (pcmdptr->result) {
907 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
914 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
915 lbs_pr_err("command response incorrect!\n");
927 static ssize_t libertas_bcnmiss_read(struct file *file, char __user *userbuf,
928 size_t count, loff_t *ppos)
930 wlan_private *priv = file->private_data;
931 wlan_adapter *adapter = priv->adapter;
932 struct cmd_ctrl_node *pcmdnode;
933 struct cmd_ds_command *pcmdptr;
934 struct cmd_ds_802_11_subscribe_event *event;
938 unsigned long addr = get_zeroed_page(GFP_KERNEL);
939 char *buf = (char *)addr;
941 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
947 event = &pcmdptr->params.subscribe_event;
948 event->action = cmd_act_get;
950 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
951 libertas_queue_cmd(adapter, pcmdnode, 1);
952 wake_up_interruptible(&priv->mainthread.waitq);
954 /* Sleep until response is generated by FW */
955 wait_event_interruptible(pcmdnode->cmdwait_q,
956 pcmdnode->cmdwaitqwoken);
958 pcmdptr = response_buf;
960 if (pcmdptr->result) {
961 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
968 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
969 lbs_pr_err("command response incorrect!\n");
975 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
976 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
977 while (cmd_len < pcmdptr->size) {
978 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
979 switch(header->type) {
980 struct mrvlietypes_beaconsmissed *bcnmiss;
981 case TLV_TYPE_BCNMISS:
982 bcnmiss = (struct mrvlietypes_beaconsmissed *)(response_buf + cmd_len);
983 pos += snprintf(buf+pos, len-pos, "%d N/A %d\n",
984 bcnmiss->beaconmissed,
985 (event->events & 0x0008)?1:0);
987 cmd_len += sizeof(struct mrvlietypes_beaconsmissed);
994 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
999 static ssize_t libertas_bcnmiss_write(struct file *file,
1000 const char __user *userbuf,
1001 size_t count, loff_t *ppos)
1003 wlan_private *priv = file->private_data;
1004 wlan_adapter *adapter = priv->adapter;
1005 ssize_t res, buf_size;
1006 int value, freq, subscribed, cmd_len;
1007 struct cmd_ctrl_node *pcmdnode;
1008 struct cmd_ds_command *pcmdptr;
1009 struct cmd_ds_802_11_subscribe_event *event;
1010 struct mrvlietypes_beaconsmissed *bcnmiss;
1014 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1015 char *buf = (char *)addr;
1017 buf_size = min(count, len - 1);
1018 if (copy_from_user(buf, userbuf, buf_size)) {
1022 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
1028 event_bitmap = libertas_get_events_bitmap(priv);
1030 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1034 event = &pcmdptr->params.subscribe_event;
1035 event->action = cmd_act_set;
1036 pcmdptr->size = cpu_to_le16(S_DS_GEN +
1037 sizeof(struct cmd_ds_802_11_subscribe_event) +
1038 sizeof(struct mrvlietypes_beaconsmissed));
1039 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1040 ptr = (u8*) pcmdptr+cmd_len;
1041 bcnmiss = (struct mrvlietypes_beaconsmissed *)(ptr);
1042 bcnmiss->header.type = cpu_to_le16(TLV_TYPE_BCNMISS);
1043 bcnmiss->header.len = 2;
1044 bcnmiss->beaconmissed = cpu_to_le16(value);
1045 event_bitmap |= subscribed ? 0x0008 : 0x0;
1046 event->events = event_bitmap;
1048 libertas_queue_cmd(adapter, pcmdnode, 1);
1049 wake_up_interruptible(&priv->mainthread.waitq);
1051 /* Sleep until response is generated by FW */
1052 wait_event_interruptible(pcmdnode->cmdwait_q,
1053 pcmdnode->cmdwaitqwoken);
1055 pcmdptr = response_buf;
1057 if (pcmdptr->result) {
1058 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1060 kfree(response_buf);
1065 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1066 lbs_pr_err("command response incorrect!\n");
1068 kfree(response_buf);
1078 static ssize_t libertas_highrssi_read(struct file *file, char __user *userbuf,
1079 size_t count, loff_t *ppos)
1081 wlan_private *priv = file->private_data;
1082 wlan_adapter *adapter = priv->adapter;
1083 struct cmd_ctrl_node *pcmdnode;
1084 struct cmd_ds_command *pcmdptr;
1085 struct cmd_ds_802_11_subscribe_event *event;
1089 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1090 char *buf = (char *)addr;
1092 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1098 event = &pcmdptr->params.subscribe_event;
1099 event->action = cmd_act_get;
1101 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
1102 libertas_queue_cmd(adapter, pcmdnode, 1);
1103 wake_up_interruptible(&priv->mainthread.waitq);
1105 /* Sleep until response is generated by FW */
1106 wait_event_interruptible(pcmdnode->cmdwait_q,
1107 pcmdnode->cmdwaitqwoken);
1109 pcmdptr = response_buf;
1111 if (pcmdptr->result) {
1112 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1114 kfree(response_buf);
1119 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1120 lbs_pr_err("command response incorrect!\n");
1121 kfree(response_buf);
1126 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1127 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
1128 while (cmd_len < pcmdptr->size) {
1129 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
1130 switch(header->type) {
1131 struct mrvlietypes_rssithreshold *Highrssi;
1132 case TLV_TYPE_RSSI_HIGH:
1133 Highrssi = (struct mrvlietypes_rssithreshold *)(response_buf + cmd_len);
1134 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
1135 Highrssi->rssivalue,
1137 (event->events & 0x0010)?1:0);
1139 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
1144 kfree(response_buf);
1146 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1151 static ssize_t libertas_highrssi_write(struct file *file,
1152 const char __user *userbuf,
1153 size_t count, loff_t *ppos)
1155 wlan_private *priv = file->private_data;
1156 wlan_adapter *adapter = priv->adapter;
1157 ssize_t res, buf_size;
1158 int value, freq, subscribed, cmd_len;
1159 struct cmd_ctrl_node *pcmdnode;
1160 struct cmd_ds_command *pcmdptr;
1161 struct cmd_ds_802_11_subscribe_event *event;
1162 struct mrvlietypes_rssithreshold *rssi_threshold;
1166 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1167 char *buf = (char *)addr;
1169 buf_size = min(count, len - 1);
1170 if (copy_from_user(buf, userbuf, buf_size)) {
1174 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
1180 event_bitmap = libertas_get_events_bitmap(priv);
1182 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1186 event = &pcmdptr->params.subscribe_event;
1187 event->action = cmd_act_set;
1188 pcmdptr->size = cpu_to_le16(S_DS_GEN +
1189 sizeof(struct cmd_ds_802_11_subscribe_event) +
1190 sizeof(struct mrvlietypes_rssithreshold));
1191 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1192 ptr = (u8*) pcmdptr+cmd_len;
1193 rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
1194 rssi_threshold->header.type = cpu_to_le16(TLV_TYPE_RSSI_HIGH);
1195 rssi_threshold->header.len = 2;
1196 rssi_threshold->rssivalue = cpu_to_le16(value);
1197 rssi_threshold->rssifreq = cpu_to_le16(freq);
1198 event_bitmap |= subscribed ? 0x0010 : 0x0;
1199 event->events = event_bitmap;
1201 libertas_queue_cmd(adapter, pcmdnode, 1);
1202 wake_up_interruptible(&priv->mainthread.waitq);
1204 /* Sleep until response is generated by FW */
1205 wait_event_interruptible(pcmdnode->cmdwait_q,
1206 pcmdnode->cmdwaitqwoken);
1208 pcmdptr = response_buf;
1210 if (pcmdptr->result) {
1211 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1213 kfree(response_buf);
1217 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1218 lbs_pr_err("command response incorrect!\n");
1219 kfree(response_buf);
1229 static ssize_t libertas_highsnr_read(struct file *file, char __user *userbuf,
1230 size_t count, loff_t *ppos)
1232 wlan_private *priv = file->private_data;
1233 wlan_adapter *adapter = priv->adapter;
1234 struct cmd_ctrl_node *pcmdnode;
1235 struct cmd_ds_command *pcmdptr;
1236 struct cmd_ds_802_11_subscribe_event *event;
1240 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1241 char *buf = (char *)addr;
1243 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1249 event = &pcmdptr->params.subscribe_event;
1250 event->action = cmd_act_get;
1252 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
1253 libertas_queue_cmd(adapter, pcmdnode, 1);
1254 wake_up_interruptible(&priv->mainthread.waitq);
1256 /* Sleep until response is generated by FW */
1257 wait_event_interruptible(pcmdnode->cmdwait_q,
1258 pcmdnode->cmdwaitqwoken);
1260 pcmdptr = response_buf;
1262 if (pcmdptr->result) {
1263 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1265 kfree(response_buf);
1270 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1271 lbs_pr_err("command response incorrect!\n");
1272 kfree(response_buf);
1277 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1278 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
1279 while (cmd_len < pcmdptr->size) {
1280 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
1281 switch(header->type) {
1282 struct mrvlietypes_snrthreshold *HighSnr;
1283 case TLV_TYPE_SNR_HIGH:
1284 HighSnr = (struct mrvlietypes_snrthreshold *)(response_buf + cmd_len);
1285 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
1288 (event->events & 0x0020)?1:0);
1290 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
1295 kfree(response_buf);
1297 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1302 static ssize_t libertas_highsnr_write(struct file *file,
1303 const char __user *userbuf,
1304 size_t count, loff_t *ppos)
1306 wlan_private *priv = file->private_data;
1307 wlan_adapter *adapter = priv->adapter;
1308 ssize_t res, buf_size;
1309 int value, freq, subscribed, cmd_len;
1310 struct cmd_ctrl_node *pcmdnode;
1311 struct cmd_ds_command *pcmdptr;
1312 struct cmd_ds_802_11_subscribe_event *event;
1313 struct mrvlietypes_snrthreshold *snr_threshold;
1317 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1318 char *buf = (char *)addr;
1320 buf_size = min(count, len - 1);
1321 if (copy_from_user(buf, userbuf, buf_size)) {
1325 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
1331 event_bitmap = libertas_get_events_bitmap(priv);
1333 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1337 event = &pcmdptr->params.subscribe_event;
1338 event->action = cmd_act_set;
1339 pcmdptr->size = cpu_to_le16(S_DS_GEN +
1340 sizeof(struct cmd_ds_802_11_subscribe_event) +
1341 sizeof(struct mrvlietypes_snrthreshold));
1342 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1343 ptr = (u8*) pcmdptr+cmd_len;
1344 snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
1345 snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_HIGH);
1346 snr_threshold->header.len = 2;
1347 snr_threshold->snrvalue = cpu_to_le16(value);
1348 snr_threshold->snrfreq = cpu_to_le16(freq);
1349 event_bitmap |= subscribed ? 0x0020 : 0x0;
1350 event->events = event_bitmap;
1352 libertas_queue_cmd(adapter, pcmdnode, 1);
1353 wake_up_interruptible(&priv->mainthread.waitq);
1355 /* Sleep until response is generated by FW */
1356 wait_event_interruptible(pcmdnode->cmdwait_q,
1357 pcmdnode->cmdwaitqwoken);
1359 pcmdptr = response_buf;
1361 if (pcmdptr->result) {
1362 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1364 kfree(response_buf);
1369 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1370 lbs_pr_err("command response incorrect!\n");
1371 kfree(response_buf);
1382 static ssize_t libertas_rdmac_read(struct file *file, char __user *userbuf,
1383 size_t count, loff_t *ppos)
1385 wlan_private *priv = file->private_data;
1386 wlan_adapter *adapter = priv->adapter;
1387 struct wlan_offset_value offval;
1390 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1391 char *buf = (char *)addr;
1393 offval.offset = priv->mac_offset;
1396 ret = libertas_prepare_and_send_command(priv,
1397 cmd_mac_reg_access, 0,
1398 cmd_option_waitforrsp, 0, &offval);
1400 pos += snprintf(buf+pos, len-pos, "MAC[0x%x] = 0x%08x\n",
1401 priv->mac_offset, adapter->offsetvalue.value);
1403 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1408 static ssize_t libertas_rdmac_write(struct file *file,
1409 const char __user *userbuf,
1410 size_t count, loff_t *ppos)
1412 wlan_private *priv = file->private_data;
1413 ssize_t res, buf_size;
1414 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1415 char *buf = (char *)addr;
1417 buf_size = min(count, len - 1);
1418 if (copy_from_user(buf, userbuf, buf_size)) {
1422 priv->mac_offset = simple_strtoul((char *)buf, NULL, 16);
1429 static ssize_t libertas_wrmac_write(struct file *file,
1430 const char __user *userbuf,
1431 size_t count, loff_t *ppos)
1434 wlan_private *priv = file->private_data;
1435 ssize_t res, buf_size;
1437 struct wlan_offset_value offval;
1438 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1439 char *buf = (char *)addr;
1441 buf_size = min(count, len - 1);
1442 if (copy_from_user(buf, userbuf, buf_size)) {
1446 res = sscanf(buf, "%x %x", &offset, &value);
1452 offval.offset = offset;
1453 offval.value = value;
1454 res = libertas_prepare_and_send_command(priv,
1455 cmd_mac_reg_access, 1,
1456 cmd_option_waitforrsp, 0, &offval);
1465 static ssize_t libertas_rdbbp_read(struct file *file, char __user *userbuf,
1466 size_t count, loff_t *ppos)
1468 wlan_private *priv = file->private_data;
1469 wlan_adapter *adapter = priv->adapter;
1470 struct wlan_offset_value offval;
1473 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1474 char *buf = (char *)addr;
1476 offval.offset = priv->bbp_offset;
1479 ret = libertas_prepare_and_send_command(priv,
1480 cmd_bbp_reg_access, 0,
1481 cmd_option_waitforrsp, 0, &offval);
1483 pos += snprintf(buf+pos, len-pos, "BBP[0x%x] = 0x%08x\n",
1484 priv->bbp_offset, adapter->offsetvalue.value);
1486 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1492 static ssize_t libertas_rdbbp_write(struct file *file,
1493 const char __user *userbuf,
1494 size_t count, loff_t *ppos)
1496 wlan_private *priv = file->private_data;
1497 ssize_t res, buf_size;
1498 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1499 char *buf = (char *)addr;
1501 buf_size = min(count, len - 1);
1502 if (copy_from_user(buf, userbuf, buf_size)) {
1506 priv->bbp_offset = simple_strtoul((char *)buf, NULL, 16);
1513 static ssize_t libertas_wrbbp_write(struct file *file,
1514 const char __user *userbuf,
1515 size_t count, loff_t *ppos)
1518 wlan_private *priv = file->private_data;
1519 ssize_t res, buf_size;
1521 struct wlan_offset_value offval;
1522 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1523 char *buf = (char *)addr;
1525 buf_size = min(count, len - 1);
1526 if (copy_from_user(buf, userbuf, buf_size)) {
1530 res = sscanf(buf, "%x %x", &offset, &value);
1536 offval.offset = offset;
1537 offval.value = value;
1538 res = libertas_prepare_and_send_command(priv,
1539 cmd_bbp_reg_access, 1,
1540 cmd_option_waitforrsp, 0, &offval);
1549 static ssize_t libertas_rdrf_read(struct file *file, char __user *userbuf,
1550 size_t count, loff_t *ppos)
1552 wlan_private *priv = file->private_data;
1553 wlan_adapter *adapter = priv->adapter;
1554 struct wlan_offset_value offval;
1557 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1558 char *buf = (char *)addr;
1560 offval.offset = priv->rf_offset;
1563 ret = libertas_prepare_and_send_command(priv,
1564 cmd_rf_reg_access, 0,
1565 cmd_option_waitforrsp, 0, &offval);
1567 pos += snprintf(buf+pos, len-pos, "RF[0x%x] = 0x%08x\n",
1568 priv->rf_offset, adapter->offsetvalue.value);
1570 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1576 static ssize_t libertas_rdrf_write(struct file *file,
1577 const char __user *userbuf,
1578 size_t count, loff_t *ppos)
1580 wlan_private *priv = file->private_data;
1581 ssize_t res, buf_size;
1582 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1583 char *buf = (char *)addr;
1585 buf_size = min(count, len - 1);
1586 if (copy_from_user(buf, userbuf, buf_size)) {
1590 priv->rf_offset = simple_strtoul((char *)buf, NULL, 16);
1597 static ssize_t libertas_wrrf_write(struct file *file,
1598 const char __user *userbuf,
1599 size_t count, loff_t *ppos)
1602 wlan_private *priv = file->private_data;
1603 ssize_t res, buf_size;
1605 struct wlan_offset_value offval;
1606 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1607 char *buf = (char *)addr;
1609 buf_size = min(count, len - 1);
1610 if (copy_from_user(buf, userbuf, buf_size)) {
1614 res = sscanf(buf, "%x %x", &offset, &value);
1620 offval.offset = offset;
1621 offval.value = value;
1622 res = libertas_prepare_and_send_command(priv,
1623 cmd_rf_reg_access, 1,
1624 cmd_option_waitforrsp, 0, &offval);
1633 #define FOPS(fread, fwrite) { \
1634 .owner = THIS_MODULE, \
1635 .open = open_file_generic, \
1637 .write = (fwrite), \
1640 struct libertas_debugfs_files {
1643 struct file_operations fops;
1646 static struct libertas_debugfs_files debugfs_files[] = {
1647 { "info", 0444, FOPS(libertas_dev_info, write_file_dummy), },
1648 { "getscantable", 0444, FOPS(libertas_getscantable,
1649 write_file_dummy), },
1650 { "sleepparams", 0644, FOPS(libertas_sleepparams_read,
1651 libertas_sleepparams_write), },
1652 { "extscan", 0600, FOPS(NULL, libertas_extscan), },
1653 { "setuserscan", 0600, FOPS(NULL, libertas_setuserscan), },
1656 static struct libertas_debugfs_files debugfs_events_files[] = {
1657 {"low_rssi", 0644, FOPS(libertas_lowrssi_read,
1658 libertas_lowrssi_write), },
1659 {"low_snr", 0644, FOPS(libertas_lowsnr_read,
1660 libertas_lowsnr_write), },
1661 {"failure_count", 0644, FOPS(libertas_failcount_read,
1662 libertas_failcount_write), },
1663 {"beacon_missed", 0644, FOPS(libertas_bcnmiss_read,
1664 libertas_bcnmiss_write), },
1665 {"high_rssi", 0644, FOPS(libertas_highrssi_read,
1666 libertas_highrssi_write), },
1667 {"high_snr", 0644, FOPS(libertas_highsnr_read,
1668 libertas_highsnr_write), },
1671 static struct libertas_debugfs_files debugfs_regs_files[] = {
1672 {"rdmac", 0644, FOPS(libertas_rdmac_read, libertas_rdmac_write), },
1673 {"wrmac", 0600, FOPS(NULL, libertas_wrmac_write), },
1674 {"rdbbp", 0644, FOPS(libertas_rdbbp_read, libertas_rdbbp_write), },
1675 {"wrbbp", 0600, FOPS(NULL, libertas_wrbbp_write), },
1676 {"rdrf", 0644, FOPS(libertas_rdrf_read, libertas_rdrf_write), },
1677 {"wrrf", 0600, FOPS(NULL, libertas_wrrf_write), },
1680 void libertas_debugfs_init(void)
1683 libertas_dir = debugfs_create_dir("libertas_wireless", NULL);
1688 void libertas_debugfs_remove(void)
1691 debugfs_remove(libertas_dir);
1695 void libertas_debugfs_init_one(wlan_private *priv, struct net_device *dev)
1698 struct libertas_debugfs_files *files;
1702 priv->debugfs_dir = debugfs_create_dir(dev->name, libertas_dir);
1703 if (!priv->debugfs_dir)
1706 for (i=0; i<ARRAY_SIZE(debugfs_files); i++) {
1707 files = &debugfs_files[i];
1708 priv->debugfs_files[i] = debugfs_create_file(files->name,
1715 priv->events_dir = debugfs_create_dir("subscribed_events", priv->debugfs_dir);
1716 if (!priv->events_dir)
1719 for (i=0; i<ARRAY_SIZE(debugfs_events_files); i++) {
1720 files = &debugfs_events_files[i];
1721 priv->debugfs_events_files[i] = debugfs_create_file(files->name,
1728 priv->regs_dir = debugfs_create_dir("registers", priv->debugfs_dir);
1729 if (!priv->regs_dir)
1732 for (i=0; i<ARRAY_SIZE(debugfs_regs_files); i++) {
1733 files = &debugfs_regs_files[i];
1734 priv->debugfs_regs_files[i] = debugfs_create_file(files->name,
1742 libertas_debug_init(priv, dev);
1748 void libertas_debugfs_remove_one(wlan_private *priv)
1752 for(i=0; i<ARRAY_SIZE(debugfs_regs_files); i++)
1753 debugfs_remove(priv->debugfs_regs_files[i]);
1755 debugfs_remove(priv->regs_dir);
1757 for(i=0; i<ARRAY_SIZE(debugfs_events_files); i++)
1758 debugfs_remove(priv->debugfs_events_files[i]);
1760 debugfs_remove(priv->events_dir);
1762 debugfs_remove(priv->debugfs_debug);
1764 for(i=0; i<ARRAY_SIZE(debugfs_files); i++)
1765 debugfs_remove(priv->debugfs_files[i]);
1766 debugfs_remove(priv->debugfs_dir);
1775 #define item_size(n) (FIELD_SIZEOF(wlan_adapter, n))
1776 #define item_addr(n) (offsetof(wlan_adapter, n))
1785 /* To debug any member of wlan_adapter, simply add one line here.
1787 static 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)},
1793 static int num_of_items = ARRAY_SIZE(items);
1796 * @brief proc read function
1798 * @param page pointer to buffer
1799 * @param s read data starting position
1801 * @param cnt counter
1802 * @param eof end of file flag
1803 * @param data data to output
1804 * @return number of output data
1806 static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf,
1807 size_t count, loff_t *ppos)
1814 struct debug_data *d;
1815 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1816 char *buf = (char *)addr;
1820 d = (struct debug_data *)file->private_data;
1822 for (i = 0; i < num_of_items; i++) {
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);
1829 else if (d[i].size == 8)
1830 val = *((u64 *) d[i].addr);
1832 pos += sprintf(p + pos, "%s=%d\n", d[i].name, val);
1835 res = simple_read_from_buffer(userbuf, count, ppos, p, pos);
1842 * @brief proc write function
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
1850 static ssize_t wlan_debugfs_write(struct file *f, const char __user *buf,
1851 size_t cnt, loff_t *ppos)
1859 struct debug_data *d = (struct debug_data *)f->private_data;
1861 pdata = (char *)kmalloc(cnt, GFP_KERNEL);
1865 if (copy_from_user(pdata, buf, cnt)) {
1866 lbs_deb_debugfs("Copy from user failed\n");
1872 for (i = 0; i < num_of_items; i++) {
1874 p = strstr(p0, d[i].name);
1877 p1 = strchr(p, '\n');
1881 p2 = strchr(p, '=');
1885 r = simple_strtoul(p2, NULL, 0);
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;
1892 else if (d[i].size == 8)
1893 *((u64 *) d[i].addr) = (u64) r;
1899 return (ssize_t)cnt;
1902 static 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,
1910 * @brief create debug proc file
1912 * @param priv pointer wlan_private
1913 * @param dev pointer net_device
1916 static void libertas_debug_init(wlan_private * priv, struct net_device *dev)
1920 if (!priv->debugfs_dir)
1923 for (i = 0; i < num_of_items; i++)
1924 items[i].addr += (size_t) priv->adapter;
1926 priv->debugfs_debug = debugfs_create_file("debug", 0644,
1927 priv->debugfs_dir, &items[0],
1928 &libertas_debug_fops);