Commit bfb24c9e authored by Juuso Oikarinen's avatar Juuso Oikarinen Committed by John W. Linville

wl1271: Add keep-alive frame template support

Add support for keep-alive templates, which are indexed.
Signed-off-by: default avatarJuuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: default avatarLuciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: default avatarLuciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent a9af092b
...@@ -698,7 +698,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, ...@@ -698,7 +698,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
} }
int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
void *buf, size_t buf_len) void *buf, size_t buf_len, int index)
{ {
struct wl1271_cmd_template_set *cmd; struct wl1271_cmd_template_set *cmd;
int ret = 0; int ret = 0;
...@@ -719,6 +719,7 @@ int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, ...@@ -719,6 +719,7 @@ int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
cmd->enabled_rates = cpu_to_le32(wl->conf.tx.rc_conf.enabled_rates); cmd->enabled_rates = cpu_to_le32(wl->conf.tx.rc_conf.enabled_rates);
cmd->short_retry_limit = wl->conf.tx.rc_conf.short_retry_limit; cmd->short_retry_limit = wl->conf.tx.rc_conf.short_retry_limit;
cmd->long_retry_limit = wl->conf.tx.rc_conf.long_retry_limit; cmd->long_retry_limit = wl->conf.tx.rc_conf.long_retry_limit;
cmd->index = index;
if (buf) if (buf)
memcpy(cmd->template_data, buf, buf_len); memcpy(cmd->template_data, buf, buf_len);
...@@ -755,7 +756,7 @@ int wl1271_cmd_build_null_data(struct wl1271 *wl) ...@@ -755,7 +756,7 @@ int wl1271_cmd_build_null_data(struct wl1271 *wl)
ptr = skb->data; ptr = skb->data;
} }
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size); ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0);
out: out:
dev_kfree_skb(skb); dev_kfree_skb(skb);
...@@ -766,6 +767,28 @@ int wl1271_cmd_build_null_data(struct wl1271 *wl) ...@@ -766,6 +767,28 @@ int wl1271_cmd_build_null_data(struct wl1271 *wl)
} }
int wl1271_cmd_build_klv_null_data(struct wl1271 *wl)
{
struct sk_buff *skb = NULL;
int ret = -ENOMEM;
skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
if (!skb)
goto out;
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV,
skb->data, skb->len,
CMD_TEMPL_KLV_IDX_NULL_DATA);
out:
dev_kfree_skb(skb);
if (ret)
wl1271_warning("cmd build klv null data failed %d", ret);
return ret;
}
int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid) int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid)
{ {
struct sk_buff *skb; struct sk_buff *skb;
...@@ -776,7 +799,7 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid) ...@@ -776,7 +799,7 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid)
goto out; goto out;
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, skb->data, ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, skb->data,
skb->len); skb->len, 0);
out: out:
dev_kfree_skb(skb); dev_kfree_skb(skb);
...@@ -801,10 +824,10 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl, ...@@ -801,10 +824,10 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl,
if (band == IEEE80211_BAND_2GHZ) if (band == IEEE80211_BAND_2GHZ)
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
skb->data, skb->len); skb->data, skb->len, 0);
else else
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
skb->data, skb->len); skb->data, skb->len, 0);
out: out:
dev_kfree_skb(skb); dev_kfree_skb(skb);
...@@ -829,7 +852,7 @@ int wl1271_build_qos_null_data(struct wl1271 *wl) ...@@ -829,7 +852,7 @@ int wl1271_build_qos_null_data(struct wl1271 *wl)
template.qos_ctrl = cpu_to_le16(0); template.qos_ctrl = cpu_to_le16(0);
return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template, return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template,
sizeof(template)); sizeof(template), 0);
} }
int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
......
...@@ -45,13 +45,14 @@ int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, ...@@ -45,13 +45,14 @@ int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
const u8 *ie, size_t ie_len, u8 active_scan, const u8 *ie, size_t ie_len, u8 active_scan,
u8 high_prio, u8 band, u8 probe_requests); u8 high_prio, u8 band, u8 probe_requests);
int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
void *buf, size_t buf_len); void *buf, size_t buf_len, int index);
int wl1271_cmd_build_null_data(struct wl1271 *wl); int wl1271_cmd_build_null_data(struct wl1271 *wl);
int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid); int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid);
int wl1271_cmd_build_probe_req(struct wl1271 *wl, int wl1271_cmd_build_probe_req(struct wl1271 *wl,
const u8 *ssid, size_t ssid_len, const u8 *ssid, size_t ssid_len,
const u8 *ie, size_t ie_len, u8 band); const u8 *ie, size_t ie_len, u8 band);
int wl1271_build_qos_null_data(struct wl1271 *wl); int wl1271_build_qos_null_data(struct wl1271 *wl);
int wl1271_cmd_build_klv_null_data(struct wl1271 *wl);
int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id); int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id);
int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
u8 key_size, const u8 *key, const u8 *addr, u8 key_size, const u8 *key, const u8 *addr,
...@@ -101,6 +102,11 @@ enum wl1271_commands { ...@@ -101,6 +102,11 @@ enum wl1271_commands {
#define MAX_CMD_PARAMS 572 #define MAX_CMD_PARAMS 572
enum {
CMD_TEMPL_KLV_IDX_NULL_DATA = 0,
CMD_TEMPL_KLV_IDX_MAX = 4
};
enum cmd_templ { enum cmd_templ {
CMD_TEMPL_NULL_DATA = 0, CMD_TEMPL_NULL_DATA = 0,
CMD_TEMPL_BEACON, CMD_TEMPL_BEACON,
......
...@@ -51,50 +51,63 @@ static int wl1271_init_hwenc_config(struct wl1271 *wl) ...@@ -51,50 +51,63 @@ static int wl1271_init_hwenc_config(struct wl1271 *wl)
int wl1271_init_templates_config(struct wl1271 *wl) int wl1271_init_templates_config(struct wl1271 *wl)
{ {
int ret; int ret, i;
/* send empty templates for fw memory reservation */ /* send empty templates for fw memory reservation */
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
sizeof(struct wl12xx_probe_req_template)); sizeof(struct wl12xx_probe_req_template),
0);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (wl1271_11a_enabled()) { if (wl1271_11a_enabled()) {
size_t size = sizeof(struct wl12xx_probe_req_template);
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
NULL, NULL, size, 0);
sizeof(struct wl12xx_probe_req_template));
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL, ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
sizeof(struct wl12xx_null_data_template)); sizeof(struct wl12xx_null_data_template),
0);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL, ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL,
sizeof(struct wl12xx_ps_poll_template)); sizeof(struct wl12xx_ps_poll_template),
0);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL, ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL,
sizeof sizeof
(struct wl12xx_qos_null_data_template)); (struct wl12xx_qos_null_data_template),
0);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL, ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL,
sizeof sizeof
(struct wl12xx_probe_resp_template)); (struct wl12xx_probe_resp_template),
0);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL, ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL,
sizeof sizeof
(struct wl12xx_beacon_template)); (struct wl12xx_beacon_template),
0);
if (ret < 0) if (ret < 0)
return ret; return ret;
for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL,
WL1271_CMD_TEMPL_MAX_SIZE, i);
if (ret < 0)
return ret;
}
return 0; return 0;
} }
......
...@@ -1596,7 +1596,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, ...@@ -1596,7 +1596,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
wl1271_ssid_set(wl, beacon); wl1271_ssid_set(wl, beacon);
ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON,
beacon->data, beacon->data,
beacon->len); beacon->len, 0);
if (ret < 0) { if (ret < 0) {
dev_kfree_skb(beacon); dev_kfree_skb(beacon);
...@@ -1611,7 +1611,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, ...@@ -1611,7 +1611,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
ret = wl1271_cmd_template_set(wl, ret = wl1271_cmd_template_set(wl,
CMD_TEMPL_PROBE_RESPONSE, CMD_TEMPL_PROBE_RESPONSE,
beacon->data, beacon->data,
beacon->len); beacon->len, 0);
dev_kfree_skb(beacon); dev_kfree_skb(beacon);
if (ret < 0) if (ret < 0)
goto out_sleep; goto out_sleep;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment