wifi: mac80211: limit A-MSDU subframes for client too
In AP/mesh where the stations are added by userspace, we
limit the number of A-MSDU subframes according to the
extended capabilities.
Refactor the code and extend that also to client-side.
Fixes: 506bcfa8ab
("mac80211: limit the A-MSDU Tx based on peer's capabilities")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
5d3a341c0d
commit
175ad2ec89
|
@ -1776,33 +1776,8 @@ static int sta_apply_parameters(struct ieee80211_local *local,
|
|||
sta->sta.max_sp = params->max_sp;
|
||||
}
|
||||
|
||||
/* The sender might not have sent the last bit, consider it to be 0 */
|
||||
if (params->ext_capab_len >= 8) {
|
||||
u8 val = (params->ext_capab[7] &
|
||||
WLAN_EXT_CAPA8_MAX_MSDU_IN_AMSDU_LSB) >> 7;
|
||||
|
||||
/* we did get all the bits, take the MSB as well */
|
||||
if (params->ext_capab_len >= 9) {
|
||||
u8 val_msb = params->ext_capab[8] &
|
||||
WLAN_EXT_CAPA9_MAX_MSDU_IN_AMSDU_MSB;
|
||||
val_msb <<= 1;
|
||||
val |= val_msb;
|
||||
}
|
||||
|
||||
switch (val) {
|
||||
case 1:
|
||||
sta->sta.max_amsdu_subframes = 32;
|
||||
break;
|
||||
case 2:
|
||||
sta->sta.max_amsdu_subframes = 16;
|
||||
break;
|
||||
case 3:
|
||||
sta->sta.max_amsdu_subframes = 8;
|
||||
break;
|
||||
default:
|
||||
sta->sta.max_amsdu_subframes = 0;
|
||||
}
|
||||
}
|
||||
ieee80211_sta_set_max_amsdu_subframes(sta, params->ext_capab,
|
||||
params->ext_capab_len);
|
||||
|
||||
/*
|
||||
* cfg80211 validates this (1-2007) and allows setting the AID
|
||||
|
|
|
@ -4488,6 +4488,9 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
|||
sta->sta.mfp = false;
|
||||
}
|
||||
|
||||
ieee80211_sta_set_max_amsdu_subframes(sta, elems->ext_capab,
|
||||
elems->ext_capab_len);
|
||||
|
||||
sta->sta.wme = (elems->wmm_param || elems->s1g_capab) &&
|
||||
local->hw.queues >= IEEE80211_NUM_ACS;
|
||||
|
||||
|
|
|
@ -2761,3 +2761,26 @@ void ieee80211_sta_remove_link(struct sta_info *sta, unsigned int link_id)
|
|||
|
||||
sta_remove_link(sta, link_id, true);
|
||||
}
|
||||
|
||||
void ieee80211_sta_set_max_amsdu_subframes(struct sta_info *sta,
|
||||
const u8 *ext_capab,
|
||||
unsigned int ext_capab_len)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
sta->sta.max_amsdu_subframes = 0;
|
||||
|
||||
if (ext_capab_len < 8)
|
||||
return;
|
||||
|
||||
/* The sender might not have sent the last bit, consider it to be 0 */
|
||||
val = u8_get_bits(ext_capab[7], WLAN_EXT_CAPA8_MAX_MSDU_IN_AMSDU_LSB);
|
||||
|
||||
/* we did get all the bits, take the MSB as well */
|
||||
if (ext_capab_len >= 9)
|
||||
val |= u8_get_bits(ext_capab[8],
|
||||
WLAN_EXT_CAPA9_MAX_MSDU_IN_AMSDU_MSB) << 1;
|
||||
|
||||
if (val)
|
||||
sta->sta.max_amsdu_subframes = 4 << val;
|
||||
}
|
||||
|
|
|
@ -910,6 +910,10 @@ void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta);
|
|||
|
||||
unsigned long ieee80211_sta_last_active(struct sta_info *sta);
|
||||
|
||||
void ieee80211_sta_set_max_amsdu_subframes(struct sta_info *sta,
|
||||
const u8 *ext_capab,
|
||||
unsigned int ext_capab_len);
|
||||
|
||||
enum sta_stats_type {
|
||||
STA_STATS_RATE_TYPE_INVALID = 0,
|
||||
STA_STATS_RATE_TYPE_LEGACY,
|
||||
|
|
Loading…
Reference in New Issue