Skip to content

Commit

Permalink
wifi: iwlwifi: extend TAS_CONFIG cmd support for v5
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Anjaneyulu authored and Johannes Berg committed Jan 13, 2025
1 parent d1f9e5e commit 5f46566
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 101 deletions.
46 changes: 22 additions & 24 deletions drivers/net/wireless/intel/iwlwifi/fw/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 ||
Expand All @@ -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) {
Expand All @@ -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;
Expand Down
42 changes: 41 additions & 1 deletion drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -487,14 +487,54 @@ 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;
struct iwl_tas_config_cmd_v4 v4;
};
};

/**
* 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
Expand Down
35 changes: 18 additions & 17 deletions drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
29 changes: 17 additions & 12 deletions drivers/net/wireless/intel/iwlwifi/fw/regulatory.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

/*
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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);

Expand Down
28 changes: 15 additions & 13 deletions drivers/net/wireless/intel/iwlwifi/fw/uefi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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;
Expand Down
Loading

0 comments on commit 5f46566

Please sign in to comment.