@@ -662,17 +662,25 @@ int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt,
}
for (i = 0; i < ACPI_NUM_GEO_PROFILES; i++) {
- struct iwl_per_chain_offset *chain =
- (struct iwl_per_chain_offset *)&table[i];
-
for (j = 0; j < n_bands; j++) {
+ struct iwl_per_chain_offset *chain =
+ &table[i * n_bands + j];
u8 *value;
+ if (j * ACPI_GEO_PER_CHAIN_SIZE >=
+ ARRAY_SIZE(fwrt->geo_profiles[0].values))
+ /*
+ * Currently we only store lb an hb values, and
+ * don't have any special ones for uhb. So leave
+ * those empty for the time being
+ */
+ break;
+
value = &fwrt->geo_profiles[i].values[j *
ACPI_GEO_PER_CHAIN_SIZE];
- chain[j].max_tx_power = cpu_to_le16(value[0]);
- chain[j].chain_a = value[1];
- chain[j].chain_b = value[2];
+ chain->max_tx_power = cpu_to_le16(value[0]);
+ chain->chain_a = value[1];
+ chain->chain_b = value[2];
IWL_DEBUG_RADIO(fwrt,
"SAR geographic profile[%d] Band[%d]: chain A = %d chain B = %d max_tx_power = %d\n",
i, j, value[1], value[2], value[0]);
@@ -105,7 +105,6 @@
#define APCI_WTAS_BLACK_LIST_MAX 16
#define ACPI_WTAS_WIFI_DATA_SIZE (3 + APCI_WTAS_BLACK_LIST_MAX)
-#define ACPI_WGDS_NUM_BANDS 2
#define ACPI_WGDS_TABLE_SIZE 3
#define ACPI_PPAG_WIFI_DATA_SIZE ((IWL_NUM_CHAIN_LIMITS * \
@@ -923,36 +923,47 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
{
union iwl_geo_tx_power_profiles_cmd cmd;
u16 len;
+ u32 n_bands;
int ret;
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, PHY_OPS_GROUP,
GEO_TX_POWER_LIMIT,
IWL_FW_CMD_VER_UNKNOWN);
- /* the table is also at the same position both in v1 and v2 */
- ret = iwl_sar_geo_init(&mvm->fwrt, &cmd.v1.table[0][0],
- ACPI_WGDS_NUM_BANDS);
-
- /*
- * It is a valid scenario to not support SAR, or miss wgds table,
- * but in that case there is no need to send the command.
- */
- if (ret)
- return 0;
-
+ BUILD_BUG_ON(offsetof(struct iwl_geo_tx_power_profiles_cmd_v1, ops) !=
+ offsetof(struct iwl_geo_tx_power_profiles_cmd_v2, ops) ||
+ offsetof(struct iwl_geo_tx_power_profiles_cmd_v2, ops) !=
+ offsetof(struct iwl_geo_tx_power_profiles_cmd_v3, ops));
/* the ops field is at the same spot for all versions, so set in v1 */
cmd.v1.ops = cpu_to_le32(IWL_PER_CHAIN_OFFSET_SET_TABLES);
if (cmd_ver == 3) {
len = sizeof(cmd.v3);
+ n_bands = ARRAY_SIZE(cmd.v3.table[0]);
cmd.v3.table_revision = cpu_to_le32(mvm->fwrt.geo_rev);
} else if (fw_has_api(&mvm->fwrt.fw->ucode_capa,
IWL_UCODE_TLV_API_SAR_TABLE_VER)) {
len = sizeof(cmd.v2);
+ n_bands = ARRAY_SIZE(cmd.v2.table[0]);
cmd.v2.table_revision = cpu_to_le32(mvm->fwrt.geo_rev);
} else {
len = sizeof(cmd.v1);
+ n_bands = ARRAY_SIZE(cmd.v1.table[0]);
}
+ BUILD_BUG_ON(offsetof(struct iwl_geo_tx_power_profiles_cmd_v1, table) !=
+ offsetof(struct iwl_geo_tx_power_profiles_cmd_v2, table) ||
+ offsetof(struct iwl_geo_tx_power_profiles_cmd_v2, table) !=
+ offsetof(struct iwl_geo_tx_power_profiles_cmd_v3, table));
+ /* the table is at the same position for all versions, so set use v1 */
+ ret = iwl_sar_geo_init(&mvm->fwrt, &cmd.v1.table[0][0], n_bands);
+
+ /*
+ * It is a valid scenario to not support SAR, or miss wgds table,
+ * but in that case there is no need to send the command.
+ */
+ if (ret)
+ return 0;
+
return iwl_mvm_send_cmd_pdu(mvm,
WIDE_ID(PHY_OPS_GROUP, GEO_TX_POWER_LIMIT),
0, len, &cmd);