Introduce the ath12k_dp_hw_group struct within ath12k_hw_group to encapsulate all Data Path fields, providing a baseline for future extensions. Add this struct to the top of ath12k_hw_group to allow optimal usage of cache lines for data path fields, as it is accessed in multiple tight loops in the per-packet path. Add cmn_def.h to define common macros shared between DP and other modules. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Ripan Deuri --- drivers/net/wireless/ath/ath12k/cmn_defs.h | 13 +++++ drivers/net/wireless/ath/ath12k/core.c | 4 ++ drivers/net/wireless/ath/ath12k/core.h | 9 ++- drivers/net/wireless/ath/ath12k/dp.c | 24 ++++++++ drivers/net/wireless/ath/ath12k/dp.h | 10 ++++ drivers/net/wireless/ath/ath12k/dp_cmn.h | 12 ++++ drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 58 +++++++++++-------- drivers/net/wireless/ath/ath12k/wmi.h | 5 +- 8 files changed, 105 insertions(+), 30 deletions(-) create mode 100644 drivers/net/wireless/ath/ath12k/cmn_defs.h diff --git a/drivers/net/wireless/ath/ath12k/cmn_defs.h b/drivers/net/wireless/ath/ath12k/cmn_defs.h new file mode 100644 index 000000000000..e1f1f50341ff --- /dev/null +++ b/drivers/net/wireless/ath/ath12k/cmn_defs.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef ATH12K_CMN_DEFS_H +#define ATH12K_CMN_DEFS_H + +#define MAX_RADIOS 2 +#define ATH12K_MAX_DEVICES 3 +#define ATH12K_GROUP_MAX_RADIO (ATH12K_MAX_DEVICES * MAX_RADIOS) + +#endif diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index e5b358f5e703..84ac706fed20 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -1993,6 +1993,8 @@ static struct ath12k_hw_group *ath12k_core_hw_group_assign(struct ath12k_base *a ag->ab[ab->device_id] = ab; ab->ag = ag; + ath12k_dp_cmn_hw_group_assign(ath12k_ab_to_dp(ab), ag); + ath12k_dbg(ab, ATH12K_DBG_BOOT, "wsi group-id %d num-devices %d index %d", ag->id, ag->num_devices, wsi->index); @@ -2020,6 +2022,8 @@ void ath12k_core_hw_group_unassign(struct ath12k_base *ab) return; } + ath12k_dp_cmn_hw_group_unassign(ath12k_ab_to_dp(ab), ag); + ag->ab[device_id] = NULL; ab->ag = NULL; ab->device_id = ATH12K_INVALID_DEVICE_ID; diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 55d421595f0e..357c3e7915fe 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -34,6 +34,7 @@ #include "wow.h" #include "debugfs_htt_stats.h" #include "coredump.h" +#include "cmn_defs.h" #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) @@ -64,8 +65,6 @@ #define ATH12K_RECONFIGURE_TIMEOUT_HZ (10 * HZ) #define ATH12K_RECOVER_START_TIMEOUT_HZ (20 * HZ) -#define ATH12K_MAX_DEVICES 3 -#define ATH12K_GROUP_MAX_RADIO (ATH12K_MAX_DEVICES * MAX_RADIOS) #define ATH12K_INVALID_GROUP_ID 0xFF #define ATH12K_INVALID_DEVICE_ID 0xFF @@ -980,6 +979,11 @@ struct ath12k_hw_link { * wiphy, protected with struct ath12k_hw_group::mutex. */ struct ath12k_hw_group { + /* Keep dp_hw_grp as the first member to allow efficient + * usage of cache lines for DP fields + */ + struct ath12k_dp_hw_group dp_hw_grp; + struct ath12k_hw_link hw_links[ATH12K_GROUP_MAX_RADIO]; struct list_head list; u8 id; u8 num_devices; @@ -1002,7 +1006,6 @@ struct ath12k_hw_group { bool mlo_capable; struct device_node *wsi_node[ATH12K_MAX_DEVICES]; struct ath12k_mlo_memory mlo_mem; - struct ath12k_hw_link hw_links[ATH12K_GROUP_MAX_RADIO]; bool hw_link_id_init_done; }; diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index f8d38562fc7f..39d6bd41b4ef 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -1685,3 +1685,27 @@ int ath12k_dp_cmn_device_init(struct ath12k_dp *dp) return 0; } + +void ath12k_dp_cmn_hw_group_unassign(struct ath12k_dp *dp, + struct ath12k_hw_group *ag) +{ + struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; + + lockdep_assert_held(&ag->mutex); + + dp_hw_grp->dp[dp->device_id] = NULL; + + dp->ag = NULL; + dp->device_id = ATH12K_INVALID_DEVICE_ID; +} + +void ath12k_dp_cmn_hw_group_assign(struct ath12k_dp *dp, + struct ath12k_hw_group *ag) +{ + struct ath12k_base *ab = dp->ab; + struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; + + dp->ag = ag; + dp->device_id = ab->device_id; + dp_hw_grp->dp[dp->device_id] = dp; +} diff --git a/drivers/net/wireless/ath/ath12k/dp.h b/drivers/net/wireless/ath/ath12k/dp.h index 8b3973e0e676..05f48b461774 100644 --- a/drivers/net/wireless/ath/ath12k/dp.h +++ b/drivers/net/wireless/ath/ath12k/dp.h @@ -11,6 +11,7 @@ #include "wifi7/hal_rx.h" #include "hw.h" #include "dp_htt.h" +#include "dp_cmn.h" #define MAX_RXDMA_PER_PDEV 2 @@ -426,6 +427,9 @@ struct ath12k_dp { struct ath12k_reo_q_addr_lut ml_reoq_lut; const struct ath12k_hw_params *hw_params; struct device *dev; + + struct ath12k_hw_group *ag; + u8 device_id; }; static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) @@ -434,6 +438,12 @@ static inline void ath12k_dp_get_mac_addr(u32 addr_l32, u16 addr_h16, u8 *addr) memcpy(addr + 4, &addr_h16, ETH_ALEN - 4); } +static inline struct ath12k_dp * +ath12k_dp_hw_grp_to_dp(struct ath12k_dp_hw_group *dp_hw_grp, u8 device_id) +{ + return dp_hw_grp->dp[device_id]; +} + void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif); void ath12k_dp_cc_config(struct ath12k_base *ab); void ath12k_dp_partner_cc_init(struct ath12k_base *ab); diff --git a/drivers/net/wireless/ath/ath12k/dp_cmn.h b/drivers/net/wireless/ath/ath12k/dp_cmn.h index acc0782ad309..70c92f6d33d6 100644 --- a/drivers/net/wireless/ath/ath12k/dp_cmn.h +++ b/drivers/net/wireless/ath/ath12k/dp_cmn.h @@ -6,7 +6,19 @@ #ifndef ATH12K_DP_CMN_H #define ATH12K_DP_CMN_H +#include "cmn_defs.h" + +struct ath12k_hw_group; + +struct ath12k_dp_hw_group { + struct ath12k_dp *dp[ATH12K_MAX_DEVICES]; +}; + void ath12k_dp_cmn_device_deinit(struct ath12k_dp *dp); int ath12k_dp_cmn_device_init(struct ath12k_dp *dp); +void ath12k_dp_cmn_hw_group_unassign(struct ath12k_dp *dp, + struct ath12k_hw_group *ag); +void ath12k_dp_cmn_hw_group_assign(struct ath12k_dp *dp, + struct ath12k_hw_group *ag); #endif diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 6353c2f1f709..04c64b904693 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -558,7 +558,9 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, struct sk_buff_head *msdu_list, int ring_id) { - struct ath12k_hw_group *ag = ab->ag; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_hw_group *ag = dp->ag; + struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct ieee80211_rx_status rx_status = {}; struct ath12k_skb_rxcb *rxcb; struct sk_buff *msdu; @@ -566,6 +568,7 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, struct ath12k_hw_link *hw_links = ag->hw_links; struct ath12k_base *partner_ab; struct hal_rx_desc_data rx_info; + struct ath12k_dp *partner_dp; u8 hw_link_id, pdev_id; int ret; @@ -580,10 +583,11 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, while ((msdu = __skb_dequeue(msdu_list))) { rxcb = ATH12K_SKB_RXCB(msdu); hw_link_id = rxcb->hw_link_id; - partner_ab = ath12k_ag_to_ab(ag, - hw_links[hw_link_id].device_id); - pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, + hw_links[hw_link_id].device_id); + pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params, hw_links[hw_link_id].pdev_idx); + partner_ab = partner_dp->ab; ar = partner_ab->pdevs[pdev_id].ar; if (!rcu_dereference(partner_ab->pdevs_active[pdev_id])) { dev_kfree_skb_any(msdu); @@ -612,12 +616,13 @@ ath12k_wifi7_dp_rx_process_received_packets(struct ath12k_base *ab, int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, struct napi_struct *napi, int budget) { - struct ath12k_hw_group *ag = ab->ag; + struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_hw_group *ag = dp->ag; + 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 ath12k_dp *dp = ath12k_ab_to_dp(ab); struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring; struct hal_reo_dest_ring *desc; struct ath12k_dp *partner_dp; @@ -660,8 +665,8 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, desc_info = (struct ath12k_rx_desc_info *)((unsigned long)desc_va); device_id = hw_links[hw_link_id].device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - if (unlikely(!partner_ab)) { + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + if (unlikely(!partner_dp)) { if (desc_info->skb) { dev_kfree_skb_any(desc_info->skb); desc_info->skb = NULL; @@ -669,6 +674,7 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, continue; } + partner_ab = partner_dp->ab; /* retry manual desc retrieval */ if (!desc_info) { @@ -755,8 +761,8 @@ int ath12k_wifi7_dp_rx_process(struct ath12k_base *ab, int ring_id, if (!num_buffs_reaped[device_id]) continue; - partner_ab = ath12k_ag_to_ab(ag, device_id); - partner_dp = ath12k_ab_to_dp(partner_ab); + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + partner_ab = partner_dp->ab; rx_ring = &partner_dp->rx_refill_buf_ring; ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, @@ -1290,8 +1296,9 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k *ar, int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, int budget) { - struct ath12k_hw_group *ag = ab->ag; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_hw_group *ag = dp->ag; + struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct ath12k_dp *partner_dp; struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; u32 msdu_cookies[HAL_NUM_RX_MSDUS_PER_LINK_DESC]; @@ -1346,8 +1353,8 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n hw_link_id = le32_get_bits(reo_desc->info0, HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); device_id = hw_links[hw_link_id].device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - partner_dp = ath12k_ab_to_dp(partner_ab); + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + partner_ab = partner_dp->ab; pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, hw_links[hw_link_id].pdev_idx); @@ -1418,8 +1425,8 @@ int ath12k_wifi7_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *n if (!num_buffs_reaped[device_id]) continue; - partner_ab = ath12k_ag_to_ab(ag, device_id); - partner_dp = ath12k_ab_to_dp(partner_ab); + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + partner_ab = partner_dp->ab; rx_ring = &partner_dp->rx_refill_buf_ring; ath12k_dp_rx_bufs_replenish(partner_ab, rx_ring, @@ -1686,9 +1693,10 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, struct napi_struct *napi, int budget) { struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES]; - struct ath12k_hw_group *ag = ab->ag; struct ath12k *ar; struct ath12k_dp *dp = ath12k_ab_to_dp(ab); + struct ath12k_hw_group *ag = dp->ag; + struct ath12k_dp_hw_group *dp_hw_grp = &ag->dp_hw_grp; struct ath12k_dp *partner_dp; struct dp_rxdma_ring *rx_ring; struct hal_rx_wbm_rel_info err_info; @@ -1751,8 +1759,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, desc_info->skb = NULL; device_id = desc_info->device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - if (unlikely(!partner_ab)) { + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + if (unlikely(!partner_dp)) { dev_kfree_skb_any(msdu); /* In any case continuation bit is set @@ -1762,10 +1770,12 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, continue; } + partner_ab = partner_dp->ab; + list_add_tail(&desc_info->list, &rx_desc_used_list[device_id]); rxcb = ATH12K_SKB_RXCB(msdu); - dma_unmap_single(partner_ab->dev, rxcb->paddr, + dma_unmap_single(partner_dp->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), DMA_FROM_DEVICE); @@ -1839,8 +1849,7 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, if (!num_buffs_reaped[device_id]) continue; - partner_ab = ath12k_ag_to_ab(ag, device_id); - partner_dp = ath12k_ab_to_dp(partner_ab); + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); rx_ring = &partner_dp->rx_refill_buf_ring; ath12k_dp_rx_bufs_replenish(ab, rx_ring, @@ -1854,8 +1863,8 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, hw_link_id = rxcb->hw_link_id; device_id = hw_links[hw_link_id].device_id; - partner_ab = ath12k_ag_to_ab(ag, device_id); - if (unlikely(!partner_ab)) { + partner_dp = ath12k_dp_hw_grp_to_dp(dp_hw_grp, device_id); + if (unlikely(!partner_dp)) { ath12k_dbg(ab, ATH12K_DBG_DATA, "Unable to process WBM error msdu due to invalid hw link id %d device id %d\n", hw_link_id, device_id); @@ -1863,8 +1872,9 @@ int ath12k_wifi7_dp_rx_process_wbm_err(struct ath12k_base *ab, continue; } - pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_dp->hw_params, hw_links[hw_link_id].pdev_idx); + partner_ab = partner_dp->ab; ar = partner_ab->pdevs[pdev_id].ar; if (!ar || !rcu_dereference(ar->ab->pdevs_active[pdev_id])) { diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h index 833f42e6b826..6dcab9fceb1e 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.h +++ b/drivers/net/wireless/ath/ath12k/wmi.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ #ifndef ATH12K_WMI_H @@ -9,6 +9,7 @@ #include #include "htc.h" +#include "cmn_defs.h" /* Naming conventions for structures: * @@ -5123,8 +5124,6 @@ struct wmi_probe_tmpl_cmd { __le32 buf_len; } __packed; -#define MAX_RADIOS 2 - #define WMI_MLO_CMD_TIMEOUT_HZ (5 * HZ) #define WMI_SERVICE_READY_TIMEOUT_HZ (5 * HZ) #define WMI_SEND_TIMEOUT_HZ (3 * HZ) -- 2.34.1