mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-04 18:09:57 +00:00
mac80211: fix and optimize MCS mask handling
Currently the code always copies the configured MCS mask (even if it is set to default), but only uses it if legacy rates were also masked out. Fix this by adding a flag that tracks whether the configured MCS mask is set to default or not. Optimize the code further by storing a pointer to the configured rate mask in txrc instead of using memcpy. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
dad6330d03
commit
2ffbe6d333
5 changed files with 28 additions and 10 deletions
|
@ -4107,7 +4107,7 @@ void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn);
|
|||
* (deprecated; this will be removed once drivers get updated to use
|
||||
* rate_idx_mask)
|
||||
* @rate_idx_mask: user-requested (legacy) rate mask
|
||||
* @rate_idx_mcs_mask: user-requested MCS rate mask
|
||||
* @rate_idx_mcs_mask: user-requested MCS rate mask (NULL if not in use)
|
||||
* @bss: whether this frame is sent out in AP or IBSS mode
|
||||
*/
|
||||
struct ieee80211_tx_rate_control {
|
||||
|
@ -4119,7 +4119,7 @@ struct ieee80211_tx_rate_control {
|
|||
bool rts, short_preamble;
|
||||
u8 max_rate_idx;
|
||||
u32 rate_idx_mask;
|
||||
u8 rate_idx_mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
|
||||
u8 *rate_idx_mcs_mask;
|
||||
bool bss;
|
||||
};
|
||||
|
||||
|
|
|
@ -2417,9 +2417,22 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
|
|||
}
|
||||
|
||||
for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
|
||||
struct ieee80211_supported_band *sband = wiphy->bands[i];
|
||||
int j;
|
||||
|
||||
sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
|
||||
memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].mcs,
|
||||
sizeof(mask->control[i].mcs));
|
||||
|
||||
sdata->rc_has_mcs_mask[i] = false;
|
||||
if (!sband)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < IEEE80211_HT_MCS_MASK_LEN; j++)
|
||||
if (~sdata->rc_rateidx_mcs_mask[i][j]) {
|
||||
sdata->rc_has_mcs_mask[i] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -739,6 +739,8 @@ struct ieee80211_sub_if_data {
|
|||
|
||||
/* bitmap of allowed (non-MCS) rate indexes for rate control */
|
||||
u32 rc_rateidx_mask[IEEE80211_NUM_BANDS];
|
||||
|
||||
bool rc_has_mcs_mask[IEEE80211_NUM_BANDS];
|
||||
u8 rc_rateidx_mcs_mask[IEEE80211_NUM_BANDS][IEEE80211_HT_MCS_MASK_LEN];
|
||||
|
||||
union {
|
||||
|
|
|
@ -460,9 +460,12 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
|
|||
* the common case.
|
||||
*/
|
||||
mask = sdata->rc_rateidx_mask[info->band];
|
||||
memcpy(mcs_mask, sdata->rc_rateidx_mcs_mask[info->band],
|
||||
sizeof(mcs_mask));
|
||||
if (mask != (1 << txrc->sband->n_bitrates) - 1) {
|
||||
if (mask != (1 << txrc->sband->n_bitrates) - 1 || txrc->rate_idx_mcs_mask) {
|
||||
if (txrc->rate_idx_mcs_mask)
|
||||
memcpy(mcs_mask, txrc->rate_idx_mcs_mask, sizeof(mcs_mask));
|
||||
else
|
||||
memset(mcs_mask, 0xff, sizeof(mcs_mask));
|
||||
|
||||
if (sta) {
|
||||
/* Filter out rates that the STA does not support */
|
||||
mask &= sta->sta.supp_rates[info->band];
|
||||
|
|
|
@ -642,9 +642,11 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
|
|||
txrc.max_rate_idx = -1;
|
||||
else
|
||||
txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
|
||||
memcpy(txrc.rate_idx_mcs_mask,
|
||||
tx->sdata->rc_rateidx_mcs_mask[info->band],
|
||||
sizeof(txrc.rate_idx_mcs_mask));
|
||||
|
||||
if (tx->sdata->rc_has_mcs_mask[info->band])
|
||||
txrc.rate_idx_mcs_mask =
|
||||
tx->sdata->rc_rateidx_mcs_mask[info->band];
|
||||
|
||||
txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
|
||||
tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
|
||||
tx->sdata->vif.type == NL80211_IFTYPE_ADHOC);
|
||||
|
@ -2508,8 +2510,6 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
|
|||
txrc.max_rate_idx = -1;
|
||||
else
|
||||
txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
|
||||
memcpy(txrc.rate_idx_mcs_mask, sdata->rc_rateidx_mcs_mask[band],
|
||||
sizeof(txrc.rate_idx_mcs_mask));
|
||||
txrc.bss = true;
|
||||
rate_control_get_rate(sdata, NULL, &txrc);
|
||||
|
||||
|
|
Loading…
Reference in a new issue