wlan-ap-Telecominfraproject/feeds/ipq95xx/mac80211/patches/qca/335-0006-ath11k-add-simple-tx-handler-for-AP-mode.patch
John Crispin b9b03a6e38 ipq95xx: add Qualcomm wifi-7 support
Signed-off-by: John Crispin <john@phrozen.org>
2023-04-10 14:25:48 +02:00

186 lines
6.2 KiB
Diff

From 9600bc899bd28386375f5b5902a33f1984ce9da8 Mon Sep 17 00:00:00 2001
From: Venkateswara Naralasetty <quic_vnaralas@quicinc.com>
Date: Thu, 18 Nov 2021 13:11:02 +0530
Subject: [PATCH] ath11k: add simple tx handler for AP mode
Add simple tx handler for AP mode to skip cheks which are not
applicable for AP mode.
Signed-off-by: Venkateswara Naralasetty <quic_vnaralas@quicinc.com>
---
drivers/net/wireless/ath/ath11k/dp_tx.c | 123 +++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath11k/dp_tx.h | 2 +
drivers/net/wireless/ath/ath11k/hal_desc.h | 6 ++
drivers/net/wireless/ath/ath11k/mac.c | 3 +
4 files changed, 134 insertions(+)
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
@@ -92,6 +92,128 @@ static int ath11k_dp_prepare_htt_metadat
return 0;
}
+int ath11k_dp_tx_simple(struct ath11k *ar, struct ath11k_vif *arvif,
+ struct sk_buff *skb, struct ath11k_sta *arsta)
+{
+ struct ath11k_base *ab = ar->ab;
+ struct ath11k_dp *dp = &ab->dp;
+ struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb);
+ struct hal_srng *tcl_ring;
+ struct dp_tx_ring *tx_ring;
+ struct hal_tcl_data_cmd *tcl_desc;
+ void *hal_tcl_desc;
+ dma_addr_t paddr;
+ u8 pool_id;
+ u8 hal_ring_id;
+ int ret;
+ u32 idr;
+ u8 tcl_ring_id, ring_id, max_tx_ring;
+ u8 buf_id;
+ u32 desc_id;
+ u8 ring_selector;
+
+ max_tx_ring = ab->hw_params.max_tx_ring;
+
+ if (unlikely(atomic_read(&ab->num_max_allowed) > DP_TX_COMP_MAX_ALLOWED)) {
+ atomic_inc(&ab->soc_stats.tx_err.max_fail);
+ ret = -EINVAL;
+ }
+
+ ring_selector = smp_processor_id();
+ pool_id = ring_selector;
+
+ if (max_tx_ring == 1) {
+ ring_id = 0;
+ tcl_ring_id = 0;
+ } else {
+ ring_id = ring_selector % max_tx_ring;
+ tcl_ring_id = (ring_id == DP_TCL_NUM_RING_MAX) ?
+ DP_TCL_NUM_RING_MAX - 1 : ring_id;
+ }
+
+ buf_id = tcl_ring_id + HAL_RX_BUF_RBM_SW0_BM;
+ tx_ring = &dp->tx_ring[tcl_ring_id];
+
+ spin_lock_bh(&tx_ring->tx_idr_lock);
+ idr = find_first_zero_bit(tx_ring->idrs, DP_TX_IDR_SIZE);
+ if (unlikely(idr >= DP_TX_IDR_SIZE)) {
+ spin_unlock_bh(&tx_ring->tx_idr_lock);
+ return -ENOSPC;
+ }
+
+ set_bit(idr, tx_ring->idrs);
+ tx_ring->idr_pool[idr].id = idr;
+ tx_ring->idr_pool[idr].buf = skb;
+ spin_unlock_bh(&tx_ring->tx_idr_lock);
+
+ desc_id = FIELD_PREP(DP_TX_DESC_ID_MAC_ID, ar->pdev_idx) |
+ FIELD_PREP(DP_TX_DESC_ID_MSDU_ID, idr) |
+ FIELD_PREP(DP_TX_DESC_ID_POOL_ID, pool_id);
+
+ skb_cb->vif = arvif->vif;
+ skb_cb->ar = ar;
+
+ paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(ab->dev, paddr))) {
+ atomic_inc(&ab->soc_stats.tx_err.misc_fail);
+ ath11k_warn(ab, "failed to DMA map data Tx buffer\n");
+ ret = -ENOMEM;
+ goto fail_remove_idr;
+ }
+
+ skb_cb->paddr = paddr;
+
+ hal_ring_id = tx_ring->tcl_data_ring.ring_id;
+ tcl_ring = &ab->hal.srng_list[hal_ring_id];
+
+ spin_lock_bh(&tcl_ring->lock);
+ ath11k_hal_srng_access_begin(ab, tcl_ring);
+
+ hal_tcl_desc = (void *)ath11k_hal_srng_src_get_next_entry(ab, tcl_ring);
+ if (unlikely(!hal_tcl_desc)) {
+ ath11k_hal_srng_access_end(ab, tcl_ring);
+ spin_unlock_bh(&tcl_ring->lock);
+ ab->soc_stats.tx_err.desc_na[tcl_ring_id]++;
+ ret = -ENOMEM;
+ goto fail_remove_idr;
+ }
+
+ tcl_desc = (struct hal_tcl_data_cmd *)(hal_tcl_desc + sizeof(struct hal_tlv_hdr));
+ tcl_desc->info3 = 0;
+ tcl_desc->info4 = 0;
+
+ tcl_desc->buf_addr_info.info0 = FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, paddr);
+ tcl_desc->buf_addr_info.info1 = FIELD_PREP(BUFFER_ADDR_INFO1_ADDR,
+ ((uint64_t)paddr >> HAL_ADDR_MSB_REG_SHIFT));
+ tcl_desc->buf_addr_info.info1 |= FIELD_PREP(BUFFER_ADDR_INFO1_RET_BUF_MGR, buf_id) |
+ FIELD_PREP(BUFFER_ADDR_INFO1_SW_COOKIE, desc_id);
+ tcl_desc->info0 = FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_SEARCH_TYPE,
+ arvif->search_type) |
+ FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_ENCAP_TYPE, HAL_TCL_ENCAP_TYPE_ETHERNET) |
+ FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_ADDR_EN, arvif->hal_addr_search_flags) |
+ FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_CMD_NUM, arvif->tcl_metadata);
+
+ tcl_desc->info1 = FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_DATA_LEN, skb->len);
+
+ if (likely(skb->ip_summed == CHECKSUM_PARTIAL))
+ tcl_desc->info1 |= TX_IP_CHECKSUM;
+
+ tcl_desc->info2 = FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_LMAC_ID, ar->lmac_id);
+
+ ath11k_hal_srng_access_end(ab, tcl_ring);
+ spin_unlock_bh(&tcl_ring->lock);
+
+ atomic_inc(&ar->dp.num_tx_pending);
+ atomic_inc(&ab->num_max_allowed);
+
+ return 0;
+
+fail_remove_idr:
+ tx_ring->idr_pool[idr].id = -1;
+ clear_bit(idr, tx_ring->idrs);
+ return ret;
+}
+
int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
struct sk_buff *skb, struct ath11k_sta *arsta)
{
--- a/drivers/net/wireless/ath/ath11k/dp_tx.h
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.h
@@ -220,6 +220,8 @@ struct htt_tx_msdu_desc_ext {
int ath11k_dp_tx_htt_h2t_ver_req_msg(struct ath11k_base *ab);
int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
struct ath11k_sta *arsta, struct sk_buff *skb);
+int ath11k_dp_tx_simple(struct ath11k *ar, struct ath11k_vif *arvif,
+ struct sk_buff *skb, struct ath11k_sta *arsta);
void ath11k_dp_tx_completion_handler(struct ath11k_base *ab, int ring_id);
int ath11k_dp_tx_send_reo_cmd(struct ath11k_base *ab, struct dp_rx_tid *rx_tid,
enum hal_reo_cmd_type type,
--- a/drivers/net/wireless/ath/ath11k/hal_desc.h
+++ b/drivers/net/wireless/ath/ath11k/hal_desc.h
@@ -952,6 +952,12 @@ struct hal_reo_flush_cache {
u32 rsvd0[6];
} __packed;
+#define TX_IP_CHECKSUM HAL_TCL_DATA_CMD_INFO1_IP4_CKSUM_EN | \
+ HAL_TCL_DATA_CMD_INFO1_UDP4_CKSUM_EN | \
+ HAL_TCL_DATA_CMD_INFO1_UDP6_CKSUM_EN | \
+ HAL_TCL_DATA_CMD_INFO1_TCP4_CKSUM_EN | \
+ HAL_TCL_DATA_CMD_INFO1_TCP6_CKSUM_EN
+
#define HAL_TCL_DATA_CMD_INFO0_DESC_TYPE BIT(0)
#define HAL_TCL_DATA_CMD_INFO0_EPD BIT(1)
#define HAL_TCL_DATA_CMD_INFO0_ENCAP_TYPE GENMASK(3, 2)
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -6784,6 +6784,9 @@ static void ath11k_mac_op_tx(struct ieee
if (ar->ab->nss.enabled)
ret = ath11k_nss_tx(arvif, skb);
+ else if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)
+ ret = ath11k_dp_tx_simple(ar, arvif, skb,
+ (control->sta) ? control->sta->drv_priv : NULL);
else
ret = ath11k_dp_tx(ar, arvif, skb,
(control->sta) ? control->sta->drv_priv : NULL);