From 0f7594489a8ab154edb899e84f877def0b48fbd0 Mon Sep 17 00:00:00 2001
From: Johannes Berg <johannes.berg@intel.com>
Date: Tue, 31 May 2022 18:00:00 +0200
Subject: [PATCH] wifi: cfg80211: mlme: get BSS entry outside
 cfg80211_mlme_assoc()

Today it makes more sense to pass the necessary parameters to
look up the BSS entry to cfg80211_mlme_assoc(), but with MLO
we will need to look up multiple, and that gets awkward. Pull
the lookup code into the callers so we can change it better.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/wireless/core.h    |  3 ---
 net/wireless/mlme.c    | 17 ++++-------------
 net/wireless/nl80211.c | 14 +++++++++++---
 net/wireless/sme.c     | 15 ++++++++++++---
 4 files changed, 27 insertions(+), 22 deletions(-)

diff --git a/net/wireless/core.h b/net/wireless/core.h
index 2c195067ddff6..f20857f36764b 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -372,9 +372,6 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 		       const u8 *auth_data, int auth_data_len);
 int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
 			struct net_device *dev,
-			struct ieee80211_channel *chan,
-			const u8 *bssid,
-			const u8 *ssid, int ssid_len,
 			struct cfg80211_assoc_request *req);
 int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
 			 struct net_device *dev, const u8 *bssid,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index fab2d6206cdd9..1263623a7a327 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -309,11 +309,9 @@ void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
 		p1[i] &= p2[i];
 }
 
+/* Note: caller must cfg80211_put_bss() regardless of result */
 int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
 			struct net_device *dev,
-			struct ieee80211_channel *chan,
-			const u8 *bssid,
-			const u8 *ssid, int ssid_len,
 			struct cfg80211_assoc_request *req)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
@@ -331,18 +329,11 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
 	cfg80211_oper_and_vht_capa(&req->vht_capa_mask,
 				   rdev->wiphy.vht_capa_mod_mask);
 
-	req->bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
-				    IEEE80211_BSS_TYPE_ESS,
-				    IEEE80211_PRIVACY_ANY);
-	if (!req->bss)
-		return -ENOENT;
-
 	err = rdev_assoc(rdev, dev, req);
-	if (!err)
+	if (!err) {
+		cfg80211_ref_bss(&rdev->wiphy, req->bss);
 		cfg80211_hold_bss(bss_from_pub(req->bss));
-	else
-		cfg80211_put_bss(&rdev->wiphy, req->bss);
-
+	}
 	return err;
 }
 
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index af31978fc9cc2..5ccd2b0f68c9e 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -10431,7 +10431,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
 	struct ieee80211_channel *chan;
 	struct cfg80211_assoc_request req = {};
 	const u8 *bssid, *ssid;
-	int err, ssid_len = 0;
+	int err, ssid_len;
 	u32 freq;
 
 	if (dev->ieee80211_ptr->conn_owner_nlportid &&
@@ -10553,12 +10553,18 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
 		       sizeof(req.s1g_capa));
 	}
 
+	req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid,
+				   ssid, ssid_len,
+				   IEEE80211_BSS_TYPE_ESS,
+				   IEEE80211_PRIVACY_ANY);
+	if (!req.bss)
+		return -ENOENT;
+
 	err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
 	if (!err) {
 		wdev_lock(dev->ieee80211_ptr);
 
-		err = cfg80211_mlme_assoc(rdev, dev, chan, bssid,
-					  ssid, ssid_len, &req);
+		err = cfg80211_mlme_assoc(rdev, dev, &req);
 
 		if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
 			dev->ieee80211_ptr->conn_owner_nlportid =
@@ -10570,6 +10576,8 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
 		wdev_unlock(dev->ieee80211_ptr);
 	}
 
+	cfg80211_put_bss(&rdev->wiphy, req.bss);
+
 	return err;
 }
 
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 35602201057b6..c869152629b69 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -193,9 +193,18 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev,
 		req.vht_capa = params->vht_capa;
 		req.vht_capa_mask = params->vht_capa_mask;
 
-		err = cfg80211_mlme_assoc(rdev, wdev->netdev, params->channel,
-					  params->bssid, params->ssid,
-					  params->ssid_len, &req);
+		req.bss = cfg80211_get_bss(&rdev->wiphy, params->channel,
+					   params->bssid,
+					   params->ssid, params->ssid_len,
+					   IEEE80211_BSS_TYPE_ESS,
+					   IEEE80211_PRIVACY_ANY);
+		if (!req.bss) {
+			err = -ENOENT;
+		} else {
+			err = cfg80211_mlme_assoc(rdev, wdev->netdev, &req);
+			cfg80211_put_bss(&rdev->wiphy, req.bss);
+		}
+
 		if (err)
 			cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
 					     NULL, 0,
-- 
2.30.2