Commit 6da7ba3a authored by Ayala Barazani's avatar Ayala Barazani Committed by Luca Coelho

iwlwifi: mvm: allow enabling UHB TAS in the USA via ACPI setting

Read a new bit defined in ACPI WTAS that allows OEMs to specify whether
TAS is allowed in UHB (6-7GHz) in the USA.  This can be used by OEMs
that got certified to use this feature.
Signed-off-by: default avatarAyala Barazani <ayala.barazani@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20220128153014.1d2ae1e6bcdb.I177929ed01ed7bf4614ea0f6db2af9e52de13316@changeidSigned-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent ad12b231
...@@ -242,7 +242,7 @@ union acpi_object *iwl_acpi_get_wifi_pkg_range(struct device *dev, ...@@ -242,7 +242,7 @@ union acpi_object *iwl_acpi_get_wifi_pkg_range(struct device *dev,
IWL_EXPORT_SYMBOL(iwl_acpi_get_wifi_pkg_range); IWL_EXPORT_SYMBOL(iwl_acpi_get_wifi_pkg_range);
int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt, int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt,
struct iwl_tas_config_cmd_v3 *cmd) union iwl_tas_config_cmd *cmd, int fw_ver)
{ {
union acpi_object *wifi_pkg, *data; union acpi_object *wifi_pkg, *data;
int ret, tbl_rev, i, block_list_size, enabled; int ret, tbl_rev, i, block_list_size, enabled;
...@@ -268,10 +268,18 @@ int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt, ...@@ -268,10 +268,18 @@ int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt,
(tas_selection & ACPI_WTAS_OVERRIDE_IEC_MSK) >> ACPI_WTAS_OVERRIDE_IEC_POS; (tas_selection & ACPI_WTAS_OVERRIDE_IEC_MSK) >> ACPI_WTAS_OVERRIDE_IEC_POS;
u16 enabled_iec = (tas_selection & ACPI_WTAS_ENABLE_IEC_MSK) >> u16 enabled_iec = (tas_selection & ACPI_WTAS_ENABLE_IEC_MSK) >>
ACPI_WTAS_ENABLE_IEC_POS; ACPI_WTAS_ENABLE_IEC_POS;
u8 usa_tas_uhb = (tas_selection & ACPI_WTAS_USA_UHB_MSK) >> ACPI_WTAS_USA_UHB_POS;
enabled = tas_selection & ACPI_WTAS_ENABLED_MSK; enabled = tas_selection & ACPI_WTAS_ENABLED_MSK;
cmd->override_tas_iec = cpu_to_le16(override_iec); if (fw_ver <= 3) {
cmd->enable_tas_iec = cpu_to_le16(enabled_iec); cmd->v3.override_tas_iec = cpu_to_le16(override_iec);
cmd->v3.enable_tas_iec = cpu_to_le16(enabled_iec);
} else {
cmd->v4.usa_tas_uhb_allowed = usa_tas_uhb;
cmd->v4.override_tas_iec = (u8)override_iec;
cmd->v4.enable_tas_iec = (u8)enabled_iec;
}
} else if (tbl_rev == 0 && } else if (tbl_rev == 0 &&
wifi_pkg->package.elements[1].type == ACPI_TYPE_INTEGER) { wifi_pkg->package.elements[1].type == ACPI_TYPE_INTEGER) {
...@@ -297,7 +305,7 @@ int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt, ...@@ -297,7 +305,7 @@ int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt,
goto out_free; goto out_free;
} }
block_list_size = wifi_pkg->package.elements[2].integer.value; block_list_size = wifi_pkg->package.elements[2].integer.value;
cmd->block_list_size = cpu_to_le32(block_list_size); cmd->v4.block_list_size = cpu_to_le32(block_list_size);
IWL_DEBUG_RADIO(fwrt, "TAS array size %u\n", block_list_size); IWL_DEBUG_RADIO(fwrt, "TAS array size %u\n", block_list_size);
if (block_list_size > APCI_WTAS_BLACK_LIST_MAX) { if (block_list_size > APCI_WTAS_BLACK_LIST_MAX) {
...@@ -319,7 +327,7 @@ int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt, ...@@ -319,7 +327,7 @@ int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt,
} }
country = wifi_pkg->package.elements[3 + i].integer.value; country = wifi_pkg->package.elements[3 + i].integer.value;
cmd->block_list_array[i] = cpu_to_le32(country); cmd->v4.block_list_array[i] = cpu_to_le32(country);
IWL_DEBUG_RADIO(fwrt, "TAS block list country %d\n", country); IWL_DEBUG_RADIO(fwrt, "TAS block list country %d\n", country);
} }
......
...@@ -77,6 +77,8 @@ ...@@ -77,6 +77,8 @@
#define ACPI_WTAS_ENABLE_IEC_MSK 0x4 #define ACPI_WTAS_ENABLE_IEC_MSK 0x4
#define ACPI_WTAS_OVERRIDE_IEC_POS 0x1 #define ACPI_WTAS_OVERRIDE_IEC_POS 0x1
#define ACPI_WTAS_ENABLE_IEC_POS 0x2 #define ACPI_WTAS_ENABLE_IEC_POS 0x2
#define ACPI_WTAS_USA_UHB_MSK BIT(16)
#define ACPI_WTAS_USA_UHB_POS 16
#define ACPI_PPAG_WIFI_DATA_SIZE_V1 ((IWL_NUM_CHAIN_LIMITS * \ #define ACPI_PPAG_WIFI_DATA_SIZE_V1 ((IWL_NUM_CHAIN_LIMITS * \
...@@ -213,7 +215,7 @@ int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, ...@@ -213,7 +215,7 @@ int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt,
u32 n_bands, u32 n_profiles); u32 n_bands, u32 n_profiles);
int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt, int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt,
struct iwl_tas_config_cmd_v3 *cmd); union iwl_tas_config_cmd *cmd, int fw_ver);
__le32 iwl_acpi_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt); __le32 iwl_acpi_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt);
...@@ -294,7 +296,7 @@ static inline bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt) ...@@ -294,7 +296,7 @@ static inline bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt)
} }
static inline int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt, static inline int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt,
struct iwl_tas_config_cmd_v3 *cmd) union iwl_tas_config_cmd *cmd, int fw_ver)
{ {
return -ENOENT; return -ENOENT;
} }
......
...@@ -419,6 +419,30 @@ struct iwl_tas_config_cmd_v3 { ...@@ -419,6 +419,30 @@ struct iwl_tas_config_cmd_v3 {
__le16 enable_tas_iec; __le16 enable_tas_iec;
} __packed; /* TAS_CONFIG_CMD_API_S_VER_3 */ } __packed; /* TAS_CONFIG_CMD_API_S_VER_3 */
/**
* struct iwl_tas_config_cmd_v3 - 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
* @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
*/
struct iwl_tas_config_cmd_v4 {
__le32 block_list_size;
__le32 block_list_array[IWL_TAS_BLOCK_LIST_MAX];
u8 override_tas_iec;
u8 enable_tas_iec;
u8 usa_tas_uhb_allowed;
u8 reserved;
} __packed; /* TAS_CONFIG_CMD_API_S_VER_4 */
union iwl_tas_config_cmd {
struct iwl_tas_config_cmd_v2 v2;
struct iwl_tas_config_cmd_v3 v3;
struct iwl_tas_config_cmd_v4 v4;
};
/** /**
* enum iwl_lari_configs - bit masks for the various LARI config operations * enum iwl_lari_configs - bit masks for the various LARI config operations
* @LARI_CONFIG_DISABLE_11AC_UKRAINE_MSK: disable 11ac in ukraine * @LARI_CONFIG_DISABLE_11AC_UKRAINE_MSK: disable 11ac in ukraine
......
...@@ -1206,10 +1206,10 @@ static bool iwl_mvm_add_to_tas_block_list(__le32 *list, __le32 *le_size, unsigne ...@@ -1206,10 +1206,10 @@ static bool iwl_mvm_add_to_tas_block_list(__le32 *list, __le32 *le_size, unsigne
static void iwl_mvm_tas_init(struct iwl_mvm *mvm) static void iwl_mvm_tas_init(struct iwl_mvm *mvm)
{ {
int ret; int ret;
struct iwl_tas_config_cmd_v3 cmd = {}; union iwl_tas_config_cmd cmd = {};
int cmd_size; int cmd_size, fw_ver;
BUILD_BUG_ON(ARRAY_SIZE(cmd.block_list_array) < BUILD_BUG_ON(ARRAY_SIZE(cmd.v3.block_list_array) <
APCI_WTAS_BLACK_LIST_MAX); APCI_WTAS_BLACK_LIST_MAX);
if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TAS_CFG)) { if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TAS_CFG)) {
...@@ -1217,7 +1217,10 @@ static void iwl_mvm_tas_init(struct iwl_mvm *mvm) ...@@ -1217,7 +1217,10 @@ static void iwl_mvm_tas_init(struct iwl_mvm *mvm)
return; return;
} }
ret = iwl_acpi_get_tas(&mvm->fwrt, &cmd); fw_ver = iwl_fw_lookup_cmd_ver(mvm->fw, REGULATORY_AND_NVM_GROUP,
TAS_CONFIG, IWL_FW_CMD_VER_UNKNOWN);
ret = iwl_acpi_get_tas(&mvm->fwrt, &cmd, fw_ver);
if (ret < 0) { if (ret < 0) {
IWL_DEBUG_RADIO(mvm, IWL_DEBUG_RADIO(mvm,
"TAS table invalid or unavailable. (%d)\n", "TAS table invalid or unavailable. (%d)\n",
...@@ -1232,19 +1235,20 @@ static void iwl_mvm_tas_init(struct iwl_mvm *mvm) ...@@ -1232,19 +1235,20 @@ static void iwl_mvm_tas_init(struct iwl_mvm *mvm)
IWL_DEBUG_RADIO(mvm, IWL_DEBUG_RADIO(mvm,
"System vendor '%s' is not in the approved list, disabling TAS in US and Canada.\n", "System vendor '%s' is not in the approved list, disabling TAS in US and Canada.\n",
dmi_get_system_info(DMI_SYS_VENDOR)); dmi_get_system_info(DMI_SYS_VENDOR));
if ((!iwl_mvm_add_to_tas_block_list(cmd.block_list_array, if ((!iwl_mvm_add_to_tas_block_list(cmd.v4.block_list_array,
&cmd.block_list_size, IWL_TAS_US_MCC)) || &cmd.v4.block_list_size,
(!iwl_mvm_add_to_tas_block_list(cmd.block_list_array, IWL_TAS_US_MCC)) ||
&cmd.block_list_size, IWL_TAS_CANADA_MCC))) { (!iwl_mvm_add_to_tas_block_list(cmd.v4.block_list_array,
&cmd.v4.block_list_size,
IWL_TAS_CANADA_MCC))) {
IWL_DEBUG_RADIO(mvm, IWL_DEBUG_RADIO(mvm,
"Unable to add US/Canada to TAS block list, disabling TAS\n"); "Unable to add US/Canada to TAS block list, disabling TAS\n");
return; return;
} }
} }
cmd_size = iwl_fw_lookup_cmd_ver(mvm->fw, REGULATORY_AND_NVM_GROUP, /* v4 is the same size as v3, so no need to differentiate here */
TAS_CONFIG, cmd_size = fw_ver < 3 ?
IWL_FW_CMD_VER_UNKNOWN) < 3 ?
sizeof(struct iwl_tas_config_cmd_v2) : sizeof(struct iwl_tas_config_cmd_v2) :
sizeof(struct iwl_tas_config_cmd_v3); sizeof(struct iwl_tas_config_cmd_v3);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment