[PATCH ath-next v4 11/11] wifi: ath12k: use link_id_map to resolve RX link id for all devices

Rameshkumar Sundaram rameshkumar.sundaram at oss.qualcomm.com
Mon Nov 9 22:07:11 PST 2026


On 11/2/2026 12:08 PM, Baochen Qiang wrote:
> Commit a2fe9dc70f3b ("wifi: ath12k: Fix low MLO RX throughput on
> WCN7850") added a set_rx_link_id() op so that each device could resolve
> the RX link id in its own way: QCN9274/IPQ5332 index
> dp_peer->link_id_map[] with the hw_link_id, while WCN7850/QCC2072 walk
> dp_peer->link_peers[] and match by peer_id, tracked with a link_peers_map
> bitmap.
> 
> Now that ath12k_skb_rxcb::drv_link_id carries the driver link id for all
> devices (the hw_link_id on QCN9274/IPQ5332 and the logical link id on
> WCN7850/QCC2072) and ath12k_dp_peer::link_id_map maps it to the IEEE80211
> link id, the RX path can resolve the link id uniformly.
> 
> Revert the set_rx_link_id() machinery and the link_peers_map bitmap, and
> derive the link id directly from link_id_map[drv_link_id] in
> ath12k_dp_rx_deliver_msdu() for all devices. The NULL dp_peer guard added
> to ath12k_mac_peer_cleanup_all() is kept as it is an independent fix.
> 

Fixes: a2fe9dc70f3b ("wifi: ath12k: Fix low MLO RX throughput on 
WCN7850") ??

> Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
> Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0.c2-00068-QCACOLSWPL_V1_TO_SILICONZ-1
> 
> Signed-off-by: Baochen Qiang <baochen.qiang at oss.qualcomm.com>
> ---
>   drivers/net/wireless/ath/ath12k/dp_peer.c     |  4 ----
>   drivers/net/wireless/ath/ath12k/dp_peer.h     |  1 -
>   drivers/net/wireless/ath/ath12k/dp_rx.c       |  8 ++-----
>   drivers/net/wireless/ath/ath12k/hw.h          | 18 ----------------
>   drivers/net/wireless/ath/ath12k/mac.c         |  2 --
>   drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 30 ---------------------------
>   drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h |  6 ------
>   drivers/net/wireless/ath/ath12k/wifi7/hw.c    |  3 ---
>   8 files changed, 2 insertions(+), 70 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c
> index ee3cdd7ca460..ff88c694e1e3 100644
> --- a/drivers/net/wireless/ath/ath12k/dp_peer.c
> +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c
> @@ -658,8 +658,6 @@ int ath12k_dp_link_peer_assign(struct ath12k_dp *dp, struct ath12k_dp_hw *dp_hw,
>   	peerid_index = ath12k_dp_peer_get_peerid_index(dp, peer->peer_id);
>   
>   	rcu_assign_pointer(dp_peer->link_peers[peer->link_id], peer);
> -	WRITE_ONCE(dp_peer->link_peers_map,
> -		   READ_ONCE(dp_peer->link_peers_map) | BIT(peer->link_id));
>   
>   	rcu_assign_pointer(dp_hw->dp_peers[peerid_index], dp_peer);
>   
> @@ -728,8 +726,6 @@ void ath12k_dp_link_peer_unassign(struct ath12k_dp *dp, struct ath12k_dp_hw *dp_
>   	peerid_index = ath12k_dp_peer_get_peerid_index(dp, peer->peer_id);
>   
>   	rcu_assign_pointer(dp_peer->link_peers[peer->link_id], NULL);
> -	WRITE_ONCE(dp_peer->link_peers_map,
> -		   READ_ONCE(dp_peer->link_peers_map) & ~BIT(peer->link_id));
>   
>   	rcu_assign_pointer(dp_hw->dp_peers[peerid_index], NULL);
>   
> diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h
> index c2d060de88ea..2ac4c6c6d535 100644
> --- a/drivers/net/wireless/ath/ath12k/dp_peer.h
> +++ b/drivers/net/wireless/ath/ath12k/dp_peer.h
> @@ -159,7 +159,6 @@ struct ath12k_dp_peer {
>   
>   	/* Info used in MMIC verification of * RX fragments */
>   	struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1];
> -	unsigned long link_peers_map;
>   	struct ath12k_dp_link_peer __rcu *link_peers[ATH12K_NUM_MAX_LINKS];
>   	struct ath12k_reoq_buf reoq_bufs[IEEE80211_NUM_TIDS + 1];
>   	struct ath12k_dp_rx_tid rx_tid[IEEE80211_NUM_TIDS + 1];
> diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
> index f11810c6e0d4..52838ade1b1d 100644
> --- a/drivers/net/wireless/ath/ath12k/dp_rx.c
> +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
> @@ -1370,13 +1370,9 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc
>   
>   	if (pubsta) {
>   		if (pubsta->valid_links) {
> -			int link_id =
> -				ath12k_hw_get_rx_link_id(dp->hw_params, peer,
> -							 rxcb, status);
> +			int link_id = peer->link_id_map[rxcb->drv_link_id];
>   
> -			if (link_id >= 0)
> -				link_pubsta =
> -					rcu_dereference(pubsta->link[link_id]);
> +			link_pubsta = rcu_dereference(pubsta->link[link_id]);
>   		} else {
>   			link_pubsta = &pubsta->deflink;
>   		}
> diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h
> index 106d858efc44..3a7d1959f19f 100644
> --- a/drivers/net/wireless/ath/ath12k/hw.h
> +++ b/drivers/net/wireless/ath/ath12k/hw.h
> @@ -13,10 +13,6 @@
>   #include "wmi.h"
>   #include "hal.h"
>   
> -struct ath12k_dp_peer;
> -struct ath12k_skb_rxcb;
> -struct ieee80211_rx_status;
> -
>   /* Target configuration defines */
>   
>   /* Num VDEVS per radio */
> @@ -255,9 +251,6 @@ struct ath12k_hw_ops {
>   	bool (*dp_srng_is_tx_comp_ring)(int ring_num);
>   	bool (*is_frame_link_agnostic)(struct ath12k_link_vif *arvif,
>   				       struct ieee80211_mgmt *mgmt);
> -	int (*get_rx_link_id)(struct ath12k_dp_peer *dp_peer,
> -			      struct ath12k_skb_rxcb *rxcb,
> -			      struct ieee80211_rx_status *status);
>   };
>   
>   static inline
> @@ -288,17 +281,6 @@ static inline int ath12k_hw_mac_id_to_srng_id(const struct ath12k_hw_params *hw,
>   	return 0;
>   }
>   
> -static inline int ath12k_hw_get_rx_link_id(const struct ath12k_hw_params *hw,
> -					   struct ath12k_dp_peer *dp_peer,
> -					   struct ath12k_skb_rxcb *rxcb,
> -					   struct ieee80211_rx_status *status)
> -{
> -	if (hw->hw_ops->get_rx_link_id)
> -		return hw->hw_ops->get_rx_link_id(dp_peer, rxcb, status);
> -
> -	return -1;
> -}
> -
>   struct ath12k_fw_ie {
>   	__le32 id;
>   	__le32 len;
> diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
> index 01c048046290..4ac31cb9a5dc 100644
> --- a/drivers/net/wireless/ath/ath12k/mac.c
> +++ b/drivers/net/wireless/ath/ath12k/mac.c
> @@ -1241,8 +1241,6 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar)
>   		if (dp_peer) {
>   			peerid_index = ath12k_dp_peer_get_peerid_index(dp, peer->peer_id);
>   			rcu_assign_pointer(dp_peer->link_peers[peer->link_id], NULL);
> -			WRITE_ONCE(dp_peer->link_peers_map,
> -				   READ_ONCE(dp_peer->link_peers_map) & ~BIT(peer->link_id));
>   			rcu_assign_pointer(dp_hw->dp_peers[peerid_index], NULL);
>   		}
>   		spin_unlock_bh(&dp_hw->peer_lock);
> diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
> index 4132578085cc..473887ed4bb1 100644
> --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
> +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
> @@ -2374,33 +2374,3 @@ ath12k_wifi7_dp_rxdesc_mpdu_valid(struct ath12k_base *ab,
>   
>   	return tlv_tag == HAL_RX_MPDU_START;
>   }
> -
> -int
> -ath12k_wifi7_dp_rx_get_link_id_qcn9274(struct ath12k_dp_peer *dp_peer,
> -				       struct ath12k_skb_rxcb *rxcb,
> -				       struct ieee80211_rx_status *status)
> -{
> -	return dp_peer->link_id_map[rxcb->drv_link_id];
> -}
> -
> -int
> -ath12k_wifi7_dp_rx_get_link_id_wcn7850(struct ath12k_dp_peer *dp_peer,
> -				       struct ath12k_skb_rxcb *rxcb,
> -				       struct ieee80211_rx_status *status)
> -{
> -	struct ath12k_dp_link_peer *link_peer;
> -	unsigned long links_map;
> -	int i;
> -
> -	RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
> -			 "ath12k set rx link id called without rcu lock");
> -
> -	links_map = READ_ONCE(dp_peer->link_peers_map);
> -	for_each_set_bit(i, &links_map, ATH12K_NUM_MAX_LINKS) {
> -		link_peer = rcu_dereference(dp_peer->link_peers[i]);
> -		if (link_peer && link_peer->peer_id == rxcb->peer_id)
> -			return link_peer->link_id;
> -	}
> -
> -	return -1;
> -}
> diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
> index 8a16fb3dd005..3da80da19ced 100644
> --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
> +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h
> @@ -59,10 +59,4 @@ ath12k_wifi7_dp_rxdesc_mpdu_valid(struct ath12k_base *ab,
>   				  struct hal_rx_desc *rx_desc);
>   int ath12k_wifi7_dp_rx_tid_delete_handler(struct ath12k_base *ab,
>   					  struct ath12k_dp_rx_tid_rxq *rx_tid);
> -int ath12k_wifi7_dp_rx_get_link_id_qcn9274(struct ath12k_dp_peer *dp_peer,
> -					   struct ath12k_skb_rxcb *rxcb,
> -					   struct ieee80211_rx_status *status);
> -int ath12k_wifi7_dp_rx_get_link_id_wcn7850(struct ath12k_dp_peer *dp_peer,
> -					   struct ath12k_skb_rxcb *rxcb,
> -					   struct ieee80211_rx_status *status);
>   #endif
> diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
> index b073282e5525..080ead233106 100644
> --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c
> +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
> @@ -159,7 +159,6 @@ static const struct ath12k_hw_ops qcn9274_ops = {
>   	.get_ring_selector = ath12k_wifi7_hw_get_ring_selector_qcn9274,
>   	.dp_srng_is_tx_comp_ring = ath12k_wifi7_dp_srng_is_comp_ring_qcn9274,
>   	.is_frame_link_agnostic = ath12k_wifi7_is_frame_link_agnostic_qcn9274,
> -	.get_rx_link_id = ath12k_wifi7_dp_rx_get_link_id_qcn9274,
>   };
>   
>   static const struct ath12k_hw_ops wcn7850_ops = {
> @@ -170,7 +169,6 @@ static const struct ath12k_hw_ops wcn7850_ops = {
>   	.get_ring_selector = ath12k_wifi7_hw_get_ring_selector_wcn7850,
>   	.dp_srng_is_tx_comp_ring = ath12k_wifi7_dp_srng_is_comp_ring_wcn7850,
>   	.is_frame_link_agnostic = ath12k_wifi7_is_frame_link_agnostic_wcn7850,
> -	.get_rx_link_id = ath12k_wifi7_dp_rx_get_link_id_wcn7850,
>   };
>   
>   static const struct ath12k_hw_ops qcc2072_ops = {
> @@ -181,7 +179,6 @@ static const struct ath12k_hw_ops qcc2072_ops = {
>   	.get_ring_selector = ath12k_wifi7_hw_get_ring_selector_wcn7850,
>   	.dp_srng_is_tx_comp_ring = ath12k_wifi7_dp_srng_is_comp_ring_wcn7850,
>   	.is_frame_link_agnostic = ath12k_wifi7_is_frame_link_agnostic_wcn7850,
> -	.get_rx_link_id = ath12k_wifi7_dp_rx_get_link_id_wcn7850,
>   };
>   
>   #define ATH12K_TX_RING_MASK_0 0x1
> 


-- 
Ramesh



More information about the ath12k mailing list