qtnfmac: fix invalid STA state on EAPOL failure

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>
This commit is contained in:
Sergey Matyukevich 2018-05-29 15:00:05 +03:00 committed by Kalle Valo
parent 40d68dbb98
commit 480daa9cb6
2 changed files with 17 additions and 12 deletions

View File

@ -649,30 +649,37 @@ qtnf_disconnect(struct wiphy *wiphy, struct net_device *dev,
{ {
struct qtnf_wmac *mac = wiphy_priv(wiphy); struct qtnf_wmac *mac = wiphy_priv(wiphy);
struct qtnf_vif *vif; struct qtnf_vif *vif;
int ret; int ret = 0;
vif = qtnf_mac_get_base_vif(mac); vif = qtnf_mac_get_base_vif(mac);
if (!vif) { if (!vif) {
pr_err("MAC%u: primary VIF is not configured\n", mac->macid); 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) if (vif->wdev.iftype != NL80211_IFTYPE_STATION) {
return -EOPNOTSUPP; ret = -EOPNOTSUPP;
goto out;
}
qtnf_scan_done(mac, true); qtnf_scan_done(mac, true);
if (vif->sta_state == QTNF_STA_DISCONNECTED) if (vif->sta_state == QTNF_STA_DISCONNECTED)
return 0; goto out;
ret = qtnf_cmd_send_disconnect(vif, reason_code); ret = qtnf_cmd_send_disconnect(vif, reason_code);
if (ret) { if (ret) {
pr_err("VIF%u.%u: failed to disconnect\n", mac->macid, pr_err("VIF%u.%u: failed to disconnect\n", mac->macid,
vif->vifid); 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 static int

View File

@ -211,11 +211,9 @@ qtnf_event_handle_bss_leave(struct qtnf_vif *vif,
return -EPROTO; return -EPROTO;
} }
if (vif->sta_state != QTNF_STA_CONNECTED) { if (vif->sta_state != QTNF_STA_CONNECTED)
pr_err("VIF%u.%u: BSS_LEAVE event when STA is not connected\n", pr_warn("VIF%u.%u: BSS_LEAVE event when STA is not connected\n",
vif->mac->macid, vif->vifid); vif->mac->macid, vif->vifid);
return -EPROTO;
}
pr_debug("VIF%u.%u: disconnected\n", vif->mac->macid, vif->vifid); pr_debug("VIF%u.%u: disconnected\n", vif->mac->macid, vif->vifid);