Commit 42ce76d6 authored by Luca Coelho's avatar Luca Coelho

iwlwifi: mvm: spin off SAR profile selection function

For dynamic SAR, we will need to select the current profile from
different places.  In preparation for that, spin the profile selection
code out of iwl_mvm_sar_init().
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent c386dacb
...@@ -2116,6 +2116,10 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) ...@@ -2116,6 +2116,10 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
*/ */
iwl_mvm_update_changed_regdom(mvm); iwl_mvm_update_changed_regdom(mvm);
if (!unified_image)
/* Re-configure default SAR profile */
iwl_mvm_sar_select_profile(mvm, 1, 1);
if (mvm->net_detect) { if (mvm->net_detect) {
/* If this is a non-unified image, we restart the FW, /* If this is a non-unified image, we restart the FW,
* so no need to stop the netdetect scan. If that * so no need to stop the netdetect scan. If that
......
...@@ -1123,49 +1123,78 @@ static int iwl_mvm_sar_get_wrds_table(struct iwl_mvm *mvm) ...@@ -1123,49 +1123,78 @@ static int iwl_mvm_sar_get_wrds_table(struct iwl_mvm *mvm)
return ret; return ret;
} }
static int iwl_mvm_sar_init(struct iwl_mvm *mvm) int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
{ {
struct iwl_dev_tx_power_cmd cmd = { struct iwl_dev_tx_power_cmd cmd = {
.v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS), .v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS),
}; };
int ret, i, j, idx; int i, j, idx;
int profs[IWL_NUM_CHAIN_LIMITS] = { prof_a, prof_b };
int len = sizeof(cmd); int len = sizeof(cmd);
BUILD_BUG_ON(IWL_NUM_CHAIN_LIMITS < 2);
BUILD_BUG_ON(IWL_NUM_CHAIN_LIMITS * IWL_NUM_SUB_BANDS !=
IWL_MVM_SAR_TABLE_SIZE);
if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TX_POWER_ACK)) if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TX_POWER_ACK))
len = sizeof(cmd.v3); len = sizeof(cmd.v3);
ret = iwl_mvm_sar_get_wrds_table(mvm); for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) {
if (ret < 0) { struct iwl_mvm_sar_profile *prof;
IWL_DEBUG_RADIO(mvm,
"SAR BIOS table invalid or unavailable. (%d)\n",
ret);
/* we don't fail if the table is not available */
return 0;
}
/* if profile 0 is disabled, there's nothing else to do here */ /* don't allow SAR to be disabled (profile 0 means disable) */
if (!mvm->sar_profiles[0].enabled) if (profs[i] == 0)
return 0; return -EPERM;
IWL_DEBUG_RADIO(mvm, "Sending REDUCE_TX_POWER_CMD per chain\n"); /* we are off by one, so allow up to IWL_MVM_SAR_PROFILE_NUM */
if (profs[i] > IWL_MVM_SAR_PROFILE_NUM)
return -EINVAL;
BUILD_BUG_ON(IWL_NUM_CHAIN_LIMITS * IWL_NUM_SUB_BANDS != /* profiles go from 1 to 4, so decrement to access the array */
IWL_MVM_SAR_TABLE_SIZE); prof = &mvm->sar_profiles[profs[i] - 1];
/* if the profile is disabled, do nothing */
if (!prof->enabled) {
IWL_DEBUG_RADIO(mvm, "SAR profile %d is disabled.\n",
profs[i]);
/* if one of the profiles is disabled, we fail all */
return -ENOENT;
}
for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) {
IWL_DEBUG_RADIO(mvm, " Chain[%d]:\n", i); IWL_DEBUG_RADIO(mvm, " Chain[%d]:\n", i);
for (j = 0; j < IWL_NUM_SUB_BANDS; j++) { for (j = 0; j < IWL_NUM_SUB_BANDS; j++) {
idx = (i * IWL_NUM_SUB_BANDS) + j; idx = (i * IWL_NUM_SUB_BANDS) + j;
cmd.v3.per_chain_restriction[i][j] = cmd.v3.per_chain_restriction[i][j] =
cpu_to_le16(mvm->sar_profiles[0].table[idx]); cpu_to_le16(prof->table[idx]);
IWL_DEBUG_RADIO(mvm, " Band[%d] = %d * .125dBm\n", IWL_DEBUG_RADIO(mvm, " Band[%d] = %d * .125dBm\n",
j, mvm->sar_profiles[0].table[idx]); j, prof->table[idx]);
} }
} }
ret = iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, 0, len, &cmd); IWL_DEBUG_RADIO(mvm, "Sending REDUCE_TX_POWER_CMD per chain\n");
if (ret)
IWL_ERR(mvm, "failed to set per-chain TX power: %d\n", ret); return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, 0, len, &cmd);
}
static int iwl_mvm_sar_init(struct iwl_mvm *mvm)
{
int ret;
ret = iwl_mvm_sar_get_wrds_table(mvm);
if (ret < 0) {
IWL_DEBUG_RADIO(mvm,
"SAR BIOS table invalid or unavailable. (%d)\n",
ret);
/* we don't fail if the table is not available */
return 0;
}
/* choose profile 1 (WRDS) as default for both chains */
ret = iwl_mvm_sar_select_profile(mvm, 1, 1);
/* if we don't have profile 0 from BIOS, just skip it */
if (ret == -ENOENT)
return 0;
return ret; return ret;
} }
......
...@@ -1818,5 +1818,6 @@ int iwl_mvm_send_lqm_cmd(struct ieee80211_vif *vif, ...@@ -1818,5 +1818,6 @@ int iwl_mvm_send_lqm_cmd(struct ieee80211_vif *vif,
enum iwl_lqm_cmd_operatrions operation, enum iwl_lqm_cmd_operatrions operation,
u32 duration, u32 timeout); u32 duration, u32 timeout);
bool iwl_mvm_lqm_active(struct iwl_mvm *mvm); bool iwl_mvm_lqm_active(struct iwl_mvm *mvm);
int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b);
#endif /* __IWL_MVM_H__ */ #endif /* __IWL_MVM_H__ */
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