Blob Blame History Raw
From c3f40c3e0273392b8c01351cf53f5183e1b06289 Mon Sep 17 00:00:00 2001
From: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Date: Sun, 19 Dec 2021 13:28:28 +0200
Subject: [PATCH] iwlwifi: mvm: add US/CA to TAS block list if OEM isn't allowed
Git-commit: c3f40c3e0273392b8c01351cf53f5183e1b06289
Patch-mainline: v5.17-rc1
References: bsc#1202131

If OEM isn't in the allowed list, TAS should be disabled in US/CA.
Currently, if the OEM isn't allowed - we're sending the TAS only
if we are not in US or CA.
But this country check is done before we even know the country
(usually the configuration is ZZ in that stage).
So do the following instead:
1. Check if the current OEM is in the allowed list
2. If not - add US and CA to tas_block_list_array
3. Send the TAS table to FW.

Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Acked-by: Takashi Iwai <tiwai@suse.de>

---
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 55 ++++++++++++++-------
 1 file changed, 36 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 65c1f9c88e67..f48459da0fcc 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -32,6 +32,9 @@
 #define IWL_PPAG_MASK 3
 #define IWL_PPAG_ETSI_MASK BIT(0)
 
+#define IWL_TAS_US_MCC 0x5553
+#define IWL_TAS_CANADA_MCC 0x4341
+
 struct iwl_mvm_alive_data {
 	bool valid;
 	u32 scd_base_addr;
@@ -1183,12 +1186,30 @@ static const struct dmi_system_id dmi_tas_approved_list[] = {
 	{}
 };
 
+static bool iwl_mvm_add_to_tas_block_list(__le32 *list, __le32 *le_size, unsigned int mcc)
+{
+	int i;
+	u32 size = le32_to_cpu(*le_size);
+
+	/* Verify that there is room for another country */
+	if (size >= IWL_TAS_BLOCK_LIST_MAX)
+		return false;
+
+	for (i = 0; i < size; i++) {
+		if (list[i] == cpu_to_le32(mcc))
+			return true;
+	}
+
+	list[size++] = cpu_to_le32(mcc);
+	*le_size = cpu_to_le32(size);
+	return true;
+}
+
 static void iwl_mvm_tas_init(struct iwl_mvm *mvm)
 {
 	int ret;
 	struct iwl_tas_config_cmd_v3 cmd = {};
 	int cmd_size;
-	const struct ieee80211_regdomain *regd;
 
 	BUILD_BUG_ON(ARRAY_SIZE(cmd.block_list_array) <
 		     APCI_WTAS_BLACK_LIST_MAX);
@@ -1198,24 +1219,6 @@ static void iwl_mvm_tas_init(struct iwl_mvm *mvm)
 		return;
 	}
 
-	/* Get the MCC from cfg80211 */
-	regd = wiphy_dereference(mvm->hw->wiphy, mvm->hw->wiphy->regd);
-
-	if (!regd) {
-		IWL_DEBUG_RADIO(mvm, "MCC is unavailable\n");
-		return;
-	}
-
-	if ((regd->alpha2[0] == 'U' && regd->alpha2[1] == 'S') ||
-	    (regd->alpha2[0] == 'C' && regd->alpha2[1] == 'A')) {
-		if (!dmi_check_system(dmi_tas_approved_list)) {
-			IWL_DEBUG_RADIO(mvm,
-					"System vendor '%s' is not in the approved list, disabling TAS.\n",
-					dmi_get_system_info(DMI_SYS_VENDOR));
-			return;
-		}
-	}
-
 	ret = iwl_acpi_get_tas(&mvm->fwrt, &cmd);
 	if (ret < 0) {
 		IWL_DEBUG_RADIO(mvm,
@@ -1227,6 +1230,20 @@ static void iwl_mvm_tas_init(struct iwl_mvm *mvm)
 	if (ret == 0)
 		return;
 
+	if (!dmi_check_system(dmi_tas_approved_list)) {
+		IWL_DEBUG_RADIO(mvm,
+				"System vendor '%s' is not in the approved list, disabling TAS in US and Canada.\n",
+				dmi_get_system_info(DMI_SYS_VENDOR));
+		if ((!iwl_mvm_add_to_tas_block_list(cmd.block_list_array,
+						    &cmd.block_list_size, IWL_TAS_US_MCC)) ||
+		    (!iwl_mvm_add_to_tas_block_list(cmd.block_list_array,
+						    &cmd.block_list_size, IWL_TAS_CANADA_MCC))) {
+			IWL_DEBUG_RADIO(mvm,
+					"Unable to add US/Canada to TAS block list, disabling TAS\n");
+			return;
+		}
+	}
+
 	cmd_size = iwl_fw_lookup_cmd_ver(mvm->fw, REGULATORY_AND_NVM_GROUP,
 					 TAS_CONFIG,
 					 IWL_FW_CMD_VER_UNKNOWN) < 3 ?
-- 
2.35.3