From: Luca Coelho <luciano.coelho@xxxxxxxxx> The SAR profile tables will be larger in the next version, so prepare the iwl_sar_select_profile() function to handle multiple sizes and update the relevant callers. Signed-off-by: Luca Coelho <luciano.coelho@xxxxxxxxx> --- drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 36 +++++++++++++------ drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 5 +-- .../net/wireless/intel/iwlwifi/fw/api/power.h | 7 ++-- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 17 +++++---- 4 files changed, 43 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c index 448af3b1d5d6..91ee767662fb 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c @@ -419,16 +419,12 @@ static int iwl_sar_set_profile(union acpi_object *table, return 0; } -int iwl_sar_select_profile(struct iwl_fw_runtime *fwrt, - __le16 per_chain[][IWL_NUM_SUB_BANDS], - int prof_a, int prof_b) +static int iwl_sar_fill_table(struct iwl_fw_runtime *fwrt, + __le16 *per_chain, u32 n_subbands, + int prof_a, int prof_b) { - int i, j, idx; int profs[ACPI_SAR_NUM_CHAIN_LIMITS] = { prof_a, prof_b }; - - BUILD_BUG_ON(ACPI_SAR_NUM_CHAIN_LIMITS < 2); - BUILD_BUG_ON(ACPI_SAR_NUM_CHAIN_LIMITS * ACPI_SAR_NUM_SUB_BANDS != - ACPI_SAR_TABLE_SIZE); + int i, j, idx; for (i = 0; i < ACPI_SAR_NUM_CHAIN_LIMITS; i++) { struct iwl_sar_profile *prof; @@ -460,9 +456,10 @@ int iwl_sar_select_profile(struct iwl_fw_runtime *fwrt, "SAR EWRD: chain %d profile index %d\n", i, profs[i]); IWL_DEBUG_RADIO(fwrt, " Chain[%d]:\n", i); - for (j = 0; j < ACPI_SAR_NUM_SUB_BANDS; j++) { - idx = (i * ACPI_SAR_NUM_SUB_BANDS) + j; - per_chain[i][j] = cpu_to_le16(prof->table[idx]); + for (j = 0; j < n_subbands; j++) { + idx = i * ACPI_SAR_NUM_SUB_BANDS + j; + per_chain[i * n_subbands + j] = + cpu_to_le16(prof->table[idx]); IWL_DEBUG_RADIO(fwrt, " Band[%d] = %d * .125dBm\n", j, prof->table[idx]); } @@ -470,6 +467,23 @@ int iwl_sar_select_profile(struct iwl_fw_runtime *fwrt, return 0; } + +int iwl_sar_select_profile(struct iwl_fw_runtime *fwrt, + __le16 *per_chain, u32 n_tables, u32 n_subbands, + int prof_a, int prof_b) +{ + int i, ret = 0; + + for (i = 0; i < n_tables; i++) { + ret = iwl_sar_fill_table(fwrt, + &per_chain[i * n_subbands * ACPI_SAR_NUM_CHAIN_LIMITS], + n_subbands, prof_a, prof_b); + if (ret) + break; + } + + return ret; +} IWL_EXPORT_SYMBOL(iwl_sar_select_profile); int iwl_sar_get_wrds_table(struct iwl_fw_runtime *fwrt) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h index 6accf5c57a44..9524750607be 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h @@ -89,6 +89,7 @@ #define ACPI_SAR_NUM_CHAIN_LIMITS 2 #define ACPI_SAR_NUM_SUB_BANDS 5 +#define ACPI_SAR_NUM_TABLES 1 #define ACPI_WRDS_WIFI_DATA_SIZE (ACPI_SAR_TABLE_SIZE + 2) #define ACPI_EWRD_WIFI_DATA_SIZE ((ACPI_SAR_PROFILE_NUM - 1) * \ @@ -183,7 +184,7 @@ u64 iwl_acpi_get_pwr_limit(struct device *dev); int iwl_acpi_get_eckv(struct device *dev, u32 *extl_clk); int iwl_sar_select_profile(struct iwl_fw_runtime *fwrt, - __le16 per_chain[][IWL_NUM_SUB_BANDS], + __le16 *per_chain, u32 n_tables, u32 n_subbands, int prof_a, int prof_b); int iwl_sar_get_wrds_table(struct iwl_fw_runtime *fwrt); @@ -242,7 +243,7 @@ static inline int iwl_acpi_get_eckv(struct device *dev, u32 *extl_clk) } static inline int iwl_sar_select_profile(struct iwl_fw_runtime *fwrt, - __le16 per_chain[][IWL_NUM_SUB_BANDS], + __le16 *per_chain, u32 n_tables, u32 n_subbands, int prof_a, int prof_b) { return -ENOENT; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h index 3114cfbbd6a2..28bb361fd0da 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h @@ -329,6 +329,7 @@ enum iwl_dev_tx_power_cmd_mode { IWL_TX_POWER_MODE_SET_SAR_TIMER_DEFAULT_TABLE = 5, }; /* TX_POWER_REDUCED_FLAGS_TYPE_API_E_VER_5 */; +#define IWL_NUM_CHAIN_TABLES 1 #define IWL_NUM_CHAIN_LIMITS 2 #define IWL_NUM_SUB_BANDS 5 #define IWL_NUM_SUB_BANDS_V2 11 @@ -356,7 +357,7 @@ struct iwl_dev_tx_power_common { * @per_chain: per chain restrictions */ struct iwl_dev_tx_power_cmd_v3 { - __le16 per_chain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS]; + __le16 per_chain[IWL_NUM_CHAIN_TABLES][IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS]; } __packed; /* TX_REDUCED_POWER_API_S_VER_3 */ #define IWL_DEV_MAX_TX_POWER 0x7FFF @@ -369,7 +370,7 @@ struct iwl_dev_tx_power_cmd_v3 { * @reserved: reserved (padding) */ struct iwl_dev_tx_power_cmd_v4 { - __le16 per_chain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS]; + __le16 per_chain[IWL_NUM_CHAIN_TABLES][IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS]; u8 enable_ack_reduction; u8 reserved[3]; } __packed; /* TX_REDUCED_POWER_API_S_VER_4 */ @@ -388,7 +389,7 @@ struct iwl_dev_tx_power_cmd_v4 { * BIOS values. relevant if setMode is IWL_TX_POWER_MODE_SET_SAR_TIMER */ struct iwl_dev_tx_power_cmd_v5 { - __le16 per_chain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS]; + __le16 per_chain[IWL_NUM_CHAIN_TABLES][IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS]; u8 enable_ack_reduction; u8 per_chain_restriction_changed; u8 reserved[2]; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index fd8d6190ee24..d55a8768ff6d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -739,23 +739,28 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b) struct iwl_dev_tx_power_cmd cmd = { .common.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS), }; + __le16 *per_chain; int ret; u16 len = 0; if (fw_has_api(&mvm->fw->ucode_capa, - IWL_UCODE_TLV_API_REDUCE_TX_POWER)) + IWL_UCODE_TLV_API_REDUCE_TX_POWER)) { len = sizeof(cmd.v5); - else if (fw_has_capa(&mvm->fw->ucode_capa, - IWL_UCODE_TLV_CAPA_TX_POWER_ACK)) + per_chain = cmd.v5.per_chain[0][0]; + } else if (fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_TX_POWER_ACK)) { len = sizeof(cmd.v4); - else + per_chain = cmd.v4.per_chain[0][0]; + } else { len = sizeof(cmd.v3); + per_chain = cmd.v3.per_chain[0][0]; + } /* all structs have the same common part, add it */ len += sizeof(cmd.common); - ret = iwl_sar_select_profile(&mvm->fwrt, cmd.v5.per_chain, - prof_a, prof_b); + ret = iwl_sar_select_profile(&mvm->fwrt, per_chain, ACPI_SAR_NUM_TABLES, + ACPI_SAR_NUM_SUB_BANDS, prof_a, prof_b); /* return on error or if the profile is disabled (positive number) */ if (ret) -- 2.28.0