summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/fw
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/fw')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/acpi.c25
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/runtime.h8
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/uefi.c6
3 files changed, 38 insertions, 1 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
index bee7d92293b8..7ec22738b5d6 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
@@ -169,7 +169,7 @@ int iwl_acpi_get_dsm(struct iwl_fw_runtime *fwrt,
BUILD_BUG_ON(ARRAY_SIZE(acpi_dsm_size) != DSM_FUNC_NUM_FUNCS);
- if (WARN_ON(func >= ARRAY_SIZE(acpi_dsm_size)))
+ if (WARN_ON(func >= ARRAY_SIZE(acpi_dsm_size) || !func))
return -EINVAL;
expected_size = acpi_dsm_size[func];
@@ -178,6 +178,29 @@ int iwl_acpi_get_dsm(struct iwl_fw_runtime *fwrt,
if (expected_size != sizeof(u8) && expected_size != sizeof(u32))
return -EOPNOTSUPP;
+ if (!fwrt->acpi_dsm_funcs_valid) {
+ ret = iwl_acpi_get_dsm_integer(fwrt->dev, ACPI_DSM_REV,
+ DSM_FUNC_QUERY,
+ &iwl_guid, &tmp,
+ acpi_dsm_size[DSM_FUNC_QUERY]);
+ if (ret) {
+ /* always indicate BIT(0) to avoid re-reading */
+ fwrt->acpi_dsm_funcs_valid = BIT(0);
+ return ret;
+ }
+
+ IWL_DEBUG_RADIO(fwrt, "ACPI DSM validity bitmap 0x%x\n",
+ (u32)tmp);
+ /* always indicate BIT(0) to avoid re-reading */
+ fwrt->acpi_dsm_funcs_valid = tmp | BIT(0);
+ }
+
+ if (!(fwrt->acpi_dsm_funcs_valid & BIT(func))) {
+ IWL_DEBUG_RADIO(fwrt, "ACPI DSM %d not indicated as valid\n",
+ func);
+ return -ENODATA;
+ }
+
ret = iwl_acpi_get_dsm_integer(fwrt->dev, ACPI_DSM_REV, func,
&iwl_guid, &tmp, expected_size);
if (ret)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
index 0444a736c2b2..bd3bc2846cfa 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
@@ -113,6 +113,10 @@ struct iwl_txf_iter_data {
* @phy_filters: specific phy filters as read from WPFC BIOS table
* @ppag_bios_rev: PPAG BIOS revision
* @ppag_bios_source: see &enum bios_source
+ * @acpi_dsm_funcs_valid: bitmap indicating which DSM values are valid,
+ * zero (default initialization) means it hasn't been read yet,
+ * and BIT(0) is set when it has since function 0 also has this
+ * bitmap and is always supported
*/
struct iwl_fw_runtime {
struct iwl_trans *trans;
@@ -189,6 +193,10 @@ struct iwl_fw_runtime {
bool uats_valid;
u8 uefi_tables_lock_status;
struct iwl_phy_specific_cfg phy_filters;
+
+#ifdef CONFIG_ACPI
+ u32 acpi_dsm_funcs_valid;
+#endif
};
void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c
index 48126ec6b94b..99a17b9323e9 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/uefi.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/uefi.c
@@ -747,6 +747,12 @@ int iwl_uefi_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
goto out;
}
+ if (!(data->functions[DSM_FUNC_QUERY] & BIT(func))) {
+ IWL_DEBUG_RADIO(fwrt, "DSM func %d not in 0x%x\n",
+ func, data->functions[DSM_FUNC_QUERY]);
+ goto out;
+ }
+
*value = data->functions[func];
IWL_DEBUG_RADIO(fwrt,