Commit 78a19d52 authored by Miri Korenblit's avatar Miri Korenblit Committed by Luca Coelho

iwlwifi: mvm: Read the PPAG and SAR tables at INIT stage

We used to read the PPAG, WRDS, EWRD, WGDS tables from ACPI
in the load stage only. This prevented vendor commands from
being executed before bringing the interface up. Move reading those tables
to INIT stage.
Signed-off-by: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20210805141826.ce3b60f0b426.I3643bf00e714aae930880cc7d6cf390b142eaccb@changeidSigned-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent b537ffb6
...@@ -416,8 +416,6 @@ static int iwl_sar_set_profile(union acpi_object *table, ...@@ -416,8 +416,6 @@ static int iwl_sar_set_profile(union acpi_object *table,
{ {
int i, j, idx = 0; int i, j, idx = 0;
profile->enabled = enabled;
/* /*
* The table from ACPI is flat, but we store it in a * The table from ACPI is flat, but we store it in a
* structured array. * structured array.
...@@ -435,6 +433,9 @@ static int iwl_sar_set_profile(union acpi_object *table, ...@@ -435,6 +433,9 @@ static int iwl_sar_set_profile(union acpi_object *table,
} }
} }
/* Only if all values were valid can the profile be enabled */
profile->enabled = enabled;
return 0; return 0;
} }
...@@ -780,20 +781,11 @@ IWL_EXPORT_SYMBOL(iwl_sar_geo_support); ...@@ -780,20 +781,11 @@ IWL_EXPORT_SYMBOL(iwl_sar_geo_support);
int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt, int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt,
struct iwl_per_chain_offset *table, u32 n_bands) struct iwl_per_chain_offset *table, u32 n_bands)
{ {
int ret, i, j; int i, j;
if (!iwl_sar_geo_support(fwrt)) if (!iwl_sar_geo_support(fwrt))
return -EOPNOTSUPP; return -EOPNOTSUPP;
ret = iwl_sar_get_wgds_table(fwrt);
if (ret < 0) {
IWL_DEBUG_RADIO(fwrt,
"Geo SAR BIOS table invalid or unavailable. (%d)\n",
ret);
/* we don't fail if the table is not available */
return -ENOENT;
}
for (i = 0; i < ACPI_NUM_GEO_PROFILES; i++) { for (i = 0; i < ACPI_NUM_GEO_PROFILES; i++) {
for (j = 0; j < n_bands; j++) { for (j = 0; j < n_bands; j++) {
struct iwl_per_chain_offset *chain = struct iwl_per_chain_offset *chain =
......
...@@ -265,7 +265,7 @@ static inline int iwl_sar_get_ewrd_table(struct iwl_fw_runtime *fwrt) ...@@ -265,7 +265,7 @@ static inline int iwl_sar_get_ewrd_table(struct iwl_fw_runtime *fwrt)
static inline int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt) static inline int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt)
{ {
return -ENOENT; return 1;
} }
static inline bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt) static inline bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt)
......
...@@ -1058,16 +1058,7 @@ static const struct dmi_system_id dmi_ppag_approved_list[] = { ...@@ -1058,16 +1058,7 @@ static const struct dmi_system_id dmi_ppag_approved_list[] = {
static int iwl_mvm_ppag_init(struct iwl_mvm *mvm) static int iwl_mvm_ppag_init(struct iwl_mvm *mvm)
{ {
int ret; /* no need to read the table, done in INIT stage */
ret = iwl_mvm_get_ppag_table(mvm);
if (ret < 0) {
IWL_DEBUG_RADIO(mvm,
"PPAG BIOS table invalid or unavailable. (%d)\n",
ret);
return 0;
}
if (!dmi_check_system(dmi_ppag_approved_list)) { if (!dmi_check_system(dmi_ppag_approved_list)) {
IWL_DEBUG_RADIO(mvm, IWL_DEBUG_RADIO(mvm,
"System vendor '%s' is not in the approved list, disabling PPAG.\n", "System vendor '%s' is not in the approved list, disabling PPAG.\n",
...@@ -1192,12 +1183,65 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm) ...@@ -1192,12 +1183,65 @@ static void iwl_mvm_lari_cfg(struct iwl_mvm *mvm)
ret); ret);
} }
} }
void iwl_mvm_get_acpi_tables(struct iwl_mvm *mvm)
{
int ret;
/* read PPAG table */
ret = iwl_mvm_get_ppag_table(mvm);
if (ret < 0) {
IWL_DEBUG_RADIO(mvm,
"PPAG BIOS table invalid or unavailable. (%d)\n",
ret);
}
/* read SAR tables */
ret = iwl_sar_get_wrds_table(&mvm->fwrt);
if (ret < 0) {
IWL_DEBUG_RADIO(mvm,
"WRDS SAR BIOS table invalid or unavailable. (%d)\n",
ret);
/*
* If not available, don't fail and don't bother with EWRD and
* WGDS */
if (!iwl_sar_get_wgds_table(&mvm->fwrt)) {
/*
* If basic SAR is not available, we check for WGDS,
* which should *not* be available either. If it is
* available, issue an error, because we can't use SAR
* Geo without basic SAR.
*/
IWL_ERR(mvm, "BIOS contains WGDS but no WRDS\n");
}
} else {
ret = iwl_sar_get_ewrd_table(&mvm->fwrt);
/* if EWRD is not available, we can still use
* WRDS, so don't fail */
if (ret < 0)
IWL_DEBUG_RADIO(mvm,
"EWRD SAR BIOS table invalid or unavailable. (%d)\n",
ret);
/* read geo SAR table */
if (iwl_sar_geo_support(&mvm->fwrt)) {
ret = iwl_sar_get_wgds_table(&mvm->fwrt);
if (ret < 0)
IWL_DEBUG_RADIO(mvm,
"Geo SAR BIOS table invalid or unavailable. (%d)\n",
ret);
/* we don't fail if the table is not available */
}
}
}
#else /* CONFIG_ACPI */ #else /* CONFIG_ACPI */
inline int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, inline int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm,
int prof_a, int prof_b) int prof_a, int prof_b)
{ {
return -ENOENT; return 1;
} }
inline int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm) inline int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
...@@ -1232,6 +1276,10 @@ static u8 iwl_mvm_eval_dsm_rfi(struct iwl_mvm *mvm) ...@@ -1232,6 +1276,10 @@ static u8 iwl_mvm_eval_dsm_rfi(struct iwl_mvm *mvm)
{ {
return DSM_VALUE_RFI_DISABLE; return DSM_VALUE_RFI_DISABLE;
} }
void iwl_mvm_get_acpi_tables(struct iwl_mvm *mvm)
{
}
#endif /* CONFIG_ACPI */ #endif /* CONFIG_ACPI */
void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags) void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
...@@ -1287,27 +1335,6 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags) ...@@ -1287,27 +1335,6 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
static int iwl_mvm_sar_init(struct iwl_mvm *mvm) static int iwl_mvm_sar_init(struct iwl_mvm *mvm)
{ {
int ret;
ret = iwl_sar_get_wrds_table(&mvm->fwrt);
if (ret < 0) {
IWL_DEBUG_RADIO(mvm,
"WRDS SAR BIOS table invalid or unavailable. (%d)\n",
ret);
/*
* If not available, don't fail and don't bother with EWRD.
* Return 1 to tell that we can't use WGDS either.
*/
return 1;
}
ret = iwl_sar_get_ewrd_table(&mvm->fwrt);
/* if EWRD is not available, we can still use WRDS, so don't fail */
if (ret < 0)
IWL_DEBUG_RADIO(mvm,
"EWRD SAR BIOS table invalid or unavailable. (%d)\n",
ret);
return iwl_mvm_sar_select_profile(mvm, 1, 1); return iwl_mvm_sar_select_profile(mvm, 1, 1);
} }
...@@ -1543,19 +1570,9 @@ int iwl_mvm_up(struct iwl_mvm *mvm) ...@@ -1543,19 +1570,9 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
goto error; goto error;
ret = iwl_mvm_sar_init(mvm); ret = iwl_mvm_sar_init(mvm);
if (ret == 0) { if (ret == 0)
ret = iwl_mvm_sar_geo_init(mvm); ret = iwl_mvm_sar_geo_init(mvm);
} else if (ret == -ENOENT && !iwl_sar_get_wgds_table(&mvm->fwrt)) { else if (ret < 0)
/*
* If basic SAR is not available, we check for WGDS,
* which should *not* be available either. If it is
* available, issue an error, because we can't use SAR
* Geo without basic SAR.
*/
IWL_ERR(mvm, "BIOS contains WGDS but no WRDS\n");
}
if (ret < 0)
goto error; goto error;
iwl_mvm_tas_init(mvm); iwl_mvm_tas_init(mvm);
......
...@@ -2043,6 +2043,7 @@ void iwl_mvm_event_frame_timeout_callback(struct iwl_mvm *mvm, ...@@ -2043,6 +2043,7 @@ void iwl_mvm_event_frame_timeout_callback(struct iwl_mvm *mvm,
int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b); int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b);
int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm); int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm);
int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm); int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm);
void iwl_mvm_get_acpi_tables(struct iwl_mvm *mvm);
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw, void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
......
...@@ -771,6 +771,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, ...@@ -771,6 +771,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
iwl_fw_runtime_init(&mvm->fwrt, trans, fw, &iwl_mvm_fwrt_ops, mvm, iwl_fw_runtime_init(&mvm->fwrt, trans, fw, &iwl_mvm_fwrt_ops, mvm,
dbgfs_dir); dbgfs_dir);
iwl_mvm_get_acpi_tables(mvm);
mvm->init_status = 0; mvm->init_status = 0;
if (iwl_mvm_has_new_rx_api(mvm)) { if (iwl_mvm_has_new_rx_api(mvm)) {
......
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