Skip to content

Commit

Permalink
wifi: mac80211: recalc station aggregate data during link switch
Browse files Browse the repository at this point in the history
During link switching, the active links change, so we need to
recalculate the aggregate data in the stations.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  • Loading branch information
Johannes Berg committed Oct 7, 2022
1 parent c2b6b1c commit 9b41a9d
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 9 deletions.
17 changes: 17 additions & 0 deletions net/mac80211/link.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,11 @@ static int _ieee80211_set_active_links(struct ieee80211_sub_if_data *sdata,
list_for_each_entry(sta, &local->sta_list, list) {
if (sdata != sta->sdata)
continue;

/* this is very temporary, but do it anyway */
__ieee80211_sta_recalc_aggregates(sta,
old_active | active_links);

ret = drv_change_sta_links(local, sdata, &sta->sta,
old_active,
old_active | active_links);
Expand All @@ -369,10 +374,22 @@ static int _ieee80211_set_active_links(struct ieee80211_sub_if_data *sdata,
list_for_each_entry(sta, &local->sta_list, list) {
if (sdata != sta->sdata)
continue;

__ieee80211_sta_recalc_aggregates(sta, active_links);

ret = drv_change_sta_links(local, sdata, &sta->sta,
old_active | active_links,
active_links);
WARN_ON_ONCE(ret);

/*
* Do it again, just in case - the driver might very
* well have called ieee80211_sta_recalc_aggregates()
* from there when filling in the new links, which
* would set it wrong since the vif's active links are
* not switched yet...
*/
__ieee80211_sta_recalc_aggregates(sta, active_links);
}

for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) {
Expand Down
33 changes: 24 additions & 9 deletions net/mac80211/sta_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -2151,22 +2151,30 @@ void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,
}
EXPORT_SYMBOL(ieee80211_sta_register_airtime);

void ieee80211_sta_recalc_aggregates(struct ieee80211_sta *pubsta)
void __ieee80211_sta_recalc_aggregates(struct sta_info *sta, u16 active_links)
{
struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
struct ieee80211_link_sta *link_sta;
int link_id, i;
bool first = true;
int link_id;

if (!pubsta->valid_links || !pubsta->mlo) {
pubsta->cur = &pubsta->deflink.agg;
if (!sta->sta.valid_links || !sta->sta.mlo) {
sta->sta.cur = &sta->sta.deflink.agg;
return;
}

rcu_read_lock();
for_each_sta_active_link(&sta->sdata->vif, pubsta, link_sta, link_id) {
for (link_id = 0; link_id < ARRAY_SIZE((sta)->link); link_id++) {
struct ieee80211_link_sta *link_sta;
int i;

if (!(active_links & BIT(link_id)))
continue;

link_sta = rcu_dereference(sta->sta.link[link_id]);
if (!link_sta)
continue;

if (first) {
sta->cur = pubsta->deflink.agg;
sta->cur = sta->sta.deflink.agg;
first = false;
continue;
}
Expand All @@ -2185,7 +2193,14 @@ void ieee80211_sta_recalc_aggregates(struct ieee80211_sta *pubsta)
}
rcu_read_unlock();

pubsta->cur = &sta->cur;
sta->sta.cur = &sta->cur;
}

void ieee80211_sta_recalc_aggregates(struct ieee80211_sta *pubsta)
{
struct sta_info *sta = container_of(pubsta, struct sta_info, sta);

__ieee80211_sta_recalc_aggregates(sta, sta->sdata->vif.active_links);
}
EXPORT_SYMBOL(ieee80211_sta_recalc_aggregates);

Expand Down
2 changes: 2 additions & 0 deletions net/mac80211/sta_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,8 @@ void ieee80211_sta_set_max_amsdu_subframes(struct sta_info *sta,
const u8 *ext_capab,
unsigned int ext_capab_len);

void __ieee80211_sta_recalc_aggregates(struct sta_info *sta, u16 active_links);

enum sta_stats_type {
STA_STATS_RATE_TYPE_INVALID = 0,
STA_STATS_RATE_TYPE_LEGACY,
Expand Down

0 comments on commit 9b41a9d

Please sign in to comment.