On the RX path the driver link id stored in ath12k_skb_rxcb::drv_link_id is later used to index ath12k_dp_peer::link_id_map and derive the IEEE80211 link id. The source of this driver link id differs per devices: QCN9274 uses the hw_link_id from the descriptor, while WCN7850/QCC2072 use the logical_link_id carried in the peer metadata. Add a HAL op rx_reo_desc_get_drv_link_id() to let each device provide its own driver link id on the REO path, so the RX code no longer needs to know where the value comes from. For QCN9274 keep the existing behavior; for WCN7850/QCC2072 extract the logical link id from the peer metadata via the common ath12k_wifi7_dp_rx_get_logical_link_id() helper. 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 --- drivers/net/wireless/ath/ath12k/dp_rx.h | 7 ++++ drivers/net/wireless/ath/ath12k/hal.h | 2 + drivers/net/wireless/ath/ath12k/hw.h | 2 + drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 49 ++++++++++++++-------- drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h | 2 + .../net/wireless/ath/ath12k/wifi7/hal_qcc2072.c | 1 + .../net/wireless/ath/ath12k/wifi7/hal_qcn9274.c | 9 ++++ .../net/wireless/ath/ath12k/wifi7/hal_wcn7850.c | 9 ++++ .../net/wireless/ath/ath12k/wifi7/hal_wcn7850.h | 2 + 9 files changed, 65 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h index 82700474548a..fcad6a7ad6ba 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/dp_rx.h @@ -170,6 +170,13 @@ static inline u8 ath12k_dp_rx_get_msdu_src_link(struct ath12k_hal *hal, return hal->ops->rx_desc_get_msdu_src_link_id(desc); } +static inline u8 +ath12k_dp_rx_reo_get_drv_link_id(struct ath12k_dp *dp, + struct hal_reo_dest_ring *reo_desc) +{ + return dp->hal->ops->rx_reo_desc_get_drv_link_id(dp, reo_desc); +} + static inline void ath12k_dp_clean_up_skb_list(struct sk_buff_head *skb_list) { struct sk_buff *skb; diff --git a/drivers/net/wireless/ath/ath12k/hal.h b/drivers/net/wireless/ath/ath12k/hal.h index 3a874db7968e..c8bb63d92bfd 100644 --- a/drivers/net/wireless/ath/ath12k/hal.h +++ b/drivers/net/wireless/ath/ath12k/hal.h @@ -1379,6 +1379,8 @@ struct hal_ops { void (*rx_desc_copy_end_tlv)(struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc); u8 (*rx_desc_get_msdu_src_link_id)(struct hal_rx_desc *desc); + u8 (*rx_reo_desc_get_drv_link_id)(struct ath12k_dp *dp, + struct hal_reo_dest_ring *reo_desc); void (*extract_rx_desc_data)(struct hal_rx_desc_data *rx_desc_data, struct hal_rx_desc *rx_desc, struct hal_rx_desc *ldesc); diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h index b5fa8e224ca5..106d858efc44 100644 --- a/drivers/net/wireless/ath/ath12k/hw.h +++ b/drivers/net/wireless/ath/ath12k/hw.h @@ -130,6 +130,8 @@ enum ath12k_bus { #define ATH12K_EXT_IRQ_GRP_NUM_MAX 11 struct hal_rx_desc; +struct hal_reo_dest_ring; +struct ath12k_dp; struct hal_tcl_data_cmd; struct htt_rx_ring_tlv_filter; enum hal_encrypt_type; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 08a9f070e4aa..312c7ac74b3b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -44,6 +44,21 @@ static u16 ath12k_wifi7_dp_rx_get_peer_id(struct ath12k_dp *dp, } } +u8 ath12k_wifi7_dp_rx_get_logical_link_id(struct ath12k_dp *dp, + __le32 peer_metadata) +{ + switch (dp->peer_metadata_ver) { + case ATH12K_PEER_METADATA_V1: + return le32_get_bits(peer_metadata, + RX_MPDU_DESC_META_DATA_V1_LOGICAL_LINK_ID); + case ATH12K_PEER_METADATA_V1A: + return le32_get_bits(peer_metadata, + RX_MPDU_DESC_META_DATA_V1A_LOGICAL_LINK_ID); + default: + return ATH12K_GROUP_MAX_RADIO; + } +} + void ath12k_wifi7_peer_rx_tid_qref_setup(struct ath12k_base *ab, u16 peer_id, u16 tid, dma_addr_t paddr) { @@ -608,7 +623,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, device_id; + u8 drv_link_id, pdev_idx, device_id; int ret; if (skb_queue_empty(msdu_list)) @@ -621,11 +636,11 @@ 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; - device_id = ath12k_dp_drv_link_id_to_device_id(ag, hw_link_id); + drv_link_id = rxcb->drv_link_id; + device_id = ath12k_dp_drv_link_id_to_device_id(ag, drv_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); + hw_links[drv_link_id].pdev_idx); partner_ab = partner_dp->ab; ar = partner_ab->pdevs[pdev_idx].ar; if (!rcu_dereference(partner_ab->pdevs_active[pdev_idx])) { @@ -677,7 +692,7 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_dp *dp, int ring_id, struct sk_buff_head msdu_list; struct ath12k_skb_rxcb *rxcb; int total_msdu_reaped = 0; - u8 hw_link_id, device_id; + u8 drv_link_id, device_id; struct hal_srng *srng; struct sk_buff *msdu; bool done = false; @@ -708,19 +723,18 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_dp *dp, int ring_id, le32_to_cpu(desc->buf_va_lo)); desc_info = (struct ath12k_rx_desc_info *)((unsigned long)desc_va); - hw_link_id = le32_get_bits(desc->info0, - HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); - if (unlikely(hw_link_id >= ATH12K_GROUP_MAX_RADIO)) { + drv_link_id = ath12k_dp_rx_reo_get_drv_link_id(dp, desc); + if (unlikely(drv_link_id >= ATH12K_GROUP_MAX_RADIO)) { if (desc_info && desc_info->skb) { dev_kfree_skb_any(desc_info->skb); desc_info->skb = NULL; } - ath12k_warn(ab, "invalid HW link id %u\n", hw_link_id); + ath12k_warn(ab, "invalid drv link id %u\n", drv_link_id); continue; } - device_id = ath12k_dp_drv_link_id_to_device_id(ag, hw_link_id); + device_id = ath12k_dp_drv_link_id_to_device_id(ag, drv_link_id); partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); if (unlikely(!partner_dp)) { if (desc_info->skb) { @@ -775,7 +789,7 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_dp *dp, int ring_id, RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU); rxcb->is_continuation = !!(le32_to_cpu(msdu_info->info0) & RX_MSDU_DESC_INFO0_MSDU_CONTINUATION); - rxcb->drv_link_id = hw_link_id; + rxcb->drv_link_id = drv_link_id; rxcb->peer_id = ath12k_wifi7_dp_rx_get_peer_id(dp, dp->peer_metadata_ver, mpdu_info->peer_meta_data); rxcb->tid = le32_get_bits(mpdu_info->info0, @@ -1446,7 +1460,7 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_dp *dp, struct napi_struct *nap struct dp_srng *reo_except; struct ath12k_hw_link *hw_links = ag->hw_links; struct ath12k_pdev_dp *dp_pdev; - u8 hw_link_id, device_id; + u8 drv_link_id, device_id; u32 desc_bank, num_msdus; struct hal_srng *srng; dma_addr_t paddr; @@ -1475,14 +1489,13 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_dp *dp, struct napi_struct *nap drop = false; dp->device_stats.err_ring_pkts++; - hw_link_id = le32_get_bits(reo_desc->info0, - HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); - if (unlikely(hw_link_id >= ATH12K_GROUP_MAX_RADIO)) { - ath12k_warn(ab, "invalid HW link id %u\n", hw_link_id); + drv_link_id = ath12k_dp_rx_reo_get_drv_link_id(dp, reo_desc); + if (unlikely(drv_link_id >= ATH12K_GROUP_MAX_RADIO)) { + ath12k_warn(ab, "invalid drv link id %u\n", drv_link_id); continue; } - device_id = ath12k_dp_drv_link_id_to_device_id(ag, hw_link_id); + device_id = ath12k_dp_drv_link_id_to_device_id(ag, drv_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. @@ -1509,7 +1522,7 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_dp *dp, struct napi_struct *nap } pdev_idx = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params, - hw_links[hw_link_id].pdev_idx); + hw_links[drv_link_id].pdev_idx); link_desc_banks = partner_dp->link_desc_banks; link_desc_va = link_desc_banks[desc_bank].vaddr + diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h index d68489ff7b03..8a16fb3dd005 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.h @@ -12,6 +12,8 @@ struct ath12k_hal_reo_cmd; +u8 ath12k_wifi7_dp_rx_get_logical_link_id(struct ath12k_dp *dp, + __le32 peer_metadata); int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_dp *dp, struct napi_struct *napi, int budget); int ath12k_wifi7_dp_rx_process_err(struct ath12k_dp *dp, struct napi_struct *napi, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c index 7ea7559e882c..edf122fd46b5 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c @@ -472,6 +472,7 @@ const struct hal_ops hal_qcc2072_ops = { .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcc2072, .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcc2072, .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_qcc2072, + .rx_reo_desc_get_drv_link_id = ath12k_hal_rx_reo_desc_get_drv_link_id_wcn7850, .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_qcc2072, .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcc2072, .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_qcc2072, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c index 355cf50d2785..7bcde08f0d76 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c @@ -813,6 +813,14 @@ u8 ath12k_hal_rx_desc_get_msdu_src_link_qcn9274(struct hal_rx_desc *desc) RX_MSDU_END_64_TLV_SRC_LINK_ID); } +static u8 +ath12k_hal_rx_reo_desc_get_drv_link_id_qcn9274(struct ath12k_dp *dp, + struct hal_reo_dest_ring *reo_desc) +{ + return le32_get_bits(reo_desc->info0, + HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); +} + u16 ath12k_hal_rx_mpdu_start_wmask_get_qcn9274(void) { return QCN9274_MPDU_START_WMASK; @@ -1114,6 +1122,7 @@ const struct hal_ops hal_qcn9274_ops = { .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_qcn9274, .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_qcn9274, .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_qcn9274, + .rx_reo_desc_get_drv_link_id = ath12k_hal_rx_reo_desc_get_drv_link_id_qcn9274, .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_qcn9274, .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_qcn9274, .rx_desc_get_mpdu_ppdu_id = ath12k_hal_rx_desc_get_mpdu_ppdu_id_qcn9274, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c index abe982faeb2b..fec625a0ea0b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c @@ -4,6 +4,7 @@ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ +#include "dp_rx.h" #include "hal_desc.h" #include "hal_wcn7850.h" #include "hw.h" @@ -509,6 +510,13 @@ u8 ath12k_hal_rx_desc_get_msdu_src_link_wcn7850(struct hal_rx_desc *desc) return 0; } +u8 ath12k_hal_rx_reo_desc_get_drv_link_id_wcn7850(struct ath12k_dp *dp, + struct hal_reo_dest_ring *reo_desc) +{ + return ath12k_wifi7_dp_rx_get_logical_link_id(dp, + reo_desc->rx_mpdu_info.peer_meta_data); +} + static u32 ath12k_hal_rx_h_mpdu_err_wcn7850(struct hal_rx_desc *desc) { u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info13); @@ -796,6 +804,7 @@ const struct hal_ops hal_wcn7850_ops = { .rx_desc_get_crypto_header = ath12k_hal_rx_desc_get_crypto_hdr_wcn7850, .rx_desc_copy_end_tlv = ath12k_hal_rx_desc_copy_end_tlv_wcn7850, .rx_desc_get_msdu_src_link_id = ath12k_hal_rx_desc_get_msdu_src_link_wcn7850, + .rx_reo_desc_get_drv_link_id = ath12k_hal_rx_reo_desc_get_drv_link_id_wcn7850, .extract_rx_desc_data = ath12k_hal_extract_rx_desc_data_wcn7850, .rx_desc_get_l3_pad_bytes = ath12k_hal_rx_desc_get_l3_pad_bytes_wcn7850, .rx_desc_get_mpdu_start_tag = ath12k_hal_rx_desc_get_mpdu_start_tag_wcn7850, diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h index a56ca9fd3de4..c7e1fba9bb4b 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h +++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.h @@ -28,6 +28,8 @@ u32 ath12k_hal_rx_desc_get_mpdu_start_offset_wcn7850(void); u32 ath12k_hal_rx_desc_get_msdu_end_offset_wcn7850(void); u32 ath12k_hal_get_rx_desc_size_wcn7850(void); u8 ath12k_hal_rx_desc_get_msdu_src_link_wcn7850(struct hal_rx_desc *desc); +u8 ath12k_hal_rx_reo_desc_get_drv_link_id_wcn7850(struct ath12k_dp *dp, + struct hal_reo_dest_ring *reo_desc); void ath12k_hal_rx_desc_get_crypto_hdr_wcn7850(struct hal_rx_desc *desc, u8 *crypto_hdr, enum hal_encrypt_type enctype); -- 2.25.1