__le32 flags;
} __packed; /* TX_REDUCED_POWER_API_S_VER_10 */
+struct iwl_dev_tx_power_cmd_v11 {
+ __le16 per_chain[IWL_NUM_CHAIN_TABLES_V2][IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V3];
+ u8 per_chain_restriction_changed;
+ u8 reserved;
+ __le32 timer_period;
+ __le32 flags;
+} __packed; /* TX_REDUCED_POWER_API_S_VER_11 */
+
/*
* struct iwl_dev_tx_power_cmd - TX power reduction command (multiversion)
* @common: common part of the command
* @v9: version 9 part of the command
* @v10: version 10 part of the command
+ * @v11: version 11 part of the command
*/
struct iwl_dev_tx_power_cmd {
struct iwl_dev_tx_power_common common;
union {
struct iwl_dev_tx_power_cmd_v9 v9;
struct iwl_dev_tx_power_cmd_v10 v10;
+ struct iwl_dev_tx_power_cmd_v11 v11;
};
-} __packed; /* TX_REDUCED_POWER_API_S_VER_9_VER10 */
+} __packed; /* TX_REDUCED_POWER_API_S_VER_9
+ * TX_REDUCED_POWER_API_S_VER_10
+ * TX_REDUCED_POWER_API_S_VER_11
+ */
#define IWL_NUM_GEO_PROFILES 3
#define IWL_NUM_GEO_PROFILES_V3 8
.common.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_LINK),
.common.pwr_restriction = cpu_to_le16(u_tx_power),
};
- int len = sizeof(cmd.common) + sizeof(cmd.v10);
+ int len = sizeof(cmd.common) + sizeof(cmd.v11);
+
+ if (iwl_fw_lookup_cmd_ver(mld->fw, cmd_id, 10) == 10)
+ len = sizeof(cmd.common) + sizeof(cmd.v10);
if (WARN_ON(!mld_link))
return -ENODEV;
int iwl_mld_config_sar_profile(struct iwl_mld *mld, int prof_a, int prof_b)
{
- u32 cmd_id = REDUCE_TX_POWER_CMD;
struct iwl_dev_tx_power_cmd cmd = {
.common.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS),
- .v10.flags = cpu_to_le32(mld->fwrt.reduced_power_flags),
};
+ u8 cmd_ver = iwl_fw_lookup_cmd_ver(mld->fw, REDUCE_TX_POWER_CMD, 10);
+ int num_subbands;
+ int cmd_size;
int ret;
+ switch (cmd_ver) {
+ case 10:
+ cmd.v10.flags = cpu_to_le32(mld->fwrt.reduced_power_flags);
+ cmd_size = sizeof(cmd.common) + sizeof(cmd.v10);
+ num_subbands = IWL_NUM_SUB_BANDS_V2;
+ break;
+ case 11:
+ cmd.v11.flags = cpu_to_le32(mld->fwrt.reduced_power_flags);
+ cmd_size = sizeof(cmd.common) + sizeof(cmd.v11);
+ num_subbands = IWL_NUM_SUB_BANDS_V3;
+ break;
+ default:
+ WARN_ONCE(1, "Bad version for REDUCE_TX_POWER_CMD: %d\n",
+ cmd_ver);
+ return -EOPNOTSUPP;
+ }
+
/* TODO: CDB - support IWL_NUM_CHAIN_TABLES_V2 */
- ret = iwl_sar_fill_profile(&mld->fwrt, &cmd.v10.per_chain[0][0][0],
- IWL_NUM_CHAIN_TABLES, IWL_NUM_SUB_BANDS_V2,
+ /* v10 and v11 have the same position for per_chain */
+ BUILD_BUG_ON(offsetof(typeof(cmd), v11.per_chain) !=
+ offsetof(typeof(cmd), v10.per_chain));
+ ret = iwl_sar_fill_profile(&mld->fwrt, &cmd.v11.per_chain[0][0][0],
+ IWL_NUM_CHAIN_TABLES, num_subbands,
prof_a, prof_b);
/* return on error or if the profile is disabled (positive number) */
if (ret)
return ret;
- return iwl_mld_send_cmd_pdu(mld, cmd_id, &cmd,
- sizeof(cmd.common) + sizeof(cmd.v10));
+ return iwl_mld_send_cmd_pdu(mld, REDUCE_TX_POWER_CMD, &cmd, cmd_size);
}
int iwl_mld_init_sar(struct iwl_mld *mld)