diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index b998aaf5efd1a6b9fa60d2d46bc1a6a1909d2bb4..e4f589898eda38132a3ac3bd61278fcc319611e1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -249,6 +249,7 @@ enum iwl_ucode_tlv_flag { * through the dedicated host command. * @IWL_UCODE_TLV_API_SINGLE_SCAN_EBS: EBS is supported for single scans too. * @IWL_UCODE_TLV_API_ASYNC_DTM: Async temperature notifications are supported. + * @IWL_UCODE_TLV_API_LQ_SS_PARAMS: Configure STBC/BFER via LQ CMD ss_params */ enum iwl_ucode_tlv_api { IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3), @@ -261,6 +262,7 @@ enum iwl_ucode_tlv_api { IWL_UCODE_TLV_API_SCD_CFG = BIT(15), IWL_UCODE_TLV_API_SINGLE_SCAN_EBS = BIT(16), IWL_UCODE_TLV_API_ASYNC_DTM = BIT(17), + IWL_UCODE_TLV_API_LQ_SS_PARAMS = BIT(18), }; /** diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h index 8bb5b94bf9639689fa6445cd046f97eccbcec834..6a2a6b0ab91b336147d47ae9a45ba70946a245b7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h @@ -308,6 +308,17 @@ enum { #define LQ_FLAG_DYNAMIC_BW_POS 6 #define LQ_FLAG_DYNAMIC_BW_MSK (1 << LQ_FLAG_DYNAMIC_BW_POS) +/* Single Stream Parameters + * SS_STBC/BFER_ALLOWED - Controls whether STBC or Beamformer (BFER) is allowed + * ucode will make a smart decision between SISO/STBC/BFER + * SS_PARAMS_VALID - if not set ignore the ss_params field. + */ +enum { + RS_SS_STBC_ALLOWED = BIT(0), + RS_SS_BFER_ALLOWED = BIT(1), + RS_SS_PARAMS_VALID = BIT(31), +}; + /** * struct iwl_lq_cmd - link quality command * @sta_id: station to update @@ -330,7 +341,7 @@ enum { * 2 - 0x3f: maximal number of frames (up to 3f == 63) * @rs_table: array of rates for each TX try, each is rate_n_flags, * meaning it is a combination of RATE_MCS_* and IWL_RATE_*_PLCP - * @bf_params: beam forming params, currently not used + * @ss_params: single stream features. declare whether STBC or BFER are allowed. */ struct iwl_lq_cmd { u8 sta_id; @@ -348,6 +359,6 @@ struct iwl_lq_cmd { u8 agg_frame_cnt_limit; __le32 reserved2; __le32 rs_table[LQ_MAX_RETRY_NUM]; - __le32 bf_params; + __le32 ss_params; }; /* LINK_QUALITY_CMD_API_S_VER_1 */ #endif /* __fw_api_rs_h__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 554b3a5e442c47235447ccf1b0f401e0718ff978..f30eff20cb6bf4049605d7d738acb517dbfbe071 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -2868,11 +2868,23 @@ static void rs_build_rates_table(struct iwl_mvm *mvm, u8 valid_tx_ant = 0; struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; bool toggle_ant = false; + bool stbc_allowed = false; memcpy(&rate, initial_rate, sizeof(rate)); valid_tx_ant = iwl_mvm_get_valid_tx_ant(mvm); - rate.stbc = rs_stbc_allow(mvm, sta, lq_sta); + + stbc_allowed = rs_stbc_allow(mvm, sta, lq_sta); + if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LQ_SS_PARAMS) { + u32 ss_params = RS_SS_PARAMS_VALID; + + if (stbc_allowed) + ss_params |= RS_SS_STBC_ALLOWED; + lq_cmd->ss_params = cpu_to_le32(ss_params); + } else { + /* TODO: remove old API when min FW API hits 14 */ + rate.stbc = stbc_allowed; + } if (is_siso(&rate)) { num_rates = IWL_MVM_RS_INITIAL_SISO_NUM_RATES;