if (ret < 0)
return ret;
- for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
+ for (i = 0; i < WLCORE_MAX_KLV_TEMPLATES; i++) {
ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
CMD_TEMPL_KLV, NULL,
sizeof(struct ieee80211_qos_hdr),
struct ieee80211_vif *vif)
{
struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
- int ret, i;
-
- /* disable all keep-alive templates */
- for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
- ret = wl1271_acx_keep_alive_config(wl, wlvif, i,
- ACX_KEEP_ALIVE_TPL_INVALID);
- if (ret < 0)
- return ret;
- }
+ int ret;
/* disable the keep-alive feature */
ret = wl1271_acx_keep_alive_mode(wl, wlvif, false);
*idx = WL12XX_MAX_RATE_POLICIES;
}
+static int wlcore_allocate_klv_template(struct wl1271 *wl, u8 *idx)
+{
+ u8 policy = find_first_zero_bit(wl->klv_templates_map,
+ WLCORE_MAX_KLV_TEMPLATES);
+ if (policy >= WLCORE_MAX_KLV_TEMPLATES)
+ return -EBUSY;
+
+ __set_bit(policy, wl->klv_templates_map);
+ *idx = policy;
+ return 0;
+}
+
+static void wlcore_free_klv_template(struct wl1271 *wl, u8 *idx)
+{
+ if (WARN_ON(*idx >= WLCORE_MAX_KLV_TEMPLATES))
+ return;
+
+ __clear_bit(*idx, wl->klv_templates_map);
+ *idx = WLCORE_MAX_KLV_TEMPLATES;
+}
+
static u8 wl12xx_get_role_type(struct wl1271 *wl, struct wl12xx_vif *wlvif)
{
switch (wlvif->bss_type) {
wl12xx_allocate_rate_policy(wl, &wlvif->sta.basic_rate_idx);
wl12xx_allocate_rate_policy(wl, &wlvif->sta.ap_rate_idx);
wl12xx_allocate_rate_policy(wl, &wlvif->sta.p2p_rate_idx);
+ wlcore_allocate_klv_template(wl, &wlvif->sta.klv_template_id);
wlvif->basic_rate_set = CONF_TX_RATE_MASK_BASIC;
wlvif->basic_rate = CONF_TX_RATE_MASK_BASIC;
wlvif->rate_set = CONF_TX_RATE_MASK_BASIC;
wl12xx_free_rate_policy(wl, &wlvif->sta.basic_rate_idx);
wl12xx_free_rate_policy(wl, &wlvif->sta.ap_rate_idx);
wl12xx_free_rate_policy(wl, &wlvif->sta.p2p_rate_idx);
+ wlcore_free_klv_template(wl, &wlvif->sta.klv_template_id);
} else {
wlvif->ap.bcast_hlid = WL12XX_INVALID_LINK_ID;
wlvif->ap.global_hlid = WL12XX_INVALID_LINK_ID;
goto out;
ret = wl1271_acx_keep_alive_config(wl, wlvif,
- CMD_TEMPL_KLV_IDX_NULL_DATA,
+ wlvif->sta.klv_template_id,
ACX_KEEP_ALIVE_TPL_VALID);
if (ret < 0)
goto out;
/* invalidate keep-alive template */
wl1271_acx_keep_alive_config(wl, wlvif,
- CMD_TEMPL_KLV_IDX_NULL_DATA,
+ wlvif->sta.klv_template_id,
ACX_KEEP_ALIVE_TPL_INVALID);
/* to stop listening to a channel, we disconnect */
ret = wl1271_acx_sta_rate_policies(wl, wlvif);
if (ret < 0)
goto out;
- ret = wl1271_acx_keep_alive_config(
- wl, wlvif, CMD_TEMPL_KLV_IDX_NULL_DATA,
- ACX_KEEP_ALIVE_TPL_INVALID);
- if (ret < 0)
- goto out;
clear_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
} else {
/* The current firmware only supports sched_scan in idle */