aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2010-07-27 16:01:07 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-07-27 15:10:52 -0400
commit4c7c6e00f17365633638848197c44552dd353d49 (patch)
tree48f658ed2c2e342dff25d65a0961b70d1939ca58 /drivers/net/wireless/libertas
parent85dfbfed34bd6372daf4934256ca7f3b251c2016 (diff)
libertas: convert register access to direct commands
Signed-off-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas')
-rw-r--r--drivers/net/wireless/libertas/cmd.c130
-rw-r--r--drivers/net/wireless/libertas/cmd.h4
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c48
-rw-r--r--drivers/net/wireless/libertas/debugfs.c67
-rw-r--r--drivers/net/wireless/libertas/dev.h1
-rw-r--r--drivers/net/wireless/libertas/host.h24
6 files changed, 94 insertions, 180 deletions
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index a09ee6b0a552..b8df1fd89240 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -848,78 +848,86 @@ int lbs_set_11d_domain_info(struct lbs_private *priv,
848 return ret; 848 return ret;
849} 849}
850 850
851static int lbs_cmd_reg_access(struct cmd_ds_command *cmdptr, 851/**
852 u8 cmd_action, void *pdata_buf) 852 * @brief Read a MAC, Baseband, or RF register
853 *
854 * @param priv pointer to struct lbs_private
855 * @param cmd register command, one of CMD_MAC_REG_ACCESS,
856 * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
857 * @param offset byte offset of the register to get
858 * @param value on success, the value of the register at 'offset'
859 *
860 * @return 0 on success, error code on failure
861*/
862int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value)
853{ 863{
854 struct lbs_offset_value *offval; 864 struct cmd_ds_reg_access cmd;
865 int ret = 0;
855 866
856 lbs_deb_enter(LBS_DEB_CMD); 867 lbs_deb_enter(LBS_DEB_CMD);
857 868
858 offval = (struct lbs_offset_value *)pdata_buf; 869 BUG_ON(value == NULL);
859
860 switch (le16_to_cpu(cmdptr->command)) {
861 case CMD_MAC_REG_ACCESS:
862 {
863 struct cmd_ds_mac_reg_access *macreg;
864
865 cmdptr->size =
866 cpu_to_le16(sizeof (struct cmd_ds_mac_reg_access)
867 + sizeof(struct cmd_header));
868 macreg =
869 (struct cmd_ds_mac_reg_access *)&cmdptr->params.
870 macreg;
871
872 macreg->action = cpu_to_le16(cmd_action);
873 macreg->offset = cpu_to_le16((u16) offval->offset);
874 macreg->value = cpu_to_le32(offval->value);
875
876 break;
877 }
878
879 case CMD_BBP_REG_ACCESS:
880 {
881 struct cmd_ds_bbp_reg_access *bbpreg;
882 870
883 cmdptr->size = 871 memset(&cmd, 0, sizeof(cmd));
884 cpu_to_le16(sizeof 872 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
885 (struct cmd_ds_bbp_reg_access) 873 cmd.action = cpu_to_le16(CMD_ACT_GET);
886 + sizeof(struct cmd_header));
887 bbpreg =
888 (struct cmd_ds_bbp_reg_access *)&cmdptr->params.
889 bbpreg;
890 874
891 bbpreg->action = cpu_to_le16(cmd_action); 875 if (reg != CMD_MAC_REG_ACCESS &&
892 bbpreg->offset = cpu_to_le16((u16) offval->offset); 876 reg != CMD_BBP_REG_ACCESS &&
893 bbpreg->value = (u8) offval->value; 877 reg != CMD_RF_REG_ACCESS) {
878 ret = -EINVAL;
879 goto out;
880 }
894 881
895 break; 882 ret = lbs_cmd_with_response(priv, reg, &cmd);
896 } 883 if (ret) {
884 if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS)
885 *value = cmd.value.bbp_rf;
886 else if (reg == CMD_MAC_REG_ACCESS)
887 *value = le32_to_cpu(cmd.value.mac);
888 }
897 889
898 case CMD_RF_REG_ACCESS: 890out:
899 { 891 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
900 struct cmd_ds_rf_reg_access *rfreg; 892 return ret;
893}
901 894
902 cmdptr->size = 895/**
903 cpu_to_le16(sizeof 896 * @brief Write a MAC, Baseband, or RF register
904 (struct cmd_ds_rf_reg_access) + 897 *
905 sizeof(struct cmd_header)); 898 * @param priv pointer to struct lbs_private
906 rfreg = 899 * @param cmd register command, one of CMD_MAC_REG_ACCESS,
907 (struct cmd_ds_rf_reg_access *)&cmdptr->params. 900 * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
908 rfreg; 901 * @param offset byte offset of the register to set
902 * @param value the value to write to the register at 'offset'
903 *
904 * @return 0 on success, error code on failure
905*/
906int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value)
907{
908 struct cmd_ds_reg_access cmd;
909 int ret = 0;
909 910
910 rfreg->action = cpu_to_le16(cmd_action); 911 lbs_deb_enter(LBS_DEB_CMD);
911 rfreg->offset = cpu_to_le16((u16) offval->offset);
912 rfreg->value = (u8) offval->value;
913 912
914 break; 913 memset(&cmd, 0, sizeof(cmd));
915 } 914 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
915 cmd.action = cpu_to_le16(CMD_ACT_SET);
916 916
917 default: 917 if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS)
918 break; 918 cmd.value.bbp_rf = (u8) (value & 0xFF);
919 else if (reg == CMD_MAC_REG_ACCESS)
920 cmd.value.mac = cpu_to_le32(value);
921 else {
922 ret = -EINVAL;
923 goto out;
919 } 924 }
920 925
921 lbs_deb_leave(LBS_DEB_CMD); 926 ret = lbs_cmd_with_response(priv, reg, &cmd);
922 return 0; 927
928out:
929 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
930 return ret;
923} 931}
924 932
925static void lbs_queue_cmd(struct lbs_private *priv, 933static void lbs_queue_cmd(struct lbs_private *priv,
@@ -1198,12 +1206,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1198 ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action); 1206 ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action);
1199 break; 1207 break;
1200 1208
1201 case CMD_MAC_REG_ACCESS:
1202 case CMD_BBP_REG_ACCESS:
1203 case CMD_RF_REG_ACCESS:
1204 ret = lbs_cmd_reg_access(cmdptr, cmd_action, pdata_buf);
1205 break;
1206
1207#ifdef CONFIG_LIBERTAS_MESH 1209#ifdef CONFIG_LIBERTAS_MESH
1208 1210
1209 case CMD_BT_ACCESS: 1211 case CMD_BT_ACCESS:
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
index 2c24c1978e82..bfb36904fd9f 100644
--- a/drivers/net/wireless/libertas/cmd.h
+++ b/drivers/net/wireless/libertas/cmd.h
@@ -139,4 +139,8 @@ int lbs_set_11d_domain_info(struct lbs_private *priv,
139 struct regulatory_request *request, 139 struct regulatory_request *request,
140 struct ieee80211_supported_band **bands); 140 struct ieee80211_supported_band **bands);
141 141
142int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value);
143
144int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value);
145
142#endif /* _LBS_CMD_H */ 146#endif /* _LBS_CMD_H */
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index 6196e54125c6..810d75882e79 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -54,48 +54,6 @@ void lbs_mac_event_disconnected(struct lbs_private *priv)
54 lbs_deb_leave(LBS_DEB_ASSOC); 54 lbs_deb_leave(LBS_DEB_ASSOC);
55} 55}
56 56
57static int lbs_ret_reg_access(struct lbs_private *priv,
58 u16 type, struct cmd_ds_command *resp)
59{
60 int ret = 0;
61
62 lbs_deb_enter(LBS_DEB_CMD);
63
64 switch (type) {
65 case CMD_RET(CMD_MAC_REG_ACCESS):
66 {
67 struct cmd_ds_mac_reg_access *reg = &resp->params.macreg;
68
69 priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
70 priv->offsetvalue.value = le32_to_cpu(reg->value);
71 break;
72 }
73
74 case CMD_RET(CMD_BBP_REG_ACCESS):
75 {
76 struct cmd_ds_bbp_reg_access *reg = &resp->params.bbpreg;
77
78 priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
79 priv->offsetvalue.value = reg->value;
80 break;
81 }
82
83 case CMD_RET(CMD_RF_REG_ACCESS):
84 {
85 struct cmd_ds_rf_reg_access *reg = &resp->params.rfreg;
86
87 priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
88 priv->offsetvalue.value = reg->value;
89 break;
90 }
91
92 default:
93 ret = -1;
94 }
95
96 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
97 return ret;
98}
99static inline int handle_cmd_response(struct lbs_private *priv, 57static inline int handle_cmd_response(struct lbs_private *priv,
100 struct cmd_header *cmd_response) 58 struct cmd_header *cmd_response)
101{ 59{
@@ -107,12 +65,6 @@ static inline int handle_cmd_response(struct lbs_private *priv,
107 lbs_deb_enter(LBS_DEB_HOST); 65 lbs_deb_enter(LBS_DEB_HOST);
108 66
109 switch (respcmd) { 67 switch (respcmd) {
110 case CMD_RET(CMD_MAC_REG_ACCESS):
111 case CMD_RET(CMD_BBP_REG_ACCESS):
112 case CMD_RET(CMD_RF_REG_ACCESS):
113 ret = lbs_ret_reg_access(priv, respcmd, resp);
114 break;
115
116 case CMD_RET(CMD_802_11_BEACON_STOP): 68 case CMD_RET(CMD_802_11_BEACON_STOP):
117 break; 69 break;
118 70
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index 3db621b18a2f..651a79c8de8a 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -446,30 +446,24 @@ static ssize_t lbs_bcnmiss_write(struct file *file, const char __user *userbuf,
446} 446}
447 447
448 448
449
450static ssize_t lbs_rdmac_read(struct file *file, char __user *userbuf, 449static ssize_t lbs_rdmac_read(struct file *file, char __user *userbuf,
451 size_t count, loff_t *ppos) 450 size_t count, loff_t *ppos)
452{ 451{
453 struct lbs_private *priv = file->private_data; 452 struct lbs_private *priv = file->private_data;
454 struct lbs_offset_value offval;
455 ssize_t pos = 0; 453 ssize_t pos = 0;
456 int ret; 454 int ret;
457 unsigned long addr = get_zeroed_page(GFP_KERNEL); 455 unsigned long addr = get_zeroed_page(GFP_KERNEL);
458 char *buf = (char *)addr; 456 char *buf = (char *)addr;
457 u32 val = 0;
458
459 if (!buf) 459 if (!buf)
460 return -ENOMEM; 460 return -ENOMEM;
461 461
462 offval.offset = priv->mac_offset; 462 ret = lbs_get_reg(priv, CMD_MAC_REG_ACCESS, priv->mac_offset, &val);
463 offval.value = 0;
464
465 ret = lbs_prepare_and_send_command(priv,
466 CMD_MAC_REG_ACCESS, 0,
467 CMD_OPTION_WAITFORRSP, 0, &offval);
468 mdelay(10); 463 mdelay(10);
469 if (!ret) { 464 if (!ret) {
470 pos += snprintf(buf+pos, len-pos, "MAC[0x%x] = 0x%08x\n", 465 pos = snprintf(buf, len, "MAC[0x%x] = 0x%08x\n",
471 priv->mac_offset, priv->offsetvalue.value); 466 priv->mac_offset, val);
472
473 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 467 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
474 } 468 }
475 free_page(addr); 469 free_page(addr);
@@ -507,7 +501,6 @@ static ssize_t lbs_wrmac_write(struct file *file,
507 struct lbs_private *priv = file->private_data; 501 struct lbs_private *priv = file->private_data;
508 ssize_t res, buf_size; 502 ssize_t res, buf_size;
509 u32 offset, value; 503 u32 offset, value;
510 struct lbs_offset_value offval;
511 unsigned long addr = get_zeroed_page(GFP_KERNEL); 504 unsigned long addr = get_zeroed_page(GFP_KERNEL);
512 char *buf = (char *)addr; 505 char *buf = (char *)addr;
513 if (!buf) 506 if (!buf)
@@ -524,11 +517,7 @@ static ssize_t lbs_wrmac_write(struct file *file,
524 goto out_unlock; 517 goto out_unlock;
525 } 518 }
526 519
527 offval.offset = offset; 520 res = lbs_set_reg(priv, CMD_MAC_REG_ACCESS, offset, value);
528 offval.value = value;
529 res = lbs_prepare_and_send_command(priv,
530 CMD_MAC_REG_ACCESS, 1,
531 CMD_OPTION_WAITFORRSP, 0, &offval);
532 mdelay(10); 521 mdelay(10);
533 522
534 if (!res) 523 if (!res)
@@ -542,25 +531,20 @@ static ssize_t lbs_rdbbp_read(struct file *file, char __user *userbuf,
542 size_t count, loff_t *ppos) 531 size_t count, loff_t *ppos)
543{ 532{
544 struct lbs_private *priv = file->private_data; 533 struct lbs_private *priv = file->private_data;
545 struct lbs_offset_value offval;
546 ssize_t pos = 0; 534 ssize_t pos = 0;
547 int ret; 535 int ret;
548 unsigned long addr = get_zeroed_page(GFP_KERNEL); 536 unsigned long addr = get_zeroed_page(GFP_KERNEL);
549 char *buf = (char *)addr; 537 char *buf = (char *)addr;
538 u32 val;
539
550 if (!buf) 540 if (!buf)
551 return -ENOMEM; 541 return -ENOMEM;
552 542
553 offval.offset = priv->bbp_offset; 543 ret = lbs_get_reg(priv, CMD_BBP_REG_ACCESS, priv->bbp_offset, &val);
554 offval.value = 0;
555
556 ret = lbs_prepare_and_send_command(priv,
557 CMD_BBP_REG_ACCESS, 0,
558 CMD_OPTION_WAITFORRSP, 0, &offval);
559 mdelay(10); 544 mdelay(10);
560 if (!ret) { 545 if (!ret) {
561 pos += snprintf(buf+pos, len-pos, "BBP[0x%x] = 0x%08x\n", 546 pos = snprintf(buf, len, "BBP[0x%x] = 0x%08x\n",
562 priv->bbp_offset, priv->offsetvalue.value); 547 priv->bbp_offset, val);
563
564 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 548 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
565 } 549 }
566 free_page(addr); 550 free_page(addr);
@@ -599,7 +583,6 @@ static ssize_t lbs_wrbbp_write(struct file *file,
599 struct lbs_private *priv = file->private_data; 583 struct lbs_private *priv = file->private_data;
600 ssize_t res, buf_size; 584 ssize_t res, buf_size;
601 u32 offset, value; 585 u32 offset, value;
602 struct lbs_offset_value offval;
603 unsigned long addr = get_zeroed_page(GFP_KERNEL); 586 unsigned long addr = get_zeroed_page(GFP_KERNEL);
604 char *buf = (char *)addr; 587 char *buf = (char *)addr;
605 if (!buf) 588 if (!buf)
@@ -616,11 +599,7 @@ static ssize_t lbs_wrbbp_write(struct file *file,
616 goto out_unlock; 599 goto out_unlock;
617 } 600 }
618 601
619 offval.offset = offset; 602 res = lbs_set_reg(priv, CMD_BBP_REG_ACCESS, offset, value);
620 offval.value = value;
621 res = lbs_prepare_and_send_command(priv,
622 CMD_BBP_REG_ACCESS, 1,
623 CMD_OPTION_WAITFORRSP, 0, &offval);
624 mdelay(10); 603 mdelay(10);
625 604
626 if (!res) 605 if (!res)
@@ -634,25 +613,20 @@ static ssize_t lbs_rdrf_read(struct file *file, char __user *userbuf,
634 size_t count, loff_t *ppos) 613 size_t count, loff_t *ppos)
635{ 614{
636 struct lbs_private *priv = file->private_data; 615 struct lbs_private *priv = file->private_data;
637 struct lbs_offset_value offval;
638 ssize_t pos = 0; 616 ssize_t pos = 0;
639 int ret; 617 int ret;
640 unsigned long addr = get_zeroed_page(GFP_KERNEL); 618 unsigned long addr = get_zeroed_page(GFP_KERNEL);
641 char *buf = (char *)addr; 619 char *buf = (char *)addr;
620 u32 val;
621
642 if (!buf) 622 if (!buf)
643 return -ENOMEM; 623 return -ENOMEM;
644 624
645 offval.offset = priv->rf_offset; 625 ret = lbs_get_reg(priv, CMD_RF_REG_ACCESS, priv->rf_offset, &val);
646 offval.value = 0;
647
648 ret = lbs_prepare_and_send_command(priv,
649 CMD_RF_REG_ACCESS, 0,
650 CMD_OPTION_WAITFORRSP, 0, &offval);
651 mdelay(10); 626 mdelay(10);
652 if (!ret) { 627 if (!ret) {
653 pos += snprintf(buf+pos, len-pos, "RF[0x%x] = 0x%08x\n", 628 pos = snprintf(buf, len, "RF[0x%x] = 0x%08x\n",
654 priv->rf_offset, priv->offsetvalue.value); 629 priv->rf_offset, val);
655
656 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 630 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
657 } 631 }
658 free_page(addr); 632 free_page(addr);
@@ -691,7 +665,6 @@ static ssize_t lbs_wrrf_write(struct file *file,
691 struct lbs_private *priv = file->private_data; 665 struct lbs_private *priv = file->private_data;
692 ssize_t res, buf_size; 666 ssize_t res, buf_size;
693 u32 offset, value; 667 u32 offset, value;
694 struct lbs_offset_value offval;
695 unsigned long addr = get_zeroed_page(GFP_KERNEL); 668 unsigned long addr = get_zeroed_page(GFP_KERNEL);
696 char *buf = (char *)addr; 669 char *buf = (char *)addr;
697 if (!buf) 670 if (!buf)
@@ -708,11 +681,7 @@ static ssize_t lbs_wrrf_write(struct file *file,
708 goto out_unlock; 681 goto out_unlock;
709 } 682 }
710 683
711 offval.offset = offset; 684 res = lbs_set_reg(priv, CMD_RF_REG_ACCESS, offset, value);
712 offval.value = value;
713 res = lbs_prepare_and_send_command(priv,
714 CMD_RF_REG_ACCESS, 1,
715 CMD_OPTION_WAITFORRSP, 0, &offval);
716 mdelay(10); 685 mdelay(10);
717 686
718 if (!res) 687 if (!res)
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index be263acf19c4..556a9c33a4a6 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -64,7 +64,6 @@ struct lbs_private {
64 u32 mac_offset; 64 u32 mac_offset;
65 u32 bbp_offset; 65 u32 bbp_offset;
66 u32 rf_offset; 66 u32 rf_offset;
67 struct lbs_offset_value offsetvalue;
68 67
69 /* Power management */ 68 /* Power management */
70 u16 psmode; 69 u16 psmode;
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index d0402aa3f30a..0a4ddc1cdd6c 100644
--- a/drivers/net/wireless/libertas/host.h
+++ b/drivers/net/wireless/libertas/host.h
@@ -567,24 +567,15 @@ struct cmd_ds_802_11_snmp_mib {
567 u8 value[128]; 567 u8 value[128];
568} __packed; 568} __packed;
569 569
570struct cmd_ds_mac_reg_access { 570struct cmd_ds_reg_access {
571 __le16 action; 571 struct cmd_header hdr;
572 __le16 offset;
573 __le32 value;
574} __packed;
575
576struct cmd_ds_bbp_reg_access {
577 __le16 action;
578 __le16 offset;
579 u8 value;
580 u8 reserved[3];
581} __packed;
582 572
583struct cmd_ds_rf_reg_access {
584 __le16 action; 573 __le16 action;
585 __le16 offset; 574 __le16 offset;
586 u8 value; 575 union {
587 u8 reserved[3]; 576 u8 bbp_rf; /* for BBP and RF registers */
577 __le32 mac; /* for MAC registers */
578 } value;
588} __packed; 579} __packed;
589 580
590struct cmd_ds_802_11_radio_control { 581struct cmd_ds_802_11_radio_control {
@@ -968,9 +959,6 @@ struct cmd_ds_command {
968 /* command Body */ 959 /* command Body */
969 union { 960 union {
970 struct cmd_ds_802_11_ps_mode psmode; 961 struct cmd_ds_802_11_ps_mode psmode;
971 struct cmd_ds_mac_reg_access macreg;
972 struct cmd_ds_bbp_reg_access bbpreg;
973 struct cmd_ds_rf_reg_access rfreg;
974 struct cmd_ds_bt_access bt; 962 struct cmd_ds_bt_access bt;
975 struct cmd_ds_fwt_access fwt; 963 struct cmd_ds_fwt_access fwt;
976 } params; 964 } params;