From 23781af74152418055531fe7fec4e55b9502ddc2 Mon Sep 17 00:00:00 2001 From: Sergey Matyukevich Date: Mon, 14 Jan 2019 09:39:47 +0000 Subject: [PATCH] qtnfmac: add missing bss record to host scan cache Make sure that valid BSS entry exists in wireless core record even in the case of successful connect reported by firmware. Signed-off-by: Sergey Matyukevich Signed-off-by: Kalle Valo --- .../net/wireless/quantenna/qtnfmac/event.c | 79 ++++++++++++++++++- .../net/wireless/quantenna/qtnfmac/qlink.h | 4 +- 2 files changed, 78 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/quantenna/qtnfmac/event.c b/drivers/net/wireless/quantenna/qtnfmac/event.c index 3038a000c287..3fd1a9217737 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/event.c +++ b/drivers/net/wireless/quantenna/qtnfmac/event.c @@ -145,6 +145,12 @@ qtnf_event_handle_bss_join(struct qtnf_vif *vif, const struct qlink_event_bss_join *join_info, u16 len) { + struct wiphy *wiphy = priv_to_wiphy(vif->mac); + enum ieee80211_statuscode status = le16_to_cpu(join_info->status); + struct cfg80211_chan_def chandef; + struct cfg80211_bss *bss = NULL; + u8 *ie = NULL; + if (unlikely(len < sizeof(*join_info))) { pr_err("VIF%u.%u: payload is too short (%u < %zu)\n", vif->mac->macid, vif->vifid, len, @@ -158,15 +164,80 @@ qtnf_event_handle_bss_join(struct qtnf_vif *vif, return -EPROTO; } - pr_debug("VIF%u.%u: BSSID:%pM\n", vif->mac->macid, vif->vifid, - join_info->bssid); + pr_debug("VIF%u.%u: BSSID:%pM status:%u\n", + vif->mac->macid, vif->vifid, join_info->bssid, status); + if (status == WLAN_STATUS_SUCCESS) { + qlink_chandef_q2cfg(wiphy, &join_info->chan, &chandef); + if (!cfg80211_chandef_valid(&chandef)) { + pr_warn("MAC%u.%u: bad channel freq=%u cf1=%u cf2=%u bw=%u\n", + vif->mac->macid, vif->vifid, + chandef.chan->center_freq, + chandef.center_freq1, + chandef.center_freq2, + chandef.width); + status = WLAN_STATUS_UNSPECIFIED_FAILURE; + goto done; + } + + bss = cfg80211_get_bss(wiphy, chandef.chan, join_info->bssid, + NULL, 0, IEEE80211_BSS_TYPE_ESS, + IEEE80211_PRIVACY_ANY); + if (!bss) { + pr_warn("VIF%u.%u: add missing BSS:%pM chan:%u\n", + vif->mac->macid, vif->vifid, + join_info->bssid, chandef.chan->hw_value); + + if (!vif->wdev.ssid_len) { + pr_warn("VIF%u.%u: SSID unknown for BSS:%pM\n", + vif->mac->macid, vif->vifid, + join_info->bssid); + status = WLAN_STATUS_UNSPECIFIED_FAILURE; + goto done; + } + + ie = kzalloc(2 + vif->wdev.ssid_len, GFP_KERNEL); + if (!ie) { + pr_warn("VIF%u.%u: IE alloc failed for BSS:%pM\n", + vif->mac->macid, vif->vifid, + join_info->bssid); + status = WLAN_STATUS_UNSPECIFIED_FAILURE; + goto done; + } + + ie[0] = WLAN_EID_SSID; + ie[1] = vif->wdev.ssid_len; + memcpy(ie + 2, vif->wdev.ssid, vif->wdev.ssid_len); + + bss = cfg80211_inform_bss(wiphy, chandef.chan, + CFG80211_BSS_FTYPE_UNKNOWN, + join_info->bssid, 0, + WLAN_CAPABILITY_ESS, 100, + ie, 2 + vif->wdev.ssid_len, + 0, GFP_KERNEL); + if (!bss) { + pr_warn("VIF%u.%u: can't connect to unknown BSS: %pM\n", + vif->mac->macid, vif->vifid, + join_info->bssid); + status = WLAN_STATUS_UNSPECIFIED_FAILURE; + goto done; + } + } + } + +done: cfg80211_connect_result(vif->netdev, join_info->bssid, NULL, 0, NULL, - 0, le16_to_cpu(join_info->status), GFP_KERNEL); + 0, status, GFP_KERNEL); + if (bss) { + if (!ether_addr_equal(vif->bssid, join_info->bssid)) + ether_addr_copy(vif->bssid, join_info->bssid); + cfg80211_put_bss(wiphy, bss); + } - if (le16_to_cpu(join_info->status) == WLAN_STATUS_SUCCESS) + if (status == WLAN_STATUS_SUCCESS) netif_carrier_on(vif->netdev); + kfree(ie); return 0; } diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink.h b/drivers/net/wireless/quantenna/qtnfmac/qlink.h index d958b268de02..27fdb5b01ee3 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/qlink.h +++ b/drivers/net/wireless/quantenna/qtnfmac/qlink.h @@ -6,7 +6,7 @@ #include -#define QLINK_PROTO_VER 12 +#define QLINK_PROTO_VER 13 #define QLINK_MACID_RSVD 0xFF #define QLINK_VIFID_RSVD 0xFF @@ -975,11 +975,13 @@ struct qlink_event_sta_deauth { /** * struct qlink_event_bss_join - data for QLINK_EVENT_BSS_JOIN event * + * @chan: new operating channel definition * @bssid: BSSID of a BSS which interface tried to joined. * @status: status of joining attempt, see &enum ieee80211_statuscode. */ struct qlink_event_bss_join { struct qlink_event ehdr; + struct qlink_chandef chan; u8 bssid[ETH_ALEN]; __le16 status; } __packed;