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: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20210805141826.ce3b60f0b426.I3643bf00e714aae930880cc7d6cf390b142eaccb@changeid
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
This commit is contained in:
Miri Korenblit 2021-08-05 14:21:56 +03:00 committed by Luca Coelho
parent b537ffb6ea
commit 78a19d5285
5 changed files with 69 additions and 57 deletions

View File

@ -416,8 +416,6 @@ static int iwl_sar_set_profile(union acpi_object *table,
{
int i, j, idx = 0;
profile->enabled = enabled;
/*
* The table from ACPI is flat, but we store it in a
* structured array.
@ -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;
}
@ -780,20 +781,11 @@ IWL_EXPORT_SYMBOL(iwl_sar_geo_support);
int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt,
struct iwl_per_chain_offset *table, u32 n_bands)
{
int ret, i, j;
int i, j;
if (!iwl_sar_geo_support(fwrt))
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 (j = 0; j < n_bands; j++) {
struct iwl_per_chain_offset *chain =

View File

@ -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)
{
return -ENOENT;
return 1;
}
static inline bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt)

View File

@ -1058,16 +1058,7 @@ static const struct dmi_system_id dmi_ppag_approved_list[] = {
static int iwl_mvm_ppag_init(struct iwl_mvm *mvm)
{
int ret;
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;
}
/* no need to read the table, done in INIT stage */
if (!dmi_check_system(dmi_ppag_approved_list)) {
IWL_DEBUG_RADIO(mvm,
"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)
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 */
inline int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm,
int prof_a, int prof_b)
{
return -ENOENT;
return 1;
}
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)
{
return DSM_VALUE_RFI_DISABLE;
}
void iwl_mvm_get_acpi_tables(struct iwl_mvm *mvm)
{
}
#endif /* CONFIG_ACPI */
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)
{
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);
}
@ -1543,19 +1570,9 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
goto error;
ret = iwl_mvm_sar_init(mvm);
if (ret == 0) {
if (ret == 0)
ret = iwl_mvm_sar_geo_init(mvm);
} else if (ret == -ENOENT && !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");
}
if (ret < 0)
else if (ret < 0)
goto error;
iwl_mvm_tas_init(mvm);

View File

@ -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_get_sar_geo_profile(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
void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,

View File

@ -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,
dbgfs_dir);
iwl_mvm_get_acpi_tables(mvm);
mvm->init_status = 0;
if (iwl_mvm_has_new_rx_api(mvm)) {