ath6kl: restart concurrent vifs on failed connect
When an ath6kl STA vif is issued a connect command, the firmware will disconnect all other beaconing vifs in preparation for a potential channel switch. The case where the connect fails is currently unhandled, so if a connection attempt on a STA vif fails and any vifs were waiting for a new channel, simply restart the concurrent vifs on their previous channel. Requires that we start tracking the last issued channel in ar->last_ch, which is valid since ath6kl only supports 1 channel at a time. Also clear the beaconing vif's want_ch_switch bit regardless of whether channel switch succeeds, to stop recommitting the same failed profile. Signed-off-by: Thomas Pedersen <c_tpeder@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
parent
fd4377b6ba
commit
b5495e666d
2 changed files with 13 additions and 6 deletions
|
@ -699,6 +699,7 @@ struct ath6kl {
|
|||
struct ath6kl_req_key ap_mode_bkey;
|
||||
struct sk_buff_head mcastpsq;
|
||||
u32 want_ch_switch;
|
||||
u16 last_ch;
|
||||
|
||||
/*
|
||||
* FIXME: protects access to mcastpsq but is actually useless as
|
||||
|
|
|
@ -441,12 +441,9 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel)
|
|||
break;
|
||||
}
|
||||
|
||||
if (ar->want_ch_switch & (1 << vif->fw_vif_idx)) {
|
||||
ar->want_ch_switch &= ~(1 << vif->fw_vif_idx);
|
||||
if (ar->last_ch != channel)
|
||||
/* we actually don't know the phymode, default to HT20 */
|
||||
ath6kl_cfg80211_ch_switch_notify(vif, channel,
|
||||
WMI_11G_HT20);
|
||||
}
|
||||
ath6kl_cfg80211_ch_switch_notify(vif, channel, WMI_11G_HT20);
|
||||
|
||||
ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0);
|
||||
set_bit(CONNECTED, &vif->flags);
|
||||
|
@ -633,6 +630,9 @@ static void ath6kl_check_ch_switch(struct ath6kl *ar, u16 channel)
|
|||
if (ar->want_ch_switch & (1 << vif->fw_vif_idx))
|
||||
res = ath6kl_commit_ch_switch(vif, channel);
|
||||
|
||||
/* if channel switch failed, oh well we tried */
|
||||
ar->want_ch_switch &= ~(1 << vif->fw_vif_idx);
|
||||
|
||||
if (res)
|
||||
ath6kl_err("channel switch failed nw_type %d res %d\n",
|
||||
vif->nw_type, res);
|
||||
|
@ -986,8 +986,11 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
|
|||
if (vif->nw_type == AP_NETWORK) {
|
||||
/* disconnect due to other STA vif switching channels */
|
||||
if (reason == BSS_DISCONNECTED &&
|
||||
prot_reason_status == WMI_AP_REASON_STA_ROAM)
|
||||
prot_reason_status == WMI_AP_REASON_STA_ROAM) {
|
||||
ar->want_ch_switch |= 1 << vif->fw_vif_idx;
|
||||
/* bail back to this channel if STA vif fails connect */
|
||||
ar->last_ch = le16_to_cpu(vif->profile.ch);
|
||||
}
|
||||
|
||||
if (!ath6kl_remove_sta(ar, bssid, prot_reason_status))
|
||||
return;
|
||||
|
@ -1046,6 +1049,9 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
|
|||
}
|
||||
}
|
||||
|
||||
/* restart disconnected concurrent vifs waiting for new channel */
|
||||
ath6kl_check_ch_switch(ar, ar->last_ch);
|
||||
|
||||
/* update connect & link status atomically */
|
||||
spin_lock_bh(&vif->if_lock);
|
||||
clear_bit(CONNECTED, &vif->flags);
|
||||
|
|
Loading…
Reference in a new issue