diff options
author | Juuso Oikarinen <juuso.oikarinen@nokia.com> | 2010-03-26 06:53:31 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-03-31 14:39:16 -0400 |
commit | bfb24c9e16921f0e57fcec5180ffa20929832545 (patch) | |
tree | efe695fedc1c879524ba3948bf65bb97b26cfdfa | |
parent | a9af092b524614dd3fc7b52bde7c87f8b82cd2a6 (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.c | 35 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_cmd.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_init.c | 31 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_main.c | 4 |
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 | ||
700 | int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, | 700 | int 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 | ||
760 | out: | 761 | out: |
761 | dev_kfree_skb(skb); | 762 | dev_kfree_skb(skb); |
@@ -766,6 +767,28 @@ out: | |||
766 | 767 | ||
767 | } | 768 | } |
768 | 769 | ||
770 | int 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 | |||
783 | out: | ||
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 | |||
769 | int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid) | 792 | int 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 | ||
781 | out: | 804 | out: |
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 | ||
809 | out: | 832 | out: |
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 | ||
835 | int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) | 858 | int 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); |
47 | int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, | 47 | int 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); |
49 | int wl1271_cmd_build_null_data(struct wl1271 *wl); | 49 | int wl1271_cmd_build_null_data(struct wl1271 *wl); |
50 | int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid); | 50 | int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid); |
51 | int wl1271_cmd_build_probe_req(struct wl1271 *wl, | 51 | int 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); |
54 | int wl1271_build_qos_null_data(struct wl1271 *wl); | 54 | int wl1271_build_qos_null_data(struct wl1271 *wl); |
55 | int wl1271_cmd_build_klv_null_data(struct wl1271 *wl); | ||
55 | int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id); | 56 | int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id); |
56 | int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, | 57 | int 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 | ||
105 | enum { | ||
106 | CMD_TEMPL_KLV_IDX_NULL_DATA = 0, | ||
107 | CMD_TEMPL_KLV_IDX_MAX = 4 | ||
108 | }; | ||
109 | |||
104 | enum cmd_templ { | 110 | enum 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 | ||
52 | int wl1271_init_templates_config(struct wl1271 *wl) | 52 | int 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; |