summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/fw
diff options
context:
space:
mode:
authorAnjaneyulu <pagadala.yesu.anjaneyulu@intel.com>2024-12-31 13:59:10 +0200
committerJohannes Berg <johannes.berg@intel.com>2025-01-13 15:34:07 +0100
commit5f4656610edb27c84d9e3378aea9024bf8d723ab (patch)
tree4505c5d4d350451675e4eaf618ebf9fdd49cc3b7 /drivers/net/wireless/intel/iwlwifi/fw
parentd1f9e5e9ed1b98e82562632bb12edb52fc23ddf1 (diff)
wifi: iwlwifi: extend TAS_CONFIG cmd support for v5
Extend TAS_CONFIG to send exact data read from bios to firmware without filtering/altering bios data. This enables driver becoming purely a pipe for TAS features. Signed-off-by: Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://patch.msgid.link/20241231135726.f46d58e7cfd1.Ifd81e632fa3e7039b8d139ee0d1c24e09669dff5@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/fw')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/acpi.c46
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h42
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/regulatory.c35
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/regulatory.h29
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/uefi.c28
5 files changed, 113 insertions, 67 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
index 747b18ebbd66..efa7b673ebc7 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
@@ -262,13 +262,14 @@ int iwl_acpi_get_tas_table(struct iwl_fw_runtime *fwrt,
struct iwl_tas_data *tas_data)
{
union acpi_object *wifi_pkg, *data;
- int ret, tbl_rev, i, block_list_size, enabled;
+ int ret, tbl_rev, block_list_size, enabled;
+ u32 tas_selection;
data = iwl_acpi_get_object(fwrt->dev, ACPI_WTAS_METHOD);
if (IS_ERR(data))
return PTR_ERR(data);
- /* try to read wtas table revision 1 or revision 0*/
+ /* try to read wtas table */
wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data,
ACPI_WTAS_WIFI_DATA_SIZE,
&tbl_rev);
@@ -277,27 +278,23 @@ int iwl_acpi_get_tas_table(struct iwl_fw_runtime *fwrt,
goto out_free;
}
- 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, tbl_rev);
-
- } else if (tbl_rev == 0 &&
- wifi_pkg->package.elements[1].type == ACPI_TYPE_INTEGER) {
- enabled = !!wifi_pkg->package.elements[1].integer.value;
- } else {
+ if (tbl_rev < 0 || tbl_rev > 2 ||
+ wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) {
ret = -EINVAL;
goto out_free;
}
- if (!enabled) {
- IWL_DEBUG_RADIO(fwrt, "TAS not enabled\n");
- ret = 0;
- goto out_free;
- }
+ tas_selection = (u32)wifi_pkg->package.elements[1].integer.value;
+ enabled = tas_selection & IWL_WTAS_ENABLED_MSK;
+
+ IWL_DEBUG_RADIO(fwrt, "TAS selection as read from BIOS: 0x%x\n",
+ tas_selection);
+ tas_data->table_source = BIOS_SOURCE_ACPI;
+ tas_data->table_revision = tbl_rev;
+ tas_data->tas_selection = tas_selection;
+
+ IWL_DEBUG_RADIO(fwrt, "TAS %s enabled\n",
+ enabled ? "is" : "not");
IWL_DEBUG_RADIO(fwrt, "Reading TAS table revision %d\n", tbl_rev);
if (wifi_pkg->package.elements[2].type != ACPI_TYPE_INTEGER ||
@@ -308,13 +305,14 @@ int iwl_acpi_get_tas_table(struct iwl_fw_runtime *fwrt,
ret = -EINVAL;
goto out_free;
}
+
block_list_size = wifi_pkg->package.elements[2].integer.value;
- tas_data->block_list_size = cpu_to_le32(block_list_size);
+ tas_data->block_list_size = block_list_size;
IWL_DEBUG_RADIO(fwrt, "TAS array size %u\n", block_list_size);
- for (i = 0; i < block_list_size; i++) {
- u32 country;
+ for (int i = 0; i < block_list_size; i++) {
+ u16 country;
if (wifi_pkg->package.elements[3 + i].type !=
ACPI_TYPE_INTEGER) {
@@ -325,11 +323,11 @@ int iwl_acpi_get_tas_table(struct iwl_fw_runtime *fwrt,
}
country = wifi_pkg->package.elements[3 + i].integer.value;
- tas_data->block_list_array[i] = cpu_to_le32(country);
+ tas_data->block_list_array[i] = country;
IWL_DEBUG_RADIO(fwrt, "TAS block list country %d\n", country);
}
- ret = 1;
+ ret = enabled;
out_free:
kfree(data);
return ret;
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 1bf549775c7c..5cdc09d465d4 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
@@ -487,7 +487,7 @@ struct iwl_tas_config_cmd_v4 {
u8 uhb_allowed_flags;
} __packed; /* TAS_CONFIG_CMD_API_S_VER_4 */
-struct iwl_tas_config_cmd {
+struct iwl_tas_config_cmd_v2_v4 {
struct iwl_tas_config_cmd_common common;
union {
struct iwl_tas_config_cmd_v3 v3;
@@ -496,6 +496,46 @@ struct iwl_tas_config_cmd {
};
/**
+ * enum bios_source - source of bios data
+ * @BIOS_SOURCE_NONE: BIOS source is not defined
+ * @BIOS_SOURCE_ACPI: BIOS source is ACPI
+ * @BIOS_SOURCE_UEFI: BIOS source is UEFI
+ */
+enum bios_source {
+ BIOS_SOURCE_NONE,
+ BIOS_SOURCE_ACPI,
+ BIOS_SOURCE_UEFI,
+};
+
+/**
+ * struct bios_value_u32 - BIOS configuration.
+ * @table_source: see &enum bios_source
+ * @table_revision: table revision.
+ * @reserved: reserved
+ * @value: value in bios.
+ */
+struct bios_value_u32 {
+ u8 table_source;
+ u8 table_revision;
+ u8 reserved[2];
+ __le32 value;
+} __packed; /* BIOS_TABLE_SOURCE_U32_S_VER_1 */
+
+/**
+ * struct iwl_tas_config_cmd - configures the TAS.
+ * @block_list_size: size of relevant field in block_list_array
+ * @block_list_array: list of countries where TAS must be disabled
+ * @reserved: reserved
+ * @tas_config_info: see @struct bios_value_u32
+ */
+struct iwl_tas_config_cmd {
+ __le16 block_list_size;
+ __le16 block_list_array[IWL_WTAS_BLACK_LIST_MAX];
+ u8 reserved[2];
+ struct bios_value_u32 tas_config_info;
+} __packed; /* TAS_CONFIG_CMD_API_S_VER_5 */
+
+/**
* enum iwl_lari_config_masks - bit masks for the various LARI config operations
* @LARI_CONFIG_DISABLE_11AC_UKRAINE_MSK: disable 11ac in ukraine
* @LARI_CONFIG_CHANGE_ETSI_TO_PASSIVE_MSK: ETSI 5.8GHz SRD passive scan
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
index 27423202a864..ea435ee94312 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
@@ -430,30 +430,31 @@ bool iwl_is_tas_approved(void)
}
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, u8 tbl_rev)
+struct iwl_tas_selection_data
+iwl_parse_tas_selection(const u32 tas_selection_in, const u8 tbl_rev)
{
- u8 override_iec = u32_get_bits(tas_selection,
+ struct iwl_tas_selection_data tas_selection_out = {};
+ u8 override_iec = u32_get_bits(tas_selection_in,
IWL_WTAS_OVERRIDE_IEC_MSK);
- u8 canada_tas_uhb = u32_get_bits(tas_selection,
+ u8 canada_tas_uhb = u32_get_bits(tas_selection_in,
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;
-
- IWL_DEBUG_RADIO(fwrt, "TAS selection as read from BIOS: 0x%x\n",
- tas_selection);
-
- tas_data->usa_tas_uhb_allowed = usa_tas_uhb;
- tas_data->override_tas_iec = override_iec;
- tas_data->enable_tas_iec = enabled_iec;
+ u8 enabled_iec = u32_get_bits(tas_selection_in,
+ IWL_WTAS_ENABLE_IEC_MSK);
+ u8 usa_tas_uhb = u32_get_bits(tas_selection_in,
+ IWL_WTAS_USA_UHB_MSK);
+
+ if (tbl_rev > 0) {
+ tas_selection_out.usa_tas_uhb_allowed = usa_tas_uhb;
+ tas_selection_out.override_tas_iec = override_iec;
+ tas_selection_out.enable_tas_iec = enabled_iec;
+ }
if (tbl_rev > 1)
- tas_data->canada_tas_uhb_allowed = canada_tas_uhb;
+ tas_selection_out.canada_tas_uhb_allowed = canada_tas_uhb;
- return enabled;
+ return tas_selection_out;
}
+IWL_EXPORT_SYMBOL(iwl_parse_tas_selection);
static __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)
{
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h
index afdc0ec75ba5..b355d7bef14c 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.h
@@ -40,12 +40,19 @@
#define IWL_PPAG_ETSI_CHINA_MASK 3
#define IWL_PPAG_REV3_MASK 0x7FF
-#define IWL_WTAS_ENABLED_MSK 0x1
-#define IWL_WTAS_OVERRIDE_IEC_MSK 0x2
-#define IWL_WTAS_ENABLE_IEC_MSK 0x4
+#define IWL_WTAS_ENABLED_MSK BIT(0)
+#define IWL_WTAS_OVERRIDE_IEC_MSK BIT(1)
+#define IWL_WTAS_ENABLE_IEC_MSK BIT(2)
#define IWL_WTAS_CANADA_UHB_MSK BIT(15)
#define IWL_WTAS_USA_UHB_MSK BIT(16)
+struct iwl_tas_selection_data {
+ u8 override_tas_iec:1,
+ enable_tas_iec:1,
+ usa_tas_uhb_allowed:1,
+ canada_tas_uhb_allowed:1;
+};
+
#define BIOS_MCC_CHINA 0x434e
/*
@@ -98,12 +105,11 @@ 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:1,
- enable_tas_iec:1,
- usa_tas_uhb_allowed:1,
- canada_tas_uhb_allowed:1;
+ u8 block_list_size;
+ u16 block_list_array[IWL_WTAS_BLACK_LIST_MAX];
+ u8 table_source;
+ u8 table_revision;
+ u32 tas_selection;
};
/* For DSM revision 0 and 4 */
@@ -185,9 +191,8 @@ bool iwl_is_ppag_approved(struct iwl_fw_runtime *fwrt);
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, u8 tbl_rev);
+struct iwl_tas_selection_data
+iwl_parse_tas_selection(const u32 tas_selection, const 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 cc7659d59cf0..434eed4130b9 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c
@@ -570,7 +570,7 @@ int iwl_uefi_get_tas_table(struct iwl_fw_runtime *fwrt,
struct iwl_tas_data *tas_data)
{
struct uefi_cnv_var_wtas *uefi_tas;
- int ret = 0, enabled, i;
+ int ret, enabled;
uefi_tas = iwl_uefi_get_verified_variable(fwrt->trans, IWL_UEFI_WTAS_NAME,
"WTAS", sizeof(*uefi_tas), NULL);
@@ -585,15 +585,16 @@ int iwl_uefi_get_tas_table(struct iwl_fw_runtime *fwrt,
goto out;
}
- enabled = iwl_parse_tas_selection(fwrt, tas_data,
- uefi_tas->tas_selection,
- uefi_tas->revision);
+ IWL_DEBUG_RADIO(fwrt, "TAS selection as read from BIOS: 0x%x\n",
+ uefi_tas->tas_selection);
- if (!enabled) {
- IWL_DEBUG_RADIO(fwrt, "TAS not enabled\n");
- ret = 0;
- goto out;
- }
+ enabled = uefi_tas->tas_selection & IWL_WTAS_ENABLED_MSK;
+ tas_data->table_source = BIOS_SOURCE_UEFI;
+ tas_data->table_revision = uefi_tas->revision;
+ tas_data->tas_selection = uefi_tas->tas_selection;
+
+ IWL_DEBUG_RADIO(fwrt, "TAS %s enabled\n",
+ enabled ? "is" : "not");
IWL_DEBUG_RADIO(fwrt, "Reading TAS table revision %d\n",
uefi_tas->revision);
@@ -603,15 +604,16 @@ int iwl_uefi_get_tas_table(struct iwl_fw_runtime *fwrt,
ret = -EINVAL;
goto out;
}
- tas_data->block_list_size = cpu_to_le32(uefi_tas->black_list_size);
+
+ tas_data->block_list_size = uefi_tas->black_list_size;
IWL_DEBUG_RADIO(fwrt, "TAS array size %u\n", uefi_tas->black_list_size);
- for (i = 0; i < uefi_tas->black_list_size; i++) {
- tas_data->block_list_array[i] =
- cpu_to_le32(uefi_tas->black_list[i]);
+ for (u8 i = 0; i < uefi_tas->black_list_size; i++) {
+ tas_data->block_list_array[i] = uefi_tas->black_list[i];
IWL_DEBUG_RADIO(fwrt, "TAS block list country %d\n",
uefi_tas->black_list[i]);
}
+ ret = enabled;
out:
kfree(uefi_tas);
return ret;