// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
 */

#include "core.h"
#include "dp_tx.h"
#include "debug.h"
#include "debugfs_sta.h"
#include "hw.h"
#include "peer.h"

enum hal_tcl_encap_type
ath11k_dp_tx_get_encap_type(struct ath11k_vif *arvif, struct sk_buff *skb)
{
	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
	struct ath11k_base *ab = arvif->ar->ab;

	if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags))
		return HAL_TCL_ENCAP_TYPE_RAW;

	if (tx_info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)
		return HAL_TCL_ENCAP_TYPE_ETHERNET;

	return HAL_TCL_ENCAP_TYPE_NATIVE_WIFI;
}

static void ath11k_dp_tx_encap_nwifi(struct sk_buff *skb)
{
	struct ieee80211_hdr *hdr = (void *)skb->data;
	u8 *qos_ctl;

	if (!ieee80211_is_data_qos(hdr->frame_control))
		return;

	qos_ctl = ieee80211_get_qos_ctl(hdr);
	memmove(skb->data + IEEE80211_QOS_CTL_LEN,
		skb->data, (void *)qos_ctl - (void *)skb->data);
	skb_pull(skb, IEEE80211_QOS_CTL_LEN);

	hdr = (void *)skb->data;
	hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
}

enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher)
{
	switch (cipher) {
	case WLAN_CIPHER_SUITE_WEP40:
		return HAL_ENCRYPT_TYPE_WEP_40;
	case WLAN_CIPHER_SUITE_WEP104:
		return HAL_ENCRYPT_TYPE_WEP_104;
	case WLAN_CIPHER_SUITE_TKIP:
		return HAL_ENCRYPT_TYPE_TKIP_MIC;
	case WLAN_CIPHER_SUITE_CCMP:
		return HAL_ENCRYPT_TYPE_CCMP_128;
	case WLAN_CIPHER_SUITE_CCMP_256:
		return HAL_ENCRYPT_TYPE_CCMP_256;
	case WLAN_CIPHER_SUITE_GCMP:
		return HAL_ENCRYPT_TYPE_GCMP_128;
	case WLAN_CIPHER_SUITE_GCMP_256:
		return HAL_ENCRYPT_TYPE_AES_GCMP_256;
	default:
		return HAL_ENCRYPT_TYPE_OPEN;
	}
}

#define HTT_META_DATA_ALIGNMENT	0x8

static int ath11k_dp_prepare_htt_metadata(struct sk_buff *skb,
					  u8 *htt_metadata_size)
{
	u8 htt_desc_size;
	/* Size rounded of multiple of 8 bytes */
	u8 htt_desc_size_aligned;
	struct htt_tx_msdu_desc_ext *desc_ext;

	htt_desc_size = sizeof(struct htt_tx_msdu_desc_ext);
	htt_desc_size_aligned = ALIGN(htt_desc_size, HTT_META_DATA_ALIGNMENT);

	if (skb_headroom(skb) < htt_desc_size_aligned)
		if (pskb_expand_head(skb, htt_desc_size_aligned, 0, GFP_ATOMIC))
			return -ENOMEM;

	skb_push(skb, htt_desc_size_aligned);
	memset(skb->data, 0, htt_desc_size_aligned);
	desc_ext = (struct htt_tx_msdu_desc_ext *)skb->data;
	desc_ext->valid_encrypt_type = 1;
	desc_ext->encrypt_type = 0;
	desc_ext->host_tx_desc_pool = 1;
	*htt_metadata_size = htt_desc_size_aligned;

	return 0;
}

static inline void ath11k_dp_tx_log_eapol(struct ath11k *ar, struct sk_buff *skb,
					  struct ieee80211_sta *sta)
{
	struct ieee80211_hw *hw = ar->hw;
	int len;

	if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
		spin_lock_bh(&hw->con_pkt_trace_lock);

		if ((hw->con_pkt_trace_wr_idx_tx == hw->con_pkt_trace_rd_idx_tx) &&
		    hw->con_pkt_trace_num_entries_tx) {
			hw->con_pkt_trace_rd_idx_tx =
				CON_PKT_INC_IDX(hw->con_pkt_trace_rd_idx_tx);
			hw->con_pkt_trace_num_entries_tx--;
		}

		memset(hw->con_pkt_trace_buf_tx[hw->con_pkt_trace_wr_idx_tx], '\0',
		       sizeof(hw->con_pkt_trace_buf_tx[hw->con_pkt_trace_wr_idx_tx]));
		len = scnprintf(hw->con_pkt_trace_buf_tx[hw->con_pkt_trace_wr_idx_tx],
				CON_PKT_ENTRY_LEN,
				"%llu:ath11k:tx:eapol->%pM",
				ktime_to_ms(ktime_get()), sta->addr);
		hw->con_pkt_trace_buf_tx[hw->con_pkt_trace_wr_idx_tx][len] = '\0';

		hw->con_pkt_trace_wr_idx_tx =
			CON_PKT_INC_IDX(hw->con_pkt_trace_wr_idx_tx);
		hw->con_pkt_trace_num_entries_tx++;

		spin_unlock_bh(&hw->con_pkt_trace_lock);
	}
}

int ath11k_dp_tx_simple(struct ath11k *ar, struct ath11k_vif *arvif,
			struct sk_buff *skb, struct ieee80211_sta *sta)
{
	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 (ar->ab->hw_params.tcl_0_only) {
		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 = virt_to_phys(skb->data);
	dmac_clean_range(skb->data, (skb->data + skb->len));

	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);

	dmac_clean_range((void *)tcl_desc, (void *)(((u8 *)tcl_desc) + 32));

	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);

	if (sta)
		ath11k_dp_tx_log_eapol(ar, skb, sta);

	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 ieee80211_sta *sta)
{
	struct ath11k_base *ab = ar->ab;
	struct ath11k_dp *dp = &ab->dp;
	struct hal_tx_info ti = {0};
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb);
	struct hal_srng *tcl_ring;
	struct ieee80211_hdr *hdr = (void *)skb->data;
	struct dp_tx_ring *tx_ring;
	struct ath11k_sta *arsta = NULL;
	void *hal_tcl_desc;
	u8 pool_id;
	u8 hal_ring_id;
	int ret;
	u8 ring_selector = 0, ring_map = 0;
	bool tcl_ring_retry;
	u8 align_pad, htt_meta_size = 0, max_tx_ring, tcl_ring_id, ring_id;
	u32 idr;

	if (unlikely(!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&
	    !ieee80211_is_data(hdr->frame_control)))
		return -ENOTSUPP;

	max_tx_ring = ab->hw_params.max_tx_ring;

	/* Let the default ring selection be based on current processor
	 * number, where one of the 3 tcl rings are selected based on
	 * the smp_processor_id(). In case that ring
	 * is full/busy, we resort to other available rings.
	 * If all rings are full, we drop the packet.
	 * //TODO Add throttling logic when all rings are full
	 */
	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;

tcl_ring_sel:
	tcl_ring_retry = false;
	/* For some chip, it can only use tcl0 to tx */
	if (ar->ab->hw_params.tcl_0_only) {
		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;
	}

	ring_map |= BIT(ring_id);

	ti.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)) {
		if (unlikely(ring_map == (BIT(max_tx_ring) - 1))) {
			spin_unlock_bh(&tx_ring->tx_idr_lock);
			ab->soc_stats.tx_err.idr_na[tcl_ring_id]++;
			return -ENOSPC;
		}

		/* Check if the next ring is available */
		spin_unlock_bh(&tx_ring->tx_idr_lock);
		ring_selector++;
		goto tcl_ring_sel;
	}

	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);

	ti.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);
	ti.encap_type = ath11k_dp_tx_get_encap_type(arvif, skb);

	if (sta)
		arsta = (struct ath11k_sta *)sta->drv_priv;

	if (ieee80211_has_a4(hdr->frame_control) &&
	    is_multicast_ether_addr(hdr->addr3) && arsta &&
	    arsta->use_4addr_set) {
		ti.meta_data_flags = arsta->tcl_metadata;
		ti.flags0 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_TO_FW, 1);
	} else {
		ti.meta_data_flags = arvif->tcl_metadata;
	}

	if (unlikely(ti.encap_type == HAL_TCL_ENCAP_TYPE_RAW)) {
		if (skb_cb->flags & ATH11K_SKB_CIPHER_SET) {
			ti.encrypt_type =
				ath11k_dp_tx_get_encrypt_type(skb_cb->cipher);

			if (ieee80211_has_protected(hdr->frame_control))
				skb_put(skb, IEEE80211_CCMP_MIC_LEN);
		} else {
			ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN;
		}
	}

	ti.addr_search_flags = arvif->hal_addr_search_flags;
	ti.search_type = arvif->search_type;
	ti.type = HAL_TCL_DESC_TYPE_BUFFER;
	ti.pkt_offset = 0;
	ti.lmac_id = ar->lmac_id;
	ti.bss_ast_hash = arvif->ast_hash;
	ti.bss_ast_idx = arvif->ast_idx;
	ti.dscp_tid_tbl_idx = 0;

	if (likely(skb->ip_summed == CHECKSUM_PARTIAL &&
	    ti.encap_type != HAL_TCL_ENCAP_TYPE_RAW)) {
		ti.flags0 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_IP4_CKSUM_EN, 1) |
			     FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_UDP4_CKSUM_EN, 1) |
			     FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_UDP6_CKSUM_EN, 1) |
			     FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_TCP4_CKSUM_EN, 1) |
			     FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_TCP6_CKSUM_EN, 1);
	}

	if (ieee80211_vif_is_mesh(arvif->vif))
		ti.enable_mesh = true;

	switch (ti.encap_type) {
	case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI:
		ath11k_dp_tx_encap_nwifi(skb);
		break;
	case HAL_TCL_ENCAP_TYPE_RAW:
		if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) {
			ret = -EINVAL;
			goto fail_remove_idr;
		}
		break;
	case HAL_TCL_ENCAP_TYPE_ETHERNET:
		/* no need to encap */
		break;
	case HAL_TCL_ENCAP_TYPE_802_3:
	default:
		/* TODO: Take care of other encap modes as well */
		ret = -EINVAL;
		atomic_inc(&ab->soc_stats.tx_err.misc_fail);
		arsta->drop_pkts++;
		arsta->drop_bytes += skb->len;
		goto fail_remove_idr;
	}

	/* Add metadata for sw encrypted vlan group traffic */
	if (!test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) &&
	    !(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&
	    !info->control.hw_key &&
	    ieee80211_has_protected(hdr->frame_control)) {
		/* HW requirement is that metadata should always point to a
		 * 8-byte aligned address. So we add alignment pad to start of
		 * buffer. HTT Metadata should be ensured to be multiple of 8-bytes
		 *  to get 8-byte aligned start address along with align_pad added
		 */
		align_pad = ((unsigned long)skb->data) & (HTT_META_DATA_ALIGNMENT - 1);
		if (skb_headroom(skb) < align_pad) {
			if (pskb_expand_head(skb, align_pad, 0, GFP_ATOMIC)) {
				ret = -ENOMEM;
				goto fail_remove_idr;
			}
		}
		skb_push(skb, align_pad);
		ti.pkt_offset += align_pad;
		memset(skb->data, 0, align_pad);
		ret = ath11k_dp_prepare_htt_metadata(skb, &htt_meta_size);
		if (ret)
			goto fail_remove_idr;

		ti.pkt_offset += htt_meta_size;
		ti.meta_data_flags |= HTT_TCL_META_DATA_VALID_HTT;
		ti.flags0 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_TO_FW, 1);
		ti.encap_type = HAL_TCL_ENCAP_TYPE_RAW;
		ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN;
	}

	ti.data_len = skb->len - ti.pkt_offset;
	skb_cb->vif = arvif->vif;
	skb_cb->ar = ar;

	ti.paddr = virt_to_phys(skb->data);
	dmac_clean_range(skb->data, (skb->data + skb->len));

	skb_cb->paddr = ti.paddr;

	if (ring_id == DP_TCL_NUM_RING_MAX)
		hal_ring_id = dp->tcl_cmd_ring.ring_id;
	else
		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)) {
		/* NOTE: It is highly unlikely we'll be running out of tcl_ring
		 * desc because the desc is directly enqueued onto hw queue.
		 */
		ath11k_hal_srng_access_end(ab, tcl_ring);
		ab->soc_stats.tx_err.desc_na[tcl_ring_id]++;
		spin_unlock_bh(&tcl_ring->lock);
		ret = -ENOMEM;

		/* Checking for available tcl descritors in another ring in
		 * case of failure due to full tcl ring now, is better than
		 * checking this ring earlier for each pkt tx.
		 * Restart ring selection if some rings are not checked yet.
		 */
		if (unlikely(ring_map != (BIT(max_tx_ring) - 1) &&
		    !ar->ab->hw_params.tcl_0_only)) {
			tcl_ring_retry = true;
			ring_selector++;
		}

		goto fail_unmap_dma;
	}

	if (sta)
		ath11k_dp_tx_log_eapol(ar, skb, sta);

	ath11k_hal_tx_cmd_desc_setup(ab, hal_tcl_desc +
					 sizeof(struct hal_tlv_hdr), &ti);

	dmac_clean_range(hal_tcl_desc, (void *)(hal_tcl_desc + 32));

	atomic_inc(&ar->dp.num_tx_pending);
	atomic_inc(&ab->num_max_allowed);
	ath11k_hal_srng_access_end(ab, tcl_ring);

	ath11k_dp_shadow_start_timer(ab, tcl_ring, &dp->tx_ring_timer[ti.buf_id]);

	spin_unlock_bh(&tcl_ring->lock);

	ath11k_dbg_dump(ab, ATH11K_DBG_DP_TX, NULL, "dp tx msdu: ",
			skb->data, skb->len);

	return 0;

fail_unmap_dma:
	dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE);

fail_remove_idr:
	if (ti.pkt_offset)
		skb_pull(skb, ti.pkt_offset);

	tx_ring->idr_pool[idr].id = -1;
	clear_bit(idr, tx_ring->idrs);

	if (tcl_ring_retry)
		goto tcl_ring_sel;

	return ret;
}

static void ath11k_dp_tx_free_txbuf(struct ath11k_base *ab, u8 mac_id,
				    u32 msdu_id,
				    struct dp_tx_ring *tx_ring)
{
	struct ath11k *ar;
	struct sk_buff *msdu = NULL;
	struct ath11k_skb_cb *skb_cb;

	if (msdu_id < DP_TX_IDR_SIZE &&
	    tx_ring->idr_pool[msdu_id].id == msdu_id) {
		msdu = tx_ring->idr_pool[msdu_id].buf;
		tx_ring->idr_pool[msdu_id].id = -1;
		clear_bit(msdu_id, tx_ring->idrs);
	}

	if (!msdu) {
		ath11k_warn(ab, "tx completion for unknown msdu_id %d\n",
			    msdu_id);
		return;
	}

	skb_cb = ATH11K_SKB_CB(msdu);

	dmac_clean_range(msdu->data, (msdu->data + msdu->len));
	dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
	dev_kfree_skb_any(msdu);

	ar = ab->pdevs[mac_id].ar;
	if (atomic_dec_and_test(&ar->dp.num_tx_pending))
		wake_up(&ar->dp.tx_empty_waitq);
}

static void
ath11k_dp_tx_htt_tx_complete_buf(struct ath11k_base *ab,
				 struct dp_tx_ring *tx_ring,
				 struct ath11k_dp_htt_wbm_tx_status *ts)
{
	struct sk_buff *msdu = NULL;
	struct ieee80211_tx_info *info;
	struct ath11k_skb_cb *skb_cb;
	struct ath11k *ar;
	struct ieee80211_vif *vif;
	u8 flags = 0;
	u32 msdu_id = ts->msdu_id;

	if (msdu_id < DP_TX_IDR_SIZE &&
	    tx_ring->idr_pool[msdu_id].id == msdu_id) {
		msdu = tx_ring->idr_pool[msdu_id].buf;
		tx_ring->idr_pool[msdu_id].id = -1;
		clear_bit(msdu_id, tx_ring->idrs);
	}

	if (unlikely(!msdu)) {
		ath11k_warn(ab, "htt tx completion for unknown msdu_id %d\n",
			    ts->msdu_id);
		return;
	}

	skb_cb = ATH11K_SKB_CB(msdu);
	info = IEEE80211_SKB_CB(msdu);

	ar = skb_cb->ar;

	if (atomic_dec_and_test(&ar->dp.num_tx_pending))
		wake_up(&ar->dp.tx_empty_waitq);

	dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);

	flags = skb_cb->flags;

	/* Free skb here if stats is disabled */
	if (ab->stats_disable && !(flags & ATH11K_SKB_TX_STATUS)) {
		if (msdu->destructor) {
			msdu->wifi_acked_valid = 1;
			msdu->wifi_acked = ts->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;
	}

	if (unlikely(!skb_cb->vif)) {
		dev_kfree_skb_any(msdu);
		return;
	}

	vif = skb_cb->vif;

	memset(&info->status, 0, sizeof(info->status));

	if (ts->acked) {
		if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
		    !(flags & ATH11K_SKB_F_NOACK_TID)) {
			info->flags |= IEEE80211_TX_STAT_ACK;
			info->status.ack_signal = ATH11K_DEFAULT_NOISE_FLOOR +
						  ts->ack_rssi;
			info->status.is_valid_ack_signal = true;
		} else {
			info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
		}
	}

	if (flags & ATH11K_SKB_HW_80211_ENCAP)
		ieee80211_tx_status_8023(ar->hw, vif, msdu);
	else
		ieee80211_tx_status(ar->hw, msdu);
}

static void
ath11k_dp_tx_process_htt_tx_complete(struct ath11k_base *ab,
				     void *desc, u8 mac_id,
				     u32 msdu_id, struct dp_tx_ring *tx_ring)
{
	struct htt_tx_wbm_completion *status_desc;
	struct ath11k_dp_htt_wbm_tx_status ts = {0};
	enum hal_wbm_htt_tx_comp_status wbm_status;

	status_desc = desc + HTT_TX_WBM_COMP_STATUS_OFFSET;

	wbm_status = FIELD_GET(HTT_TX_WBM_COMP_INFO0_STATUS,
			       status_desc->info0);
	switch (wbm_status) {
	case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK:
	case HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP:
	case HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL:
		ts.acked = (wbm_status == HAL_WBM_REL_HTT_TX_COMP_STATUS_OK);
		ts.msdu_id = msdu_id;
		ts.ack_rssi = FIELD_GET(HTT_TX_WBM_COMP_INFO1_ACK_RSSI,
					status_desc->info1);
		ath11k_dp_tx_htt_tx_complete_buf(ab, tx_ring, &ts);
		break;
	case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ:
	case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT:
		ath11k_dp_tx_free_txbuf(ab, mac_id, msdu_id, tx_ring);
		break;
	case HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY:
		/* This event is to be handled only when the driver decides to
		 * use WDS offload functionality on NSS disabled case.
		 */
		break;
	default:
		ath11k_warn(ab, "Unknown htt tx status %d\n", wbm_status);
		break;
	}
}

static void ath11k_dp_tx_cache_peer_stats(struct ath11k *ar,
					  struct sk_buff *msdu,
					  struct hal_tx_status *ts)
{
	struct ath11k_per_peer_tx_stats *peer_stats = &ar->cached_stats;

	if (ts->try_cnt > 1) {
		peer_stats->retry_pkts += ts->try_cnt - 1;
		peer_stats->retry_bytes += (ts->try_cnt - 1) * msdu->len;

		if (ts->status != HAL_WBM_TQM_REL_REASON_FRAME_ACKED) {
			peer_stats->failed_pkts += 1;
			peer_stats->failed_bytes += msdu->len;
		}
	}
}

static inline void ath11k_dp_tx_status_parse(struct ath11k_base *ab,
					     struct hal_wbm_release_ring *desc,
					     struct hal_tx_status *ts)
{
	ts->buf_rel_source =
		FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, desc->info0);
	ts->status = FIELD_GET(HAL_WBM_RELEASE_INFO0_TQM_RELEASE_REASON,
			       desc->info0);
	ts->ppdu_id = FIELD_GET(HAL_WBM_RELEASE_INFO1_TQM_STATUS_NUMBER,
				desc->info1);
	ts->try_cnt = FIELD_GET(HAL_WBM_RELEASE_INFO1_TRANSMIT_COUNT,
				desc->info1);
	ts->ack_rssi = FIELD_GET(HAL_WBM_RELEASE_INFO2_ACK_FRAME_RSSI,
				 desc->info2);
	if (desc->info2 & HAL_WBM_RELEASE_INFO2_FIRST_MSDU)
		ts->flags |= HAL_TX_STATUS_FLAGS_FIRST_MSDU;
	ts->peer_id = FIELD_GET(HAL_WBM_RELEASE_INFO3_PEER_ID, desc->info3);
	ts->tid = FIELD_GET(HAL_WBM_RELEASE_INFO3_TID, desc->info3);
	if (desc->rate_stats.info0 & HAL_TX_RATE_STATS_INFO0_VALID)
		ts->rate_stats = desc->rate_stats.info0;
	else
		ts->rate_stats = 0;
}

static void ath11k_dp_tx_complete_msdu(struct ath11k *ar,
				       struct sk_buff *msdu,
				       struct hal_wbm_release_ring *tx_status,
				       enum hal_wbm_rel_src_module buf_rel_source)
{
	struct ieee80211_tx_status status = { 0 };
	struct ath11k_base *ab = ar->ab;
	struct ieee80211_hw *hw = ar->hw;
	struct ieee80211_tx_info *info;
	struct ath11k_skb_cb *skb_cb;
	struct ath11k_peer *peer;
	struct ath11k_sta *arsta;
	struct ieee80211_vif *vif = NULL;
	struct rate_info rate;
	struct ath11k_vif *arvif = NULL;
	struct hal_tx_status ts = { 0 };
	enum hal_wbm_htt_tx_comp_status wbm_status;
	enum hal_wbm_tqm_rel_reason rel_status;
	int len;
	u8 flags = 0;

	if (unlikely(WARN_ON_ONCE(buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM))) {
		/* Must not happen */
		return;
	}

	skb_cb = ATH11K_SKB_CB(msdu);

	dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);

	flags = skb_cb->flags;

	rel_status = FIELD_GET(HAL_WBM_RELEASE_INFO0_TQM_RELEASE_REASON,
			       tx_status->info0);

	/* Free skb here if stats is disabled */
	if (ab->stats_disable && !(flags & ATH11K_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;
	}

	ath11k_dp_tx_status_parse(ab, tx_status, &ts);

	rcu_read_lock();

	if (unlikely(!rcu_dereference(ab->pdevs_active[ar->pdev_idx]))) {
		dev_kfree_skb_any(msdu);
		goto exit;
	}

	if (unlikely(!skb_cb->vif)) {
		dev_kfree_skb_any(msdu);
		goto exit;
	}

	wbm_status = FIELD_GET(HTT_TX_WBM_COMP_INFO0_STATUS,
			       tx_status->info0);

	vif = skb_cb->vif;
	arvif = (void *)vif->drv_priv;
	if(arvif && wbm_status < HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX)
		arvif->wbm_tx_comp_stats[wbm_status]++;

	info = IEEE80211_SKB_CB(msdu);
	memset(&info->status, 0, sizeof(info->status));

	/* skip tx rate update from ieee80211_status*/
	info->status.rates[0].idx = -1;

	if (ts.status == HAL_WBM_TQM_REL_REASON_FRAME_ACKED &&
	    !(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
	    !(flags & ATH11K_SKB_F_NOACK_TID)) {
		info->flags |= IEEE80211_TX_STAT_ACK;
		info->status.ack_signal = ATH11K_DEFAULT_NOISE_FLOOR +
					  ts.ack_rssi;
		info->status.is_valid_ack_signal = true;
	}

	if (ts.status == HAL_WBM_TQM_REL_REASON_CMD_REMOVE_TX &&
	    (info->flags & IEEE80211_TX_CTL_NO_ACK) &&
	    (flags & ATH11K_SKB_F_NOACK_TID))
		info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;

	if (unlikely(ath11k_debugfs_is_extd_tx_stats_enabled(ar))) {
		if (ts.flags & HAL_TX_STATUS_FLAGS_FIRST_MSDU) {
			if (ar->last_ppdu_id == 0) {
				ar->last_ppdu_id = ts.ppdu_id;
			} else if (ar->last_ppdu_id == ts.ppdu_id ||
				   ar->cached_ppdu_id == ar->last_ppdu_id) {
				ar->cached_ppdu_id = ar->last_ppdu_id;
				ar->cached_stats.is_ampdu = true;
				ath11k_debugfs_sta_update_txcompl(ar, msdu, &ts);
				memset(&ar->cached_stats, 0,
				       sizeof(struct ath11k_per_peer_tx_stats));
			} else {
				ar->cached_stats.is_ampdu = false;
				ath11k_debugfs_sta_update_txcompl(ar, msdu, &ts);
				memset(&ar->cached_stats, 0,
				       sizeof(struct ath11k_per_peer_tx_stats));
			}
			ar->last_ppdu_id = ts.ppdu_id;
		}

		ath11k_dp_tx_cache_peer_stats(ar, msdu, &ts);
	}

	/* NOTE: Tx rate status reporting. Tx completion status does not have
	 * necessary information (for example nss) to build the tx rate.
	 * Might end up reporting it out-of-band from HTT stats.
	 */

	spin_lock_bh(&ab->base_lock);
	peer = ath11k_peer_find_by_id(ab, ts.peer_id);
	if (unlikely(!peer || !peer->sta)) {
		ath11k_dbg(ab, ATH11K_DBG_DATA,
			   "dp_tx: failed to find the peer with peer_id %d\n",
			    ts.peer_id);
		spin_unlock_bh(&ab->base_lock);
		dev_kfree_skb_any(msdu);
		goto exit;
	}
	arsta = (struct ath11k_sta *)peer->sta->drv_priv;
	status.sta = peer->sta;
	status.skb = msdu;
	status.info = info;
	rate = arsta->last_txrate;
	status.rate = &rate;
	arsta->tx_retry_count += ts.try_cnt > 1 ? (ts.try_cnt - 1) : 0;

	if (unlikely(ath11k_debugfs_is_extd_tx_stats_enabled(ar))) {
		if(arsta->wbm_tx_stats && wbm_status < HAL_WBM_REL_HTT_TX_COMP_STATUS_MAX)
			arsta->wbm_tx_stats->wbm_tx_comp_stats[wbm_status]++;
	}

	if (ts.status != HAL_WBM_TQM_REL_REASON_FRAME_ACKED) {
		if (ts.status == HAL_WBM_TQM_REL_REASON_CMD_REMOVE_MPDU) {
			arsta->drop_pkts += 1;
			arsta->drop_bytes += msdu->len;
			spin_unlock_bh(&ab->base_lock);
			dev_kfree_skb_any(msdu);
			goto exit;
		} else {
			arsta->fail_pkts += 1;
			arsta->per_fail_pkts += 1;
			arsta->fail_bytes += msdu->len;
			arsta->ber_fail_bytes += msdu->len;
		}

		if(arsta->per_fail_pkts + arsta->per_succ_pkts >=
		   ATH11K_NUM_PKTS_THRSHLD_FOR_PER)
			ath11k_sta_stats_update_per(arsta);
		if(arsta->ber_fail_bytes + arsta->ber_succ_bytes >=
		   ATH11K_NUM_BYTES_THRSHLD_FOR_BER)
			ath11k_sta_stats_update_ber(arsta);
	}

	spin_unlock_bh(&ab->base_lock);
	rcu_read_unlock();

	if (unlikely(msdu->protocol == cpu_to_be16(ETH_P_PAE))) {
		spin_lock_bh(&hw->con_pkt_trace_lock);

		if ((hw->con_pkt_trace_wr_idx_tx == hw->con_pkt_trace_rd_idx_tx) &&
		    hw->con_pkt_trace_num_entries_tx) {
			hw->con_pkt_trace_rd_idx_tx =
				CON_PKT_INC_IDX(hw->con_pkt_trace_rd_idx_tx);
			hw->con_pkt_trace_num_entries_tx--;
		}

		memset(hw->con_pkt_trace_buf_tx[hw->con_pkt_trace_wr_idx_tx], '\0',
		       sizeof(hw->con_pkt_trace_buf_tx[hw->con_pkt_trace_wr_idx_tx]));
		len = scnprintf(hw->con_pkt_trace_buf_tx[hw->con_pkt_trace_wr_idx_tx],
				CON_PKT_ENTRY_LEN,
				"%llu:ath11k:tx_compl:%s:eapol->%pM",
				ktime_to_ms(ktime_get()),
				ts.status == HAL_WBM_TQM_REL_REASON_FRAME_ACKED ?
				"OKAY" : "FAILED", peer->sta->addr);
		hw->con_pkt_trace_buf_tx[hw->con_pkt_trace_wr_idx_tx][len] = '\0';

		hw->con_pkt_trace_wr_idx_tx =
			CON_PKT_INC_IDX(hw->con_pkt_trace_wr_idx_tx);
		hw->con_pkt_trace_num_entries_tx++;

		spin_unlock_bh(&hw->con_pkt_trace_lock);
	}

	if (flags & ATH11K_SKB_HW_80211_ENCAP)
		ieee80211_tx_status_8023(hw, vif, msdu);
	else
		ieee80211_tx_status_ext(hw, &status);
	return;
exit:
	rcu_read_unlock();
}

static inline bool ath11k_dp_tx_completion_valid(struct hal_wbm_release_ring *desc)
{
	struct htt_tx_wbm_completion *status_desc;

	if (FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, desc->info0) ==
	    HAL_WBM_REL_SRC_MODULE_FW) {
		status_desc = (struct htt_tx_wbm_completion *)(((u8 *)desc) + HTT_TX_WBM_COMP_STATUS_OFFSET);
		/* Dont consider HTT_TX_COMP_STATUS_MEC_NOTIFY */
		if (FIELD_GET(HTT_TX_WBM_COMP_INFO0_STATUS, status_desc->info0) ==
		    HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY)
			return false;
	}
	return true;
}

static inline u32 txdelay_time_to_ms(u32 val)
{
	u64 valns = ((u64)val << IEEE80211_TX_DELAY_SHIFT);

	do_div(valns, NSEC_PER_MSEC);
	return (u32)valns;
}

/* Returns transmit delay histogram stats bin to credit based on latency. */
static inline int txdelay_ms_to_bin(u32 latency)
{
	int top_bit_set;
	int bin_offset;

	/* The exponential (power-of-two) bucket range is determined by the high
	 * order bit set.  The first two 1ms bin (i.e. [0, 1) and [1, 2)) are
	 * returned directly.  All other bins are subdivided in half by
	 * calculating bin_offset based on the bit immediately to the right of
	 * the high order bit set.
	 */
	top_bit_set = fls(latency);
	if (top_bit_set < 2)
		return top_bit_set;
	if (top_bit_set > ATH11K_DELAY_STATS_SCALED_BINS)
		return ATH11K_DELAY_STATS_SCALED_BINS;
	bin_offset = (latency & (1 << (top_bit_set - 2))) ? 1 : 0;
	return (top_bit_set - 1) * 2 + bin_offset;
}

void ath11k_update_latency_stats(struct ath11k *ar, struct sk_buff *msdu, u8 tid)
{
	u32 enqueue_time, now;
	struct ieee80211_tx_info *info;
	int bin;

	info = IEEE80211_SKB_CB(msdu);
	enqueue_time = info->latency.tx_start_time;
	if (enqueue_time == 0)
		return;

	now = ieee80211_txdelay_get_time();
	bin = txdelay_ms_to_bin(txdelay_time_to_ms(now - enqueue_time));

	if (!ar->debug.tx_delay_stats) {
		ath11k_warn(ar->ab, "tx delay stats invalid\n");
		return;
	}

	ar->debug.tx_delay_stats[tid]->counts[bin]++;
}

void ath11k_dp_tx_completion_handler(struct ath11k_base *ab, int ring_id)
{
	struct ath11k *ar;
	struct ath11k_dp *dp = &ab->dp;
	struct ath11k_skb_cb *skb_cb;
	int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id;
	struct hal_srng *status_ring = &ab->hal.srng_list[hal_ring_id];
	struct sk_buff *msdu;
	struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id];
	struct hal_wbm_release_ring *tx_status;
	enum hal_wbm_rel_src_module buf_rel_source;
	int valid_entries, count = 0, i = 0;
	u32 *desc;
	u32 msdu_id, desc_id;
	u8 mac_id, tid;

	spin_lock_bh(&status_ring->lock);

	ath11k_hal_srng_access_begin(ab, status_ring);

	valid_entries = ath11k_hal_srng_dst_num_valid(ab, status_ring, false);
	if (!valid_entries) {
		ath11k_hal_srng_access_end(ab, status_ring);
		spin_unlock_bh(&status_ring->lock);
		return;
	}

	ath11k_hal_srng_dst_invalidate_entry(ab, status_ring, valid_entries);

	while ((desc = ath11k_hal_srng_dst_get_next_cache_entry(ab, status_ring))) {
		if (!ath11k_dp_tx_completion_valid(((struct hal_wbm_release_ring *)desc)))
			continue;

		memcpy(&tx_ring->tx_status[count],
		       desc, sizeof(struct hal_wbm_release_ring));
		count++;
	}

	ath11k_hal_srng_access_end(ab, status_ring);

	spin_unlock_bh(&status_ring->lock);

	if (atomic_sub_return(count, &ab->num_max_allowed) < 0) {
		ath11k_warn(ab, "tx completion mismatch count %d ring id %d max_num %d\n",
			    count, tx_ring->tcl_data_ring_id,
			    atomic_read(&ab->num_max_allowed));
	}

	while (count--) {
		msdu=NULL;
		tx_status = &tx_ring->tx_status[i++];

		desc_id = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
				    tx_status->buf_addr_info.info1);
		mac_id = FIELD_GET(DP_TX_DESC_ID_MAC_ID, desc_id);
		msdu_id = FIELD_GET(DP_TX_DESC_ID_MSDU_ID, desc_id);

		buf_rel_source = FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE,
					   tx_status->info0);

		if (unlikely(buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW)) {
			ath11k_dp_tx_process_htt_tx_complete(ab,
							     (void *)tx_status,
							     mac_id, msdu_id,
							     tx_ring);
			continue;
		}

		if (msdu_id < DP_TX_IDR_SIZE &&
		    tx_ring->idr_pool[msdu_id].id == msdu_id) {
			msdu = tx_ring->idr_pool[msdu_id].buf;
			tx_ring->idr_pool[msdu_id].id = -1;
			clear_bit(msdu_id, tx_ring->idrs);
		}

		if (unlikely(!msdu)) {
			ath11k_warn(ab, "tx completion for unknown msdu_id %d\n",
				    msdu_id);
			continue;
		}
		skb_cb = ATH11K_SKB_CB(msdu);
		ar = ab->pdevs[mac_id].ar;

		tid = FIELD_GET(HAL_WBM_RELEASE_INFO3_TID, tx_status->info3);
		if (tid < IEEE80211_NUM_TIDS)
			ath11k_update_latency_stats(ar, msdu, tid);
		else
			ath11k_warn(ab, "Received data with invalid tid\n");

		if (atomic_dec_and_test(&ar->dp.num_tx_pending))
			wake_up(&ar->dp.tx_empty_waitq);

		if (skb_cb->vif->type == NL80211_IFTYPE_AP && performance_mode) {
			dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
			dev_kfree_skb(msdu);
			continue;
		}

		ath11k_dp_tx_complete_msdu(ar, msdu, tx_status, buf_rel_source);
	}
}

int ath11k_dp_tx_send_reo_cmd(struct ath11k_base *ab, struct dp_rx_tid *rx_tid,
			      enum hal_reo_cmd_type type,
			      struct ath11k_hal_reo_cmd *cmd,
			      void (*cb)(struct ath11k_dp *, void *,
					 enum hal_reo_cmd_status))
{
	struct ath11k_dp *dp = &ab->dp;
	struct dp_reo_cmd *dp_cmd;
	struct hal_srng *cmd_ring;
	int cmd_num;

	if (test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags))
		return -ESHUTDOWN;

	cmd_ring = &ab->hal.srng_list[dp->reo_cmd_ring.ring_id];
	cmd_num = ath11k_hal_reo_cmd_send(ab, cmd_ring, type, cmd);

	/* cmd_num should start from 1, during failure return the error code */
	if (cmd_num < 0)
		return cmd_num;

	/* reo cmd ring descriptors has cmd_num starting from 1 */
	if (cmd_num == 0)
		return -EINVAL;

	if (!cb)
		return 0;

	/* Can this be optimized so that we keep the pending command list only
	 * for tid delete command to free up the resoruce on the command status
	 * indication?
	 */
	dp_cmd = kzalloc(sizeof(*dp_cmd), GFP_ATOMIC);

	if (!dp_cmd)
		return -ENOMEM;

	memcpy(&dp_cmd->data, rx_tid, sizeof(struct dp_rx_tid));
	dp_cmd->cmd_num = cmd_num;
	dp_cmd->handler = cb;

	spin_lock_bh(&dp->reo_cmd_lock);
	list_add_tail(&dp_cmd->list, &dp->reo_cmd_list);
	spin_unlock_bh(&dp->reo_cmd_lock);

	return 0;
}

static int
ath11k_dp_tx_get_ring_id_type(struct ath11k_base *ab,
			      int mac_id, u32 ring_id,
			      enum hal_ring_type ring_type,
			      enum htt_srng_ring_type *htt_ring_type,
			      enum htt_srng_ring_id *htt_ring_id)
{
	int lmac_ring_id_offset = 0;
	int ret = 0;

	switch (ring_type) {
	case HAL_RXDMA_BUF:
		lmac_ring_id_offset = mac_id * HAL_SRNG_RINGS_PER_LMAC;

		/* for QCA6390, host fills rx buffer to fw and fw fills to
		 * rxbuf ring for each rxdma
		 */
		if (!ab->hw_params.rx_mac_buf_ring) {
			if (!(ring_id == (HAL_SRNG_RING_ID_WMAC1_SW2RXDMA0_BUF +
					  lmac_ring_id_offset) ||
				ring_id == (HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_BUF +
					lmac_ring_id_offset))) {
				ret = -EINVAL;
			}
			*htt_ring_id = HTT_RXDMA_HOST_BUF_RING;
			*htt_ring_type = HTT_SW_TO_HW_RING;
		} else {
			if (ring_id == HAL_SRNG_RING_ID_WMAC1_SW2RXDMA0_BUF) {
				*htt_ring_id = HTT_HOST1_TO_FW_RXBUF_RING;
				*htt_ring_type = HTT_SW_TO_SW_RING;
			} else {
				*htt_ring_id = HTT_RXDMA_HOST_BUF_RING;
				*htt_ring_type = HTT_SW_TO_HW_RING;
			}
		}
		break;
	case HAL_RXDMA_DST:
		*htt_ring_id = HTT_RXDMA_NON_MONITOR_DEST_RING;
		*htt_ring_type = HTT_HW_TO_SW_RING;
		break;
	case HAL_RXDMA_MONITOR_BUF:
		*htt_ring_id = HTT_RXDMA_MONITOR_BUF_RING;
		*htt_ring_type = HTT_SW_TO_HW_RING;
		break;
	case HAL_RXDMA_MONITOR_STATUS:
		*htt_ring_id = HTT_RXDMA_MONITOR_STATUS_RING;
		*htt_ring_type = HTT_SW_TO_HW_RING;
		break;
	case HAL_RXDMA_MONITOR_DST:
		*htt_ring_id = HTT_RXDMA_MONITOR_DEST_RING;
		*htt_ring_type = HTT_HW_TO_SW_RING;
		break;
	case HAL_RXDMA_MONITOR_DESC:
		*htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING;
		*htt_ring_type = HTT_SW_TO_HW_RING;
		break;
	default:
		ath11k_warn(ab, "Unsupported ring type in DP :%d\n", ring_type);
		ret = -EINVAL;
	}
	return ret;
}

int ath11k_dp_tx_htt_srng_setup(struct ath11k_base *ab, u32 ring_id,
				int mac_id, enum hal_ring_type ring_type)
{
	struct htt_srng_setup_cmd *cmd;
	struct hal_srng *srng = &ab->hal.srng_list[ring_id];
	struct hal_srng_params params;
	struct sk_buff *skb;
	u32 ring_entry_sz;
	int len = sizeof(*cmd);
	dma_addr_t hp_addr, tp_addr;
	enum htt_srng_ring_type htt_ring_type;
	enum htt_srng_ring_id htt_ring_id;
	int ret;

	skb = ath11k_htc_alloc_skb(ab, len);
	if (!skb)
		return -ENOMEM;

	memset(&params, 0, sizeof(params));
	ath11k_hal_srng_get_params(ab, srng, &params);

	hp_addr = ath11k_hal_srng_get_hp_addr(ab, srng);
	tp_addr = ath11k_hal_srng_get_tp_addr(ab, srng);

	ret = ath11k_dp_tx_get_ring_id_type(ab, mac_id, ring_id,
					    ring_type, &htt_ring_type,
					    &htt_ring_id);
	if (ret)
		goto err_free;

	skb_put(skb, len);
	cmd = (struct htt_srng_setup_cmd *)skb->data;
	cmd->info0 = FIELD_PREP(HTT_SRNG_SETUP_CMD_INFO0_MSG_TYPE,
				HTT_H2T_MSG_TYPE_SRING_SETUP);
	if (htt_ring_type == HTT_SW_TO_HW_RING ||
	    htt_ring_type == HTT_HW_TO_SW_RING)
		cmd->info0 |= FIELD_PREP(HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID,
					 DP_SW2HW_MACID(mac_id));
	else
		cmd->info0 |= FIELD_PREP(HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID,
					 mac_id);
	cmd->info0 |= FIELD_PREP(HTT_SRNG_SETUP_CMD_INFO0_RING_TYPE,
				 htt_ring_type);
	cmd->info0 |= FIELD_PREP(HTT_SRNG_SETUP_CMD_INFO0_RING_ID, htt_ring_id);

	cmd->ring_base_addr_lo = params.ring_base_paddr &
				 HAL_ADDR_LSB_REG_MASK;

	cmd->ring_base_addr_hi = (u64)params.ring_base_paddr >>
				 HAL_ADDR_MSB_REG_SHIFT;

	ret = ath11k_hal_srng_get_entrysize(ab, ring_type);
	if (ret < 0)
		goto err_free;

	ring_entry_sz = ret;

	ring_entry_sz >>= 2;
	cmd->info1 = FIELD_PREP(HTT_SRNG_SETUP_CMD_INFO1_RING_ENTRY_SIZE,
				ring_entry_sz);
	cmd->info1 |= FIELD_PREP(HTT_SRNG_SETUP_CMD_INFO1_RING_SIZE,
				 params.num_entries * ring_entry_sz);
	cmd->info1 |= FIELD_PREP(HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_MSI_SWAP,
				 !!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP));
	cmd->info1 |= FIELD_PREP(
			HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_TLV_SWAP,
			!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP));
	cmd->info1 |= FIELD_PREP(
			HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_HOST_FW_SWAP,
			!!(params.flags & HAL_SRNG_FLAGS_RING_PTR_SWAP));
	if (htt_ring_type == HTT_SW_TO_HW_RING)
		cmd->info1 |= HTT_SRNG_SETUP_CMD_INFO1_RING_LOOP_CNT_DIS;

	cmd->ring_head_off32_remote_addr_lo = hp_addr & HAL_ADDR_LSB_REG_MASK;
	cmd->ring_head_off32_remote_addr_hi = (u64)hp_addr >>
					      HAL_ADDR_MSB_REG_SHIFT;

	cmd->ring_tail_off32_remote_addr_lo = tp_addr & HAL_ADDR_LSB_REG_MASK;
	cmd->ring_tail_off32_remote_addr_hi = (u64)tp_addr >>
					      HAL_ADDR_MSB_REG_SHIFT;

	cmd->ring_msi_addr_lo = lower_32_bits(params.msi_addr);
	cmd->ring_msi_addr_hi = upper_32_bits(params.msi_addr);
	cmd->msi_data = params.msi_data;

	cmd->intr_info = FIELD_PREP(
			HTT_SRNG_SETUP_CMD_INTR_INFO_BATCH_COUNTER_THRESH,
			params.intr_batch_cntr_thres_entries * ring_entry_sz);
	cmd->intr_info |= FIELD_PREP(
			HTT_SRNG_SETUP_CMD_INTR_INFO_INTR_TIMER_THRESH,
			params.intr_timer_thres_us >> 3);

	cmd->info2 = 0;
	if (params.flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) {
		cmd->info2 = FIELD_PREP(
				HTT_SRNG_SETUP_CMD_INFO2_INTR_LOW_THRESH,
				params.low_threshold);
	}

	ath11k_dbg(ab, ATH11k_DBG_HAL,
		   "%s msi_addr_lo:0x%x, msi_addr_hi:0x%x, msi_data:0x%x\n",
		   __func__, cmd->ring_msi_addr_lo, cmd->ring_msi_addr_hi,
		   cmd->msi_data);

	ath11k_dbg(ab, ATH11k_DBG_HAL,
		   "ring_id:%d, ring_type:%d, intr_info:0x%x, flags:0x%x\n",
		   ring_id, ring_type, cmd->intr_info, cmd->info2);

	ret = ath11k_htc_send(&ab->htc, ab->dp.eid, skb);
	if (ret)
		goto err_free;

	return 0;

err_free:
	dev_kfree_skb_any(skb);

	return ret;
}

#define HTT_TARGET_VERSION_TIMEOUT_HZ (3 * HZ)

int ath11k_dp_tx_htt_h2t_ver_req_msg(struct ath11k_base *ab)
{
	struct ath11k_dp *dp = &ab->dp;
	struct sk_buff *skb;
	struct htt_ver_req_cmd *cmd;
	int len = sizeof(*cmd);
	int ret;

	init_completion(&dp->htt_tgt_version_received);

	skb = ath11k_htc_alloc_skb(ab, len);
	if (!skb)
		return -ENOMEM;

	skb_put(skb, len);
	cmd = (struct htt_ver_req_cmd *)skb->data;
	cmd->ver_reg_info = FIELD_PREP(HTT_VER_REQ_INFO_MSG_ID,
				       HTT_H2T_MSG_TYPE_VERSION_REQ);

	ret = ath11k_htc_send(&ab->htc, dp->eid, skb);
	if (ret) {
		dev_kfree_skb_any(skb);
		return ret;
	}

	ret = wait_for_completion_timeout(&dp->htt_tgt_version_received,
					  HTT_TARGET_VERSION_TIMEOUT_HZ);
	if (ret == 0) {
		ath11k_warn(ab, "htt target version request timed out\n");
		return -ETIMEDOUT;
	}

	if (dp->htt_tgt_ver_major != HTT_TARGET_VERSION_MAJOR) {
		ath11k_err(ab, "unsupported htt major version %d supported version is %d\n",
			   dp->htt_tgt_ver_major, HTT_TARGET_VERSION_MAJOR);
		return -ENOTSUPP;
	}

	return 0;
}

int ath11k_dp_tx_htt_h2t_ppdu_stats_req(struct ath11k *ar, u32 mask)
{
	struct ath11k_base *ab = ar->ab;
	struct ath11k_dp *dp = &ab->dp;
	struct sk_buff *skb;
	struct htt_ppdu_stats_cfg_cmd *cmd;
	int len = sizeof(*cmd);
	u8 pdev_mask;
	int ret;
	int i;

	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
		skb = ath11k_htc_alloc_skb(ab, len);
		if (!skb)
			return -ENOMEM;

		skb_put(skb, len);
		cmd = (struct htt_ppdu_stats_cfg_cmd *)skb->data;
		cmd->msg = FIELD_PREP(HTT_PPDU_STATS_CFG_MSG_TYPE,
				      HTT_H2T_MSG_TYPE_PPDU_STATS_CFG);

		pdev_mask = 1 << (i + 1);
		cmd->msg |= FIELD_PREP(HTT_PPDU_STATS_CFG_PDEV_ID, pdev_mask);
		cmd->msg |= FIELD_PREP(HTT_PPDU_STATS_CFG_TLV_TYPE_BITMASK, mask);

		ret = ath11k_htc_send(&ab->htc, dp->eid, skb);
		if (ret) {
			dev_kfree_skb_any(skb);
			return ret;
		}
	}

	return 0;
}

int ath11k_dp_tx_htt_rx_full_mon_setup(struct ath11k_base *ab, int mac_id,
				       bool config)
{
	struct htt_rx_full_monitor_mode_cfg_cmd *cmd;
	struct sk_buff *skb;
	int ret, len = sizeof(*cmd);

	skb = ath11k_htc_alloc_skb(ab, len);
	if (!skb)
		return -ENOMEM;

	skb_put(skb, len);
	cmd = (struct htt_rx_full_monitor_mode_cfg_cmd*)skb->data;
	memset(cmd, 0, sizeof(*cmd));
	cmd->info0 = FIELD_PREP(HTT_RX_FULL_MON_MODE_CFG_CMD_INFO0_MSG_TYPE,
				HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE);

	cmd->info0 |= FIELD_PREP(HTT_RX_FULL_MON_MODE_CFG_CMD_INFO0_PDEV_ID,
				 DP_SW2HW_MACID(mac_id));

	cmd->cfg = HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_ENABLE |
		   FIELD_PREP(HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_RELEASE_RING,
			      HTT_RX_MON_RING_SW);
	if (config) {
		cmd->cfg |= HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_ZERO_MPDUS_END |
			    HTT_RX_FULL_MON_MODE_CFG_CMD_CFG_NON_ZERO_MPDUS_END;
	}

	ret = ath11k_htc_send(&ab->htc, ab->dp.eid, skb);
	if (ret)
		goto err_free;

	return 0;

err_free:
	dev_kfree_skb_any(skb);

	return ret;
}

int ath11k_dp_tx_htt_rx_filter_setup(struct ath11k_base *ab, u32 ring_id,
				     int mac_id, enum hal_ring_type ring_type,
				     int rx_buf_size,
				     struct htt_rx_ring_tlv_filter *tlv_filter)
{
	struct htt_rx_ring_selection_cfg_cmd *cmd;
	struct hal_srng *srng = &ab->hal.srng_list[ring_id];
	struct hal_srng_params params;
	struct sk_buff *skb;
	int len = sizeof(*cmd);
	enum htt_srng_ring_type htt_ring_type;
	enum htt_srng_ring_id htt_ring_id;
	int ret;

	skb = ath11k_htc_alloc_skb(ab, len);
	if (!skb)
		return -ENOMEM;

	memset(&params, 0, sizeof(params));
	ath11k_hal_srng_get_params(ab, srng, &params);

	ret = ath11k_dp_tx_get_ring_id_type(ab, mac_id, ring_id,
					    ring_type, &htt_ring_type,
					    &htt_ring_id);
	if (ret)
		goto err_free;

	skb_put(skb, len);
	cmd = (struct htt_rx_ring_selection_cfg_cmd *)skb->data;
	cmd->info0 = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE,
				HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG);
	if (htt_ring_type == HTT_SW_TO_HW_RING ||
	    htt_ring_type == HTT_HW_TO_SW_RING)
		cmd->info0 |=
			FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID,
				   DP_SW2HW_MACID(mac_id));
	else
		cmd->info0 |=
			FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID,
				   mac_id);
	cmd->info0 |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_INFO0_RING_ID,
				 htt_ring_id);
	cmd->info0 |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_INFO0_SS,
				 !!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP));
	cmd->info0 |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS,
				 !!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP));
	cmd->info0 |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_OFFSET_VALID,
				tlv_filter->offset_valid);

	cmd->info1 = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE,
				rx_buf_size);
	cmd->pkt_type_en_flags0 = tlv_filter->pkt_filter_flags0;
	cmd->pkt_type_en_flags1 = tlv_filter->pkt_filter_flags1;
	cmd->pkt_type_en_flags2 = tlv_filter->pkt_filter_flags2;
	cmd->pkt_type_en_flags3 = tlv_filter->pkt_filter_flags3;
	cmd->rx_filter_tlv = tlv_filter->rx_filter;

	if (tlv_filter->offset_valid) {
		cmd->rx_packet_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET,
						   tlv_filter->rx_packet_offset);
		cmd->rx_packet_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET,
						    tlv_filter->rx_header_offset);

		cmd->rx_mpdu_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET,
						 tlv_filter->rx_mpdu_end_offset);
		cmd->rx_mpdu_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET,
						  tlv_filter->rx_mpdu_start_offset);

		cmd->rx_msdu_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET,
						 tlv_filter->rx_msdu_end_offset);
		cmd->rx_msdu_offset |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET,
						  tlv_filter->rx_msdu_start_offset);

		cmd->rx_attn_offset = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET,
						 tlv_filter->rx_attn_offset);
	}

	ret = ath11k_htc_send(&ab->htc, ab->dp.eid, skb);
	if (ret)
		goto err_free;

	return 0;

err_free:
	dev_kfree_skb_any(skb);

	return ret;
}

int
ath11k_dp_tx_htt_h2t_ext_stats_req(struct ath11k *ar, u8 type,
				   struct htt_ext_stats_cfg_params *cfg_params,
				   u64 cookie)
{
	struct ath11k_base *ab = ar->ab;
	struct ath11k_dp *dp = &ab->dp;
	struct sk_buff *skb;
	struct htt_ext_stats_cfg_cmd *cmd;
	int len = sizeof(*cmd);
	int ret;

	skb = ath11k_htc_alloc_skb(ab, len);
	if (!skb)
		return -ENOMEM;

	skb_put(skb, len);

	cmd = (struct htt_ext_stats_cfg_cmd *)skb->data;
	memset(cmd, 0, sizeof(*cmd));
	cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_EXT_STATS_CFG;

	cmd->hdr.pdev_mask = 1 << ar->pdev->pdev_id;

	cmd->hdr.stats_type = type;
	cmd->cfg_param0 = cfg_params->cfg0;
	cmd->cfg_param1 = cfg_params->cfg1;
	cmd->cfg_param2 = cfg_params->cfg2;
	cmd->cfg_param3 = cfg_params->cfg3;
	cmd->cookie_lsb = lower_32_bits(cookie);
	cmd->cookie_msb = upper_32_bits(cookie);

	ret = ath11k_htc_send(&ab->htc, dp->eid, skb);
	if (ret) {
		ath11k_warn(ab, "failed to send htt type stats request: %d",
			    ret);
		dev_kfree_skb_any(skb);
		return ret;
	}

	return 0;
}

int ath11k_dp_tx_htt_monitor_mode_ring_config(struct ath11k *ar, bool reset)
{
	struct ath11k_pdev_dp *dp = &ar->dp;
	struct ath11k_base *ab = ar->ab;
	struct htt_rx_ring_tlv_filter tlv_filter = {0};
	int ret = 0, ring_id = 0, i;

	if (ab->hw_params.full_monitor_mode) {
		ret = ath11k_dp_tx_htt_rx_full_mon_setup(ab,
							 dp->mac_id, !reset);
		if (ret < 0) {
			ath11k_err(ab, "failed to setup full monitor %d\n", ret);
			return ret;
		}
	}

	ring_id = dp->rxdma_mon_buf_ring.refill_buf_ring.ring_id;
	tlv_filter.offset_valid = false;

	if (!reset) {
		tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_BUF_RING;
		tlv_filter.pkt_filter_flags0 =
					HTT_RX_MON_FP_MGMT_FILTER_FLAGS0 |
					HTT_RX_MON_MO_MGMT_FILTER_FLAGS0;
		tlv_filter.pkt_filter_flags1 =
					HTT_RX_MON_FP_MGMT_FILTER_FLAGS1 |
					HTT_RX_MON_MO_MGMT_FILTER_FLAGS1;
		tlv_filter.pkt_filter_flags2 =
					HTT_RX_MON_FP_CTRL_FILTER_FLASG2 |
					HTT_RX_MON_MO_CTRL_FILTER_FLASG2;
		tlv_filter.pkt_filter_flags3 =
					HTT_RX_MON_FP_CTRL_FILTER_FLASG3 |
					HTT_RX_MON_MO_CTRL_FILTER_FLASG3 |
					HTT_RX_MON_FP_DATA_FILTER_FLASG3 |
					HTT_RX_MON_MO_DATA_FILTER_FLASG3;
	}

	if (ab->hw_params.rxdma1_enable) {
		ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, dp->mac_id,
						       HAL_RXDMA_MONITOR_BUF,
						       DP_RXDMA_REFILL_RING_SIZE,
						       &tlv_filter);
	} else if (!reset) {
		/* set in monitor mode only */
		for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
			ring_id = dp->rx_mac_buf_ring[i].ring_id;
			ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id,
							       dp->mac_id + i,
							       HAL_RXDMA_BUF,
							       1024,
							       &tlv_filter);
		}
	}

	if (ret)
		return ret;

	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
		ring_id = dp->rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
		if (!reset)
			tlv_filter.rx_filter =
					HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING;
		else {
			tlv_filter = ath11k_mac_mon_status_filter_default;

			if (ath11k_debugfs_is_extd_rx_stats_enabled(ar))
				tlv_filter.rx_filter = ar->debug.rx_filter;
		}

		ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id,
						       dp->mac_id + i,
						       HAL_RXDMA_MONITOR_STATUS,
						       DP_RXDMA_REFILL_RING_SIZE,
						       &tlv_filter);
	}

	if (!ar->ab->hw_params.rxdma1_enable)
		mod_timer(&ar->ab->mon_reap_timer, jiffies +
			  msecs_to_jiffies(ATH11K_MON_TIMER_INTERVAL));

	return ret;
}
