summaryrefslogtreecommitdiff
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorRipan Deuri <quic_rdeuri@quicinc.com>2025-12-07 12:57:17 +0530
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>2025-12-09 10:18:44 -0800
commit5a58414fe107e4844e0b5b33e94d8f3e563cd38e (patch)
tree7dd26f57e9fb08f2de8ca08d4b03a4f1b4a7b202 /drivers/net/wireless
parenta1e19289932aeef26085feb97597d624da6302ab (diff)
wifi: ath12k: Skip DP peer creation for scan vdev
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@quicinc.com> Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com> Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com> Link: https://patch.msgid.link/20251207072717.95542-1-quic_rdeuri@quicinc.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath12k/mac.c22
-rw-r--r--drivers/net/wireless/ath/ath12k/peer.c12
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 @@ err_peer_del:
}
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;
}