[PATCH ath-next v5 06/11] wifi: ath12k: derive device id without drv_link_id for single device group
Baochen Qiang
baochen.qiang at oss.qualcomm.com
Mon Nov 9 22:40:27 PST 2026
On the RX path several functions derive the device id from the
drv_link_id via ag->hw_links[drv_link_id].device_id. This does not work
for WCN7850/QCC2072, which use a logical link id rather than a
hw_link_id.
For these devices the whole hardware group contains only a single device,
so the device id is unambiguous and there is no need to look it up from
the drv_link_id. Add ath12k_dp_drv_link_id_to_device_id(), which returns
the device id of the only device when the group has a single device,
and falls back to the drv_link_id based lookup otherwise. Use it in the
RX path in place of the direct hw_links[] dereference.
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
Tested-by: Burke Cates <burke.cates at gmail.com> # ASUS Zenbook A16 (UX3607OA)
Signed-off-by: Baochen Qiang <baochen.qiang at oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/dp.c | 18 ++++++++++++++++++
drivers/net/wireless/ath/ath12k/dp.h | 1 +
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 13 ++++++-------
3 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c
index 0f0800388935..d49576d29da9 100644
--- a/drivers/net/wireless/ath/ath12k/dp.c
+++ b/drivers/net/wireless/ath/ath12k/dp.c
@@ -939,6 +939,24 @@ static void ath12k_dp_update_vdev_search(struct ath12k_link_vif *arvif)
}
}
+u8 ath12k_dp_drv_link_id_to_device_id(struct ath12k_hw_group *ag, u8 drv_link_id)
+{
+ /*
+ * For a single device group there is only one device, so its
+ * device id is returned directly without consulting the drv_link_id.
+ * Otherwise, derive the device id from the drv_link_id.
+ *
+ * This is general and works for all chips, but particularly useful for
+ * WCN7850/QCC2072, which cannot rely on the drv_link_id to look up the
+ * device id.
+ */
+ if (ag->num_devices == 1)
+ return ag->ab[0]->device_id;
+
+ return ag->hw_links[drv_link_id].device_id;
+}
+EXPORT_SYMBOL(ath12k_dp_drv_link_id_to_device_id);
+
void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif)
{
struct ath12k_base *ab = ar->ab;
diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h
index 5e9cdf72670f..82724b87733a 100644
--- a/drivers/net/wireless/ath/ath12k/dp.h
+++ b/drivers/net/wireless/ath/ath12k/dp.h
@@ -736,6 +736,7 @@ ath12k_dp_rxdma_buf_ring_size(const struct ath12k_dp_profile_params *p)
return p->rxdma_buf_ring_size;
}
+u8 ath12k_dp_drv_link_id_to_device_id(struct ath12k_hw_group *ag, u8 drv_link_id);
void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif);
int ath12k_dp_partner_cc_init(struct ath12k_base *ab);
int ath12k_dp_pdev_alloc(struct ath12k_base *ab);
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
index a59adbb78c76..08a9f070e4aa 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
@@ -608,7 +608,7 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_dp *dp,
struct ath12k_base *partner_ab;
struct hal_rx_desc_data rx_info;
struct ath12k_dp *partner_dp;
- u8 hw_link_id, pdev_idx;
+ u8 hw_link_id, pdev_idx, device_id;
int ret;
if (skb_queue_empty(msdu_list))
@@ -622,8 +622,8 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_dp *dp,
while ((msdu = __skb_dequeue(msdu_list))) {
rxcb = ATH12K_SKB_RXCB(msdu);
hw_link_id = rxcb->drv_link_id;
- partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp,
- hw_links[hw_link_id].device_id);
+ device_id = ath12k_dp_drv_link_id_to_device_id(ag, hw_link_id);
+ partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id);
pdev_idx = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params,
hw_links[hw_link_id].pdev_idx);
partner_ab = partner_dp->ab;
@@ -669,7 +669,6 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_dp *dp, int ring_id,
struct ath12k_hal *hal = dp->hal;
struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp;
struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES];
- struct ath12k_hw_link *hw_links = ag->hw_links;
int num_buffs_reaped[ATH12K_MAX_DEVICES] = {};
struct ath12k_rx_desc_info *desc_info;
struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;
@@ -721,7 +720,7 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_dp *dp, int ring_id,
continue;
}
- device_id = hw_links[hw_link_id].device_id;
+ device_id = ath12k_dp_drv_link_id_to_device_id(ag, hw_link_id);
partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id);
if (unlikely(!partner_dp)) {
if (desc_info->skb) {
@@ -1483,7 +1482,7 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_dp *dp, struct napi_struct *nap
continue;
}
- device_id = hw_links[hw_link_id].device_id;
+ device_id = ath12k_dp_drv_link_id_to_device_id(ag, hw_link_id);
partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id);
/* Below case is added to handle data packet from un-associated clients.
@@ -2104,7 +2103,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp,
rxcb = ATH12K_SKB_RXCB(msdu);
hw_link_id = rxcb->drv_link_id;
- device_id = hw_links[hw_link_id].device_id;
+ device_id = ath12k_dp_drv_link_id_to_device_id(ag, hw_link_id);
partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id);
if (unlikely(!partner_dp)) {
ath12k_dbg(ab, ATH12K_DBG_DATA,
--
2.25.1
More information about the ath12k
mailing list