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

wifi: iwlwifi: implement GLAI ACPI table loading

All the regulatory tables from BIOS are going to be loaded
(preferably) from the UEFI instead of the ACPI.
There is a security issue with the fact that anyone can
add these UEFI variables.
The solution for that is to have a lock for all WIFI GUID UEFI
variables, and only if the UEFI variables are locked then we can
read it.
The status of the lock (unlocked, locked, test mode) is indicated
in a ACPI table: Guid Lock ACPI Indicator.
Load this table so the driver knows whether to read from UEFI or
not
Signed-off-by: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Reviewed-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Link: https://msgid.link/20240128084842.53994809fbdd.I1bd10aafc387bc04f375e386861ee2bcb82f0a61@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent d3b2c6c6
......@@ -1318,3 +1318,38 @@ void iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt,
kfree(data);
}
IWL_EXPORT_SYMBOL(iwl_acpi_get_phy_filters);
void iwl_acpi_get_guid_lock_status(struct iwl_fw_runtime *fwrt)
{
union acpi_object *wifi_pkg, *data;
int tbl_rev;
data = iwl_acpi_get_object(fwrt->dev, ACPI_GLAI_METHOD);
if (IS_ERR(data))
return;
wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data,
ACPI_GLAI_WIFI_DATA_SIZE,
&tbl_rev);
if (IS_ERR(wifi_pkg))
goto out_free;
if (tbl_rev != 0) {
IWL_DEBUG_RADIO(fwrt, "Invalid GLAI revision: %d\n", tbl_rev);
goto out_free;
}
if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER ||
wifi_pkg->package.elements[1].integer.value > ACPI_GLAI_MAX_STATUS)
goto out_free;
fwrt->uefi_tables_lock_status =
wifi_pkg->package.elements[1].integer.value;
IWL_DEBUG_RADIO(fwrt,
"Loaded UEFI WIFI GUID lock status: %d from ACPI\n",
fwrt->uefi_tables_lock_status);
out_free:
kfree(data);
}
IWL_EXPORT_SYMBOL(iwl_acpi_get_guid_lock_status);
......@@ -25,6 +25,7 @@
#define ACPI_PPAG_METHOD "PPAG"
#define ACPI_WTAS_METHOD "WTAS"
#define ACPI_WPFC_METHOD "WPFC"
#define ACPI_GLAI_METHOD "GLAI"
#define ACPI_WIFI_DOMAIN (0x07)
......@@ -66,7 +67,12 @@
#define ACPI_WRDD_WIFI_DATA_SIZE 2
#define ACPI_SPLC_WIFI_DATA_SIZE 2
#define ACPI_ECKV_WIFI_DATA_SIZE 2
/*
* One element for domain type,
* and one for the status
*/
#define ACPI_GLAI_WIFI_DATA_SIZE 2
#define ACPI_GLAI_MAX_STATUS 2
/*
* TAS size: 1 elelment for type,
* 1 element for enabled field,
......@@ -237,6 +243,8 @@ bool iwl_acpi_is_ppag_approved(struct iwl_fw_runtime *fwrt);
void iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt,
struct iwl_phy_specific_cfg *filters);
void iwl_acpi_get_guid_lock_status(struct iwl_fw_runtime *fwrt);
#else /* CONFIG_ACPI */
static inline void *iwl_acpi_get_dsm_object(struct device *dev, int rev,
......@@ -331,6 +339,9 @@ static inline void iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt,
{
}
static inline void iwl_acpi_get_guid_lock_status(struct iwl_fw_runtime *fwrt)
{
}
#endif /* CONFIG_ACPI */
#endif /* __iwl_fw_acpi__ */
......@@ -100,6 +100,9 @@ struct iwl_txf_iter_data {
* @dump: debug dump data
* @uats_enabled: VLP or AFC AP is enabled
* @uats_table: AP type table
* @uefi_tables_lock_status: The status of the WIFI GUID UEFI variables lock:
* 0: Unlocked, 1 and 2: Locked.
* Only read the UEFI variables if locked.
*/
struct iwl_fw_runtime {
struct iwl_trans *trans;
......@@ -175,6 +178,7 @@ struct iwl_fw_runtime {
u8 reduced_power_flags;
bool uats_enabled;
struct iwl_uats_table_cmd uats_table;
u8 uefi_tables_lock_status;
#endif
};
......
......@@ -1402,6 +1402,8 @@ void iwl_mvm_get_acpi_tables(struct iwl_mvm *mvm)
{
int ret;
iwl_acpi_get_guid_lock_status(&mvm->fwrt);
/* read PPAG table */
ret = iwl_acpi_get_ppag_table(&mvm->fwrt);
if (ret < 0) {
......
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