git: d4d3ba68b7ec - stable/13 - LinuxKPI: 802.11: sync sta->addr in lkpi_iv_update_bss()

From: Bjoern A. Zeeb <bz_at_FreeBSD.org>
Date: Fri, 01 Jul 2022 14:57:46 UTC
The branch stable/13 has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=d4d3ba68b7ec94a7c0b2d2722e3242f04885f618

commit d4d3ba68b7ec94a7c0b2d2722e3242f04885f618
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2022-06-26 19:04:16 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2022-07-01 13:49:42 +0000

    LinuxKPI: 802.11: sync sta->addr in lkpi_iv_update_bss()
    
    In lkpi_iv_update_bss() introduced in d9f59799fc3e7 we swap lsta and
    along with that sta and drv state if ni gets reused and swapped under
    us by net80211.  What we did not do was to sync sta->addr which later
    (usually in lkpi_sta_assoc_to_run) during a bss_info update cause
    problems in drivers (or firmware) as the BSSID and the station address
    were not aligned.
    
    If this proves to hold up to fix iwlwifi issues seem on firmware
    for older chipsets, multi-assoc runs, and rtw89 (which this fixes)
    we should add asserts that lkpi_iv_update_bss() can only happen in
    pre-auth stages and/or make sure we factor out synching more state
    fields.
    
    Found debugging:        rtw89
    
    (cherry picked from commit ed3ef56b29fd194a5ac0b820fd09bf01a4922bb7)
---
 sys/compat/linuxkpi/common/src/linux_80211.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c
index 8a6ddf63e3f5..c19dca862d0a 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -2073,8 +2073,8 @@ lkpi_iv_update_bss(struct ieee80211vap *vap, struct ieee80211_node *ni)
 	struct lkpi_vif *lvif;
 	struct ieee80211_node *obss;
 	struct lkpi_sta *lsta;
+	struct ieee80211_sta *sta;
 
-	lvif = VAP_TO_LVIF(vap);
 	obss = vap->iv_bss;
 
 #ifdef LINUXKPI_DEBUG_80211
@@ -2101,13 +2101,20 @@ lkpi_iv_update_bss(struct ieee80211vap *vap, struct ieee80211_node *ni)
 	lsta = obss->ni_drv_data;
 	obss->ni_drv_data = ni->ni_drv_data;
 	ni->ni_drv_data = lsta;
-	if (lsta != NULL)
+	if (lsta != NULL) {
 		lsta->ni = ni;
+		sta = LSTA_TO_STA(lsta);
+		IEEE80211_ADDR_COPY(sta->addr, lsta->ni->ni_macaddr);
+	}
 	lsta = obss->ni_drv_data;
-	if (lsta != NULL)
+	if (lsta != NULL) {
 		lsta->ni = obss;
+		sta = LSTA_TO_STA(lsta);
+		IEEE80211_ADDR_COPY(sta->addr, lsta->ni->ni_macaddr);
+	}
 
 out:
+	lvif = VAP_TO_LVIF(vap);
 	return (lvif->iv_update_bss(vap, ni));
 }