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;
67 pos += snprintf(buf+pos, len-pos,
68 "# | ch | ss | bssid | cap | TSF | Qual | SSID \n");
70 while (numscansdone < priv->adapter->numinscantable) {
71 struct bss_descriptor *pbssinfo;
74 pbssinfo = &priv->adapter->scantable[numscansdone];
75 memcpy(&cap, &pbssinfo->cap, sizeof(cap));
76 pos += snprintf(buf+pos, len-pos,
77 "%02u| %03d | %03ld | %02x:%02x:%02x:%02x:%02x:%02x |",
78 numscansdone, pbssinfo->channel, pbssinfo->rssi,
79 pbssinfo->macaddress[0], pbssinfo->macaddress[1],
80 pbssinfo->macaddress[2], pbssinfo->macaddress[3],
81 pbssinfo->macaddress[4], pbssinfo->macaddress[5]);
82 pos += snprintf(buf+pos, len-pos, " %04x-", cap);
83 pos += snprintf(buf+pos, len-pos, "%c%c%c |",
84 pbssinfo->cap.ibss ? 'A' : 'I',
85 pbssinfo->cap.privacy ? 'P' : ' ',
86 pbssinfo->cap.spectrummgmt ? 'S' : ' ');
87 pos += snprintf(buf+pos, len-pos, " %08llx |", pbssinfo->networktsf);
88 pos += snprintf(buf+pos, len-pos, " %d |",
89 SCAN_RSSI(priv->adapter->scantable[numscansdone].rssi));
91 pos += snprintf(buf+pos, len-pos, " %s\n", pbssinfo->ssid.ssid);
96 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
102 static ssize_t libertas_sleepparams_write(struct file *file,
103 const char __user *user_buf, size_t count,
106 wlan_private *priv = file->private_data;
107 ssize_t buf_size, res;
108 int p1, p2, p3, p4, p5, p6;
109 struct sleep_params sp;
110 unsigned long addr = get_zeroed_page(GFP_KERNEL);
111 char *buf = (char *)addr;
113 buf_size = min(count, len - 1);
114 if (copy_from_user(buf, user_buf, buf_size)) {
118 res = sscanf(buf, "%d %d %d %d %d %d", &p1, &p2, &p3, &p4, &p5, &p6);
125 sp.sp_stabletime = p3;
126 sp.sp_calcontrol = p4;
127 sp.sp_extsleepclk = p5;
130 memcpy(&priv->adapter->sp, &sp, sizeof(struct sleep_params));
132 res = libertas_prepare_and_send_command(priv,
133 cmd_802_11_sleep_params,
135 cmd_option_waitforrsp, 0, NULL);
147 static ssize_t libertas_sleepparams_read(struct file *file, char __user *userbuf,
148 size_t count, loff_t *ppos)
150 wlan_private *priv = file->private_data;
151 wlan_adapter *adapter = priv->adapter;
154 unsigned long addr = get_zeroed_page(GFP_KERNEL);
155 char *buf = (char *)addr;
157 res = libertas_prepare_and_send_command(priv,
158 cmd_802_11_sleep_params,
160 cmd_option_waitforrsp, 0, NULL);
166 pos += snprintf(buf, len, "%d %d %d %d %d %d\n", adapter->sp.sp_error,
167 adapter->sp.sp_offset, adapter->sp.sp_stabletime,
168 adapter->sp.sp_calcontrol, adapter->sp.sp_extsleepclk,
169 adapter->sp.sp_reserved);
171 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
178 static ssize_t libertas_extscan(struct file *file, const char __user *userbuf,
179 size_t count, loff_t *ppos)
181 wlan_private *priv = file->private_data;
182 ssize_t res, buf_size;
183 struct WLAN_802_11_SSID extscan_ssid;
184 union iwreq_data wrqu;
185 unsigned long addr = get_zeroed_page(GFP_KERNEL);
186 char *buf = (char *)addr;
188 buf_size = min(count, len - 1);
189 if (copy_from_user(buf, userbuf, buf_size)) {
194 memcpy(&extscan_ssid.ssid, buf, strlen(buf)-1);
195 extscan_ssid.ssidlength = strlen(buf)-1;
197 libertas_send_specific_SSID_scan(priv, &extscan_ssid, 1);
199 memset(&wrqu, 0, sizeof(union iwreq_data));
200 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
207 static int libertas_parse_chan(char *buf, size_t count,
208 struct wlan_ioctl_user_scan_cfg *scan_cfg, int dur)
210 char *start, *end, *hold, *str;
213 start = strstr(buf, "chan=");
217 end = strstr(start, " ");
220 hold = kzalloc((end - start)+1, GFP_KERNEL);
223 strncpy(hold, start, end - start);
224 hold[(end-start)+1] = '\0';
225 while(hold && (str = strsep(&hold, ","))) {
227 char band, passive = 0;
228 sscanf(str, "%d%c%c", &chan, &band, &passive);
229 scan_cfg->chanlist[i].channumber = chan;
230 scan_cfg->chanlist[i].scantype = passive ? 1 : 0;
231 if (band == 'b' || band == 'g')
232 scan_cfg->chanlist[i].radiotype = 0;
233 else if (band == 'a')
234 scan_cfg->chanlist[i].radiotype = 1;
236 scan_cfg->chanlist[i].scantime = dur;
244 static void libertas_parse_bssid(char *buf, size_t count,
245 struct wlan_ioctl_user_scan_cfg *scan_cfg)
248 unsigned int mac[ETH_ALEN];
251 hold = strstr(buf, "bssid=");
255 sscanf(hold, "%2x:%2x:%2x:%2x:%2x:%2x", mac, mac+1, mac+2, mac+3,
257 for(i=0;i<ETH_ALEN;i++)
258 scan_cfg->specificBSSID[i] = mac[i];
261 static void libertas_parse_ssid(char *buf, size_t count,
262 struct wlan_ioctl_user_scan_cfg *scan_cfg)
267 hold = strstr(buf, "ssid=");
271 end = strstr(hold, " ");
273 end = buf + count - 1;
275 size = min((size_t)IW_ESSID_MAX_SIZE, (size_t) (end - hold));
276 strncpy(scan_cfg->specificSSID, hold, size);
281 static void libertas_parse_keep(char *buf, size_t count,
282 struct wlan_ioctl_user_scan_cfg *scan_cfg)
287 hold = strstr(buf, "keep=");
291 sscanf(hold, "%d", &val);
296 scan_cfg->keeppreviousscan = val;
300 static int libertas_parse_dur(char *buf, size_t count,
301 struct wlan_ioctl_user_scan_cfg *scan_cfg)
306 hold = strstr(buf, "dur=");
310 sscanf(hold, "%d", &val);
315 static void libertas_parse_probes(char *buf, size_t count,
316 struct wlan_ioctl_user_scan_cfg *scan_cfg)
321 hold = strstr(buf, "probes=");
325 sscanf(hold, "%d", &val);
327 scan_cfg->numprobes = val;
332 static void libertas_parse_type(char *buf, size_t count,
333 struct wlan_ioctl_user_scan_cfg *scan_cfg)
338 hold = strstr(buf, "type=");
342 sscanf(hold, "%d", &val);
345 if (val < 1 || val > 3)
348 scan_cfg->bsstype = val;
353 static ssize_t libertas_setuserscan(struct file *file,
354 const char __user *userbuf,
355 size_t count, loff_t *ppos)
357 wlan_private *priv = file->private_data;
358 ssize_t res, buf_size;
359 struct wlan_ioctl_user_scan_cfg *scan_cfg;
360 union iwreq_data wrqu;
362 unsigned long addr = get_zeroed_page(GFP_KERNEL);
363 char *buf = (char *)addr;
365 scan_cfg = kzalloc(sizeof(struct wlan_ioctl_user_scan_cfg), GFP_KERNEL);
369 buf_size = min(count, len - 1);
370 if (copy_from_user(buf, userbuf, buf_size)) {
375 scan_cfg->bsstype = WLAN_SCAN_BSS_TYPE_ANY;
377 dur = libertas_parse_dur(buf, count, scan_cfg);
378 libertas_parse_chan(buf, count, scan_cfg, dur);
379 libertas_parse_bssid(buf, count, scan_cfg);
380 libertas_parse_ssid(buf, count, scan_cfg);
381 libertas_parse_keep(buf, count, scan_cfg);
382 libertas_parse_probes(buf, count, scan_cfg);
383 libertas_parse_type(buf, count, scan_cfg);
385 wlan_scan_networks(priv, scan_cfg, 1);
386 wait_event_interruptible(priv->adapter->cmd_pending,
387 !priv->adapter->nr_cmd_pending);
389 memset(&wrqu, 0x00, sizeof(union iwreq_data));
390 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
398 static int libertas_event_initcmd(wlan_private *priv, void **response_buf,
399 struct cmd_ctrl_node **cmdnode,
400 struct cmd_ds_command **cmd)
402 u16 wait_option = cmd_option_waitforrsp;
404 if (!(*cmdnode = libertas_get_free_cmd_ctrl_node(priv))) {
405 lbs_deb_debugfs("failed libertas_get_free_cmd_ctrl_node\n");
408 if (!(*response_buf = kmalloc(3000, GFP_KERNEL))) {
409 lbs_deb_debugfs("failed to allocate response buffer!\n");
412 libertas_set_cmd_ctrl_node(priv, *cmdnode, 0, wait_option, NULL);
413 init_waitqueue_head(&(*cmdnode)->cmdwait_q);
414 (*cmdnode)->pdata_buf = *response_buf;
415 (*cmdnode)->cmdflags |= CMD_F_HOSTCMD;
416 (*cmdnode)->cmdwaitqwoken = 0;
417 *cmd = (struct cmd_ds_command *)(*cmdnode)->bufvirtualaddr;
418 (*cmd)->command = cmd_802_11_subscribe_event;
419 (*cmd)->seqnum = ++priv->adapter->seqnum;
424 static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf,
425 size_t count, loff_t *ppos)
427 wlan_private *priv = file->private_data;
428 wlan_adapter *adapter = priv->adapter;
429 struct cmd_ctrl_node *pcmdnode;
430 struct cmd_ds_command *pcmdptr;
431 struct cmd_ds_802_11_subscribe_event *event;
435 unsigned long addr = get_zeroed_page(GFP_KERNEL);
436 char *buf = (char *)addr;
438 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
444 event = &pcmdptr->params.subscribe_event;
445 event->action = cmd_act_get;
447 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
448 libertas_queue_cmd(adapter, pcmdnode, 1);
449 wake_up_interruptible(&priv->mainthread.waitq);
451 /* Sleep until response is generated by FW */
452 wait_event_interruptible(pcmdnode->cmdwait_q,
453 pcmdnode->cmdwaitqwoken);
455 pcmdptr = response_buf;
456 if (pcmdptr->result) {
457 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
464 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
465 lbs_pr_err("command response incorrect!\n");
471 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
472 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
473 while (cmd_len < pcmdptr->size) {
474 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
475 switch(header->type) {
476 struct mrvlietypes_rssithreshold *Lowrssi;
477 case TLV_TYPE_RSSI_LOW:
478 Lowrssi = (struct mrvlietypes_rssithreshold *)(response_buf + cmd_len);
479 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
482 (event->events & 0x0001)?1:0);
484 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
490 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
495 static u16 libertas_get_events_bitmap(wlan_private *priv)
497 wlan_adapter *adapter = priv->adapter;
498 struct cmd_ctrl_node *pcmdnode;
499 struct cmd_ds_command *pcmdptr;
500 struct cmd_ds_802_11_subscribe_event *event;
505 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
509 event = &pcmdptr->params.subscribe_event;
510 event->action = cmd_act_get;
512 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
513 libertas_queue_cmd(adapter, pcmdnode, 1);
514 wake_up_interruptible(&priv->mainthread.waitq);
516 /* Sleep until response is generated by FW */
517 wait_event_interruptible(pcmdnode->cmdwait_q,
518 pcmdnode->cmdwaitqwoken);
520 pcmdptr = response_buf;
522 if (pcmdptr->result) {
523 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
529 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
530 lbs_pr_err("command response incorrect!\n");
535 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
536 event_bitmap = event->events;
541 static ssize_t libertas_lowrssi_write(struct file *file,
542 const char __user *userbuf,
543 size_t count, loff_t *ppos)
545 wlan_private *priv = file->private_data;
546 wlan_adapter *adapter = priv->adapter;
547 ssize_t res, buf_size;
548 int value, freq, subscribed, cmd_len;
549 struct cmd_ctrl_node *pcmdnode;
550 struct cmd_ds_command *pcmdptr;
551 struct cmd_ds_802_11_subscribe_event *event;
552 struct mrvlietypes_rssithreshold *rssi_threshold;
556 unsigned long addr = get_zeroed_page(GFP_KERNEL);
557 char *buf = (char *)addr;
559 buf_size = min(count, len - 1);
560 if (copy_from_user(buf, userbuf, buf_size)) {
564 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
570 event_bitmap = libertas_get_events_bitmap(priv);
572 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
576 event = &pcmdptr->params.subscribe_event;
577 event->action = cmd_act_set;
578 pcmdptr->size = cpu_to_le16(S_DS_GEN +
579 sizeof(struct cmd_ds_802_11_subscribe_event) +
580 sizeof(struct mrvlietypes_rssithreshold));
582 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
583 ptr = (u8*) pcmdptr+cmd_len;
584 rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
585 rssi_threshold->header.type = cpu_to_le16(0x0104);
586 rssi_threshold->header.len = 2;
587 rssi_threshold->rssivalue = cpu_to_le16(value);
588 rssi_threshold->rssifreq = cpu_to_le16(freq);
589 event_bitmap |= subscribed ? 0x0001 : 0x0;
590 event->events = event_bitmap;
592 libertas_queue_cmd(adapter, pcmdnode, 1);
593 wake_up_interruptible(&priv->mainthread.waitq);
595 /* Sleep until response is generated by FW */
596 wait_event_interruptible(pcmdnode->cmdwait_q,
597 pcmdnode->cmdwaitqwoken);
599 pcmdptr = response_buf;
601 if (pcmdptr->result) {
602 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
609 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
610 lbs_pr_err("command response incorrect!\n");
622 static ssize_t libertas_lowsnr_read(struct file *file, char __user *userbuf,
623 size_t count, loff_t *ppos)
625 wlan_private *priv = file->private_data;
626 wlan_adapter *adapter = priv->adapter;
627 struct cmd_ctrl_node *pcmdnode;
628 struct cmd_ds_command *pcmdptr;
629 struct cmd_ds_802_11_subscribe_event *event;
633 unsigned long addr = get_zeroed_page(GFP_KERNEL);
634 char *buf = (char *)addr;
636 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
642 event = &pcmdptr->params.subscribe_event;
643 event->action = cmd_act_get;
645 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
646 libertas_queue_cmd(adapter, pcmdnode, 1);
647 wake_up_interruptible(&priv->mainthread.waitq);
649 /* Sleep until response is generated by FW */
650 wait_event_interruptible(pcmdnode->cmdwait_q,
651 pcmdnode->cmdwaitqwoken);
653 pcmdptr = response_buf;
655 if (pcmdptr->result) {
656 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
663 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
664 lbs_pr_err("command response incorrect!\n");
670 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
671 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
672 while (cmd_len < pcmdptr->size) {
673 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
674 switch(header->type) {
675 struct mrvlietypes_snrthreshold *LowSnr;
676 case TLV_TYPE_SNR_LOW:
677 LowSnr = (struct mrvlietypes_snrthreshold *)(response_buf + cmd_len);
678 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
681 (event->events & 0x0002)?1:0);
683 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
690 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
695 static ssize_t libertas_lowsnr_write(struct file *file,
696 const char __user *userbuf,
697 size_t count, loff_t *ppos)
699 wlan_private *priv = file->private_data;
700 wlan_adapter *adapter = priv->adapter;
701 ssize_t res, buf_size;
702 int value, freq, subscribed, cmd_len;
703 struct cmd_ctrl_node *pcmdnode;
704 struct cmd_ds_command *pcmdptr;
705 struct cmd_ds_802_11_subscribe_event *event;
706 struct mrvlietypes_snrthreshold *snr_threshold;
710 unsigned long addr = get_zeroed_page(GFP_KERNEL);
711 char *buf = (char *)addr;
713 buf_size = min(count, len - 1);
714 if (copy_from_user(buf, userbuf, buf_size)) {
718 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
724 event_bitmap = libertas_get_events_bitmap(priv);
726 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
730 event = &pcmdptr->params.subscribe_event;
731 event->action = cmd_act_set;
732 pcmdptr->size = cpu_to_le16(S_DS_GEN +
733 sizeof(struct cmd_ds_802_11_subscribe_event) +
734 sizeof(struct mrvlietypes_snrthreshold));
735 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
736 ptr = (u8*) pcmdptr+cmd_len;
737 snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
738 snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_LOW);
739 snr_threshold->header.len = 2;
740 snr_threshold->snrvalue = cpu_to_le16(value);
741 snr_threshold->snrfreq = cpu_to_le16(freq);
742 event_bitmap |= subscribed ? 0x0002 : 0x0;
743 event->events = event_bitmap;
745 libertas_queue_cmd(adapter, pcmdnode, 1);
746 wake_up_interruptible(&priv->mainthread.waitq);
748 /* Sleep until response is generated by FW */
749 wait_event_interruptible(pcmdnode->cmdwait_q,
750 pcmdnode->cmdwaitqwoken);
752 pcmdptr = response_buf;
754 if (pcmdptr->result) {
755 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
762 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
763 lbs_pr_err("command response incorrect!\n");
776 static ssize_t libertas_failcount_read(struct file *file, char __user *userbuf,
777 size_t count, loff_t *ppos)
779 wlan_private *priv = file->private_data;
780 wlan_adapter *adapter = priv->adapter;
781 struct cmd_ctrl_node *pcmdnode;
782 struct cmd_ds_command *pcmdptr;
783 struct cmd_ds_802_11_subscribe_event *event;
787 unsigned long addr = get_zeroed_page(GFP_KERNEL);
788 char *buf = (char *)addr;
790 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
796 event = &pcmdptr->params.subscribe_event;
797 event->action = cmd_act_get;
799 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
800 libertas_queue_cmd(adapter, pcmdnode, 1);
801 wake_up_interruptible(&priv->mainthread.waitq);
803 /* Sleep until response is generated by FW */
804 wait_event_interruptible(pcmdnode->cmdwait_q,
805 pcmdnode->cmdwaitqwoken);
807 pcmdptr = response_buf;
809 if (pcmdptr->result) {
810 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
817 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
818 lbs_pr_err("command response incorrect!\n");
824 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
825 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
826 while (cmd_len < pcmdptr->size) {
827 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
828 switch(header->type) {
829 struct mrvlietypes_failurecount *failcount;
830 case TLV_TYPE_FAILCOUNT:
831 failcount = (struct mrvlietypes_failurecount *)(response_buf + cmd_len);
832 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
833 failcount->failvalue,
835 (event->events & 0x0004)?1:0);
837 cmd_len += sizeof(struct mrvlietypes_failurecount);
843 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
848 static ssize_t libertas_failcount_write(struct file *file,
849 const char __user *userbuf,
850 size_t count, loff_t *ppos)
852 wlan_private *priv = file->private_data;
853 wlan_adapter *adapter = priv->adapter;
854 ssize_t res, buf_size;
855 int value, freq, subscribed, cmd_len;
856 struct cmd_ctrl_node *pcmdnode;
857 struct cmd_ds_command *pcmdptr;
858 struct cmd_ds_802_11_subscribe_event *event;
859 struct mrvlietypes_failurecount *failcount;
863 unsigned long addr = get_zeroed_page(GFP_KERNEL);
864 char *buf = (char *)addr;
866 buf_size = min(count, len - 1);
867 if (copy_from_user(buf, userbuf, buf_size)) {
871 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
877 event_bitmap = libertas_get_events_bitmap(priv);
879 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
883 event = &pcmdptr->params.subscribe_event;
884 event->action = cmd_act_set;
885 pcmdptr->size = cpu_to_le16(S_DS_GEN +
886 sizeof(struct cmd_ds_802_11_subscribe_event) +
887 sizeof(struct mrvlietypes_failurecount));
888 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
889 ptr = (u8*) pcmdptr+cmd_len;
890 failcount = (struct mrvlietypes_failurecount *)(ptr);
891 failcount->header.type = cpu_to_le16(TLV_TYPE_FAILCOUNT);
892 failcount->header.len = 2;
893 failcount->failvalue = cpu_to_le16(value);
894 failcount->Failfreq = cpu_to_le16(freq);
895 event_bitmap |= subscribed ? 0x0004 : 0x0;
896 event->events = event_bitmap;
898 libertas_queue_cmd(adapter, pcmdnode, 1);
899 wake_up_interruptible(&priv->mainthread.waitq);
901 /* Sleep until response is generated by FW */
902 wait_event_interruptible(pcmdnode->cmdwait_q,
903 pcmdnode->cmdwaitqwoken);
905 pcmdptr = (struct cmd_ds_command *)response_buf;
907 if (pcmdptr->result) {
908 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
915 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
916 lbs_pr_err("command response incorrect!\n");
928 static ssize_t libertas_bcnmiss_read(struct file *file, char __user *userbuf,
929 size_t count, loff_t *ppos)
931 wlan_private *priv = file->private_data;
932 wlan_adapter *adapter = priv->adapter;
933 struct cmd_ctrl_node *pcmdnode;
934 struct cmd_ds_command *pcmdptr;
935 struct cmd_ds_802_11_subscribe_event *event;
939 unsigned long addr = get_zeroed_page(GFP_KERNEL);
940 char *buf = (char *)addr;
942 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
948 event = &pcmdptr->params.subscribe_event;
949 event->action = cmd_act_get;
951 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
952 libertas_queue_cmd(adapter, pcmdnode, 1);
953 wake_up_interruptible(&priv->mainthread.waitq);
955 /* Sleep until response is generated by FW */
956 wait_event_interruptible(pcmdnode->cmdwait_q,
957 pcmdnode->cmdwaitqwoken);
959 pcmdptr = response_buf;
961 if (pcmdptr->result) {
962 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
969 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
970 lbs_pr_err("command response incorrect!\n");
976 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
977 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
978 while (cmd_len < pcmdptr->size) {
979 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
980 switch(header->type) {
981 struct mrvlietypes_beaconsmissed *bcnmiss;
982 case TLV_TYPE_BCNMISS:
983 bcnmiss = (struct mrvlietypes_beaconsmissed *)(response_buf + cmd_len);
984 pos += snprintf(buf+pos, len-pos, "%d N/A %d\n",
985 bcnmiss->beaconmissed,
986 (event->events & 0x0008)?1:0);
988 cmd_len += sizeof(struct mrvlietypes_beaconsmissed);
995 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1000 static ssize_t libertas_bcnmiss_write(struct file *file,
1001 const char __user *userbuf,
1002 size_t count, loff_t *ppos)
1004 wlan_private *priv = file->private_data;
1005 wlan_adapter *adapter = priv->adapter;
1006 ssize_t res, buf_size;
1007 int value, freq, subscribed, cmd_len;
1008 struct cmd_ctrl_node *pcmdnode;
1009 struct cmd_ds_command *pcmdptr;
1010 struct cmd_ds_802_11_subscribe_event *event;
1011 struct mrvlietypes_beaconsmissed *bcnmiss;
1015 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1016 char *buf = (char *)addr;
1018 buf_size = min(count, len - 1);
1019 if (copy_from_user(buf, userbuf, buf_size)) {
1023 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
1029 event_bitmap = libertas_get_events_bitmap(priv);
1031 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1035 event = &pcmdptr->params.subscribe_event;
1036 event->action = cmd_act_set;
1037 pcmdptr->size = cpu_to_le16(S_DS_GEN +
1038 sizeof(struct cmd_ds_802_11_subscribe_event) +
1039 sizeof(struct mrvlietypes_beaconsmissed));
1040 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1041 ptr = (u8*) pcmdptr+cmd_len;
1042 bcnmiss = (struct mrvlietypes_beaconsmissed *)(ptr);
1043 bcnmiss->header.type = cpu_to_le16(TLV_TYPE_BCNMISS);
1044 bcnmiss->header.len = 2;
1045 bcnmiss->beaconmissed = cpu_to_le16(value);
1046 event_bitmap |= subscribed ? 0x0008 : 0x0;
1047 event->events = event_bitmap;
1049 libertas_queue_cmd(adapter, pcmdnode, 1);
1050 wake_up_interruptible(&priv->mainthread.waitq);
1052 /* Sleep until response is generated by FW */
1053 wait_event_interruptible(pcmdnode->cmdwait_q,
1054 pcmdnode->cmdwaitqwoken);
1056 pcmdptr = response_buf;
1058 if (pcmdptr->result) {
1059 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1061 kfree(response_buf);
1066 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1067 lbs_pr_err("command response incorrect!\n");
1069 kfree(response_buf);
1079 static ssize_t libertas_highrssi_read(struct file *file, char __user *userbuf,
1080 size_t count, loff_t *ppos)
1082 wlan_private *priv = file->private_data;
1083 wlan_adapter *adapter = priv->adapter;
1084 struct cmd_ctrl_node *pcmdnode;
1085 struct cmd_ds_command *pcmdptr;
1086 struct cmd_ds_802_11_subscribe_event *event;
1090 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1091 char *buf = (char *)addr;
1093 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1099 event = &pcmdptr->params.subscribe_event;
1100 event->action = cmd_act_get;
1102 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
1103 libertas_queue_cmd(adapter, pcmdnode, 1);
1104 wake_up_interruptible(&priv->mainthread.waitq);
1106 /* Sleep until response is generated by FW */
1107 wait_event_interruptible(pcmdnode->cmdwait_q,
1108 pcmdnode->cmdwaitqwoken);
1110 pcmdptr = response_buf;
1112 if (pcmdptr->result) {
1113 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1115 kfree(response_buf);
1120 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1121 lbs_pr_err("command response incorrect!\n");
1122 kfree(response_buf);
1127 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1128 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
1129 while (cmd_len < pcmdptr->size) {
1130 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
1131 switch(header->type) {
1132 struct mrvlietypes_rssithreshold *Highrssi;
1133 case TLV_TYPE_RSSI_HIGH:
1134 Highrssi = (struct mrvlietypes_rssithreshold *)(response_buf + cmd_len);
1135 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
1136 Highrssi->rssivalue,
1138 (event->events & 0x0010)?1:0);
1140 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
1145 kfree(response_buf);
1147 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1152 static ssize_t libertas_highrssi_write(struct file *file,
1153 const char __user *userbuf,
1154 size_t count, loff_t *ppos)
1156 wlan_private *priv = file->private_data;
1157 wlan_adapter *adapter = priv->adapter;
1158 ssize_t res, buf_size;
1159 int value, freq, subscribed, cmd_len;
1160 struct cmd_ctrl_node *pcmdnode;
1161 struct cmd_ds_command *pcmdptr;
1162 struct cmd_ds_802_11_subscribe_event *event;
1163 struct mrvlietypes_rssithreshold *rssi_threshold;
1167 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1168 char *buf = (char *)addr;
1170 buf_size = min(count, len - 1);
1171 if (copy_from_user(buf, userbuf, buf_size)) {
1175 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
1181 event_bitmap = libertas_get_events_bitmap(priv);
1183 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1187 event = &pcmdptr->params.subscribe_event;
1188 event->action = cmd_act_set;
1189 pcmdptr->size = cpu_to_le16(S_DS_GEN +
1190 sizeof(struct cmd_ds_802_11_subscribe_event) +
1191 sizeof(struct mrvlietypes_rssithreshold));
1192 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1193 ptr = (u8*) pcmdptr+cmd_len;
1194 rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
1195 rssi_threshold->header.type = cpu_to_le16(TLV_TYPE_RSSI_HIGH);
1196 rssi_threshold->header.len = 2;
1197 rssi_threshold->rssivalue = cpu_to_le16(value);
1198 rssi_threshold->rssifreq = cpu_to_le16(freq);
1199 event_bitmap |= subscribed ? 0x0010 : 0x0;
1200 event->events = event_bitmap;
1202 libertas_queue_cmd(adapter, pcmdnode, 1);
1203 wake_up_interruptible(&priv->mainthread.waitq);
1205 /* Sleep until response is generated by FW */
1206 wait_event_interruptible(pcmdnode->cmdwait_q,
1207 pcmdnode->cmdwaitqwoken);
1209 pcmdptr = response_buf;
1211 if (pcmdptr->result) {
1212 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1214 kfree(response_buf);
1218 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1219 lbs_pr_err("command response incorrect!\n");
1220 kfree(response_buf);
1230 static ssize_t libertas_highsnr_read(struct file *file, char __user *userbuf,
1231 size_t count, loff_t *ppos)
1233 wlan_private *priv = file->private_data;
1234 wlan_adapter *adapter = priv->adapter;
1235 struct cmd_ctrl_node *pcmdnode;
1236 struct cmd_ds_command *pcmdptr;
1237 struct cmd_ds_802_11_subscribe_event *event;
1241 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1242 char *buf = (char *)addr;
1244 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1250 event = &pcmdptr->params.subscribe_event;
1251 event->action = cmd_act_get;
1253 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
1254 libertas_queue_cmd(adapter, pcmdnode, 1);
1255 wake_up_interruptible(&priv->mainthread.waitq);
1257 /* Sleep until response is generated by FW */
1258 wait_event_interruptible(pcmdnode->cmdwait_q,
1259 pcmdnode->cmdwaitqwoken);
1261 pcmdptr = response_buf;
1263 if (pcmdptr->result) {
1264 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1266 kfree(response_buf);
1271 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1272 lbs_pr_err("command response incorrect!\n");
1273 kfree(response_buf);
1278 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1279 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
1280 while (cmd_len < pcmdptr->size) {
1281 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
1282 switch(header->type) {
1283 struct mrvlietypes_snrthreshold *HighSnr;
1284 case TLV_TYPE_SNR_HIGH:
1285 HighSnr = (struct mrvlietypes_snrthreshold *)(response_buf + cmd_len);
1286 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
1289 (event->events & 0x0020)?1:0);
1291 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
1296 kfree(response_buf);
1298 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1303 static ssize_t libertas_highsnr_write(struct file *file,
1304 const char __user *userbuf,
1305 size_t count, loff_t *ppos)
1307 wlan_private *priv = file->private_data;
1308 wlan_adapter *adapter = priv->adapter;
1309 ssize_t res, buf_size;
1310 int value, freq, subscribed, cmd_len;
1311 struct cmd_ctrl_node *pcmdnode;
1312 struct cmd_ds_command *pcmdptr;
1313 struct cmd_ds_802_11_subscribe_event *event;
1314 struct mrvlietypes_snrthreshold *snr_threshold;
1318 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1319 char *buf = (char *)addr;
1321 buf_size = min(count, len - 1);
1322 if (copy_from_user(buf, userbuf, buf_size)) {
1326 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
1332 event_bitmap = libertas_get_events_bitmap(priv);
1334 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1338 event = &pcmdptr->params.subscribe_event;
1339 event->action = cmd_act_set;
1340 pcmdptr->size = cpu_to_le16(S_DS_GEN +
1341 sizeof(struct cmd_ds_802_11_subscribe_event) +
1342 sizeof(struct mrvlietypes_snrthreshold));
1343 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1344 ptr = (u8*) pcmdptr+cmd_len;
1345 snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
1346 snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_HIGH);
1347 snr_threshold->header.len = 2;
1348 snr_threshold->snrvalue = cpu_to_le16(value);
1349 snr_threshold->snrfreq = cpu_to_le16(freq);
1350 event_bitmap |= subscribed ? 0x0020 : 0x0;
1351 event->events = event_bitmap;
1353 libertas_queue_cmd(adapter, pcmdnode, 1);
1354 wake_up_interruptible(&priv->mainthread.waitq);
1356 /* Sleep until response is generated by FW */
1357 wait_event_interruptible(pcmdnode->cmdwait_q,
1358 pcmdnode->cmdwaitqwoken);
1360 pcmdptr = response_buf;
1362 if (pcmdptr->result) {
1363 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1365 kfree(response_buf);
1370 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1371 lbs_pr_err("command response incorrect!\n");
1372 kfree(response_buf);
1383 static ssize_t libertas_rdmac_read(struct file *file, char __user *userbuf,
1384 size_t count, loff_t *ppos)
1386 wlan_private *priv = file->private_data;
1387 wlan_adapter *adapter = priv->adapter;
1388 struct wlan_offset_value offval;
1391 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1392 char *buf = (char *)addr;
1394 offval.offset = priv->mac_offset;
1397 ret = libertas_prepare_and_send_command(priv,
1398 cmd_mac_reg_access, 0,
1399 cmd_option_waitforrsp, 0, &offval);
1401 pos += snprintf(buf+pos, len-pos, "MAC[0x%x] = 0x%08x\n",
1402 priv->mac_offset, adapter->offsetvalue.value);
1404 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1409 static ssize_t libertas_rdmac_write(struct file *file,
1410 const char __user *userbuf,
1411 size_t count, loff_t *ppos)
1413 wlan_private *priv = file->private_data;
1414 ssize_t res, buf_size;
1415 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1416 char *buf = (char *)addr;
1418 buf_size = min(count, len - 1);
1419 if (copy_from_user(buf, userbuf, buf_size)) {
1423 priv->mac_offset = simple_strtoul((char *)buf, NULL, 16);
1430 static ssize_t libertas_wrmac_write(struct file *file,
1431 const char __user *userbuf,
1432 size_t count, loff_t *ppos)
1435 wlan_private *priv = file->private_data;
1436 ssize_t res, buf_size;
1438 struct wlan_offset_value offval;
1439 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1440 char *buf = (char *)addr;
1442 buf_size = min(count, len - 1);
1443 if (copy_from_user(buf, userbuf, buf_size)) {
1447 res = sscanf(buf, "%x %x", &offset, &value);
1453 offval.offset = offset;
1454 offval.value = value;
1455 res = libertas_prepare_and_send_command(priv,
1456 cmd_mac_reg_access, 1,
1457 cmd_option_waitforrsp, 0, &offval);
1466 static ssize_t libertas_rdbbp_read(struct file *file, char __user *userbuf,
1467 size_t count, loff_t *ppos)
1469 wlan_private *priv = file->private_data;
1470 wlan_adapter *adapter = priv->adapter;
1471 struct wlan_offset_value offval;
1474 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1475 char *buf = (char *)addr;
1477 offval.offset = priv->bbp_offset;
1480 ret = libertas_prepare_and_send_command(priv,
1481 cmd_bbp_reg_access, 0,
1482 cmd_option_waitforrsp, 0, &offval);
1484 pos += snprintf(buf+pos, len-pos, "BBP[0x%x] = 0x%08x\n",
1485 priv->bbp_offset, adapter->offsetvalue.value);
1487 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1493 static ssize_t libertas_rdbbp_write(struct file *file,
1494 const char __user *userbuf,
1495 size_t count, loff_t *ppos)
1497 wlan_private *priv = file->private_data;
1498 ssize_t res, buf_size;
1499 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1500 char *buf = (char *)addr;
1502 buf_size = min(count, len - 1);
1503 if (copy_from_user(buf, userbuf, buf_size)) {
1507 priv->bbp_offset = simple_strtoul((char *)buf, NULL, 16);
1514 static ssize_t libertas_wrbbp_write(struct file *file,
1515 const char __user *userbuf,
1516 size_t count, loff_t *ppos)
1519 wlan_private *priv = file->private_data;
1520 ssize_t res, buf_size;
1522 struct wlan_offset_value offval;
1523 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1524 char *buf = (char *)addr;
1526 buf_size = min(count, len - 1);
1527 if (copy_from_user(buf, userbuf, buf_size)) {
1531 res = sscanf(buf, "%x %x", &offset, &value);
1537 offval.offset = offset;
1538 offval.value = value;
1539 res = libertas_prepare_and_send_command(priv,
1540 cmd_bbp_reg_access, 1,
1541 cmd_option_waitforrsp, 0, &offval);
1550 static ssize_t libertas_rdrf_read(struct file *file, char __user *userbuf,
1551 size_t count, loff_t *ppos)
1553 wlan_private *priv = file->private_data;
1554 wlan_adapter *adapter = priv->adapter;
1555 struct wlan_offset_value offval;
1558 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1559 char *buf = (char *)addr;
1561 offval.offset = priv->rf_offset;
1564 ret = libertas_prepare_and_send_command(priv,
1565 cmd_rf_reg_access, 0,
1566 cmd_option_waitforrsp, 0, &offval);
1568 pos += snprintf(buf+pos, len-pos, "RF[0x%x] = 0x%08x\n",
1569 priv->rf_offset, adapter->offsetvalue.value);
1571 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1577 static ssize_t libertas_rdrf_write(struct file *file,
1578 const char __user *userbuf,
1579 size_t count, loff_t *ppos)
1581 wlan_private *priv = file->private_data;
1582 ssize_t res, buf_size;
1583 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1584 char *buf = (char *)addr;
1586 buf_size = min(count, len - 1);
1587 if (copy_from_user(buf, userbuf, buf_size)) {
1591 priv->rf_offset = simple_strtoul((char *)buf, NULL, 16);
1598 static ssize_t libertas_wrrf_write(struct file *file,
1599 const char __user *userbuf,
1600 size_t count, loff_t *ppos)
1603 wlan_private *priv = file->private_data;
1604 ssize_t res, buf_size;
1606 struct wlan_offset_value offval;
1607 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1608 char *buf = (char *)addr;
1610 buf_size = min(count, len - 1);
1611 if (copy_from_user(buf, userbuf, buf_size)) {
1615 res = sscanf(buf, "%x %x", &offset, &value);
1621 offval.offset = offset;
1622 offval.value = value;
1623 res = libertas_prepare_and_send_command(priv,
1624 cmd_rf_reg_access, 1,
1625 cmd_option_waitforrsp, 0, &offval);
1634 #define FOPS(fread, fwrite) { \
1635 .owner = THIS_MODULE, \
1636 .open = open_file_generic, \
1638 .write = (fwrite), \
1641 struct libertas_debugfs_files {
1644 struct file_operations fops;
1647 static struct libertas_debugfs_files debugfs_files[] = {
1648 { "info", 0444, FOPS(libertas_dev_info, write_file_dummy), },
1649 { "getscantable", 0444, FOPS(libertas_getscantable,
1650 write_file_dummy), },
1651 { "sleepparams", 0644, FOPS(libertas_sleepparams_read,
1652 libertas_sleepparams_write), },
1653 { "extscan", 0600, FOPS(NULL, libertas_extscan), },
1654 { "setuserscan", 0600, FOPS(NULL, libertas_setuserscan), },
1657 static struct libertas_debugfs_files debugfs_events_files[] = {
1658 {"low_rssi", 0644, FOPS(libertas_lowrssi_read,
1659 libertas_lowrssi_write), },
1660 {"low_snr", 0644, FOPS(libertas_lowsnr_read,
1661 libertas_lowsnr_write), },
1662 {"failure_count", 0644, FOPS(libertas_failcount_read,
1663 libertas_failcount_write), },
1664 {"beacon_missed", 0644, FOPS(libertas_bcnmiss_read,
1665 libertas_bcnmiss_write), },
1666 {"high_rssi", 0644, FOPS(libertas_highrssi_read,
1667 libertas_highrssi_write), },
1668 {"high_snr", 0644, FOPS(libertas_highsnr_read,
1669 libertas_highsnr_write), },
1672 static struct libertas_debugfs_files debugfs_regs_files[] = {
1673 {"rdmac", 0644, FOPS(libertas_rdmac_read, libertas_rdmac_write), },
1674 {"wrmac", 0600, FOPS(NULL, libertas_wrmac_write), },
1675 {"rdbbp", 0644, FOPS(libertas_rdbbp_read, libertas_rdbbp_write), },
1676 {"wrbbp", 0600, FOPS(NULL, libertas_wrbbp_write), },
1677 {"rdrf", 0644, FOPS(libertas_rdrf_read, libertas_rdrf_write), },
1678 {"wrrf", 0600, FOPS(NULL, libertas_wrrf_write), },
1681 void libertas_debugfs_init(void)
1684 libertas_dir = debugfs_create_dir("libertas_wireless", NULL);
1689 void libertas_debugfs_remove(void)
1692 debugfs_remove(libertas_dir);
1696 void libertas_debugfs_init_one(wlan_private *priv, struct net_device *dev)
1699 struct libertas_debugfs_files *files;
1703 priv->debugfs_dir = debugfs_create_dir(dev->name, libertas_dir);
1704 if (!priv->debugfs_dir)
1707 for (i=0; i<ARRAY_SIZE(debugfs_files); i++) {
1708 files = &debugfs_files[i];
1709 priv->debugfs_files[i] = debugfs_create_file(files->name,
1716 priv->events_dir = debugfs_create_dir("subscribed_events", priv->debugfs_dir);
1717 if (!priv->events_dir)
1720 for (i=0; i<ARRAY_SIZE(debugfs_events_files); i++) {
1721 files = &debugfs_events_files[i];
1722 priv->debugfs_events_files[i] = debugfs_create_file(files->name,
1729 priv->regs_dir = debugfs_create_dir("registers", priv->debugfs_dir);
1730 if (!priv->regs_dir)
1733 for (i=0; i<ARRAY_SIZE(debugfs_regs_files); i++) {
1734 files = &debugfs_regs_files[i];
1735 priv->debugfs_regs_files[i] = debugfs_create_file(files->name,
1743 libertas_debug_init(priv, dev);
1749 void libertas_debugfs_remove_one(wlan_private *priv)
1753 for(i=0; i<ARRAY_SIZE(debugfs_regs_files); i++)
1754 debugfs_remove(priv->debugfs_regs_files[i]);
1756 debugfs_remove(priv->regs_dir);
1758 for(i=0; i<ARRAY_SIZE(debugfs_events_files); i++)
1759 debugfs_remove(priv->debugfs_events_files[i]);
1761 debugfs_remove(priv->events_dir);
1763 debugfs_remove(priv->debugfs_debug);
1765 for(i=0; i<ARRAY_SIZE(debugfs_files); i++)
1766 debugfs_remove(priv->debugfs_files[i]);
1767 debugfs_remove(priv->debugfs_dir);
1776 #define item_size(n) (FIELD_SIZEOF(wlan_adapter, n))
1777 #define item_addr(n) (offsetof(wlan_adapter, n))
1786 /* To debug any member of wlan_adapter, simply add one line here.
1788 static struct debug_data items[] = {
1789 {"intcounter", item_size(intcounter), item_addr(intcounter)},
1790 {"psmode", item_size(psmode), item_addr(psmode)},
1791 {"psstate", item_size(psstate), item_addr(psstate)},
1794 static int num_of_items = ARRAY_SIZE(items);
1797 * @brief proc read function
1799 * @param page pointer to buffer
1800 * @param s read data starting position
1802 * @param cnt counter
1803 * @param eof end of file flag
1804 * @param data data to output
1805 * @return number of output data
1807 static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf,
1808 size_t count, loff_t *ppos)
1815 struct debug_data *d;
1816 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1817 char *buf = (char *)addr;
1821 d = (struct debug_data *)file->private_data;
1823 for (i = 0; i < num_of_items; i++) {
1825 val = *((u8 *) d[i].addr);
1826 else if (d[i].size == 2)
1827 val = *((u16 *) d[i].addr);
1828 else if (d[i].size == 4)
1829 val = *((u32 *) d[i].addr);
1830 else if (d[i].size == 8)
1831 val = *((u64 *) d[i].addr);
1833 pos += sprintf(p + pos, "%s=%d\n", d[i].name, val);
1836 res = simple_read_from_buffer(userbuf, count, ppos, p, pos);
1843 * @brief proc write function
1845 * @param f file pointer
1846 * @param buf pointer to data buffer
1847 * @param cnt data number to write
1848 * @param data data to write
1849 * @return number of data
1851 static ssize_t wlan_debugfs_write(struct file *f, const char __user *buf,
1852 size_t cnt, loff_t *ppos)
1860 struct debug_data *d = (struct debug_data *)f->private_data;
1862 pdata = (char *)kmalloc(cnt, GFP_KERNEL);
1866 if (copy_from_user(pdata, buf, cnt)) {
1867 lbs_deb_debugfs("Copy from user failed\n");
1873 for (i = 0; i < num_of_items; i++) {
1875 p = strstr(p0, d[i].name);
1878 p1 = strchr(p, '\n');
1882 p2 = strchr(p, '=');
1886 r = simple_strtoul(p2, NULL, 0);
1888 *((u8 *) d[i].addr) = (u8) r;
1889 else if (d[i].size == 2)
1890 *((u16 *) d[i].addr) = (u16) r;
1891 else if (d[i].size == 4)
1892 *((u32 *) d[i].addr) = (u32) r;
1893 else if (d[i].size == 8)
1894 *((u64 *) d[i].addr) = (u64) r;
1900 return (ssize_t)cnt;
1903 static struct file_operations libertas_debug_fops = {
1904 .owner = THIS_MODULE,
1905 .open = open_file_generic,
1906 .write = wlan_debugfs_write,
1907 .read = wlan_debugfs_read,
1911 * @brief create debug proc file
1913 * @param priv pointer wlan_private
1914 * @param dev pointer net_device
1917 static void libertas_debug_init(wlan_private * priv, struct net_device *dev)
1921 if (!priv->debugfs_dir)
1924 for (i = 0; i < num_of_items; i++)
1925 items[i].addr += (size_t) priv->adapter;
1927 priv->debugfs_debug = debugfs_create_file("debug", 0644,
1928 priv->debugfs_dir, &items[0],
1929 &libertas_debug_fops);