wifi: iwlwifi: read DSM functions from UEFI

For each DSM function, try to first read it from the UEFI.
If the UEFI WIFI GUID is unclocked, or the DSM function in
UEFI is invalid/unavailable - read it from ACPI.

Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Reviewed-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://msgid.link/20240201155157.27dd626ce2bd.Ib90bab74a9d56deb2362edb712294360e4ddae5b@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Miri Korenblit 2024-02-01 16:17:37 +02:00 committed by Johannes Berg
parent dc4fe7500e
commit fc7214c3c9
7 changed files with 75 additions and 12 deletions

View file

@ -187,7 +187,6 @@ int iwl_acpi_get_dsm(struct iwl_fw_runtime *fwrt,
return 0;
}
IWL_EXPORT_SYMBOL(iwl_acpi_get_dsm);
static union acpi_object *
iwl_acpi_get_wifi_pkg_range(struct device *dev,

View file

@ -443,7 +443,7 @@ __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)
case IWL_CFG_RF_TYPE_HR2:
case IWL_CFG_RF_TYPE_JF1:
case IWL_CFG_RF_TYPE_JF2:
ret = iwl_acpi_get_dsm(fwrt, DSM_FUNC_ENABLE_INDONESIA_5G2,
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_ENABLE_INDONESIA_5G2,
&val);
if (!ret && val == DSM_VALUE_INDONESIA_ENABLE)
@ -454,7 +454,7 @@ __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)
break;
}
ret = iwl_acpi_get_dsm(fwrt, DSM_FUNC_DISABLE_SRD, &val);
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_DISABLE_SRD, &val);
if (!ret) {
if (val == DSM_VALUE_SRD_PASSIVE)
config_bitmap |=
@ -466,7 +466,7 @@ __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)
if (fw_has_capa(&fwrt->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_CHINA_22_REG_SUPPORT)) {
ret = iwl_acpi_get_dsm(fwrt, DSM_FUNC_REGULATORY_CONFIG,
ret = iwl_bios_get_dsm(fwrt, DSM_FUNC_REGULATORY_CONFIG,
&val);
/*
* China 2022 enable if the BIOS object does not exist or
@ -480,3 +480,10 @@ __le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)
return config_bitmap;
}
IWL_EXPORT_SYMBOL(iwl_get_lari_config_bitmap);
int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
u32 *value)
{
GET_BIOS_TABLE(dsm, fwrt, func, value);
}
IWL_EXPORT_SYMBOL(iwl_bios_get_dsm);

View file

@ -186,4 +186,7 @@ int iwl_bios_get_mcc(struct iwl_fw_runtime *fwrt, char *mcc);
int iwl_bios_get_eckv(struct iwl_fw_runtime *fwrt, u32 *ext_clk);
__le32 iwl_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt);
int iwl_bios_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
u32 *value);
#endif /* __fw_regulatory_h__ */

View file

@ -674,3 +674,36 @@ int iwl_uefi_get_eckv(struct iwl_fw_runtime *fwrt, u32 *extl_clk)
kfree(data);
return ret;
}
int iwl_uefi_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
u32 *value)
{
struct uefi_cnv_var_general_cfg *data;
int ret = EINVAL;
/* Not supported function index */
if (func >= DSM_FUNC_NUM_FUNCS || func == 5)
return -EOPNOTSUPP;
data = iwl_uefi_get_verified_variable(fwrt->trans, IWL_UEFI_DSM_NAME,
"DSM", sizeof(*data), NULL);
if (IS_ERR(data))
return -EINVAL;
if (data->revision != IWL_UEFI_DSM_REVISION) {
IWL_DEBUG_RADIO(fwrt, "Unsupported UEFI DSM revision:%d\n",
data->revision);
goto out;
}
if (ARRAY_SIZE(data->functions) != UEFI_MAX_DSM_FUNCS) {
IWL_DEBUG_RADIO(fwrt, "Invalid size of DSM functions array\n");
goto out;
}
*value = data->functions[func];
ret = 0;
out:
kfree(data);
return ret;
}

View file

@ -20,6 +20,7 @@
#define IWL_UEFI_SPLC_NAME L"UefiCnvWlanSPLC"
#define IWL_UEFI_WRDD_NAME L"UefiCnvWlanWRDD"
#define IWL_UEFI_ECKV_NAME L"UefiCnvWlanECKV"
#define IWL_UEFI_DSM_NAME L"UefiCnvWlanGeneralCfg"
#define IWL_SGOM_MAP_SIZE 339
@ -34,6 +35,7 @@
#define IWL_UEFI_SPLC_REVISION 0
#define IWL_UEFI_WRDD_REVISION 0
#define IWL_UEFI_ECKV_REVISION 0
#define IWL_UEFI_DSM_REVISION 4
struct pnvm_sku_package {
u8 rev;
@ -166,6 +168,17 @@ struct uefi_cnv_var_eckv {
u32 ext_clock_valid;
} __packed;
#define UEFI_MAX_DSM_FUNCS 32
/* struct uefi_cnv_var_general_cfg - DSM-like table as defined in UEFI
* @revision: the revision of the table
* @functions: payload of the different DSM functions
*/
struct uefi_cnv_var_general_cfg {
u8 revision;
u32 functions[UEFI_MAX_DSM_FUNCS];
} __packed;
/*
* This is known to be broken on v4.19 and to work on v5.4. Until we
* figure out why this is the case and how to make it work, simply
@ -190,6 +203,8 @@ int iwl_uefi_get_pwr_limit(struct iwl_fw_runtime *fwrt,
u64 *dflt_pwr_limit);
int iwl_uefi_get_mcc(struct iwl_fw_runtime *fwrt, char *mcc);
int iwl_uefi_get_eckv(struct iwl_fw_runtime *fwrt, u32 *extl_clk);
int iwl_uefi_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
u32 *value);
#else /* CONFIG_EFI */
static inline void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len)
{
@ -263,6 +278,12 @@ static inline int iwl_uefi_get_eckv(struct iwl_fw_runtime *fwrt, u32 *extl_clk)
{
return -ENOENT;
}
static inline int iwl_uefi_get_dsm(struct iwl_fw_runtime *fwrt,
enum iwl_dsm_funcs func, u32 *value)
{
return -ENOENT;
}
#endif /* CONFIG_EFI */
#if defined(CONFIG_EFI) && defined(CONFIG_ACPI)

View file

@ -391,7 +391,7 @@ static ssize_t iwl_dbgfs_wifi_6e_enable_read(struct file *file,
char buf[12];
u32 value;
err = iwl_acpi_get_dsm(&mvm->fwrt, DSM_FUNC_ENABLE_6E, &value);
err = iwl_bios_get_dsm(&mvm->fwrt, DSM_FUNC_ENABLE_6E, &value);
if (err)
return err;

View file

@ -1206,7 +1206,7 @@ static bool iwl_mvm_eval_dsm_rfi(struct iwl_mvm *mvm)
u32 value = 0;
/* default behaviour is disabled */
bool bios_enable_rfi = false;
int ret = iwl_acpi_get_dsm(&mvm->fwrt, DSM_FUNC_RFI_CONFIG, &value);
int ret = iwl_bios_get_dsm(&mvm->fwrt, DSM_FUNC_RFI_CONFIG, &value);
if (ret < 0) {
@ -1244,31 +1244,31 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm)
cmd.config_bitmap = iwl_get_lari_config_bitmap(&mvm->fwrt);
ret = iwl_acpi_get_dsm(&mvm->fwrt, DSM_FUNC_11AX_ENABLEMENT, &value);
ret = iwl_bios_get_dsm(&mvm->fwrt, DSM_FUNC_11AX_ENABLEMENT, &value);
if (!ret)
cmd.oem_11ax_allow_bitmap = cpu_to_le32(value);
ret = iwl_acpi_get_dsm(&mvm->fwrt, DSM_FUNC_ENABLE_UNII4_CHAN, &value);
ret = iwl_bios_get_dsm(&mvm->fwrt, DSM_FUNC_ENABLE_UNII4_CHAN, &value);
if (!ret)
cmd.oem_unii4_allow_bitmap = cpu_to_le32(value);
ret = iwl_acpi_get_dsm(&mvm->fwrt, DSM_FUNC_ACTIVATE_CHANNEL, &value);
ret = iwl_bios_get_dsm(&mvm->fwrt, DSM_FUNC_ACTIVATE_CHANNEL, &value);
if (!ret) {
if (cmd_ver < 8)
value &= ~ACTIVATE_5G2_IN_WW_MASK;
cmd.chan_state_active_bitmap = cpu_to_le32(value);
}
ret = iwl_acpi_get_dsm(&mvm->fwrt, DSM_FUNC_ENABLE_6E, &value);
ret = iwl_bios_get_dsm(&mvm->fwrt, DSM_FUNC_ENABLE_6E, &value);
if (!ret)
cmd.oem_uhb_allow_bitmap = cpu_to_le32(value);
ret = iwl_acpi_get_dsm(&mvm->fwrt, DSM_FUNC_FORCE_DISABLE_CHANNELS,
ret = iwl_bios_get_dsm(&mvm->fwrt, DSM_FUNC_FORCE_DISABLE_CHANNELS,
&value);
if (!ret)
cmd.force_disable_channels_bitmap = cpu_to_le32(value);
ret = iwl_acpi_get_dsm(&mvm->fwrt, DSM_FUNC_ENERGY_DETECTION_THRESHOLD,
ret = iwl_bios_get_dsm(&mvm->fwrt, DSM_FUNC_ENERGY_DETECTION_THRESHOLD,
&value);
if (!ret)
cmd.edt_bitmap = cpu_to_le32(value);