wifi: mac80211: allow rate_control_rate_init() for links

Andrei previously fixed an issue in the client where the NSS
for links other than the primary/assoc/deflink isn't set. The
same issue appears to exist on the AP side, because there's
only a call to rate_control_rate_init() for the deflink, and
not any other links.

Rework the code a bit to do rate_control_rate_init() for links,
even if it really doesn't work with software rate control yet,
it does other things as well.

Also add rate_control_rate_init_all_links() to actually do it
properly when moving to ASSOC state in cfg80211.

Change the explicit call to ieee80211_sta_init_nss() to instead
be rate_control_rate_init() now in the client code, but also
add a call to rate_control_rate_init() when a link is added in
AP mode and the STA is already associated.

This should fix the NSS initialization issue, and perhaps pave
the way for actual software rate scaling a bit, in case anyone
cares in the future, but that of course needs a lot more than
just the init call.

We still need to fix the rate control _update_ as well, and the
sta_rc_update() driver method especially, but that will be in a
different patch.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20241007144851.c693274a908f.I0376da02e9f5a30eaa1b5d0d01371ff09506d453@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2024-10-07 15:00:53 +03:00
parent c4382d5ca1
commit f828deb70c
7 changed files with 40 additions and 12 deletions

View File

@ -1720,7 +1720,7 @@ static int sta_apply_auth_flags(struct ieee80211_local *local,
* before drv_sta_state() is called. * before drv_sta_state() is called.
*/ */
if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
rate_control_rate_init(sta); rate_control_rate_init_all_links(sta);
ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC); ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
if (ret) if (ret)
@ -2149,7 +2149,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
*/ */
if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER) && if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
test_sta_flag(sta, WLAN_STA_ASSOC)) test_sta_flag(sta, WLAN_STA_ASSOC))
rate_control_rate_init(sta); rate_control_rate_init_all_links(sta);
return sta_info_insert(sta); return sta_info_insert(sta);
} }
@ -5063,6 +5063,13 @@ ieee80211_add_link_station(struct wiphy *wiphy, struct net_device *dev,
return ret; return ret;
} }
if (test_sta_flag(sta, WLAN_STA_ASSOC)) {
struct link_sta_info *link_sta;
link_sta = sdata_dereference(sta->link[params->link_id], sdata);
rate_control_rate_init(link_sta);
}
/* ieee80211_sta_activate_link frees the link upon failure */ /* ieee80211_sta_activate_link frees the link upon failure */
return ieee80211_sta_activate_link(sta, params->link_id); return ieee80211_sta_activate_link(sta, params->link_id);
} }

View File

@ -569,7 +569,7 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta)
if (!sta->sdata->u.ibss.control_port) if (!sta->sdata->u.ibss.control_port)
sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
rate_control_rate_init(sta); rate_control_rate_init(&sta->deflink);
/* If it fails, maybe we raced another insertion? */ /* If it fails, maybe we raced another insertion? */
if (sta_info_insert_rcu(sta)) if (sta_info_insert_rcu(sta))
@ -1068,7 +1068,7 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata,
/* Force rx_nss recalculation */ /* Force rx_nss recalculation */
sta->sta.deflink.rx_nss = 0; sta->sta.deflink.rx_nss = 0;
rate_control_rate_init(sta); rate_control_rate_init(&sta->deflink);
if (sta->sta.deflink.rx_nss != rx_nss) if (sta->sta.deflink.rx_nss != rx_nss)
changed |= IEEE80211_RC_NSS_CHANGED; changed |= IEEE80211_RC_NSS_CHANGED;

View File

@ -487,7 +487,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
} }
if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
rate_control_rate_init(sta); rate_control_rate_init(&sta->deflink);
else else
rate_control_rate_update(local, sband, sta, 0, changed); rate_control_rate_update(local, sband, sta, 0, changed);
out: out:

View File

@ -5750,7 +5750,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
/* links might have changed due to rejected ones, set them again */ /* links might have changed due to rejected ones, set them again */
ieee80211_vif_set_links(sdata, valid_links, dormant_links); ieee80211_vif_set_links(sdata, valid_links, dormant_links);
rate_control_rate_init(sta); rate_control_rate_init_all_links(sta);
if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) { if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) {
set_sta_flag(sta, WLAN_STA_MFP); set_sta_flag(sta, WLAN_STA_MFP);

View File

@ -4,7 +4,7 @@
* *
* Copyright: (c) 2014 Czech Technical University in Prague * Copyright: (c) 2014 Czech Technical University in Prague
* (c) 2014 Volkswagen Group Research * (c) 2014 Volkswagen Group Research
* Copyright (C) 2022 - 2023 Intel Corporation * Copyright (C) 2022 - 2024 Intel Corporation
* Author: Rostislav Lisovy <rostislav.lisovy@fel.cvut.cz> * Author: Rostislav Lisovy <rostislav.lisovy@fel.cvut.cz>
* Funded by: Volkswagen Group Research * Funded by: Volkswagen Group Research
*/ */
@ -96,7 +96,7 @@ static struct sta_info *ieee80211_ocb_finish_sta(struct sta_info *sta)
sta_info_move_state(sta, IEEE80211_STA_ASSOC); sta_info_move_state(sta, IEEE80211_STA_ASSOC);
sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
rate_control_rate_init(sta); rate_control_rate_init(&sta->deflink);
/* If it fails, maybe we raced another insertion? */ /* If it fails, maybe we raced another insertion? */
if (sta_info_insert_rcu(sta)) if (sta_info_insert_rcu(sta))

View File

@ -28,8 +28,9 @@ module_param(ieee80211_default_rc_algo, charp, 0644);
MODULE_PARM_DESC(ieee80211_default_rc_algo, MODULE_PARM_DESC(ieee80211_default_rc_algo,
"Default rate control algorithm for mac80211 to use"); "Default rate control algorithm for mac80211 to use");
void rate_control_rate_init(struct sta_info *sta) void rate_control_rate_init(struct link_sta_info *link_sta)
{ {
struct sta_info *sta = link_sta->sta;
struct ieee80211_local *local = sta->sdata->local; struct ieee80211_local *local = sta->sdata->local;
struct rate_control_ref *ref = sta->rate_ctrl; struct rate_control_ref *ref = sta->rate_ctrl;
struct ieee80211_sta *ista = &sta->sta; struct ieee80211_sta *ista = &sta->sta;
@ -37,11 +38,15 @@ void rate_control_rate_init(struct sta_info *sta)
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
struct ieee80211_chanctx_conf *chanctx_conf; struct ieee80211_chanctx_conf *chanctx_conf;
ieee80211_sta_init_nss(&sta->deflink); ieee80211_sta_init_nss(link_sta);
if (!ref) if (!ref)
return; return;
/* SW rate control isn't supported with MLO right now */
if (WARN_ON(ieee80211_vif_is_mld(&sta->sdata->vif)))
return;
rcu_read_lock(); rcu_read_lock();
chanctx_conf = rcu_dereference(sta->sdata->vif.bss_conf.chanctx_conf); chanctx_conf = rcu_dereference(sta->sdata->vif.bss_conf.chanctx_conf);
@ -67,6 +72,21 @@ void rate_control_rate_init(struct sta_info *sta)
set_sta_flag(sta, WLAN_STA_RATE_CONTROL); set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
} }
void rate_control_rate_init_all_links(struct sta_info *sta)
{
int link_id;
for (link_id = 0; link_id < ARRAY_SIZE(sta->link); link_id++) {
struct link_sta_info *link_sta;
link_sta = sdata_dereference(sta->link[link_id], sta->sdata);
if (!link_sta)
continue;
rate_control_rate_init(link_sta);
}
}
void rate_control_tx_status(struct ieee80211_local *local, void rate_control_tx_status(struct ieee80211_local *local,
struct ieee80211_tx_status *st) struct ieee80211_tx_status *st)
{ {

View File

@ -3,7 +3,7 @@
* Copyright 2002-2005, Instant802 Networks, Inc. * Copyright 2002-2005, Instant802 Networks, Inc.
* Copyright 2005, Devicescape Software, Inc. * Copyright 2005, Devicescape Software, Inc.
* Copyright (c) 2006 Jiri Benc <jbenc@suse.cz> * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
* Copyright (C) 2022 Intel Corporation * Copyright (C) 2022, 2024 Intel Corporation
*/ */
#ifndef IEEE80211_RATE_H #ifndef IEEE80211_RATE_H
@ -29,7 +29,8 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
void rate_control_tx_status(struct ieee80211_local *local, void rate_control_tx_status(struct ieee80211_local *local,
struct ieee80211_tx_status *st); struct ieee80211_tx_status *st);
void rate_control_rate_init(struct sta_info *sta); void rate_control_rate_init(struct link_sta_info *link_sta);
void rate_control_rate_init_all_links(struct sta_info *sta);
void rate_control_rate_update(struct ieee80211_local *local, void rate_control_rate_update(struct ieee80211_local *local,
struct ieee80211_supported_band *sband, struct ieee80211_supported_band *sband,
struct sta_info *sta, struct sta_info *sta,