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:
Родитель
5d3a341c0d
Коммит
175ad2ec89
|
@ -1776,33 +1776,8 @@ static int sta_apply_parameters(struct ieee80211_local *local,
|
||||||
sta->sta.max_sp = params->max_sp;
|
sta->sta.max_sp = params->max_sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The sender might not have sent the last bit, consider it to be 0 */
|
ieee80211_sta_set_max_amsdu_subframes(sta, params->ext_capab,
|
||||||
if (params->ext_capab_len >= 8) {
|
params->ext_capab_len);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cfg80211 validates this (1-2007) and allows setting the AID
|
* 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;
|
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) &&
|
sta->sta.wme = (elems->wmm_param || elems->s1g_capab) &&
|
||||||
local->hw.queues >= IEEE80211_NUM_ACS;
|
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);
|
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);
|
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 {
|
enum sta_stats_type {
|
||||||
STA_STATS_RATE_TYPE_INVALID = 0,
|
STA_STATS_RATE_TYPE_INVALID = 0,
|
||||||
STA_STATS_RATE_TYPE_LEGACY,
|
STA_STATS_RATE_TYPE_LEGACY,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче