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, 0);
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];
249 hold = strstr(buf, "bssid=");
253 sscanf(hold, MAC_FMT, mac, mac+1, mac+2, mac+3, mac+4, mac+5);
254 memcpy(scan_cfg->bssid, mac, ETH_ALEN);
257 static void libertas_parse_ssid(char *buf, size_t count,
258 struct wlan_ioctl_user_scan_cfg *scan_cfg)
263 hold = strstr(buf, "ssid=");
267 end = strstr(hold, " ");
269 end = buf + count - 1;
271 size = min((size_t)IW_ESSID_MAX_SIZE, (size_t) (end - hold));
272 strncpy(scan_cfg->ssid, hold, size);
277 static int libertas_parse_clear(char *buf, size_t count, const char *tag)
282 hold = strstr(buf, tag);
286 sscanf(hold, "%d", &val);
294 static int libertas_parse_dur(char *buf, size_t count,
295 struct wlan_ioctl_user_scan_cfg *scan_cfg)
300 hold = strstr(buf, "dur=");
304 sscanf(hold, "%d", &val);
309 static void libertas_parse_probes(char *buf, size_t count,
310 struct wlan_ioctl_user_scan_cfg *scan_cfg)
315 hold = strstr(buf, "probes=");
319 sscanf(hold, "%d", &val);
321 scan_cfg->numprobes = val;
326 static void libertas_parse_type(char *buf, size_t count,
327 struct wlan_ioctl_user_scan_cfg *scan_cfg)
332 hold = strstr(buf, "type=");
336 sscanf(hold, "%d", &val);
339 if (val < 1 || val > 3)
342 scan_cfg->bsstype = val;
347 static ssize_t libertas_setuserscan(struct file *file,
348 const char __user *userbuf,
349 size_t count, loff_t *ppos)
351 wlan_private *priv = file->private_data;
352 ssize_t res, buf_size;
353 struct wlan_ioctl_user_scan_cfg *scan_cfg;
354 union iwreq_data wrqu;
356 unsigned long addr = get_zeroed_page(GFP_KERNEL);
357 char *buf = (char *)addr;
359 scan_cfg = kzalloc(sizeof(struct wlan_ioctl_user_scan_cfg), GFP_KERNEL);
363 buf_size = min(count, len - 1);
364 if (copy_from_user(buf, userbuf, buf_size)) {
369 scan_cfg->bsstype = WLAN_SCAN_BSS_TYPE_ANY;
371 dur = libertas_parse_dur(buf, count, scan_cfg);
372 libertas_parse_chan(buf, count, scan_cfg, dur);
373 libertas_parse_bssid(buf, count, scan_cfg);
374 scan_cfg->clear_bssid = libertas_parse_clear(buf, count, "clear_bssid=");
375 libertas_parse_ssid(buf, count, scan_cfg);
376 scan_cfg->clear_ssid = libertas_parse_clear(buf, count, "clear_ssid=");
377 libertas_parse_probes(buf, count, scan_cfg);
378 libertas_parse_type(buf, count, scan_cfg);
380 wlan_scan_networks(priv, scan_cfg, 1);
381 wait_event_interruptible(priv->adapter->cmd_pending,
382 !priv->adapter->nr_cmd_pending);
384 memset(&wrqu, 0x00, sizeof(union iwreq_data));
385 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
393 static int libertas_event_initcmd(wlan_private *priv, void **response_buf,
394 struct cmd_ctrl_node **cmdnode,
395 struct cmd_ds_command **cmd)
397 u16 wait_option = cmd_option_waitforrsp;
399 if (!(*cmdnode = libertas_get_free_cmd_ctrl_node(priv))) {
400 lbs_deb_debugfs("failed libertas_get_free_cmd_ctrl_node\n");
403 if (!(*response_buf = kmalloc(3000, GFP_KERNEL))) {
404 lbs_deb_debugfs("failed to allocate response buffer!\n");
407 libertas_set_cmd_ctrl_node(priv, *cmdnode, 0, wait_option, NULL);
408 init_waitqueue_head(&(*cmdnode)->cmdwait_q);
409 (*cmdnode)->pdata_buf = *response_buf;
410 (*cmdnode)->cmdflags |= CMD_F_HOSTCMD;
411 (*cmdnode)->cmdwaitqwoken = 0;
412 *cmd = (struct cmd_ds_command *)(*cmdnode)->bufvirtualaddr;
413 (*cmd)->command = cmd_802_11_subscribe_event;
414 (*cmd)->seqnum = ++priv->adapter->seqnum;
419 static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf,
420 size_t count, loff_t *ppos)
422 wlan_private *priv = file->private_data;
423 wlan_adapter *adapter = priv->adapter;
424 struct cmd_ctrl_node *pcmdnode;
425 struct cmd_ds_command *pcmdptr;
426 struct cmd_ds_802_11_subscribe_event *event;
430 unsigned long addr = get_zeroed_page(GFP_KERNEL);
431 char *buf = (char *)addr;
433 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
439 event = &pcmdptr->params.subscribe_event;
440 event->action = cmd_act_get;
442 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
443 libertas_queue_cmd(adapter, pcmdnode, 1);
444 wake_up_interruptible(&priv->mainthread.waitq);
446 /* Sleep until response is generated by FW */
447 wait_event_interruptible(pcmdnode->cmdwait_q,
448 pcmdnode->cmdwaitqwoken);
450 pcmdptr = response_buf;
451 if (pcmdptr->result) {
452 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
459 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
460 lbs_pr_err("command response incorrect!\n");
466 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
467 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
468 while (cmd_len < pcmdptr->size) {
469 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
470 switch(header->type) {
471 struct mrvlietypes_rssithreshold *Lowrssi;
472 case TLV_TYPE_RSSI_LOW:
473 Lowrssi = (struct mrvlietypes_rssithreshold *)(response_buf + cmd_len);
474 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
477 (event->events & 0x0001)?1:0);
479 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
485 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
490 static u16 libertas_get_events_bitmap(wlan_private *priv)
492 wlan_adapter *adapter = priv->adapter;
493 struct cmd_ctrl_node *pcmdnode;
494 struct cmd_ds_command *pcmdptr;
495 struct cmd_ds_802_11_subscribe_event *event;
500 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
504 event = &pcmdptr->params.subscribe_event;
505 event->action = cmd_act_get;
507 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
508 libertas_queue_cmd(adapter, pcmdnode, 1);
509 wake_up_interruptible(&priv->mainthread.waitq);
511 /* Sleep until response is generated by FW */
512 wait_event_interruptible(pcmdnode->cmdwait_q,
513 pcmdnode->cmdwaitqwoken);
515 pcmdptr = response_buf;
517 if (pcmdptr->result) {
518 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
524 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
525 lbs_pr_err("command response incorrect!\n");
530 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
531 event_bitmap = event->events;
536 static ssize_t libertas_lowrssi_write(struct file *file,
537 const char __user *userbuf,
538 size_t count, loff_t *ppos)
540 wlan_private *priv = file->private_data;
541 wlan_adapter *adapter = priv->adapter;
542 ssize_t res, buf_size;
543 int value, freq, subscribed, cmd_len;
544 struct cmd_ctrl_node *pcmdnode;
545 struct cmd_ds_command *pcmdptr;
546 struct cmd_ds_802_11_subscribe_event *event;
547 struct mrvlietypes_rssithreshold *rssi_threshold;
551 unsigned long addr = get_zeroed_page(GFP_KERNEL);
552 char *buf = (char *)addr;
554 buf_size = min(count, len - 1);
555 if (copy_from_user(buf, userbuf, buf_size)) {
559 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
565 event_bitmap = libertas_get_events_bitmap(priv);
567 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
571 event = &pcmdptr->params.subscribe_event;
572 event->action = cmd_act_set;
573 pcmdptr->size = cpu_to_le16(S_DS_GEN +
574 sizeof(struct cmd_ds_802_11_subscribe_event) +
575 sizeof(struct mrvlietypes_rssithreshold));
577 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
578 ptr = (u8*) pcmdptr+cmd_len;
579 rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
580 rssi_threshold->header.type = cpu_to_le16(0x0104);
581 rssi_threshold->header.len = 2;
582 rssi_threshold->rssivalue = cpu_to_le16(value);
583 rssi_threshold->rssifreq = cpu_to_le16(freq);
584 event_bitmap |= subscribed ? 0x0001 : 0x0;
585 event->events = event_bitmap;
587 libertas_queue_cmd(adapter, pcmdnode, 1);
588 wake_up_interruptible(&priv->mainthread.waitq);
590 /* Sleep until response is generated by FW */
591 wait_event_interruptible(pcmdnode->cmdwait_q,
592 pcmdnode->cmdwaitqwoken);
594 pcmdptr = response_buf;
596 if (pcmdptr->result) {
597 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
604 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
605 lbs_pr_err("command response incorrect!\n");
617 static ssize_t libertas_lowsnr_read(struct file *file, char __user *userbuf,
618 size_t count, loff_t *ppos)
620 wlan_private *priv = file->private_data;
621 wlan_adapter *adapter = priv->adapter;
622 struct cmd_ctrl_node *pcmdnode;
623 struct cmd_ds_command *pcmdptr;
624 struct cmd_ds_802_11_subscribe_event *event;
628 unsigned long addr = get_zeroed_page(GFP_KERNEL);
629 char *buf = (char *)addr;
631 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
637 event = &pcmdptr->params.subscribe_event;
638 event->action = cmd_act_get;
640 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
641 libertas_queue_cmd(adapter, pcmdnode, 1);
642 wake_up_interruptible(&priv->mainthread.waitq);
644 /* Sleep until response is generated by FW */
645 wait_event_interruptible(pcmdnode->cmdwait_q,
646 pcmdnode->cmdwaitqwoken);
648 pcmdptr = response_buf;
650 if (pcmdptr->result) {
651 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
658 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
659 lbs_pr_err("command response incorrect!\n");
665 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
666 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
667 while (cmd_len < pcmdptr->size) {
668 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
669 switch(header->type) {
670 struct mrvlietypes_snrthreshold *LowSnr;
671 case TLV_TYPE_SNR_LOW:
672 LowSnr = (struct mrvlietypes_snrthreshold *)(response_buf + cmd_len);
673 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
676 (event->events & 0x0002)?1:0);
678 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
685 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
690 static ssize_t libertas_lowsnr_write(struct file *file,
691 const char __user *userbuf,
692 size_t count, loff_t *ppos)
694 wlan_private *priv = file->private_data;
695 wlan_adapter *adapter = priv->adapter;
696 ssize_t res, buf_size;
697 int value, freq, subscribed, cmd_len;
698 struct cmd_ctrl_node *pcmdnode;
699 struct cmd_ds_command *pcmdptr;
700 struct cmd_ds_802_11_subscribe_event *event;
701 struct mrvlietypes_snrthreshold *snr_threshold;
705 unsigned long addr = get_zeroed_page(GFP_KERNEL);
706 char *buf = (char *)addr;
708 buf_size = min(count, len - 1);
709 if (copy_from_user(buf, userbuf, buf_size)) {
713 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
719 event_bitmap = libertas_get_events_bitmap(priv);
721 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
725 event = &pcmdptr->params.subscribe_event;
726 event->action = cmd_act_set;
727 pcmdptr->size = cpu_to_le16(S_DS_GEN +
728 sizeof(struct cmd_ds_802_11_subscribe_event) +
729 sizeof(struct mrvlietypes_snrthreshold));
730 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
731 ptr = (u8*) pcmdptr+cmd_len;
732 snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
733 snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_LOW);
734 snr_threshold->header.len = 2;
735 snr_threshold->snrvalue = cpu_to_le16(value);
736 snr_threshold->snrfreq = cpu_to_le16(freq);
737 event_bitmap |= subscribed ? 0x0002 : 0x0;
738 event->events = event_bitmap;
740 libertas_queue_cmd(adapter, pcmdnode, 1);
741 wake_up_interruptible(&priv->mainthread.waitq);
743 /* Sleep until response is generated by FW */
744 wait_event_interruptible(pcmdnode->cmdwait_q,
745 pcmdnode->cmdwaitqwoken);
747 pcmdptr = response_buf;
749 if (pcmdptr->result) {
750 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
757 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
758 lbs_pr_err("command response incorrect!\n");
771 static ssize_t libertas_failcount_read(struct file *file, char __user *userbuf,
772 size_t count, loff_t *ppos)
774 wlan_private *priv = file->private_data;
775 wlan_adapter *adapter = priv->adapter;
776 struct cmd_ctrl_node *pcmdnode;
777 struct cmd_ds_command *pcmdptr;
778 struct cmd_ds_802_11_subscribe_event *event;
782 unsigned long addr = get_zeroed_page(GFP_KERNEL);
783 char *buf = (char *)addr;
785 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
791 event = &pcmdptr->params.subscribe_event;
792 event->action = cmd_act_get;
794 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
795 libertas_queue_cmd(adapter, pcmdnode, 1);
796 wake_up_interruptible(&priv->mainthread.waitq);
798 /* Sleep until response is generated by FW */
799 wait_event_interruptible(pcmdnode->cmdwait_q,
800 pcmdnode->cmdwaitqwoken);
802 pcmdptr = response_buf;
804 if (pcmdptr->result) {
805 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
812 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
813 lbs_pr_err("command response incorrect!\n");
819 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
820 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
821 while (cmd_len < pcmdptr->size) {
822 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
823 switch(header->type) {
824 struct mrvlietypes_failurecount *failcount;
825 case TLV_TYPE_FAILCOUNT:
826 failcount = (struct mrvlietypes_failurecount *)(response_buf + cmd_len);
827 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
828 failcount->failvalue,
830 (event->events & 0x0004)?1:0);
832 cmd_len += sizeof(struct mrvlietypes_failurecount);
838 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
843 static ssize_t libertas_failcount_write(struct file *file,
844 const char __user *userbuf,
845 size_t count, loff_t *ppos)
847 wlan_private *priv = file->private_data;
848 wlan_adapter *adapter = priv->adapter;
849 ssize_t res, buf_size;
850 int value, freq, subscribed, cmd_len;
851 struct cmd_ctrl_node *pcmdnode;
852 struct cmd_ds_command *pcmdptr;
853 struct cmd_ds_802_11_subscribe_event *event;
854 struct mrvlietypes_failurecount *failcount;
858 unsigned long addr = get_zeroed_page(GFP_KERNEL);
859 char *buf = (char *)addr;
861 buf_size = min(count, len - 1);
862 if (copy_from_user(buf, userbuf, buf_size)) {
866 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
872 event_bitmap = libertas_get_events_bitmap(priv);
874 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
878 event = &pcmdptr->params.subscribe_event;
879 event->action = cmd_act_set;
880 pcmdptr->size = cpu_to_le16(S_DS_GEN +
881 sizeof(struct cmd_ds_802_11_subscribe_event) +
882 sizeof(struct mrvlietypes_failurecount));
883 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
884 ptr = (u8*) pcmdptr+cmd_len;
885 failcount = (struct mrvlietypes_failurecount *)(ptr);
886 failcount->header.type = cpu_to_le16(TLV_TYPE_FAILCOUNT);
887 failcount->header.len = 2;
888 failcount->failvalue = cpu_to_le16(value);
889 failcount->Failfreq = cpu_to_le16(freq);
890 event_bitmap |= subscribed ? 0x0004 : 0x0;
891 event->events = event_bitmap;
893 libertas_queue_cmd(adapter, pcmdnode, 1);
894 wake_up_interruptible(&priv->mainthread.waitq);
896 /* Sleep until response is generated by FW */
897 wait_event_interruptible(pcmdnode->cmdwait_q,
898 pcmdnode->cmdwaitqwoken);
900 pcmdptr = (struct cmd_ds_command *)response_buf;
902 if (pcmdptr->result) {
903 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
910 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
911 lbs_pr_err("command response incorrect!\n");
923 static ssize_t libertas_bcnmiss_read(struct file *file, char __user *userbuf,
924 size_t count, loff_t *ppos)
926 wlan_private *priv = file->private_data;
927 wlan_adapter *adapter = priv->adapter;
928 struct cmd_ctrl_node *pcmdnode;
929 struct cmd_ds_command *pcmdptr;
930 struct cmd_ds_802_11_subscribe_event *event;
934 unsigned long addr = get_zeroed_page(GFP_KERNEL);
935 char *buf = (char *)addr;
937 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
943 event = &pcmdptr->params.subscribe_event;
944 event->action = cmd_act_get;
946 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
947 libertas_queue_cmd(adapter, pcmdnode, 1);
948 wake_up_interruptible(&priv->mainthread.waitq);
950 /* Sleep until response is generated by FW */
951 wait_event_interruptible(pcmdnode->cmdwait_q,
952 pcmdnode->cmdwaitqwoken);
954 pcmdptr = response_buf;
956 if (pcmdptr->result) {
957 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
964 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
965 lbs_pr_err("command response incorrect!\n");
971 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
972 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
973 while (cmd_len < pcmdptr->size) {
974 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
975 switch(header->type) {
976 struct mrvlietypes_beaconsmissed *bcnmiss;
977 case TLV_TYPE_BCNMISS:
978 bcnmiss = (struct mrvlietypes_beaconsmissed *)(response_buf + cmd_len);
979 pos += snprintf(buf+pos, len-pos, "%d N/A %d\n",
980 bcnmiss->beaconmissed,
981 (event->events & 0x0008)?1:0);
983 cmd_len += sizeof(struct mrvlietypes_beaconsmissed);
990 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
995 static ssize_t libertas_bcnmiss_write(struct file *file,
996 const char __user *userbuf,
997 size_t count, loff_t *ppos)
999 wlan_private *priv = file->private_data;
1000 wlan_adapter *adapter = priv->adapter;
1001 ssize_t res, buf_size;
1002 int value, freq, subscribed, cmd_len;
1003 struct cmd_ctrl_node *pcmdnode;
1004 struct cmd_ds_command *pcmdptr;
1005 struct cmd_ds_802_11_subscribe_event *event;
1006 struct mrvlietypes_beaconsmissed *bcnmiss;
1010 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1011 char *buf = (char *)addr;
1013 buf_size = min(count, len - 1);
1014 if (copy_from_user(buf, userbuf, buf_size)) {
1018 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
1024 event_bitmap = libertas_get_events_bitmap(priv);
1026 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1030 event = &pcmdptr->params.subscribe_event;
1031 event->action = cmd_act_set;
1032 pcmdptr->size = cpu_to_le16(S_DS_GEN +
1033 sizeof(struct cmd_ds_802_11_subscribe_event) +
1034 sizeof(struct mrvlietypes_beaconsmissed));
1035 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1036 ptr = (u8*) pcmdptr+cmd_len;
1037 bcnmiss = (struct mrvlietypes_beaconsmissed *)(ptr);
1038 bcnmiss->header.type = cpu_to_le16(TLV_TYPE_BCNMISS);
1039 bcnmiss->header.len = 2;
1040 bcnmiss->beaconmissed = cpu_to_le16(value);
1041 event_bitmap |= subscribed ? 0x0008 : 0x0;
1042 event->events = event_bitmap;
1044 libertas_queue_cmd(adapter, pcmdnode, 1);
1045 wake_up_interruptible(&priv->mainthread.waitq);
1047 /* Sleep until response is generated by FW */
1048 wait_event_interruptible(pcmdnode->cmdwait_q,
1049 pcmdnode->cmdwaitqwoken);
1051 pcmdptr = response_buf;
1053 if (pcmdptr->result) {
1054 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1056 kfree(response_buf);
1061 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1062 lbs_pr_err("command response incorrect!\n");
1064 kfree(response_buf);
1074 static ssize_t libertas_highrssi_read(struct file *file, char __user *userbuf,
1075 size_t count, loff_t *ppos)
1077 wlan_private *priv = file->private_data;
1078 wlan_adapter *adapter = priv->adapter;
1079 struct cmd_ctrl_node *pcmdnode;
1080 struct cmd_ds_command *pcmdptr;
1081 struct cmd_ds_802_11_subscribe_event *event;
1085 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1086 char *buf = (char *)addr;
1088 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1094 event = &pcmdptr->params.subscribe_event;
1095 event->action = cmd_act_get;
1097 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
1098 libertas_queue_cmd(adapter, pcmdnode, 1);
1099 wake_up_interruptible(&priv->mainthread.waitq);
1101 /* Sleep until response is generated by FW */
1102 wait_event_interruptible(pcmdnode->cmdwait_q,
1103 pcmdnode->cmdwaitqwoken);
1105 pcmdptr = response_buf;
1107 if (pcmdptr->result) {
1108 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1110 kfree(response_buf);
1115 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1116 lbs_pr_err("command response incorrect!\n");
1117 kfree(response_buf);
1122 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1123 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
1124 while (cmd_len < pcmdptr->size) {
1125 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
1126 switch(header->type) {
1127 struct mrvlietypes_rssithreshold *Highrssi;
1128 case TLV_TYPE_RSSI_HIGH:
1129 Highrssi = (struct mrvlietypes_rssithreshold *)(response_buf + cmd_len);
1130 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
1131 Highrssi->rssivalue,
1133 (event->events & 0x0010)?1:0);
1135 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
1140 kfree(response_buf);
1142 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1147 static ssize_t libertas_highrssi_write(struct file *file,
1148 const char __user *userbuf,
1149 size_t count, loff_t *ppos)
1151 wlan_private *priv = file->private_data;
1152 wlan_adapter *adapter = priv->adapter;
1153 ssize_t res, buf_size;
1154 int value, freq, subscribed, cmd_len;
1155 struct cmd_ctrl_node *pcmdnode;
1156 struct cmd_ds_command *pcmdptr;
1157 struct cmd_ds_802_11_subscribe_event *event;
1158 struct mrvlietypes_rssithreshold *rssi_threshold;
1162 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1163 char *buf = (char *)addr;
1165 buf_size = min(count, len - 1);
1166 if (copy_from_user(buf, userbuf, buf_size)) {
1170 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
1176 event_bitmap = libertas_get_events_bitmap(priv);
1178 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1182 event = &pcmdptr->params.subscribe_event;
1183 event->action = cmd_act_set;
1184 pcmdptr->size = cpu_to_le16(S_DS_GEN +
1185 sizeof(struct cmd_ds_802_11_subscribe_event) +
1186 sizeof(struct mrvlietypes_rssithreshold));
1187 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1188 ptr = (u8*) pcmdptr+cmd_len;
1189 rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
1190 rssi_threshold->header.type = cpu_to_le16(TLV_TYPE_RSSI_HIGH);
1191 rssi_threshold->header.len = 2;
1192 rssi_threshold->rssivalue = cpu_to_le16(value);
1193 rssi_threshold->rssifreq = cpu_to_le16(freq);
1194 event_bitmap |= subscribed ? 0x0010 : 0x0;
1195 event->events = event_bitmap;
1197 libertas_queue_cmd(adapter, pcmdnode, 1);
1198 wake_up_interruptible(&priv->mainthread.waitq);
1200 /* Sleep until response is generated by FW */
1201 wait_event_interruptible(pcmdnode->cmdwait_q,
1202 pcmdnode->cmdwaitqwoken);
1204 pcmdptr = response_buf;
1206 if (pcmdptr->result) {
1207 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1209 kfree(response_buf);
1213 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1214 lbs_pr_err("command response incorrect!\n");
1215 kfree(response_buf);
1225 static ssize_t libertas_highsnr_read(struct file *file, char __user *userbuf,
1226 size_t count, loff_t *ppos)
1228 wlan_private *priv = file->private_data;
1229 wlan_adapter *adapter = priv->adapter;
1230 struct cmd_ctrl_node *pcmdnode;
1231 struct cmd_ds_command *pcmdptr;
1232 struct cmd_ds_802_11_subscribe_event *event;
1236 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1237 char *buf = (char *)addr;
1239 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1245 event = &pcmdptr->params.subscribe_event;
1246 event->action = cmd_act_get;
1248 cpu_to_le16(sizeof(struct cmd_ds_802_11_subscribe_event) + S_DS_GEN);
1249 libertas_queue_cmd(adapter, pcmdnode, 1);
1250 wake_up_interruptible(&priv->mainthread.waitq);
1252 /* Sleep until response is generated by FW */
1253 wait_event_interruptible(pcmdnode->cmdwait_q,
1254 pcmdnode->cmdwaitqwoken);
1256 pcmdptr = response_buf;
1258 if (pcmdptr->result) {
1259 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1261 kfree(response_buf);
1266 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1267 lbs_pr_err("command response incorrect!\n");
1268 kfree(response_buf);
1273 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1274 event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
1275 while (cmd_len < pcmdptr->size) {
1276 struct mrvlietypesheader *header = (struct mrvlietypesheader *)(response_buf + cmd_len);
1277 switch(header->type) {
1278 struct mrvlietypes_snrthreshold *HighSnr;
1279 case TLV_TYPE_SNR_HIGH:
1280 HighSnr = (struct mrvlietypes_snrthreshold *)(response_buf + cmd_len);
1281 pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
1284 (event->events & 0x0020)?1:0);
1286 cmd_len += sizeof(struct mrvlietypes_snrthreshold);
1291 kfree(response_buf);
1293 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1298 static ssize_t libertas_highsnr_write(struct file *file,
1299 const char __user *userbuf,
1300 size_t count, loff_t *ppos)
1302 wlan_private *priv = file->private_data;
1303 wlan_adapter *adapter = priv->adapter;
1304 ssize_t res, buf_size;
1305 int value, freq, subscribed, cmd_len;
1306 struct cmd_ctrl_node *pcmdnode;
1307 struct cmd_ds_command *pcmdptr;
1308 struct cmd_ds_802_11_subscribe_event *event;
1309 struct mrvlietypes_snrthreshold *snr_threshold;
1313 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1314 char *buf = (char *)addr;
1316 buf_size = min(count, len - 1);
1317 if (copy_from_user(buf, userbuf, buf_size)) {
1321 res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
1327 event_bitmap = libertas_get_events_bitmap(priv);
1329 res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
1333 event = &pcmdptr->params.subscribe_event;
1334 event->action = cmd_act_set;
1335 pcmdptr->size = cpu_to_le16(S_DS_GEN +
1336 sizeof(struct cmd_ds_802_11_subscribe_event) +
1337 sizeof(struct mrvlietypes_snrthreshold));
1338 cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
1339 ptr = (u8*) pcmdptr+cmd_len;
1340 snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
1341 snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_HIGH);
1342 snr_threshold->header.len = 2;
1343 snr_threshold->snrvalue = cpu_to_le16(value);
1344 snr_threshold->snrfreq = cpu_to_le16(freq);
1345 event_bitmap |= subscribed ? 0x0020 : 0x0;
1346 event->events = event_bitmap;
1348 libertas_queue_cmd(adapter, pcmdnode, 1);
1349 wake_up_interruptible(&priv->mainthread.waitq);
1351 /* Sleep until response is generated by FW */
1352 wait_event_interruptible(pcmdnode->cmdwait_q,
1353 pcmdnode->cmdwaitqwoken);
1355 pcmdptr = response_buf;
1357 if (pcmdptr->result) {
1358 lbs_pr_err("%s: fail, result=%d\n", __FUNCTION__,
1360 kfree(response_buf);
1365 if (pcmdptr->command != cmd_ret_802_11_subscribe_event) {
1366 lbs_pr_err("command response incorrect!\n");
1367 kfree(response_buf);
1378 static ssize_t libertas_rdmac_read(struct file *file, char __user *userbuf,
1379 size_t count, loff_t *ppos)
1381 wlan_private *priv = file->private_data;
1382 wlan_adapter *adapter = priv->adapter;
1383 struct wlan_offset_value offval;
1386 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1387 char *buf = (char *)addr;
1389 offval.offset = priv->mac_offset;
1392 ret = libertas_prepare_and_send_command(priv,
1393 cmd_mac_reg_access, 0,
1394 cmd_option_waitforrsp, 0, &offval);
1396 pos += snprintf(buf+pos, len-pos, "MAC[0x%x] = 0x%08x\n",
1397 priv->mac_offset, adapter->offsetvalue.value);
1399 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1404 static ssize_t libertas_rdmac_write(struct file *file,
1405 const char __user *userbuf,
1406 size_t count, loff_t *ppos)
1408 wlan_private *priv = file->private_data;
1409 ssize_t res, buf_size;
1410 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1411 char *buf = (char *)addr;
1413 buf_size = min(count, len - 1);
1414 if (copy_from_user(buf, userbuf, buf_size)) {
1418 priv->mac_offset = simple_strtoul((char *)buf, NULL, 16);
1425 static ssize_t libertas_wrmac_write(struct file *file,
1426 const char __user *userbuf,
1427 size_t count, loff_t *ppos)
1430 wlan_private *priv = file->private_data;
1431 ssize_t res, buf_size;
1433 struct wlan_offset_value offval;
1434 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1435 char *buf = (char *)addr;
1437 buf_size = min(count, len - 1);
1438 if (copy_from_user(buf, userbuf, buf_size)) {
1442 res = sscanf(buf, "%x %x", &offset, &value);
1448 offval.offset = offset;
1449 offval.value = value;
1450 res = libertas_prepare_and_send_command(priv,
1451 cmd_mac_reg_access, 1,
1452 cmd_option_waitforrsp, 0, &offval);
1461 static ssize_t libertas_rdbbp_read(struct file *file, char __user *userbuf,
1462 size_t count, loff_t *ppos)
1464 wlan_private *priv = file->private_data;
1465 wlan_adapter *adapter = priv->adapter;
1466 struct wlan_offset_value offval;
1469 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1470 char *buf = (char *)addr;
1472 offval.offset = priv->bbp_offset;
1475 ret = libertas_prepare_and_send_command(priv,
1476 cmd_bbp_reg_access, 0,
1477 cmd_option_waitforrsp, 0, &offval);
1479 pos += snprintf(buf+pos, len-pos, "BBP[0x%x] = 0x%08x\n",
1480 priv->bbp_offset, adapter->offsetvalue.value);
1482 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1488 static ssize_t libertas_rdbbp_write(struct file *file,
1489 const char __user *userbuf,
1490 size_t count, loff_t *ppos)
1492 wlan_private *priv = file->private_data;
1493 ssize_t res, buf_size;
1494 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1495 char *buf = (char *)addr;
1497 buf_size = min(count, len - 1);
1498 if (copy_from_user(buf, userbuf, buf_size)) {
1502 priv->bbp_offset = simple_strtoul((char *)buf, NULL, 16);
1509 static ssize_t libertas_wrbbp_write(struct file *file,
1510 const char __user *userbuf,
1511 size_t count, loff_t *ppos)
1514 wlan_private *priv = file->private_data;
1515 ssize_t res, buf_size;
1517 struct wlan_offset_value offval;
1518 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1519 char *buf = (char *)addr;
1521 buf_size = min(count, len - 1);
1522 if (copy_from_user(buf, userbuf, buf_size)) {
1526 res = sscanf(buf, "%x %x", &offset, &value);
1532 offval.offset = offset;
1533 offval.value = value;
1534 res = libertas_prepare_and_send_command(priv,
1535 cmd_bbp_reg_access, 1,
1536 cmd_option_waitforrsp, 0, &offval);
1545 static ssize_t libertas_rdrf_read(struct file *file, char __user *userbuf,
1546 size_t count, loff_t *ppos)
1548 wlan_private *priv = file->private_data;
1549 wlan_adapter *adapter = priv->adapter;
1550 struct wlan_offset_value offval;
1553 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1554 char *buf = (char *)addr;
1556 offval.offset = priv->rf_offset;
1559 ret = libertas_prepare_and_send_command(priv,
1560 cmd_rf_reg_access, 0,
1561 cmd_option_waitforrsp, 0, &offval);
1563 pos += snprintf(buf+pos, len-pos, "RF[0x%x] = 0x%08x\n",
1564 priv->rf_offset, adapter->offsetvalue.value);
1566 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
1572 static ssize_t libertas_rdrf_write(struct file *file,
1573 const char __user *userbuf,
1574 size_t count, loff_t *ppos)
1576 wlan_private *priv = file->private_data;
1577 ssize_t res, buf_size;
1578 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1579 char *buf = (char *)addr;
1581 buf_size = min(count, len - 1);
1582 if (copy_from_user(buf, userbuf, buf_size)) {
1586 priv->rf_offset = simple_strtoul((char *)buf, NULL, 16);
1593 static ssize_t libertas_wrrf_write(struct file *file,
1594 const char __user *userbuf,
1595 size_t count, loff_t *ppos)
1598 wlan_private *priv = file->private_data;
1599 ssize_t res, buf_size;
1601 struct wlan_offset_value offval;
1602 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1603 char *buf = (char *)addr;
1605 buf_size = min(count, len - 1);
1606 if (copy_from_user(buf, userbuf, buf_size)) {
1610 res = sscanf(buf, "%x %x", &offset, &value);
1616 offval.offset = offset;
1617 offval.value = value;
1618 res = libertas_prepare_and_send_command(priv,
1619 cmd_rf_reg_access, 1,
1620 cmd_option_waitforrsp, 0, &offval);
1629 #define FOPS(fread, fwrite) { \
1630 .owner = THIS_MODULE, \
1631 .open = open_file_generic, \
1633 .write = (fwrite), \
1636 struct libertas_debugfs_files {
1639 struct file_operations fops;
1642 static struct libertas_debugfs_files debugfs_files[] = {
1643 { "info", 0444, FOPS(libertas_dev_info, write_file_dummy), },
1644 { "getscantable", 0444, FOPS(libertas_getscantable,
1645 write_file_dummy), },
1646 { "sleepparams", 0644, FOPS(libertas_sleepparams_read,
1647 libertas_sleepparams_write), },
1648 { "extscan", 0600, FOPS(NULL, libertas_extscan), },
1649 { "setuserscan", 0600, FOPS(NULL, libertas_setuserscan), },
1652 static struct libertas_debugfs_files debugfs_events_files[] = {
1653 {"low_rssi", 0644, FOPS(libertas_lowrssi_read,
1654 libertas_lowrssi_write), },
1655 {"low_snr", 0644, FOPS(libertas_lowsnr_read,
1656 libertas_lowsnr_write), },
1657 {"failure_count", 0644, FOPS(libertas_failcount_read,
1658 libertas_failcount_write), },
1659 {"beacon_missed", 0644, FOPS(libertas_bcnmiss_read,
1660 libertas_bcnmiss_write), },
1661 {"high_rssi", 0644, FOPS(libertas_highrssi_read,
1662 libertas_highrssi_write), },
1663 {"high_snr", 0644, FOPS(libertas_highsnr_read,
1664 libertas_highsnr_write), },
1667 static struct libertas_debugfs_files debugfs_regs_files[] = {
1668 {"rdmac", 0644, FOPS(libertas_rdmac_read, libertas_rdmac_write), },
1669 {"wrmac", 0600, FOPS(NULL, libertas_wrmac_write), },
1670 {"rdbbp", 0644, FOPS(libertas_rdbbp_read, libertas_rdbbp_write), },
1671 {"wrbbp", 0600, FOPS(NULL, libertas_wrbbp_write), },
1672 {"rdrf", 0644, FOPS(libertas_rdrf_read, libertas_rdrf_write), },
1673 {"wrrf", 0600, FOPS(NULL, libertas_wrrf_write), },
1676 void libertas_debugfs_init(void)
1679 libertas_dir = debugfs_create_dir("libertas_wireless", NULL);
1684 void libertas_debugfs_remove(void)
1687 debugfs_remove(libertas_dir);
1691 void libertas_debugfs_init_one(wlan_private *priv, struct net_device *dev)
1694 struct libertas_debugfs_files *files;
1698 priv->debugfs_dir = debugfs_create_dir(dev->name, libertas_dir);
1699 if (!priv->debugfs_dir)
1702 for (i=0; i<ARRAY_SIZE(debugfs_files); i++) {
1703 files = &debugfs_files[i];
1704 priv->debugfs_files[i] = debugfs_create_file(files->name,
1711 priv->events_dir = debugfs_create_dir("subscribed_events", priv->debugfs_dir);
1712 if (!priv->events_dir)
1715 for (i=0; i<ARRAY_SIZE(debugfs_events_files); i++) {
1716 files = &debugfs_events_files[i];
1717 priv->debugfs_events_files[i] = debugfs_create_file(files->name,
1724 priv->regs_dir = debugfs_create_dir("registers", priv->debugfs_dir);
1725 if (!priv->regs_dir)
1728 for (i=0; i<ARRAY_SIZE(debugfs_regs_files); i++) {
1729 files = &debugfs_regs_files[i];
1730 priv->debugfs_regs_files[i] = debugfs_create_file(files->name,
1738 libertas_debug_init(priv, dev);
1744 void libertas_debugfs_remove_one(wlan_private *priv)
1748 for(i=0; i<ARRAY_SIZE(debugfs_regs_files); i++)
1749 debugfs_remove(priv->debugfs_regs_files[i]);
1751 debugfs_remove(priv->regs_dir);
1753 for(i=0; i<ARRAY_SIZE(debugfs_events_files); i++)
1754 debugfs_remove(priv->debugfs_events_files[i]);
1756 debugfs_remove(priv->events_dir);
1758 debugfs_remove(priv->debugfs_debug);
1760 for(i=0; i<ARRAY_SIZE(debugfs_files); i++)
1761 debugfs_remove(priv->debugfs_files[i]);
1762 debugfs_remove(priv->debugfs_dir);
1771 #define item_size(n) (FIELD_SIZEOF(wlan_adapter, n))
1772 #define item_addr(n) (offsetof(wlan_adapter, n))
1781 /* To debug any member of wlan_adapter, simply add one line here.
1783 static struct debug_data items[] = {
1784 {"intcounter", item_size(intcounter), item_addr(intcounter)},
1785 {"psmode", item_size(psmode), item_addr(psmode)},
1786 {"psstate", item_size(psstate), item_addr(psstate)},
1789 static int num_of_items = ARRAY_SIZE(items);
1792 * @brief proc read function
1794 * @param page pointer to buffer
1795 * @param s read data starting position
1797 * @param cnt counter
1798 * @param eof end of file flag
1799 * @param data data to output
1800 * @return number of output data
1802 static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf,
1803 size_t count, loff_t *ppos)
1810 struct debug_data *d;
1811 unsigned long addr = get_zeroed_page(GFP_KERNEL);
1812 char *buf = (char *)addr;
1816 d = (struct debug_data *)file->private_data;
1818 for (i = 0; i < num_of_items; i++) {
1820 val = *((u8 *) d[i].addr);
1821 else if (d[i].size == 2)
1822 val = *((u16 *) d[i].addr);
1823 else if (d[i].size == 4)
1824 val = *((u32 *) d[i].addr);
1825 else if (d[i].size == 8)
1826 val = *((u64 *) d[i].addr);
1828 pos += sprintf(p + pos, "%s=%d\n", d[i].name, val);
1831 res = simple_read_from_buffer(userbuf, count, ppos, p, pos);
1838 * @brief proc write function
1840 * @param f file pointer
1841 * @param buf pointer to data buffer
1842 * @param cnt data number to write
1843 * @param data data to write
1844 * @return number of data
1846 static ssize_t wlan_debugfs_write(struct file *f, const char __user *buf,
1847 size_t cnt, loff_t *ppos)
1855 struct debug_data *d = (struct debug_data *)f->private_data;
1857 pdata = (char *)kmalloc(cnt, GFP_KERNEL);
1861 if (copy_from_user(pdata, buf, cnt)) {
1862 lbs_deb_debugfs("Copy from user failed\n");
1868 for (i = 0; i < num_of_items; i++) {
1870 p = strstr(p0, d[i].name);
1873 p1 = strchr(p, '\n');
1877 p2 = strchr(p, '=');
1881 r = simple_strtoul(p2, NULL, 0);
1883 *((u8 *) d[i].addr) = (u8) r;
1884 else if (d[i].size == 2)
1885 *((u16 *) d[i].addr) = (u16) r;
1886 else if (d[i].size == 4)
1887 *((u32 *) d[i].addr) = (u32) r;
1888 else if (d[i].size == 8)
1889 *((u64 *) d[i].addr) = (u64) r;
1895 return (ssize_t)cnt;
1898 static struct file_operations libertas_debug_fops = {
1899 .owner = THIS_MODULE,
1900 .open = open_file_generic,
1901 .write = wlan_debugfs_write,
1902 .read = wlan_debugfs_read,
1906 * @brief create debug proc file
1908 * @param priv pointer wlan_private
1909 * @param dev pointer net_device
1912 static void libertas_debug_init(wlan_private * priv, struct net_device *dev)
1916 if (!priv->debugfs_dir)
1919 for (i = 0; i < num_of_items; i++)
1920 items[i].addr += (size_t) priv->adapter;
1922 priv->debugfs_debug = debugfs_create_file("debug", 0644,
1923 priv->debugfs_dir, &items[0],
1924 &libertas_debug_fops);