Commit fc7214c3 authored by Miri Korenblit's avatar Miri Korenblit Committed by Johannes Berg
Browse files

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: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Reviewed-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Link: https://msgid.link/20240201155157.27dd626ce2bd.Ib90bab74a9d56deb2362edb712294360e4ddae5b@changeid


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent dc4fe750
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -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,
+10 −3
Original line number Diff line number Diff line
@@ -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);
+3 −0
Original line number Diff line number Diff line
@@ -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__ */
+33 −0
Original line number Diff line number Diff line
@@ -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;
}
+21 −0
Original line number Diff line number Diff line
@@ -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)
Loading