From: Emmanuel Grumbach Date: Thu, 19 Mar 2026 18:48:47 +0000 (+0200) Subject: wifi: iwlwifi: mld: support version 11 of REDUCE_TX_POWER_CMD X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c239a0d8d75e83e28e5866f15234fff34f4103c5;p=thirdparty%2Flinux.git wifi: iwlwifi: mld: support version 11 of REDUCE_TX_POWER_CMD This introduces support for UNII-9. After we increased the size of the arrays of the subbands in SAR structure, we now support the new firmware command. Signed-off-by: Emmanuel Grumbach Reviewed-by: Johannes Berg Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260319204647.9cea60b78a1b.Ia91c59829af0dc4d6c351c5b09ce33800c1f9e44@changeid --- diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h index 118c08f956495..ec923162a44bb 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h @@ -426,19 +426,32 @@ struct iwl_dev_tx_power_cmd_v10 { __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 diff --git a/drivers/net/wireless/intel/iwlwifi/mld/power.c b/drivers/net/wireless/intel/iwlwifi/mld/power.c index c3318e84f4a27..49b0d9f8f865d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/power.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/power.c @@ -405,7 +405,10 @@ int iwl_mld_set_tx_power(struct iwl_mld *mld, .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; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c index 27059ec938473..f009c884e6cdb 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/regulatory.c @@ -95,23 +95,43 @@ static int iwl_mld_geo_sar_init(struct iwl_mld *mld) 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)