]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: iwlwifi: mld: always take beacon ies in link grading
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>
Mon, 10 Nov 2025 12:57:00 +0000 (14:57 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 24 Nov 2025 09:37:32 +0000 (10:37 +0100)
[ Upstream commit 1a222625b468effd13d1ebb662c36a41c28a835a ]

One of the factors of a link's grade is the channel load, which is
calculated from the AP's bss load element.
The current code takes this element from the beacon for an active link,
and from bss->ies for an inactive link.

bss->ies is set to either the beacon's ies or to the probe response
ones, with preference to the probe response (meaning that if there was
even one probe response, the ies of it will be stored in bss->ies and
won't be overiden by the beacon ies).

The probe response can be very old, i.e. from the connection time,
where a beacon is updated before each link selection (which is
triggered only after a passive scan).

In such case, the bss load element in the probe response will not
include the channel load caused by the STA, where the beacon will.

This will cause the inactive link to always have a lower channel
load, and therefore an higher grade than the active link's one.

This causes repeated link switches, causing the throughput to drop.

Fix this by always taking the ies from the beacon, as those are for
sure new.

Fixes: d1e879ec600f ("wifi: iwlwifi: add iwlmld sub-driver")
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20251110145652.b493dbb1853a.I058ba7309c84159f640cc9682d1bda56dd56a536@changeid
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/wireless/intel/iwlwifi/mld/link.c

index 131190977d4b0800c9fd77cf33310e4d657a9d1a..5b10e1e443178124fe745eb64dc362e00bce6869 100644 (file)
@@ -701,18 +701,13 @@ static int
 iwl_mld_get_chan_load_from_element(struct iwl_mld *mld,
                                   struct ieee80211_bss_conf *link_conf)
 {
-       struct ieee80211_vif *vif = link_conf->vif;
        const struct cfg80211_bss_ies *ies;
        const struct element *bss_load_elem = NULL;
        const struct ieee80211_bss_load_elem *bss_load;
 
        guard(rcu)();
 
-       if (ieee80211_vif_link_active(vif, link_conf->link_id))
-               ies = rcu_dereference(link_conf->bss->beacon_ies);
-       else
-               ies = rcu_dereference(link_conf->bss->ies);
-
+       ies = rcu_dereference(link_conf->bss->beacon_ies);
        if (ies)
                bss_load_elem = cfg80211_find_elem(WLAN_EID_QBSS_LOAD,
                                                   ies->data, ies->len);