[PATCH ath12k-ng] wifi: ath12k: Skip DP peer creation for scan vdev

Baochen Qiang baochen.qiang at oss.qualcomm.com
Mon Dec 8 17:50:00 PST 2025



On 12/7/2025 3:27 PM, Ripan Deuri wrote:
> Consider a multi-link AP configuration:
> 
>     MLD vif (MAC addr: aa:bb)
>         |-- 2.4 GHz link (BSSID: aa:bb)
>         |-- 5 GHz link   (BSSID: cc:dd)
> 
> For AP vdevs, ath12k creates a DP peer using the arvif's BSSID and stores
> it in dp_hw->dp_peers_list. During scan operations, the driver assigns an
> arvif to the scan vdev and uses the vif's MAC address as its BSSID. In
> the above scenario, the scan vdev MAC address (aa:bb) matches the BSSID
> of the 2.4 GHz AP link, causing a duplicate entry in dp_hw->dp_peers_list
> and leading to scan vdev creation failure.
> 
> Failure in vif bringup sequence:
> 1. Create AP vdev for 2.4 GHz link:
>    - Assign arvif with BSSID = aa:bb and link_id = 0.
>    - Create DP peer with address aa:bb and add to dp_hw->dp_peers_list.
> 
> 2. Create scan vdev for 5 GHz link:
>    - Assign arvif with BSSID = aa:bb (same as vif MAC address) and
>      link_id = 15.
>    - Attempt to create another DP peer with address aa:bb.
>    - Operation fails because aa:bb already exists in dp_hw->dp_peers_list,
>      resulting in duplicate entry conflict.
> 
> 3. Delete scan vdev for 5 GHz link.
> 4. Create AP vdev for 5 GHz link.
> 
> Since DP peer is not needed for scan operations, identify scan vdev using
> arvif->link_id >= IEEE80211_MLD_MAX_NUM_LINKS and skip DP peer creation
> and deletion.
> 
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.5-01651-QCAHKSWPL_SILICONZ-1
> 
> Signed-off-by: Ripan Deuri <quic_rdeuri at quicinc.com>
> ---
>  drivers/net/wireless/ath/ath12k/mac.c  | 22 ++++++++++++++--------
>  drivers/net/wireless/ath/ath12k/peer.c | 12 +++++++-----
>  2 files changed, 21 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
> index 3649f58fef84..42e750376926 100644
> --- a/drivers/net/wireless/ath/ath12k/mac.c
> +++ b/drivers/net/wireless/ath/ath12k/mac.c
> @@ -1229,7 +1229,8 @@ void ath12k_mac_peer_cleanup_all(struct ath12k *ar)
>  
>  	/* Delete all the self dp_peers on asserted radio */
>  	list_for_each_entry_safe_reverse(arvif, tmp_vif, &ar->arvifs, list) {
> -		if (arvif->ahvif->vdev_type == WMI_VDEV_TYPE_AP) {
> +		if ((arvif->ahvif->vdev_type == WMI_VDEV_TYPE_AP) &&
> +		    (arvif->link_id < IEEE80211_MLD_MAX_NUM_LINKS)) {
>  			ath12k_dp_peer_delete(dp_hw, arvif->bssid, NULL);
>  			arvif->num_stations = 0;
>  		}
> @@ -4031,7 +4032,8 @@ static void ath12k_mac_remove_link_interface(struct ieee80211_hw *hw,
>  			ath12k_warn(ar->ab, "failed to submit AP self-peer removal on vdev %d link id %d: %d",
>  				    arvif->vdev_id, arvif->link_id, ret);
>  
> -		ath12k_dp_peer_delete(&ah->dp_hw, arvif->bssid, NULL);
> +		if (arvif->link_id < IEEE80211_MLD_MAX_NUM_LINKS)
> +			ath12k_dp_peer_delete(&ah->dp_hw, arvif->bssid, NULL);
>  	}
>  	ath12k_mac_vdev_delete(ar, arvif);
>  }
> @@ -9720,6 +9722,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
>  	u8 link_id;
>  	struct ath12k_dp_link_vif *dp_link_vif = NULL;
>  	struct ath12k_dp_peer_create_params params = {};
> +	bool dp_peer_created = false;
>  
>  	lockdep_assert_wiphy(hw->wiphy);
>  
> @@ -9805,11 +9808,14 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
>  	case WMI_VDEV_TYPE_AP:
>  		params.ucast_ra_only = true;
>  
> -		ret = ath12k_dp_peer_create(&ah->dp_hw, arvif->bssid, &params);
> -		if (ret) {
> -			ath12k_warn(ab, "failed to vdev %d create dp_peer for AP: %d\n",
> -				    arvif->vdev_id, ret);
> -			goto err_vdev_del;
> +		if (arvif->link_id < IEEE80211_MLD_MAX_NUM_LINKS) {
> +			ret = ath12k_dp_peer_create(&ah->dp_hw, arvif->bssid, &params);
> +			if (ret) {
> +				ath12k_warn(ab, "failed to vdev %d create dp_peer for AP: %d\n",
> +					    arvif->vdev_id, ret);
> +				goto err_vdev_del;
> +			}
> +			dp_peer_created = true;
>  		}
>  
>  		peer_param.vdev_id = arvif->vdev_id;
> @@ -9925,7 +9931,7 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
>  	}
>  
>  err_dp_peer_del:
> -	if (ahvif->vdev_type == WMI_VDEV_TYPE_AP)
> +	if (dp_peer_created)
>  		ath12k_dp_peer_delete(&ah->dp_hw, arvif->bssid, NULL);
>  
>  err_vdev_del:
> diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c
> index c2fb5bbd6cea..5f3bd3b9a3e9 100644
> --- a/drivers/net/wireless/ath/ath12k/peer.c
> +++ b/drivers/net/wireless/ath/ath12k/peer.c
> @@ -241,11 +241,13 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif,
>  
>  	spin_unlock_bh(&dp->dp_lock);
>  
> -	ret = ath12k_dp_link_peer_assign(ath12k_ab_to_dp(ar->ab),
> -					 &(ath12k_ar_to_ah(ar)->dp_hw),
> -					 arvif->vdev_id, sta,
> -					 (u8 *)arg->peer_addr, link_id,
> -					 ar->hw_link_id);
> +	if (arvif->link_id < IEEE80211_MLD_MAX_NUM_LINKS) {
> +		ret = ath12k_dp_link_peer_assign(ath12k_ab_to_dp(ar->ab),
> +						 &(ath12k_ar_to_ah(ar)->dp_hw),
> +						 arvif->vdev_id, sta,
> +						 (u8 *)arg->peer_addr, link_id,
> +						 ar->hw_link_id);
> +	}
>  
>  	return ret;
>  }
> 
> base-commit: a1e19289932aeef26085feb97597d624da6302ab

Reviewed-by: Baochen Qiang <baochen.qiang at oss.qualcomm.com>




More information about the ath12k mailing list