wlcore: update beacon and probe_resp templates when rates change
When the data rates change, we get BSS_CHANGED_BASIC_RATES. At this point, we should update all the templates to match the new rates. We were changing some of the templates, but the beacon and the probe response templates were missing. [Remove redundant min_rate variable - Arik] Signed-off-by: Luciano Coelho <coelho@ti.com> Signed-off-by: Arik Nemtsov <arik@wizery.com>
This commit is contained in:
parent
7ae25da396
commit
62c2e579e0
|
@ -3277,8 +3277,15 @@ static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl, u32 rates,
|
||||||
skb->data,
|
skb->data,
|
||||||
skb->len, 0,
|
skb->len, 0,
|
||||||
rates);
|
rates);
|
||||||
|
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
wl1271_debug(DEBUG_AP, "probe response updated");
|
||||||
|
set_bit(WLVIF_FLAG_AP_PROBE_RESP_SET, &wlvif->flags);
|
||||||
|
|
||||||
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3383,6 +3390,87 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int wlcore_set_beacon_template(struct wl1271 *wl,
|
||||||
|
struct ieee80211_vif *vif,
|
||||||
|
bool is_ap)
|
||||||
|
{
|
||||||
|
struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
|
||||||
|
struct ieee80211_hdr *hdr;
|
||||||
|
u32 min_rate;
|
||||||
|
int ret;
|
||||||
|
int ieoffset = offsetof(struct ieee80211_mgmt,
|
||||||
|
u.beacon.variable);
|
||||||
|
struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif);
|
||||||
|
u16 tmpl_id;
|
||||||
|
|
||||||
|
if (!beacon) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl1271_debug(DEBUG_MASTER, "beacon updated");
|
||||||
|
|
||||||
|
ret = wl1271_ssid_set(vif, beacon, ieoffset);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_kfree_skb(beacon);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
min_rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
|
||||||
|
tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON :
|
||||||
|
CMD_TEMPL_BEACON;
|
||||||
|
ret = wl1271_cmd_template_set(wl, wlvif->role_id, tmpl_id,
|
||||||
|
beacon->data,
|
||||||
|
beacon->len, 0,
|
||||||
|
min_rate);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_kfree_skb(beacon);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In case we already have a probe-resp beacon set explicitly
|
||||||
|
* by usermode, don't use the beacon data.
|
||||||
|
*/
|
||||||
|
if (test_bit(WLVIF_FLAG_AP_PROBE_RESP_SET, &wlvif->flags))
|
||||||
|
goto end_bcn;
|
||||||
|
|
||||||
|
/* remove TIM ie from probe response */
|
||||||
|
wl12xx_remove_ie(beacon, WLAN_EID_TIM, ieoffset);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* remove p2p ie from probe response.
|
||||||
|
* the fw reponds to probe requests that don't include
|
||||||
|
* the p2p ie. probe requests with p2p ie will be passed,
|
||||||
|
* and will be responded by the supplicant (the spec
|
||||||
|
* forbids including the p2p ie when responding to probe
|
||||||
|
* requests that didn't include it).
|
||||||
|
*/
|
||||||
|
wl12xx_remove_vendor_ie(beacon, WLAN_OUI_WFA,
|
||||||
|
WLAN_OUI_TYPE_WFA_P2P, ieoffset);
|
||||||
|
|
||||||
|
hdr = (struct ieee80211_hdr *) beacon->data;
|
||||||
|
hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
||||||
|
IEEE80211_STYPE_PROBE_RESP);
|
||||||
|
if (is_ap)
|
||||||
|
ret = wl1271_ap_set_probe_resp_tmpl_legacy(wl, vif,
|
||||||
|
beacon->data,
|
||||||
|
beacon->len,
|
||||||
|
min_rate);
|
||||||
|
else
|
||||||
|
ret = wl1271_cmd_template_set(wl, wlvif->role_id,
|
||||||
|
CMD_TEMPL_PROBE_RESPONSE,
|
||||||
|
beacon->data,
|
||||||
|
beacon->len, 0,
|
||||||
|
min_rate);
|
||||||
|
end_bcn:
|
||||||
|
dev_kfree_skb(beacon);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
|
static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
|
||||||
struct ieee80211_vif *vif,
|
struct ieee80211_vif *vif,
|
||||||
struct ieee80211_bss_conf *bss_conf,
|
struct ieee80211_bss_conf *bss_conf,
|
||||||
|
@ -3401,81 +3489,12 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
|
||||||
|
|
||||||
if ((changed & BSS_CHANGED_AP_PROBE_RESP) && is_ap) {
|
if ((changed & BSS_CHANGED_AP_PROBE_RESP) && is_ap) {
|
||||||
u32 rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
|
u32 rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
|
||||||
if (!wl1271_ap_set_probe_resp_tmpl(wl, rate, vif)) {
|
|
||||||
wl1271_debug(DEBUG_AP, "probe response updated");
|
wl1271_ap_set_probe_resp_tmpl(wl, rate, vif);
|
||||||
set_bit(WLVIF_FLAG_AP_PROBE_RESP_SET, &wlvif->flags);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((changed & BSS_CHANGED_BEACON)) {
|
if ((changed & BSS_CHANGED_BEACON)) {
|
||||||
struct ieee80211_hdr *hdr;
|
ret = wlcore_set_beacon_template(wl, vif, is_ap);
|
||||||
u32 min_rate;
|
|
||||||
int ieoffset = offsetof(struct ieee80211_mgmt,
|
|
||||||
u.beacon.variable);
|
|
||||||
struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif);
|
|
||||||
u16 tmpl_id;
|
|
||||||
|
|
||||||
if (!beacon) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
wl1271_debug(DEBUG_MASTER, "beacon updated");
|
|
||||||
|
|
||||||
ret = wl1271_ssid_set(vif, beacon, ieoffset);
|
|
||||||
if (ret < 0) {
|
|
||||||
dev_kfree_skb(beacon);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
min_rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
|
|
||||||
tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON :
|
|
||||||
CMD_TEMPL_BEACON;
|
|
||||||
ret = wl1271_cmd_template_set(wl, wlvif->role_id, tmpl_id,
|
|
||||||
beacon->data,
|
|
||||||
beacon->len, 0,
|
|
||||||
min_rate);
|
|
||||||
if (ret < 0) {
|
|
||||||
dev_kfree_skb(beacon);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* In case we already have a probe-resp beacon set explicitly
|
|
||||||
* by usermode, don't use the beacon data.
|
|
||||||
*/
|
|
||||||
if (test_bit(WLVIF_FLAG_AP_PROBE_RESP_SET, &wlvif->flags))
|
|
||||||
goto end_bcn;
|
|
||||||
|
|
||||||
/* remove TIM ie from probe response */
|
|
||||||
wl12xx_remove_ie(beacon, WLAN_EID_TIM, ieoffset);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* remove p2p ie from probe response.
|
|
||||||
* the fw reponds to probe requests that don't include
|
|
||||||
* the p2p ie. probe requests with p2p ie will be passed,
|
|
||||||
* and will be responded by the supplicant (the spec
|
|
||||||
* forbids including the p2p ie when responding to probe
|
|
||||||
* requests that didn't include it).
|
|
||||||
*/
|
|
||||||
wl12xx_remove_vendor_ie(beacon, WLAN_OUI_WFA,
|
|
||||||
WLAN_OUI_TYPE_WFA_P2P, ieoffset);
|
|
||||||
|
|
||||||
hdr = (struct ieee80211_hdr *) beacon->data;
|
|
||||||
hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
|
||||||
IEEE80211_STYPE_PROBE_RESP);
|
|
||||||
if (is_ap)
|
|
||||||
ret = wl1271_ap_set_probe_resp_tmpl_legacy(wl, vif,
|
|
||||||
beacon->data,
|
|
||||||
beacon->len,
|
|
||||||
min_rate);
|
|
||||||
else
|
|
||||||
ret = wl1271_cmd_template_set(wl, wlvif->role_id,
|
|
||||||
CMD_TEMPL_PROBE_RESPONSE,
|
|
||||||
beacon->data,
|
|
||||||
beacon->len, 0,
|
|
||||||
min_rate);
|
|
||||||
end_bcn:
|
|
||||||
dev_kfree_skb(beacon);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -3512,6 +3531,14 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
|
||||||
ret = wl1271_ap_init_templates(wl, vif);
|
ret = wl1271_ap_init_templates(wl, vif);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
ret = wl1271_ap_set_probe_resp_tmpl(wl, wlvif->basic_rate, vif);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = wlcore_set_beacon_template(wl, vif, true);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf, changed);
|
ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf, changed);
|
||||||
|
|
Loading…
Reference in New Issue