mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-20 19:03:39 +00:00
190 lines
6.1 KiB
Diff
190 lines
6.1 KiB
Diff
From 93d245dc2e34d85a559bcc85fcdd1322b7f434c3 Mon Sep 17 00:00:00 2001
|
|
From: Ramanathan Choodamani <quic_rchoodam@quicinc.com>
|
|
Date: Tue, 7 Mar 2023 02:00:58 -0800
|
|
Subject: [PATCH 3/6] ath12k: Optimize the tx completion routine by avoid a
|
|
function call context switch.
|
|
|
|
Optimize the workdone calculation
|
|
|
|
Signed-off-by: Balamurugan Mahalingam <quic_bmahalin@quicinc.com>
|
|
Signed-off-by: Ramanathan Choodamani <quic_rchoodam@quicinc.com>
|
|
---
|
|
drivers/net/wireless/ath/ath12k/dp_tx.c | 96 ++++++++++++++++-----------------
|
|
1 file changed, 46 insertions(+), 50 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ath/ath12k/dp_tx.c
|
|
+++ b/drivers/net/wireless/ath/ath12k/dp_tx.c
|
|
@@ -827,7 +827,7 @@ static void ath12k_dp_tx_complete_msdu(s
|
|
struct sk_buff *msdu,
|
|
struct hal_wbm_release_ring *tx_status,
|
|
enum hal_wbm_rel_src_module buf_rel_source,
|
|
- struct sk_buff *skb_ext_desc, int ring)
|
|
+ int ring)
|
|
{
|
|
struct ieee80211_tx_status status = { 0 };
|
|
struct ath12k_base *ab = ar->ab;
|
|
@@ -837,49 +837,16 @@ static void ath12k_dp_tx_complete_msdu(s
|
|
struct ath12k_link_sta *arsta;
|
|
struct rate_info rate;
|
|
struct hal_tx_status ts = { 0 };
|
|
- enum hal_wbm_tqm_rel_reason rel_status;
|
|
enum hal_wbm_htt_tx_comp_status wbm_status;
|
|
struct ieee80211_vif *vif;
|
|
struct ath12k_vif *ahvif;
|
|
u8 flags = 0;
|
|
|
|
-
|
|
- if (unlikely(WARN_ON_ONCE(buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM))) {
|
|
- /* Must not happen */
|
|
- return;
|
|
- }
|
|
-
|
|
skb_cb = ATH12K_SKB_CB(msdu);
|
|
ab->soc_stats.tx_completed[ring]++;
|
|
- dma_unmap_single_attrs(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE,
|
|
- DMA_ATTR_SKIP_CPU_SYNC);
|
|
- if (unlikely(skb_cb->paddr_ext_desc)) {
|
|
- dma_unmap_single_attrs(ab->dev, skb_cb->paddr_ext_desc,
|
|
- skb_ext_desc->len,
|
|
- DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
|
|
- dev_kfree_skb_any(skb_ext_desc);
|
|
- }
|
|
|
|
flags = skb_cb->flags;
|
|
|
|
- rel_status = FIELD_GET(HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON,
|
|
- tx_status->info0);
|
|
-
|
|
- /* Free skb here if stats is disabled */
|
|
- if (ab->stats_disable && !(flags & ATH12K_SKB_TX_STATUS)) {
|
|
- if (msdu->destructor) {
|
|
- msdu->wifi_acked_valid = 1;
|
|
- msdu->wifi_acked = rel_status ==
|
|
- HAL_WBM_TQM_REL_REASON_FRAME_ACKED;
|
|
- }
|
|
- if (skb_has_frag_list(msdu)) {
|
|
- kfree_skb_list(skb_shinfo(msdu)->frag_list);
|
|
- skb_shinfo(msdu)->frag_list = NULL;
|
|
- }
|
|
- dev_kfree_skb(msdu);
|
|
- return;
|
|
- }
|
|
-
|
|
ath12k_dp_tx_status_parse(ab, tx_status, &ts);
|
|
|
|
ar->wmm_stats.tx_type = ath12k_tid_to_ac(ts.tid > ATH12K_DSCP_PRIORITY ? 0:ts.tid);
|
|
@@ -1018,14 +985,18 @@ int ath12k_dp_tx_completion_handler(stru
|
|
struct hal_srng *status_ring = &ab->hal.srng_list[hal_ring_id];
|
|
struct ath12k_tx_desc_info *tx_desc = NULL;
|
|
struct sk_buff *msdu, *skb_ext_desc;
|
|
+ struct ath12k_skb_cb *skb_cb;
|
|
struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id];
|
|
- u32 *desc, desc_id;
|
|
+ struct ath12k_vif *ahvif;
|
|
+ u32 desc_id;
|
|
+ u8 flags = 0;
|
|
u8 mac_id;
|
|
u64 desc_va;
|
|
int valid_entries;
|
|
- int workdone = 0;
|
|
+ int orig_budget = budget;
|
|
struct hal_wbm_completion_ring_tx *tx_status;
|
|
enum hal_wbm_rel_src_module buf_rel_source;
|
|
+ enum hal_wbm_tqm_rel_reason rel_status;
|
|
|
|
|
|
ath12k_hal_srng_access_dst_ring_begin_nolock(ab, status_ring);
|
|
@@ -1033,18 +1004,15 @@ int ath12k_dp_tx_completion_handler(stru
|
|
valid_entries = ath12k_hal_srng_dst_num_free(ab, status_ring, false);
|
|
if (!valid_entries) {
|
|
ath12k_hal_srng_access_umac_dst_ring_end_nolock(ab->mem, status_ring);
|
|
- return workdone;
|
|
+ return 0;
|
|
}
|
|
|
|
ath12k_hal_srng_dst_invalidate_entry(ab, status_ring, valid_entries);
|
|
|
|
- while (budget && (desc = ath12k_hal_srng_dst_get_next_cache_entry(ab, status_ring))) {
|
|
- if (!ath12k_dp_tx_completion_valid(desc))
|
|
+ while (budget && (tx_status = ath12k_hal_srng_dst_get_next_cache_entry(ab, status_ring))) {
|
|
+ if (!ath12k_dp_tx_completion_valid(tx_status))
|
|
continue;
|
|
|
|
- tx_status = desc;
|
|
-
|
|
-
|
|
if (likely(HAL_WBM_COMPL_TX_INFO0_CC_DONE & tx_status->info0)) {
|
|
/* HW done cookie conversion */
|
|
desc_va = ((u64)tx_status->buf_va_hi << 32 |
|
|
@@ -1081,20 +1049,63 @@ int ath12k_dp_tx_completion_handler(stru
|
|
tx_desc);
|
|
continue;
|
|
}
|
|
- workdone++;
|
|
- ar = ab->pdevs[mac_id].ar;
|
|
+ budget--;
|
|
|
|
if (atomic_dec_and_test(&ar->dp.num_tx_pending))
|
|
wake_up(&ar->dp.tx_empty_waitq);
|
|
|
|
- ath12k_dp_tx_complete_msdu(ar, msdu, tx_status,
|
|
- buf_rel_source, skb_ext_desc,
|
|
- tx_ring->tcl_data_ring_id);
|
|
- budget--;
|
|
+ if (unlikely(WARN_ON_ONCE(buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM))) {
|
|
+ /* Must not happen */
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ skb_cb = (struct ath12k_skb_cb *)&IEEE80211_SKB_CB(msdu)->driver_data;
|
|
+ flags = skb_cb->flags;
|
|
+ dma_unmap_single_attrs(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE,
|
|
+ DMA_ATTR_SKIP_CPU_SYNC);
|
|
+ if (unlikely(skb_ext_desc)) {
|
|
+ dma_unmap_single_attrs(ab->dev, skb_cb->paddr_ext_desc,
|
|
+ skb_ext_desc->len,
|
|
+ DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
|
|
+ dev_kfree_skb_any(skb_ext_desc);
|
|
+ }
|
|
+ /* Free skb here if stats is disabled */
|
|
+ if (ab->stats_disable && !(flags & ATH12K_SKB_TX_STATUS)) {
|
|
+ ar->ab->soc_stats.tx_completed[tx_ring->tcl_data_ring_id]++;
|
|
+
|
|
+ if (skb_cb->vif) {
|
|
+ ahvif = (void *)skb_cb->vif->drv_priv;
|
|
+ if (ahvif->links_map & BIT(skb_cb->link_id))
|
|
+ ahvif->link[skb_cb->link_id]->link_stats.tx_completed++;
|
|
+ else
|
|
+ ath12k_warn(ab,
|
|
+ "invalid linkid 0x%X in tx completion handler for linkmap 0x%X\n",
|
|
+ skb_cb->link_id,
|
|
+ ahvif->links_map);
|
|
+ }
|
|
+
|
|
+ if (unlikely(msdu->destructor)) {
|
|
+ msdu->wifi_acked_valid = 1;
|
|
+ rel_status = FIELD_GET(HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON,
|
|
+ tx_status->info0);
|
|
+ msdu->wifi_acked = rel_status == HAL_WBM_TQM_REL_REASON_FRAME_ACKED;
|
|
+ }
|
|
+ if (unlikely(skb_has_frag_list(msdu))) {
|
|
+ kfree_skb_list(skb_shinfo(msdu)->frag_list);
|
|
+ skb_shinfo(msdu)->frag_list = NULL;
|
|
+ }
|
|
+ dev_kfree_skb(msdu);
|
|
+ } else {
|
|
+ ar = ab->pdevs[mac_id].ar;
|
|
+
|
|
+ ath12k_dp_tx_complete_msdu(ar, msdu, tx_status,
|
|
+ buf_rel_source,
|
|
+ tx_ring->tcl_data_ring_id);
|
|
+ }
|
|
}
|
|
ath12k_hal_srng_access_umac_dst_ring_end_nolock(ab->mem, status_ring);
|
|
|
|
- return workdone;
|
|
+ return (orig_budget - budget);
|
|
}
|
|
|
|
static int
|