From 425ff4573ecb36257af5dc57c84c7e0a37820fe6 Mon Sep 17 00:00:00 2001
From: Carter Chen <carter.chen@infineon.com>
Date: Thu, 11 Aug 2022 02:02:24 -0500
Subject: [PATCH 107/296] brcmfmac: trying to get GCMP cap before doing set it

trying to get GCMP cp to make sure the firmware supports it before set.


Signed-off-by: Carter Chen <carter.chen@infineon.com>
---
 .../broadcom/brcm80211/brcmfmac/cfg80211.c    | 45 +++++++++++++++----
 .../broadcom/brcm80211/brcmfmac/feature.c     |  1 +
 .../broadcom/brcm80211/brcmfmac/feature.h     |  4 +-
 3 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index a78544ff0240..04b76412cc3e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -2244,6 +2244,10 @@ brcmf_set_wsec_mode(struct net_device *ndev,
 			pval = AES_ENABLED;
 			break;
 		case WLAN_CIPHER_SUITE_GCMP_256:
+			if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GCMP)) {
+				brcmf_err("the low layer not support GCMP\n");
+				return -EOPNOTSUPP;
+			}
 			pval = AES_ENABLED;
 			algos = KEY_ALGO_MASK(CRYPTO_ALGO_AES_GCM256);
 			mask = algos | KEY_ALGO_MASK(CRYPTO_ALGO_AES_CCM);
@@ -2270,6 +2274,10 @@ brcmf_set_wsec_mode(struct net_device *ndev,
 			gval = AES_ENABLED;
 			break;
 		case WLAN_CIPHER_SUITE_GCMP_256:
+			if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GCMP)) {
+				brcmf_err("the low layer not support GCMP\n");
+				return -EOPNOTSUPP;
+			}
 			gval = AES_ENABLED;
 			algos = KEY_ALGO_MASK(CRYPTO_ALGO_AES_GCM256);
 			mask = algos | KEY_ALGO_MASK(CRYPTO_ALGO_AES_CCM);
@@ -2296,10 +2304,15 @@ brcmf_set_wsec_mode(struct net_device *ndev,
 		return err;
 	}
 
-	err = wl_set_wsec_info_algos(ifp, algos, mask);
-	if (err) {
-		bphy_err(drvr, "set wsec_info error (%d)\n", err);
-		return err;
+	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GCMP)) {
+		brcmf_dbg(CONN,
+			  "set_wsdec_info algos (0x%x) mask (0x%x)\n",
+			  algos, mask);
+		err = wl_set_wsec_info_algos(ifp, algos, mask);
+		if (err) {
+			brcmf_err("set wsec_info error (%d)\n", err);
+			return err;
+		}
 	}
 
 	sec = &profile->sec;
@@ -3223,6 +3236,11 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
 		brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
 		break;
 	case WLAN_CIPHER_SUITE_GCMP_256:
+		if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GCMP)) {
+			brcmf_err("the low layer not support GCMP\n");
+			err = -EOPNOTSUPP;
+			goto done;
+		}
 		key->algo = CRYPTO_ALGO_AES_GCM256;
 		val = AES_ENABLED;
 		brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_GCMP_256\n");
@@ -3230,6 +3248,11 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
 		mask = algos | KEY_ALGO_MASK(CRYPTO_ALGO_AES_CCM);
 		break;
 	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+		if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GCMP)) {
+			brcmf_err("the low layer not support GCMP\n");
+			err = -EOPNOTSUPP;
+			goto done;
+		}
 		key->algo = CRYPTO_ALGO_BIP_GMAC256;
 		val = AES_ENABLED;
 		algos = KEY_ALGO_MASK(CRYPTO_ALGO_BIP_GMAC256);
@@ -3258,10 +3281,16 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
 		goto done;
 	}
 
-	brcmf_dbg(CONN, "algos (0x%x) mask (0x%x)\n", algos, mask);
-	err = wl_set_wsec_info_algos(ifp, algos, mask);
-	if (err)
-		bphy_err(drvr, "set wsec_info error (%d)\n", err);
+	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GCMP)) {
+		brcmf_dbg(CONN,
+			  "set_wsdec_info algos (0x%x) mask (0x%x)\n",
+			  algos, mask);
+		err = wl_set_wsec_info_algos(ifp, algos, mask);
+		if (err) {
+			brcmf_err("set wsec_info error (%d)\n", err);
+			return err;
+		}
+	}
 
 done:
 	brcmf_dbg(TRACE, "Exit\n");
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
index 0e520b2fab13..c14bf4d9158d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
@@ -45,6 +45,7 @@ static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = {
 	{ BRCMF_FEAT_SAE_EXT, "sae_ext " },
 	{ BRCMF_FEAT_FBT, "fbt " },
 	{ BRCMF_FEAT_OKC, "okc" },
+	{ BRCMF_FEAT_GCMP, "gcmp" },
 };
 
 #ifdef DEBUG
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
index 71bf9d806306..3039d82efa8d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
@@ -32,6 +32,7 @@
  * DUMP_OBSS: Firmware has capable to dump obss info to support ACS
  * SCAN_V2: Version 2 scan params
  * SAE_EXT: SAE be handled by userspace supplicant
+ * GCMP: firmware has defined GCMP or not.
  */
 #define BRCMF_FEAT_LIST \
 	BRCMF_FEAT_DEF(MBSS) \
@@ -61,7 +62,8 @@
 	BRCMF_FEAT_DEF(PMKID_V3) \
 	BRCMF_FEAT_DEF(SAE_EXT) \
 	BRCMF_FEAT_DEF(FBT) \
-	BRCMF_FEAT_DEF(OKC)
+	BRCMF_FEAT_DEF(OKC) \
+	BRCMF_FEAT_DEF(GCMP)
 
 /*
  * Quirks:
-- 
2.25.1

