Skip to content

Commit

Permalink
wifi: iwlwifi: mvm: refactor TX rate handling
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Johannes Berg committed Sep 25, 2023
1 parent a856ce6 commit b99c460
Showing 1 changed file with 45 additions and 33 deletions.
78 changes: 45 additions & 33 deletions drivers/net/wireless/intel/iwlwifi/mvm/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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,
Expand All @@ -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;
}

Expand All @@ -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 */
Expand All @@ -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,
Expand Down

0 comments on commit b99c460

Please sign in to comment.