Takashi Iwai 1f8a3d
From d673cb6fe6c03b2be157cc6c5db40481828d282d Mon Sep 17 00:00:00 2001
Takashi Iwai 1f8a3d
From: Christian 'Ansuel' Marangi <ansuelsmth@gmail.com>
Takashi Iwai 1f8a3d
Date: Thu, 22 Sep 2022 10:35:14 +0300
Takashi Iwai 1f8a3d
Subject: [PATCH] wifi: ath11k: fix peer addition/deletion error on sta band migration
Takashi Iwai 1f8a3d
Git-commit: d673cb6fe6c03b2be157cc6c5db40481828d282d
Takashi Iwai 1f8a3d
Patch-mainline: v6.1-rc1
Takashi Iwai 1f8a3d
References: bsc#1206451
Takashi Iwai 1f8a3d
Takashi Iwai 1f8a3d
This patch try to fix the following error.
Takashi Iwai 1f8a3d
Takashi Iwai 1f8a3d
Wed Jun  1 22:19:30 2022 kern.warn kernel: [  119.561227] ath11k c000000.wifi: peer already added vdev id 0 req, vdev id 1 present
Takashi Iwai 1f8a3d
Wed Jun  1 22:19:30 2022 kern.warn kernel: [  119.561282] ath11k c000000.wifi: Failed to add peer: 28:c2:1f:xx:xx:xx for VDEV: 0
Takashi Iwai 1f8a3d
Wed Jun  1 22:19:30 2022 kern.warn kernel: [  119.568053] ath11k c000000.wifi: Failed to add station: 28:c2:1f:xx:xx:xx for VDEV: 0
Takashi Iwai 1f8a3d
Wed Jun  1 22:19:31 2022 daemon.notice hostapd: wlan2: STA 28:c2:1f:xx:xx:xx IEEE 802.11: Could not add STA to kernel driver
Takashi Iwai 1f8a3d
Wed Jun  1 22:19:31 2022 daemon.notice hostapd: wlan2: STA 28:c2:1f:xx:xx:xx IEEE 802.11: did not acknowledge authentication response
Takashi Iwai 1f8a3d
Wed Jun  1 22:19:31 2022 daemon.notice hostapd: wlan1: AP-STA-DISCONNECTED 28:c2:1f:xx:xx:xx
Takashi Iwai 1f8a3d
Wed Jun  1 22:19:31 2022 daemon.info hostapd: wlan1: STA 28:c2:1f:xx:xx:xx IEEE 802.11: disassociated due to inactivity
Takashi Iwai 1f8a3d
Wed Jun  1 22:19:32 2022 daemon.info hostapd: wlan1: STA 28:c2:1f:xx:xx:xx IEEE 802.11: deauthenticated due to inactivity (timer DEAUTH/REMOVE)
Takashi Iwai 1f8a3d
Takashi Iwai 1f8a3d
To repro this:
Takashi Iwai 1f8a3d
- Have 2 Wifi with the same bssid and pass on different band (2.4 and
Takashi Iwai 1f8a3d
5GHz)
Takashi Iwai 1f8a3d
- Enable 802.11r Fast Transaction with same mobility domain
Takashi Iwai 1f8a3d
- FT Protocol: FT over the Air
Takashi Iwai 1f8a3d
From a openwrt system issue the command (with the correct mac)
Takashi Iwai 1f8a3d
ubus call hostapd.wlan1 wnm_disassoc_imminent '{"addr":"28:C2:1F:xx:xx:xx"}'
Takashi Iwai 1f8a3d
Notice the log printing the errors.
Takashi Iwai 1f8a3d
Takashi Iwai 1f8a3d
The cause of this error has been investigated and we found that this is
Takashi Iwai 1f8a3d
related to the WiFi Fast Transaction feature. We observed that this is
Takashi Iwai 1f8a3d
triggered when the router tells the device to change band. In this case
Takashi Iwai 1f8a3d
the device first auth to the other band and then the disconnect path
Takashi Iwai 1f8a3d
from the prev band is triggered.
Takashi Iwai 1f8a3d
This is problematic with the current rhash implementation since the
Takashi Iwai 1f8a3d
addrs is used as key and the logic of "adding first, delete later"
Takashi Iwai 1f8a3d
conflicts with the rhash logic.
Takashi Iwai 1f8a3d
In fact peer addition will fail since the peer is already added and with
Takashi Iwai 1f8a3d
that fixed a peer deletion will cause unitended effect by removing the
Takashi Iwai 1f8a3d
peer just added.
Takashi Iwai 1f8a3d
Takashi Iwai 1f8a3d
Current solution to this is to add additional logic to the peer delete,
Takashi Iwai 1f8a3d
make sure we are deleting the correct peer taken from the rhash
Takashi Iwai 1f8a3d
table (and fallback to the peer list) and for the peer add logic delete
Takashi Iwai 1f8a3d
the peer entry for the rhash list before adding the new one (counting as
Takashi Iwai 1f8a3d
an error only when a peer with the same vlan_id is asked to be added).
Takashi Iwai 1f8a3d
Takashi Iwai 1f8a3d
With this change, a sta can correctly transition from 2.4GHz and 5GHZ
Takashi Iwai 1f8a3d
with no drop and no error are printed.
Takashi Iwai 1f8a3d
Takashi Iwai 1f8a3d
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1
Takashi Iwai 1f8a3d
Takashi Iwai 1f8a3d
Fixes: 7b0c70d92a43 ("ath11k: Add peer rhash table support")
Takashi Iwai 1f8a3d
Signed-off-by: Christian 'Ansuel' Marangi <ansuelsmth@gmail.com>
Takashi Iwai 1f8a3d
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Takashi Iwai 1f8a3d
Link: https://lore.kernel.org/r/20220603164559.27769-1-ansuelsmth@gmail.com
Takashi Iwai 1f8a3d
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai 1f8a3d
Takashi Iwai 1f8a3d
---
Takashi Iwai 1f8a3d
 drivers/net/wireless/ath/ath11k/peer.c | 30 ++++++++++++++++++++++----
Takashi Iwai 1f8a3d
 1 file changed, 26 insertions(+), 4 deletions(-)
Takashi Iwai 1f8a3d
Takashi Iwai 1f8a3d
diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c
Takashi Iwai 1f8a3d
index 9e22aaf34b88..1ae7af02c364 100644
Takashi Iwai 1f8a3d
--- a/drivers/net/wireless/ath/ath11k/peer.c
Takashi Iwai 1f8a3d
+++ b/drivers/net/wireless/ath/ath11k/peer.c
Takashi Iwai 1f8a3d
@@ -302,6 +302,21 @@ static int __ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, const u8 *addr)
Takashi Iwai 1f8a3d
 	spin_lock_bh(&ab->base_lock);
Takashi Iwai 1f8a3d
 
Takashi Iwai 1f8a3d
 	peer = ath11k_peer_find_by_addr(ab, addr);
Takashi Iwai 1f8a3d
+	/* Check if the found peer is what we want to remove.
Takashi Iwai 1f8a3d
+	 * While the sta is transitioning to another band we may
Takashi Iwai 1f8a3d
+	 * have 2 peer with the same addr assigned to different
Takashi Iwai 1f8a3d
+	 * vdev_id. Make sure we are deleting the correct peer.
Takashi Iwai 1f8a3d
+	 */
Takashi Iwai 1f8a3d
+	if (peer && peer->vdev_id == vdev_id)
Takashi Iwai 1f8a3d
+		ath11k_peer_rhash_delete(ab, peer);
Takashi Iwai 1f8a3d
+
Takashi Iwai 1f8a3d
+	/* Fallback to peer list search if the correct peer can't be found.
Takashi Iwai 1f8a3d
+	 * Skip the deletion of the peer from the rhash since it has already
Takashi Iwai 1f8a3d
+	 * been deleted in peer add.
Takashi Iwai 1f8a3d
+	 */
Takashi Iwai 1f8a3d
+	if (!peer)
Takashi Iwai 1f8a3d
+		peer = ath11k_peer_find(ab, vdev_id, addr);
Takashi Iwai 1f8a3d
+
Takashi Iwai 1f8a3d
 	if (!peer) {
Takashi Iwai 1f8a3d
 		spin_unlock_bh(&ab->base_lock);
Takashi Iwai 1f8a3d
 		mutex_unlock(&ab->tbl_mtx_lock);
Takashi Iwai 1f8a3d
@@ -312,8 +327,6 @@ static int __ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, const u8 *addr)
Takashi Iwai 1f8a3d
 		return -EINVAL;
Takashi Iwai 1f8a3d
 	}
Takashi Iwai 1f8a3d
 
Takashi Iwai 1f8a3d
-	ath11k_peer_rhash_delete(ab, peer);
Takashi Iwai 1f8a3d
-
Takashi Iwai 1f8a3d
 	spin_unlock_bh(&ab->base_lock);
Takashi Iwai 1f8a3d
 	mutex_unlock(&ab->tbl_mtx_lock);
Takashi Iwai 1f8a3d
 
Takashi Iwai 1f8a3d
@@ -372,8 +385,17 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,
Takashi Iwai 1f8a3d
 	spin_lock_bh(&ar->ab->base_lock);
Takashi Iwai 1f8a3d
 	peer = ath11k_peer_find_by_addr(ar->ab, param->peer_addr);
Takashi Iwai 1f8a3d
 	if (peer) {
Takashi Iwai 1f8a3d
-		spin_unlock_bh(&ar->ab->base_lock);
Takashi Iwai 1f8a3d
-		return -EINVAL;
Takashi Iwai 1f8a3d
+		if (peer->vdev_id == param->vdev_id) {
Takashi Iwai 1f8a3d
+			spin_unlock_bh(&ar->ab->base_lock);
Takashi Iwai 1f8a3d
+			return -EINVAL;
Takashi Iwai 1f8a3d
+		}
Takashi Iwai 1f8a3d
+
Takashi Iwai 1f8a3d
+		/* Assume sta is transitioning to another band.
Takashi Iwai 1f8a3d
+		 * Remove here the peer from rhash.
Takashi Iwai 1f8a3d
+		 */
Takashi Iwai 1f8a3d
+		mutex_lock(&ar->ab->tbl_mtx_lock);
Takashi Iwai 1f8a3d
+		ath11k_peer_rhash_delete(ar->ab, peer);
Takashi Iwai 1f8a3d
+		mutex_unlock(&ar->ab->tbl_mtx_lock);
Takashi Iwai 1f8a3d
 	}
Takashi Iwai 1f8a3d
 	spin_unlock_bh(&ar->ab->base_lock);
Takashi Iwai 1f8a3d
 
Takashi Iwai 1f8a3d
-- 
Takashi Iwai 1f8a3d
2.35.3
Takashi Iwai 1f8a3d