4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergey Matyukevich sergey.matyukevich.os@quantenna.com
[ 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@quantenna.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin alexander.levin@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- 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);