From 89789900f523e2f03679a4b94703d2a2c145240d Mon Sep 17 00:00:00 2001 From: Arif Alam Date: Wed, 28 May 2025 10:58:48 -0400 Subject: [PATCH] ath11k: fix roaming firmware crash Fix the case where firmware crashes when STA sends AUTH with same MAC address to multiple SSIDs on the same radio. Fixes: WIFI-13276 Signed-off-by: Arif Alam --- .../a-003-fix-roaming-firmware-crash.patch | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 feeds/ipq807x_v5.4/mac80211/patches/pending/a-003-fix-roaming-firmware-crash.patch diff --git a/feeds/ipq807x_v5.4/mac80211/patches/pending/a-003-fix-roaming-firmware-crash.patch b/feeds/ipq807x_v5.4/mac80211/patches/pending/a-003-fix-roaming-firmware-crash.patch new file mode 100644 index 000000000..1d36ba150 --- /dev/null +++ b/feeds/ipq807x_v5.4/mac80211/patches/pending/a-003-fix-roaming-firmware-crash.patch @@ -0,0 +1,119 @@ +--- a/drivers/net/wireless/ath/ath11k/peer.c ++++ b/drivers/net/wireless/ath/ath11k/peer.c +@@ -819,10 +819,7 @@ int ath11k_peer_delete(struct ath11k *ar + #ifdef CPTCFG_ATH11K_NSS_SUPPORT + mutex_unlock(&ar->ab->base_ast_lock); + #endif +- ath11k_warn(ar->ab, +- "failed to find peer vdev_id %d addr %pM in delete\n", +- vdev_id, addr); +- return -EINVAL; ++ return 0; + } + + #ifdef CPTCFG_ATH11K_NSS_SUPPORT +@@ -883,6 +880,7 @@ int ath11k_peer_create(struct ath11k *ar + struct ieee80211_vif *vif = arvif->vif; + struct ath11k_sta *arsta; + int ret, fbret; ++ u8 vdev_id = 0; + + lockdep_assert_held(&ar->conf_mutex); + +@@ -891,20 +889,21 @@ int ath11k_peer_create(struct ath11k *ar + "failed to create peer due to insufficient peer entry resource in firmware\n"); + return -ENOBUFS; + } ++ + mutex_lock(&ar->ab->tbl_mtx_lock); + spin_lock_bh(&ar->ab->base_lock); + peer = ath11k_peer_find_by_addr(ar->ab, param->peer_addr); ++ if (peer) ++ vdev_id = peer->vdev_id; ++ spin_unlock_bh(&ar->ab->base_lock); ++ mutex_unlock(&ar->ab->tbl_mtx_lock); ++ + if (peer) { +- if (peer->vdev_id == param->vdev_id) { +- spin_unlock_bh(&ar->ab->base_lock); +- mutex_unlock(&ar->ab->tbl_mtx_lock); ++ if (vdev_id == param->vdev_id) + return -EINVAL; +- } +- ath11k_peer_rhash_delete(ar->ab, peer); +- } + +- spin_unlock_bh(&ar->ab->base_lock); +- mutex_unlock(&ar->ab->tbl_mtx_lock); ++ ath11k_peer_delete(ar, vdev_id, param->peer_addr); ++ } + + ret = ath11k_wmi_send_peer_create_cmd(ar, param); + if (ret) { +--- a/drivers/net/wireless/ath/ath11k/dp.c ++++ b/drivers/net/wireless/ath/ath11k/dp.c +@@ -28,7 +28,7 @@ void ath11k_dp_peer_cleanup(struct ath11 + spin_lock_bh(&ab->base_lock); + peer = ath11k_peer_find(ab, vdev_id, addr); + if (!peer) { +- ath11k_warn(ab, "failed to lookup peer %pM on vdev %d\n", ++ ath11k_dbg(ab, ATH11K_DBG_MAC, "failed to lookup peer %pM on vdev %d\n", + addr, vdev_id); + spin_unlock_bh(&ab->base_lock); + return; +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -1204,9 +1204,9 @@ int ath11k_dp_rx_ampdu_stop(struct ath11 + + peer = ath11k_peer_find(ab, vdev_id, params->sta->addr); + if (!peer) { +- ath11k_warn(ab, "failed to find the peer to stop rx aggregation\n"); ++ ath11k_dbg(ab, ATH11K_DBG_MAC, "failed to find the peer to stop rx aggregation\n"); + spin_unlock_bh(&ab->base_lock); +- return -ENOENT; ++ return 0; + } + + paddr = peer->rx_tid[params->tid].paddr; +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -4075,7 +4075,7 @@ static int ath11k_clear_peer_keys(struct + peer = ath11k_peer_find(ab, arvif->vdev_id, addr); + if (!peer) { + spin_unlock_bh(&ab->base_lock); +- return -ENOENT; ++ return 0; + } + for (i = 0; i < ARRAY_SIZE(keys); i++) { + keys[i]= peer->keys[i]; +@@ -4325,6 +4325,10 @@ static int ath11k_mac_op_set_key(struct + + spin_lock_bh(&ab->base_lock); + peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr); ++ if (!peer && cmd == DISABLE_KEY) { ++ ret = 0; ++ goto unlock; ++ } + + /* TODO: Check if vdev specific security cfg is mandatory */ + ret = ath11k_nss_vdev_set_cmd(arvif, ATH11K_NSS_WIFI_VDEV_SECURITY_TYPE_CMD, key->cipher); +@@ -5961,7 +5965,7 @@ static void ath11k_mac_op_sta_rc_update( + peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr); + if (!peer) { + spin_unlock_bh(&ar->ab->base_lock); +- ath11k_warn(ar->ab, "mac sta rc update failed to find peer %pM on vdev %i\n", ++ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac sta rc update failed to find peer %pM on vdev %i\n", + sta->addr, arvif->vdev_id); + return; + } +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -8425,7 +8425,7 @@ static void ath11k_peer_sta_kickout_even + peer = ath11k_peer_find_by_addr(ab, arg.mac_addr); + if (!peer) { + spin_unlock_bh(&ab->base_lock); +- ath11k_warn(ab, "peer not found %pM\n", ++ ath11k_dbg(ab, ATH11K_DBG_WMI, "peer not found %pM\n", + arg.mac_addr); + goto exit; + }