summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2022-07-13 18:08:03 +0200
committerJohannes Berg <johannes.berg@intel.com>2022-07-15 11:43:23 +0200
commit175ad2ec89feb8c01f87be64882af67481b1b1f5 (patch)
tree29d6662f686510e1a4e1681f120f68bc2374acb9 /net
parent5d3a341c0dd21f14eb97cea3754621d8aa1637de (diff)
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: 506bcfa8abeb ("mac80211: limit the A-MSDU Tx based on peer's capabilities") Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c29
-rw-r--r--net/mac80211/mlme.c3
-rw-r--r--net/mac80211/sta_info.c23
-rw-r--r--net/mac80211/sta_info.h4
4 files changed, 32 insertions, 27 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index bdc3d74eecc1..1545648e2031 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -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
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 308a8fe50212..3263bb188284 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -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;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index f52a7fa6dde5..eed88630594f 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -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;
+}
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index ea0eeee808a5..6bc26a2c4607 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -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,