Skip to content

Commit

Permalink
iwlwifi: acpi: prepare SAR profile selection code for multiple sizes
Browse files Browse the repository at this point in the history
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@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20200928121852.da5a95917df4.I84d44c9dd0b858c403a81ca621b5a7b615a3aa7e@changeid
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
  • Loading branch information
Luca Coelho committed Oct 1, 2020
1 parent 216cdfb commit 9c08cef
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 22 deletions.
36 changes: 25 additions & 11 deletions drivers/net/wireless/intel/iwlwifi/fw/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -460,16 +456,34 @@ 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]);
}
}

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)
Expand Down
5 changes: 3 additions & 2 deletions drivers/net/wireless/intel/iwlwifi/fw/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) * \
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 4 additions & 3 deletions drivers/net/wireless/intel/iwlwifi/fw/api/power.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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 */
Expand All @@ -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];
Expand Down
17 changes: 11 additions & 6 deletions drivers/net/wireless/intel/iwlwifi/mvm/fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 9c08cef

Please sign in to comment.