Commit ad5a85d8 authored by Miri Korenblit's avatar Miri Korenblit Committed by Johannes Berg

wifi: iwlwifi: prepare for reading TAS table from UEFI

We are going to support reading BIOS tables from UEFI
too, Refactor the TAS table flow:

1. Rename and move the common code to the regulatory.h/c files.
2. Remove the IWL_TAS_BLOCK_LIST_MAX, as we can use IWL_WTAS_BLACK_LIST_MAX
   instead.
Signed-off-by: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Reviewed-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Link: https://msgid.link/20240131091413.0c2197cf1feb.Ib0e83d5bd3f4d5cfa9c3d2925317ba49377d257f@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent e1c54d63
......@@ -273,22 +273,9 @@ int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt,
ACPI_TYPE_INTEGER) {
u32 tas_selection =
(u32)wifi_pkg->package.elements[1].integer.value;
u16 override_iec =
(tas_selection & ACPI_WTAS_OVERRIDE_IEC_MSK) >> ACPI_WTAS_OVERRIDE_IEC_POS;
u16 enabled_iec = (tas_selection & ACPI_WTAS_ENABLE_IEC_MSK) >>
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;
if (fw_ver <= 3) {
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;
}
enabled = iwl_parse_tas_selection(fwrt, cmd, fw_ver,
tas_selection);
} else if (tbl_rev == 0 &&
wifi_pkg->package.elements[1].type == ACPI_TYPE_INTEGER) {
......@@ -307,7 +294,7 @@ int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt,
IWL_DEBUG_RADIO(fwrt, "Reading TAS table revision %d\n", tbl_rev);
if (wifi_pkg->package.elements[2].type != ACPI_TYPE_INTEGER ||
wifi_pkg->package.elements[2].integer.value >
APCI_WTAS_BLACK_LIST_MAX) {
IWL_WTAS_BLACK_LIST_MAX) {
IWL_DEBUG_RADIO(fwrt, "TAS invalid array size %llu\n",
wifi_pkg->package.elements[2].integer.value);
ret = -EINVAL;
......
......@@ -78,16 +78,7 @@
* 1 element for block list size,
* 16 elements for block list array
*/
#define APCI_WTAS_BLACK_LIST_MAX 16
#define ACPI_WTAS_WIFI_DATA_SIZE (3 + APCI_WTAS_BLACK_LIST_MAX)
#define ACPI_WTAS_ENABLED_MSK 0x1
#define ACPI_WTAS_OVERRIDE_IEC_MSK 0x2
#define ACPI_WTAS_ENABLE_IEC_MSK 0x4
#define ACPI_WTAS_OVERRIDE_IEC_POS 0x1
#define ACPI_WTAS_ENABLE_IEC_POS 0x2
#define ACPI_WTAS_USA_UHB_MSK BIT(16)
#define ACPI_WTAS_USA_UHB_POS 16
#define ACPI_WTAS_WIFI_DATA_SIZE (3 + IWL_WTAS_BLACK_LIST_MAX)
#define ACPI_PPAG_WIFI_DATA_SIZE_V1 ((IWL_NUM_CHAIN_LIMITS * \
IWL_NUM_SUB_BANDS_V1) + 2)
......
......@@ -7,6 +7,7 @@
#ifndef __iwl_fw_api_nvm_reg_h__
#define __iwl_fw_api_nvm_reg_h__
#include "fw/regulatory.h"
/**
* enum iwl_regulatory_and_nvm_subcmd_ids - regulatory/NVM commands
*/
......@@ -438,7 +439,6 @@ enum iwl_mcc_source {
MCC_SOURCE_GETTING_MCC_TEST_MODE = 0x11,
};
#define IWL_TAS_BLOCK_LIST_MAX 16
/**
* struct iwl_tas_config_cmd_v2 - configures the TAS
* @block_list_size: size of relevant field in block_list_array
......@@ -446,7 +446,7 @@ enum iwl_mcc_source {
*/
struct iwl_tas_config_cmd_v2 {
__le32 block_list_size;
__le32 block_list_array[IWL_TAS_BLOCK_LIST_MAX];
__le32 block_list_array[IWL_WTAS_BLACK_LIST_MAX];
} __packed; /* TAS_CONFIG_CMD_API_S_VER_2 */
/**
......@@ -459,7 +459,7 @@ struct iwl_tas_config_cmd_v2 {
*/
struct iwl_tas_config_cmd_v3 {
__le32 block_list_size;
__le32 block_list_array[IWL_TAS_BLOCK_LIST_MAX];
__le32 block_list_array[IWL_WTAS_BLACK_LIST_MAX];
__le16 override_tas_iec;
__le16 enable_tas_iec;
} __packed; /* TAS_CONFIG_CMD_API_S_VER_3 */
......@@ -476,7 +476,7 @@ struct iwl_tas_config_cmd_v3 {
*/
struct iwl_tas_config_cmd_v4 {
__le32 block_list_size;
__le32 block_list_array[IWL_TAS_BLOCK_LIST_MAX];
__le32 block_list_array[IWL_WTAS_BLACK_LIST_MAX];
u8 override_tas_iec;
u8 enable_tas_iec;
u8 usa_tas_uhb_allowed;
......
......@@ -3,6 +3,7 @@
* Copyright (C) 2023 Intel Corporation
*/
#include <linux/dmi.h>
#include "fw/api/nvm-reg.h"
#include "iwl-drv.h"
#include "iwl-debug.h"
#include "regulatory.h"
......@@ -83,6 +84,62 @@ static const struct dmi_system_id dmi_ppag_approved_list[] = {
{}
};
static const struct dmi_system_id dmi_tas_approved_list[] = {
{ .ident = "HP",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
},
},
{ .ident = "SAMSUNG",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
},
},
{ .ident = "LENOVO",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
},
},
{ .ident = "DELL",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
},
},
{ .ident = "MSFT",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
},
},
{ .ident = "Acer",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
},
},
{ .ident = "ASUS",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
},
},
{ .ident = "GOOGLE-HP",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
},
},
{ .ident = "MSI",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
},
},
{ .ident = "Honor",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "HONOR"),
},
},
/* keep last */
{}
};
bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt)
{
/*
......@@ -335,3 +392,37 @@ bool iwl_is_ppag_approved(struct iwl_fw_runtime *fwrt)
return true;
}
IWL_EXPORT_SYMBOL(iwl_is_ppag_approved);
bool iwl_is_tas_approved(void)
{
return dmi_check_system(dmi_tas_approved_list);
}
IWL_EXPORT_SYMBOL(iwl_is_tas_approved);
int iwl_parse_tas_selection(struct iwl_fw_runtime *fwrt,
union iwl_tas_config_cmd *cmd, int fw_ver,
const u32 tas_selection)
{
u8 override_iec = u32_get_bits(tas_selection,
IWL_WTAS_OVERRIDE_IEC_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);
if (fw_ver < 3)
return enabled;
if (fw_ver == 3) {
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 = override_iec;
cmd->v4.enable_tas_iec = enabled_iec;
}
return enabled;
}
......@@ -10,7 +10,6 @@
#include "fw/api/commands.h"
#include "fw/api/power.h"
#include "fw/api/phy.h"
#include "fw/api/nvm-reg.h"
#include "fw/api/config.h"
#include "fw/img.h"
#include "iwl-trans.h"
......@@ -40,6 +39,12 @@
#define IWL_PPAG_ETSI_CHINA_MASK 3
#define IWL_PPAG_ETSI_MASK BIT(0)
#define IWL_WTAS_BLACK_LIST_MAX 16
#define IWL_WTAS_ENABLED_MSK 0x1
#define IWL_WTAS_OVERRIDE_IEC_MSK 0x2
#define IWL_WTAS_ENABLE_IEC_MSK 0x4
#define IWL_WTAS_USA_UHB_MSK BIT(16)
/*
* The profile for revision 2 is a superset of revision 1, which is in
* turn a superset of revision 0. So we can store all revisions
......@@ -91,6 +96,8 @@ struct iwl_ppag_chain {
struct iwl_fw_runtime;
union iwl_tas_config_cmd;
bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt);
int iwl_sar_geo_fill_table(struct iwl_fw_runtime *fwrt,
......@@ -107,6 +114,12 @@ int iwl_fill_ppag_table(struct iwl_fw_runtime *fwrt,
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,
union iwl_tas_config_cmd *cmd, int fw_ver,
const u32 tas_selection);
int iwl_bios_get_wrds_table(struct iwl_fw_runtime *fwrt);
int iwl_bios_get_ewrd_table(struct iwl_fw_runtime *fwrt);
......
......@@ -877,14 +877,14 @@ static ssize_t iwl_dbgfs_tas_get_status_read(struct file *file,
le16_to_cpu(rsp->curr_mcc));
pos += scnprintf(pos, endpos - pos, "Block list entries:");
for (i = 0; i < APCI_WTAS_BLACK_LIST_MAX; i++)
for (i = 0; i < IWL_WTAS_BLACK_LIST_MAX; i++)
pos += scnprintf(pos, endpos - pos, " 0x%x",
le16_to_cpu(rsp->block_list[i]));
pos += scnprintf(pos, endpos - pos, "\nOEM name: %s\n",
dmi_get_system_info(DMI_SYS_VENDOR));
pos += scnprintf(pos, endpos - pos, "\tVendor In Approved List: %s\n",
iwl_mvm_is_vendor_in_approved_list() ? "YES" : "NO");
iwl_is_tas_approved() ? "YES" : "NO");
pos += scnprintf(pos, endpos - pos,
"\tDo TAS Support Dual Radio?: %s\n",
rsp->in_dual_radio ? "TRUE" : "FALSE");
......
......@@ -1110,66 +1110,7 @@ static int iwl_mvm_ppag_init(struct iwl_mvm *mvm)
#ifdef CONFIG_ACPI
static const struct dmi_system_id dmi_tas_approved_list[] = {
{ .ident = "HP",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
},
},
{ .ident = "SAMSUNG",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD"),
},
},
{ .ident = "LENOVO",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
},
},
{ .ident = "DELL",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
},
},
{ .ident = "MSFT",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
},
},
{ .ident = "Acer",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
},
},
{ .ident = "ASUS",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
},
},
{ .ident = "GOOGLE-HP",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
},
},
{ .ident = "MSI",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
},
},
{ .ident = "Honor",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "HONOR"),
},
},
/* keep last */
{}
};
bool iwl_mvm_is_vendor_in_approved_list(void)
{
return dmi_check_system(dmi_tas_approved_list);
}
static bool iwl_mvm_add_to_tas_block_list(__le32 *list, __le32 *le_size, unsigned int mcc)
{
......@@ -1177,7 +1118,7 @@ static bool iwl_mvm_add_to_tas_block_list(__le32 *list, __le32 *le_size, unsigne
u32 size = le32_to_cpu(*le_size);
/* Verify that there is room for another country */
if (size >= IWL_TAS_BLOCK_LIST_MAX)
if (size >= IWL_WTAS_BLACK_LIST_MAX)
return false;
for (i = 0; i < size; i++) {
......@@ -1198,7 +1139,7 @@ static void iwl_mvm_tas_init(struct iwl_mvm *mvm)
int cmd_size, fw_ver;
BUILD_BUG_ON(ARRAY_SIZE(cmd.v3.block_list_array) <
APCI_WTAS_BLACK_LIST_MAX);
IWL_WTAS_BLACK_LIST_MAX);
if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TAS_CFG)) {
IWL_DEBUG_RADIO(mvm, "TAS not enabled in FW\n");
......@@ -1219,7 +1160,7 @@ static void iwl_mvm_tas_init(struct iwl_mvm *mvm)
if (ret == 0)
return;
if (!iwl_mvm_is_vendor_in_approved_list()) {
if (!iwl_is_tas_approved()) {
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));
......@@ -1397,11 +1338,6 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm)
{
}
bool iwl_mvm_is_vendor_in_approved_list(void)
{
return false;
}
static u8 iwl_mvm_eval_dsm_rfi(struct iwl_mvm *mvm)
{
return DSM_VALUE_RFI_DISABLE;
......
......@@ -2620,7 +2620,6 @@ static inline bool iwl_mvm_mei_filter_scan(struct iwl_mvm *mvm,
void iwl_mvm_send_roaming_forbidden_event(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
bool forbidden);
bool iwl_mvm_is_vendor_in_approved_list(void);
/* Callbacks for ieee80211_ops */
void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
......
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