[PATCH 3/5] wifi: ath12k: fix MLO dp_peer ID desync with firmware

Baochen Qiang baochen.qiang at oss.qualcomm.com
Fri Jul 31 01:02:52 PDT 2026



On 7/28/2026 12:27 AM, Jose Ignacio Tornos Martinez wrote:
> TX completions fail with:
>   "dp_tx: failed to find the peer with peer_id <N>"
> 
> where <N> is an ML peer_id (host-assigned ml_peer_id OR'd with
> ATH12K_PEER_ML_ID_VALID, BIT(13) = 0x2000). This happens because
> the firmware uses an internal monotonic counter for ML peer IDs that
> does not necessarily match the host-assigned ml_peer_id. The desync
> has been observed in normal MLO operation and is particularly
> reproducible after firmware crash recovery, where the
> create-delete-create cycle guarantees the firmware increments its
> internal counter.
> 
> Currently, ath12k_dp_peer_create() stores the host-assigned
> ml_peer_id (with ATH12K_PEER_ML_ID_VALID OR'd in) as dp_peer->peer_id
> and immediately populates the dp_peers[] RCU lookup table at that
> index. When the firmware later uses a different peer_id in its data
> path descriptors, ath12k_dp_peer_find_by_peerid() looks up the wrong
> index and returns NULL, causing the "failed to find peer" error on
> every TX completion.
> 
> Fix this by initializing dp_peer->peer_id to ATH12K_DP_PEER_ID_INVALID
> for MLO peers at creation time, deferring the dp_peers[] RCU table
> population. When ath12k_dp_peer_find_by_peerid() encounters a lookup
> miss for an ML peer_id (one with ATH12K_PEER_ML_ID_VALID set), it
> walks dp_peers_list for an MLO peer whose peer_id is still INVALID,
> syncs peer_id from the firmware's actual value, and populates the
> dp_peers[] table. This lazy sync approach ensures the host always uses
> the firmware's real ML peer_id regardless of any internal firmware
> counter behavior.
> 
> Guard the dp_peers[] RCU table clear in ath12k_dp_peer_delete() and
> ath12k_mac_dp_peer_cleanup() against ATH12K_DP_PEER_ID_INVALID to
> avoid clearing uninitialized slots. Replace per-peer clear_bit() with
> bitmap_zero() in ath12k_mac_dp_peer_cleanup() to avoid out-of-bounds
> access when peer_id has not been synced yet.
> 

this is a known issue and has been fixed by [1], and that fix has landed in ath.git [2], please try.

[1] https://lore.kernel.org/ath12k/20260720-ath12k-fw-allocated-ml-peer-id-v2-0-630632758a80@oss.qualcomm.com/
[2] https://git.kernel.org/pub/scm/linux/kernel/git/ath/ath.git/




More information about the ath12k mailing list