4.17-stable review patch. If anyone has any objections, please let me know. ------------------ From: Sergey Matyukevich <sergey.matyukevich.os@xxxxxxxxxxxxx> [ Upstream commit 480daa9cb62c14bbd1b87a01cd9bc10cc56dbf32 ] Driver switches vif sta_state into QTNF_STA_CONNECTING when cfg80211 core initiates connect procedure. Further this state is changed either to QTNF_STA_CONNECTED or to QTNF_STA_DISCONNECTED by BSS_JOIN and BSS_LEAVE events from firmware. However it is possible that no such events will be sent by firmware, e.g. if EAPOL timed out. In this case vif sta_mode will remain in QTNF_STA_CONNECTING state and all subsequent connection attempts will fail with -EBUSY error code. Fix this by perfroming STA state transition from QTNF_STA_CONNECTING to QTNF_STA_DISCONNECTED in cfg80211 disconnect callback. No need to rely upon firmware events in this case. Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@xxxxxxxxxxxxx> Signed-off-by: Kalle Valo <kvalo@xxxxxxxxxxxxxx> Signed-off-by: Sasha Levin <alexander.levin@xxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 21 ++++++++++++++------- drivers/net/wireless/quantenna/qtnfmac/event.c | 8 +++----- 2 files changed, 17 insertions(+), 12 deletions(-) --- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c +++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c @@ -651,28 +651,35 @@ qtnf_disconnect(struct wiphy *wiphy, str { struct qtnf_wmac *mac = wiphy_priv(wiphy); struct qtnf_vif *vif; - int ret; + int ret = 0; vif = qtnf_mac_get_base_vif(mac); if (!vif) { pr_err("MAC%u: primary VIF is not configured\n", mac->macid); - return -EFAULT; + ret = -EFAULT; + goto out; } - if (vif->wdev.iftype != NL80211_IFTYPE_STATION) - return -EOPNOTSUPP; + if (vif->wdev.iftype != NL80211_IFTYPE_STATION) { + ret = -EOPNOTSUPP; + goto out; + } if (vif->sta_state == QTNF_STA_DISCONNECTED) - return 0; + goto out; ret = qtnf_cmd_send_disconnect(vif, reason_code); if (ret) { pr_err("VIF%u.%u: failed to disconnect\n", mac->macid, vif->vifid); - return ret; + goto out; } - return 0; +out: + if (vif->sta_state == QTNF_STA_CONNECTING) + vif->sta_state = QTNF_STA_DISCONNECTED; + + return ret; } static int --- a/drivers/net/wireless/quantenna/qtnfmac/event.c +++ b/drivers/net/wireless/quantenna/qtnfmac/event.c @@ -198,11 +198,9 @@ qtnf_event_handle_bss_leave(struct qtnf_ return -EPROTO; } - if (vif->sta_state != QTNF_STA_CONNECTED) { - pr_err("VIF%u.%u: BSS_LEAVE event when STA is not connected\n", - vif->mac->macid, vif->vifid); - return -EPROTO; - } + if (vif->sta_state != QTNF_STA_CONNECTED) + pr_warn("VIF%u.%u: BSS_LEAVE event when STA is not connected\n", + vif->mac->macid, vif->vifid); pr_debug("VIF%u.%u: disconnected\n", vif->mac->macid, vif->vifid);