diff mbox series

[14/15] wifi: iwlwifi: mvm: add UHB canada support in TAS_CONFIG cmd

Message ID 20241226174257.0b1d92ad59b8.Ib80f8514a64fc2800a2a20131e730c2bd9c4c4af@changeid (mailing list archive)
State New
Delegated to: Johannes Berg
Headers show
Series wifi: iwlwifi: updates - 26-12-24 | expand

Commit Message

Miri Korenblit Dec. 26, 2024, 3:44 p.m. UTC
From: Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>

extend TAS table support to revision 2 for getting UHB canada
enablement from BIOS and send to firmware via TAS_CONFIG cmd
based on firmware capability. While on it fixed kernel-doc for
struct iwl_tas_config_cmd_v4.

Signed-off-by: Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/acpi.c      |  6 +++---
 .../net/wireless/intel/iwlwifi/fw/api/nvm-reg.h   | 15 ++++++++++++---
 drivers/net/wireless/intel/iwlwifi/fw/file.h      |  2 ++
 .../net/wireless/intel/iwlwifi/fw/regulatory.c    |  7 ++++++-
 .../net/wireless/intel/iwlwifi/fw/regulatory.h    | 10 ++++++----
 drivers/net/wireless/intel/iwlwifi/fw/uefi.c      |  7 +++++--
 drivers/net/wireless/intel/iwlwifi/fw/uefi.h      |  3 ++-
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c       |  4 ++++
 8 files changed, 40 insertions(+), 14 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
index 0bc32291815e..7d6e6c80b892 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
@@ -274,13 +274,13 @@  int iwl_acpi_get_tas_table(struct iwl_fw_runtime *fwrt,
 		goto out_free;
 	}
 
-	if (tbl_rev == 1 && wifi_pkg->package.elements[1].type ==
-		ACPI_TYPE_INTEGER) {
+	if ((tbl_rev == 2 || tbl_rev == 1) &&
+	    wifi_pkg->package.elements[1].type == ACPI_TYPE_INTEGER) {
 		u32 tas_selection =
 			(u32)wifi_pkg->package.elements[1].integer.value;
 
 		enabled = iwl_parse_tas_selection(fwrt, tas_data,
-						  tas_selection);
+						  tas_selection, tbl_rev);
 
 	} else if (tbl_rev == 0 &&
 		wifi_pkg->package.elements[1].type == ACPI_TYPE_INTEGER) {
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
index d424d0126367..1bf549775c7c 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
@@ -463,19 +463,28 @@  struct iwl_tas_config_cmd_v3 {
 	__le16 enable_tas_iec;
 } __packed; /* TAS_CONFIG_CMD_API_S_VER_3 */
 
+/**
+ * enum iwl_tas_uhb_allowed_flags - per country TAS UHB allowed flags.
+ * @TAS_UHB_ALLOWED_CANADA: TAS UHB is allowed in Canada. This flag is valid
+ *	only when fw has %IWL_UCODE_TLV_CAPA_UHB_CANADA_TAS_SUPPORT capability.
+ */
+enum iwl_tas_uhb_allowed_flags {
+	TAS_UHB_ALLOWED_CANADA	= BIT(0),
+};
+
 /**
  * struct iwl_tas_config_cmd_v4 - configures the TAS
  * @override_tas_iec: indicates whether to override default value of IEC regulatory
  * @enable_tas_iec: in case override_tas_iec is set -
  *	indicates whether IEC regulatory is enabled or disabled
  * @usa_tas_uhb_allowed: if set, allow TAS UHB in the USA
- * @reserved: reserved
-*/
+ * @uhb_allowed_flags: see &enum iwl_tas_uhb_allowed_flags.
+ */
 struct iwl_tas_config_cmd_v4 {
 	u8 override_tas_iec;
 	u8 enable_tas_iec;
 	u8 usa_tas_uhb_allowed;
-	u8 reserved;
+	u8 uhb_allowed_flags;
 } __packed; /* TAS_CONFIG_CMD_API_S_VER_4 */
 
 struct iwl_tas_config_cmd {
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index f5fbe7692f6c..dce61869a7e3 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -400,6 +400,7 @@  typedef unsigned int __bitwise iwl_ucode_tlv_capa_t;
  *	passive channels
  * @IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_5G9_FOR_CA: supports (de)activating 5G9
  *	for CA from BIOS.
+ * @IWL_UCODE_TLV_CAPA_UHB_CANADA_TAS_SUPPORT: supports %TAS_UHB_ALLOWED_CANADA
  *
  * @NUM_IWL_UCODE_TLV_CAPA: number of bits used
  */
@@ -501,6 +502,7 @@  enum iwl_ucode_tlv_capa {
 	IWL_UCODE_TLV_CAPA_SECURE_LTF_SUPPORT		= (__force iwl_ucode_tlv_capa_t)121,
 	IWL_UCODE_TLV_CAPA_MONITOR_PASSIVE_CHANS	= (__force iwl_ucode_tlv_capa_t)122,
 	IWL_UCODE_TLV_CAPA_BIOS_OVERRIDE_5G9_FOR_CA	= (__force iwl_ucode_tlv_capa_t)123,
+	IWL_UCODE_TLV_CAPA_UHB_CANADA_TAS_SUPPORT	= (__force iwl_ucode_tlv_capa_t)124,
 	NUM_IWL_UCODE_TLV_CAPA
 /*
  * This construction make both sparse (which cannot increment the previous
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
index 4b5eeff4a140..c89ff380b86d 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
@@ -426,10 +426,12 @@  IWL_EXPORT_SYMBOL(iwl_is_tas_approved);
 
 int iwl_parse_tas_selection(struct iwl_fw_runtime *fwrt,
 			    struct iwl_tas_data *tas_data,
-			    const u32 tas_selection)
+			    const u32 tas_selection, u8 tbl_rev)
 {
 	u8 override_iec = u32_get_bits(tas_selection,
 				       IWL_WTAS_OVERRIDE_IEC_MSK);
+	u8 canada_tas_uhb = u32_get_bits(tas_selection,
+					 IWL_WTAS_CANADA_UHB_MSK);
 	u8 enabled_iec = u32_get_bits(tas_selection, IWL_WTAS_ENABLE_IEC_MSK);
 	u8 usa_tas_uhb = u32_get_bits(tas_selection, IWL_WTAS_USA_UHB_MSK);
 	int enabled = tas_selection & IWL_WTAS_ENABLED_MSK;
@@ -441,6 +443,9 @@  int iwl_parse_tas_selection(struct iwl_fw_runtime *fwrt,
 	tas_data->override_tas_iec = override_iec;
 	tas_data->enable_tas_iec = enabled_iec;
 
+	if (tbl_rev > 1)
+		tas_data->canada_tas_uhb_allowed = canada_tas_uhb;
+
 	return enabled;
 }
 
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h
index 4ced1711d913..f247d31ebdd6 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h
@@ -43,6 +43,7 @@ 
 #define IWL_WTAS_ENABLED_MSK		0x1
 #define IWL_WTAS_OVERRIDE_IEC_MSK	0x2
 #define IWL_WTAS_ENABLE_IEC_MSK	0x4
+#define IWL_WTAS_CANADA_UHB_MSK		BIT(15)
 #define IWL_WTAS_USA_UHB_MSK		BIT(16)
 
 #define BIOS_MCC_CHINA 0x434e
@@ -99,9 +100,10 @@  struct iwl_ppag_chain {
 struct iwl_tas_data {
 	__le32 block_list_size;
 	__le32 block_list_array[IWL_WTAS_BLACK_LIST_MAX];
-	u8 override_tas_iec;
-	u8 enable_tas_iec;
-	u8 usa_tas_uhb_allowed;
+	u8 override_tas_iec:1,
+	   enable_tas_iec:1,
+	   usa_tas_uhb_allowed:1,
+	   canada_tas_uhb_allowed:1;
 };
 
 /* For DSM revision 0 and 4 */
@@ -185,7 +187,7 @@  bool iwl_is_tas_approved(void);
 
 int iwl_parse_tas_selection(struct iwl_fw_runtime *fwrt,
 			    struct iwl_tas_data *tas_data,
-			    const u32 tas_selection);
+			    const u32 tas_selection, u8 tbl_rev);
 
 int iwl_bios_get_wrds_table(struct iwl_fw_runtime *fwrt);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c
index 091fb6fd7c78..dcbb3c387c10 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c
@@ -561,7 +561,8 @@  int iwl_uefi_get_tas_table(struct iwl_fw_runtime *fwrt,
 	if (IS_ERR(uefi_tas))
 		return -EINVAL;
 
-	if (uefi_tas->revision != IWL_UEFI_WTAS_REVISION) {
+	if (uefi_tas->revision < IWL_UEFI_MIN_WTAS_REVISION ||
+	    uefi_tas->revision > IWL_UEFI_MAX_WTAS_REVISION) {
 		ret = -EINVAL;
 		IWL_DEBUG_RADIO(fwrt, "Unsupported UEFI WTAS revision:%d\n",
 				uefi_tas->revision);
@@ -569,7 +570,9 @@  int iwl_uefi_get_tas_table(struct iwl_fw_runtime *fwrt,
 	}
 
 	enabled = iwl_parse_tas_selection(fwrt, tas_data,
-					  uefi_tas->tas_selection);
+					  uefi_tas->tas_selection,
+					  uefi_tas->revision);
+
 	if (!enabled) {
 		IWL_DEBUG_RADIO(fwrt, "TAS not enabled\n");
 		ret = 0;
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h
index e525d449e656..4e98f752b3d2 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.h
@@ -33,7 +33,8 @@ 
 #define IWL_UEFI_WGDS_REVISION		3
 #define IWL_UEFI_MIN_PPAG_REV		1
 #define IWL_UEFI_MAX_PPAG_REV		3
-#define IWL_UEFI_WTAS_REVISION		1
+#define IWL_UEFI_MIN_WTAS_REVISION	1
+#define IWL_UEFI_MAX_WTAS_REVISION	2
 #define IWL_UEFI_SPLC_REVISION		0
 #define IWL_UEFI_WRDD_REVISION		0
 #define IWL_UEFI_ECKV_REVISION		0
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 5ea684802ad1..029347b79655 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -1171,6 +1171,10 @@  static void iwl_mvm_tas_init(struct iwl_mvm *mvm)
 		cmd.v4.override_tas_iec = data.override_tas_iec;
 		cmd.v4.enable_tas_iec = data.enable_tas_iec;
 		cmd.v4.usa_tas_uhb_allowed = data.usa_tas_uhb_allowed;
+		if (fw_has_capa(&mvm->fw->ucode_capa,
+				IWL_UCODE_TLV_CAPA_UHB_CANADA_TAS_SUPPORT) &&
+		    data.canada_tas_uhb_allowed)
+			cmd.v4.uhb_allowed_flags = TAS_UHB_ALLOWED_CANADA;
 	} else {
 		cmd.v3.override_tas_iec = cpu_to_le16(data.override_tas_iec);
 		cmd.v3.enable_tas_iec = cpu_to_le16(data.enable_tas_iec);