aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>2010-03-26 06:53:31 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-03-31 14:39:16 -0400
commitbfb24c9e16921f0e57fcec5180ffa20929832545 (patch)
treeefe695fedc1c879524ba3948bf65bb97b26cfdfa
parenta9af092b524614dd3fc7b52bde7c87f8b82cd2a6 (diff)
wl1271: Add keep-alive frame template support
Add support for keep-alive templates, which are indexed. Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com> Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com> Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.c35
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.h8
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_init.c31
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c4
4 files changed, 60 insertions, 18 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index 0dcb3c2afe07..0cb4cbb00395 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -698,7 +698,7 @@ out:
698} 698}
699 699
700int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, 700int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
701 void *buf, size_t buf_len) 701 void *buf, size_t buf_len, int index)
702{ 702{
703 struct wl1271_cmd_template_set *cmd; 703 struct wl1271_cmd_template_set *cmd;
704 int ret = 0; 704 int ret = 0;
@@ -719,6 +719,7 @@ int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
719 cmd->enabled_rates = cpu_to_le32(wl->conf.tx.rc_conf.enabled_rates); 719 cmd->enabled_rates = cpu_to_le32(wl->conf.tx.rc_conf.enabled_rates);
720 cmd->short_retry_limit = wl->conf.tx.rc_conf.short_retry_limit; 720 cmd->short_retry_limit = wl->conf.tx.rc_conf.short_retry_limit;
721 cmd->long_retry_limit = wl->conf.tx.rc_conf.long_retry_limit; 721 cmd->long_retry_limit = wl->conf.tx.rc_conf.long_retry_limit;
722 cmd->index = index;
722 723
723 if (buf) 724 if (buf)
724 memcpy(cmd->template_data, buf, buf_len); 725 memcpy(cmd->template_data, buf, buf_len);
@@ -755,7 +756,7 @@ int wl1271_cmd_build_null_data(struct wl1271 *wl)
755 ptr = skb->data; 756 ptr = skb->data;
756 } 757 }
757 758
758 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size); 759 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0);
759 760
760out: 761out:
761 dev_kfree_skb(skb); 762 dev_kfree_skb(skb);
@@ -766,6 +767,28 @@ out:
766 767
767} 768}
768 769
770int wl1271_cmd_build_klv_null_data(struct wl1271 *wl)
771{
772 struct sk_buff *skb = NULL;
773 int ret = -ENOMEM;
774
775 skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
776 if (!skb)
777 goto out;
778
779 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV,
780 skb->data, skb->len,
781 CMD_TEMPL_KLV_IDX_NULL_DATA);
782
783out:
784 dev_kfree_skb(skb);
785 if (ret)
786 wl1271_warning("cmd build klv null data failed %d", ret);
787
788 return ret;
789
790}
791
769int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid) 792int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid)
770{ 793{
771 struct sk_buff *skb; 794 struct sk_buff *skb;
@@ -776,7 +799,7 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid)
776 goto out; 799 goto out;
777 800
778 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, skb->data, 801 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, skb->data,
779 skb->len); 802 skb->len, 0);
780 803
781out: 804out:
782 dev_kfree_skb(skb); 805 dev_kfree_skb(skb);
@@ -801,10 +824,10 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl,
801 824
802 if (band == IEEE80211_BAND_2GHZ) 825 if (band == IEEE80211_BAND_2GHZ)
803 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, 826 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
804 skb->data, skb->len); 827 skb->data, skb->len, 0);
805 else 828 else
806 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, 829 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
807 skb->data, skb->len); 830 skb->data, skb->len, 0);
808 831
809out: 832out:
810 dev_kfree_skb(skb); 833 dev_kfree_skb(skb);
@@ -829,7 +852,7 @@ int wl1271_build_qos_null_data(struct wl1271 *wl)
829 template.qos_ctrl = cpu_to_le16(0); 852 template.qos_ctrl = cpu_to_le16(0);
830 853
831 return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template, 854 return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template,
832 sizeof(template)); 855 sizeof(template), 0);
833} 856}
834 857
835int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) 858int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h
index bdd7a3d8ece6..e1131bc0d15c 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.h
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h
@@ -45,13 +45,14 @@ int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
45 const u8 *ie, size_t ie_len, u8 active_scan, 45 const u8 *ie, size_t ie_len, u8 active_scan,
46 u8 high_prio, u8 band, u8 probe_requests); 46 u8 high_prio, u8 band, u8 probe_requests);
47int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, 47int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
48 void *buf, size_t buf_len); 48 void *buf, size_t buf_len, int index);
49int wl1271_cmd_build_null_data(struct wl1271 *wl); 49int wl1271_cmd_build_null_data(struct wl1271 *wl);
50int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid); 50int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid);
51int wl1271_cmd_build_probe_req(struct wl1271 *wl, 51int wl1271_cmd_build_probe_req(struct wl1271 *wl,
52 const u8 *ssid, size_t ssid_len, 52 const u8 *ssid, size_t ssid_len,
53 const u8 *ie, size_t ie_len, u8 band); 53 const u8 *ie, size_t ie_len, u8 band);
54int wl1271_build_qos_null_data(struct wl1271 *wl); 54int wl1271_build_qos_null_data(struct wl1271 *wl);
55int wl1271_cmd_build_klv_null_data(struct wl1271 *wl);
55int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id); 56int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id);
56int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, 57int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
57 u8 key_size, const u8 *key, const u8 *addr, 58 u8 key_size, const u8 *key, const u8 *addr,
@@ -101,6 +102,11 @@ enum wl1271_commands {
101 102
102#define MAX_CMD_PARAMS 572 103#define MAX_CMD_PARAMS 572
103 104
105enum {
106 CMD_TEMPL_KLV_IDX_NULL_DATA = 0,
107 CMD_TEMPL_KLV_IDX_MAX = 4
108};
109
104enum cmd_templ { 110enum cmd_templ {
105 CMD_TEMPL_NULL_DATA = 0, 111 CMD_TEMPL_NULL_DATA = 0,
106 CMD_TEMPL_BEACON, 112 CMD_TEMPL_BEACON,
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c
index 987978c3bce0..0106663bc45b 100644
--- a/drivers/net/wireless/wl12xx/wl1271_init.c
+++ b/drivers/net/wireless/wl12xx/wl1271_init.c
@@ -51,50 +51,63 @@ static int wl1271_init_hwenc_config(struct wl1271 *wl)
51 51
52int wl1271_init_templates_config(struct wl1271 *wl) 52int wl1271_init_templates_config(struct wl1271 *wl)
53{ 53{
54 int ret; 54 int ret, i;
55 55
56 /* send empty templates for fw memory reservation */ 56 /* send empty templates for fw memory reservation */
57 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, 57 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
58 sizeof(struct wl12xx_probe_req_template)); 58 sizeof(struct wl12xx_probe_req_template),
59 0);
59 if (ret < 0) 60 if (ret < 0)
60 return ret; 61 return ret;
61 62
62 if (wl1271_11a_enabled()) { 63 if (wl1271_11a_enabled()) {
64 size_t size = sizeof(struct wl12xx_probe_req_template);
63 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, 65 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
64 NULL, 66 NULL, size, 0);
65 sizeof(struct wl12xx_probe_req_template));
66 if (ret < 0) 67 if (ret < 0)
67 return ret; 68 return ret;
68 } 69 }
69 70
70 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL, 71 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
71 sizeof(struct wl12xx_null_data_template)); 72 sizeof(struct wl12xx_null_data_template),
73 0);
72 if (ret < 0) 74 if (ret < 0)
73 return ret; 75 return ret;
74 76
75 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL, 77 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL,
76 sizeof(struct wl12xx_ps_poll_template)); 78 sizeof(struct wl12xx_ps_poll_template),
79 0);
77 if (ret < 0) 80 if (ret < 0)
78 return ret; 81 return ret;
79 82
80 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL, 83 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL,
81 sizeof 84 sizeof
82 (struct wl12xx_qos_null_data_template)); 85 (struct wl12xx_qos_null_data_template),
86 0);
83 if (ret < 0) 87 if (ret < 0)
84 return ret; 88 return ret;
85 89
86 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL, 90 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL,
87 sizeof 91 sizeof
88 (struct wl12xx_probe_resp_template)); 92 (struct wl12xx_probe_resp_template),
93 0);
89 if (ret < 0) 94 if (ret < 0)
90 return ret; 95 return ret;
91 96
92 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL, 97 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL,
93 sizeof 98 sizeof
94 (struct wl12xx_beacon_template)); 99 (struct wl12xx_beacon_template),
100 0);
95 if (ret < 0) 101 if (ret < 0)
96 return ret; 102 return ret;
97 103
104 for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
105 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL,
106 WL1271_CMD_TEMPL_MAX_SIZE, i);
107 if (ret < 0)
108 return ret;
109 }
110
98 return 0; 111 return 0;
99} 112}
100 113
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 2df00adcf903..afab52bec134 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -1596,7 +1596,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1596 wl1271_ssid_set(wl, beacon); 1596 wl1271_ssid_set(wl, beacon);
1597 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, 1597 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON,
1598 beacon->data, 1598 beacon->data,
1599 beacon->len); 1599 beacon->len, 0);
1600 1600
1601 if (ret < 0) { 1601 if (ret < 0) {
1602 dev_kfree_skb(beacon); 1602 dev_kfree_skb(beacon);
@@ -1611,7 +1611,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1611 ret = wl1271_cmd_template_set(wl, 1611 ret = wl1271_cmd_template_set(wl,
1612 CMD_TEMPL_PROBE_RESPONSE, 1612 CMD_TEMPL_PROBE_RESPONSE,
1613 beacon->data, 1613 beacon->data,
1614 beacon->len); 1614 beacon->len, 0);
1615 dev_kfree_skb(beacon); 1615 dev_kfree_skb(beacon);
1616 if (ret < 0) 1616 if (ret < 0)
1617 goto out_sleep; 1617 goto out_sleep;