[PATCH 4.17 087/336] qtnfmac: fix invalid STA state on EAPOL failure

From: Greg Kroah-Hartman
Date: Wed Aug 01 2018 - 14:22:19 EST


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);