diff options
author | Johannes Berg <johannes.berg@intel.com> | 2023-09-21 11:58:07 +0300 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2023-09-25 10:15:00 +0300 |
commit | b99c4607973ae69af3b953c28952d3c9872007c8 (patch) | |
tree | e252ac8d74b10fb586d6d99826b6743c75d4c96b /drivers/net/wireless/intel/iwlwifi/mvm/tx.c | |
parent | a856ce662c476d75405f576809b84f752909ddac (diff) | |
download | linux-b99c4607973ae69af3b953c28952d3c9872007c8.tar.xz |
wifi: iwlwifi: mvm: refactor TX rate handling
Refactor the injection and other frame TX rate handling
to always return the injection rate directly, by factoring
the legay rate portion out into a new function called in
the two relevant places (injection and non-injection).
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230921110727.dc920357bad0.I5ee8512fb63f0423c1da35b59fea8811d60c1ad3@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/tx.c')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 78 |
1 files changed, 45 insertions, 33 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 6e2e52936761..c398e04b597c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -262,6 +262,38 @@ static u32 iwl_mvm_get_tx_ant(struct iwl_mvm *mvm, return BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS; } +static u32 iwl_mvm_convert_rate_idx(struct iwl_mvm *mvm, + struct ieee80211_tx_info *info, + int rate_idx) +{ + u32 rate_flags = 0; + u8 rate_plcp; + bool is_cck; + + /* if the rate isn't a well known legacy rate, take the lowest one */ + if (rate_idx < 0 || rate_idx >= IWL_RATE_COUNT_LEGACY) + rate_idx = iwl_mvm_mac_ctxt_get_lowest_rate(mvm, + info, + info->control.vif); + + /* Get PLCP rate for tx_cmd->rate_n_flags */ + rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate_idx); + is_cck = (rate_idx >= IWL_FIRST_CCK_RATE) && + (rate_idx <= IWL_LAST_CCK_RATE); + + /* Set CCK or OFDM flag */ + if (iwl_fw_lookup_cmd_ver(mvm->fw, TX_CMD, 0) > 8) { + if (!is_cck) + rate_flags |= RATE_MCS_LEGACY_OFDM_MSK; + else + rate_flags |= RATE_MCS_CCK_MSK; + } else if (is_cck) { + rate_flags |= RATE_MCS_CCK_MSK_V1; + } + + return (u32)rate_plcp | rate_flags; +} + static u32 iwl_mvm_get_inject_tx_rate(struct iwl_mvm *mvm, struct ieee80211_tx_info *info) { @@ -288,6 +320,9 @@ static u32 iwl_mvm_get_inject_tx_rate(struct iwl_mvm *mvm, result |= u32_encode_bits(2, RATE_MCS_CHAN_WIDTH_MSK_V1); else if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH) result |= u32_encode_bits(3, RATE_MCS_CHAN_WIDTH_MSK_V1); + + if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, TX_CMD, 0) > 6) + result = iwl_new_rate_from_v1(result); } else if (rate->flags & IEEE80211_TX_RC_MCS) { result = RATE_MCS_HT_MSK_V1; result |= u32_encode_bits(rate->idx, @@ -301,12 +336,15 @@ static u32 iwl_mvm_get_inject_tx_rate(struct iwl_mvm *mvm, result |= RATE_MCS_LDPC_MSK_V1; if (u32_get_bits(info->flags, IEEE80211_TX_CTL_STBC)) result |= RATE_MCS_STBC_MSK; + + if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, TX_CMD, 0) > 6) + result = iwl_new_rate_from_v1(result); } else { - return 0; + int rate_idx = info->control.rates[0].idx; + + result = iwl_mvm_convert_rate_idx(mvm, info, rate_idx); } - if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, TX_CMD, 0) > 6) - return iwl_new_rate_from_v1(result); return result; } @@ -315,17 +353,11 @@ static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm, struct ieee80211_sta *sta, __le16 fc) { int rate_idx = -1; - u8 rate_plcp; - u32 rate_flags = 0; - bool is_cck; - if (unlikely(info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT)) { - u32 result = iwl_mvm_get_inject_tx_rate(mvm, info); + if (unlikely(info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT)) + return iwl_mvm_get_inject_tx_rate(mvm, info); - if (result) - return result; - rate_idx = info->control.rates[0].idx; - } else if (!ieee80211_hw_check(mvm->hw, HAS_RATE_CONTROL)) { + if (!ieee80211_hw_check(mvm->hw, HAS_RATE_CONTROL)) { /* info->control is only relevant for non HW rate control */ /* HT rate doesn't make sense for a non data frame */ @@ -350,27 +382,7 @@ static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm, BUILD_BUG_ON(IWL_FIRST_CCK_RATE != 0); } - /* if the rate isn't a well known legacy rate, take the lowest one */ - if (rate_idx < 0 || rate_idx >= IWL_RATE_COUNT_LEGACY) - rate_idx = iwl_mvm_mac_ctxt_get_lowest_rate(mvm, - info, - info->control.vif); - - /* Get PLCP rate for tx_cmd->rate_n_flags */ - rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate_idx); - is_cck = (rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE); - - /* Set CCK or OFDM flag */ - if (iwl_fw_lookup_cmd_ver(mvm->fw, TX_CMD, 0) > 8) { - if (!is_cck) - rate_flags |= RATE_MCS_LEGACY_OFDM_MSK; - else - rate_flags |= RATE_MCS_CCK_MSK; - } else if (is_cck) { - rate_flags |= RATE_MCS_CCK_MSK_V1; - } - - return (u32)rate_plcp | rate_flags; + return iwl_mvm_convert_rate_idx(mvm, info, rate_idx); } static u32 iwl_mvm_get_tx_rate_n_flags(struct iwl_mvm *mvm, |