Commit 23781af7 authored by Sergey Matyukevich's avatar Sergey Matyukevich Committed by Kalle Valo
Browse files

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: default avatarSergey Matyukevich <sergey.matyukevich.os@quantenna.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent ff233cb5
Loading
Loading
Loading
Loading
+75 −4
Original line number Diff line number Diff line
@@ -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,
	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;
}

+3 −1
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@

#include <linux/ieee80211.h>

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