Path: blob/main/sys/contrib/dev/athk/ath12k/dp_tx.c
48375 views
// SPDX-License-Identifier: BSD-3-Clause-Clear1/*2* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.3* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.4*/56#include "core.h"7#include "dp_tx.h"8#include "debug.h"9#include "hw.h"1011static enum hal_tcl_encap_type12ath12k_dp_tx_get_encap_type(struct ath12k_vif *arvif, struct sk_buff *skb)13{14struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);15struct ath12k_base *ab = arvif->ar->ab;1617if (test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags))18return HAL_TCL_ENCAP_TYPE_RAW;1920if (tx_info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)21return HAL_TCL_ENCAP_TYPE_ETHERNET;2223return HAL_TCL_ENCAP_TYPE_NATIVE_WIFI;24}2526static void ath12k_dp_tx_encap_nwifi(struct sk_buff *skb)27{28struct ieee80211_hdr *hdr = (void *)skb->data;29u8 *qos_ctl;3031if (!ieee80211_is_data_qos(hdr->frame_control))32return;3334qos_ctl = ieee80211_get_qos_ctl(hdr);35memmove(skb->data + IEEE80211_QOS_CTL_LEN,36#if defined(__linux__)37skb->data, (void *)qos_ctl - (void *)skb->data);38#elif defined(__FreeBSD__)39skb->data, qos_ctl - skb->data);40#endif41skb_pull(skb, IEEE80211_QOS_CTL_LEN);4243hdr = (void *)skb->data;44hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);45}4647static u8 ath12k_dp_tx_get_tid(struct sk_buff *skb)48{49struct ieee80211_hdr *hdr = (void *)skb->data;50struct ath12k_skb_cb *cb = ATH12K_SKB_CB(skb);5152if (cb->flags & ATH12K_SKB_HW_80211_ENCAP)53return skb->priority & IEEE80211_QOS_CTL_TID_MASK;54else if (!ieee80211_is_data_qos(hdr->frame_control))55return HAL_DESC_REO_NON_QOS_TID;56else57return skb->priority & IEEE80211_QOS_CTL_TID_MASK;58}5960enum hal_encrypt_type ath12k_dp_tx_get_encrypt_type(u32 cipher)61{62switch (cipher) {63case WLAN_CIPHER_SUITE_WEP40:64return HAL_ENCRYPT_TYPE_WEP_40;65case WLAN_CIPHER_SUITE_WEP104:66return HAL_ENCRYPT_TYPE_WEP_104;67case WLAN_CIPHER_SUITE_TKIP:68return HAL_ENCRYPT_TYPE_TKIP_MIC;69case WLAN_CIPHER_SUITE_CCMP:70return HAL_ENCRYPT_TYPE_CCMP_128;71case WLAN_CIPHER_SUITE_CCMP_256:72return HAL_ENCRYPT_TYPE_CCMP_256;73case WLAN_CIPHER_SUITE_GCMP:74return HAL_ENCRYPT_TYPE_GCMP_128;75case WLAN_CIPHER_SUITE_GCMP_256:76return HAL_ENCRYPT_TYPE_AES_GCMP_256;77default:78return HAL_ENCRYPT_TYPE_OPEN;79}80}8182static void ath12k_dp_tx_release_txbuf(struct ath12k_dp *dp,83struct ath12k_tx_desc_info *tx_desc,84u8 pool_id)85{86spin_lock_bh(&dp->tx_desc_lock[pool_id]);87list_move_tail(&tx_desc->list, &dp->tx_desc_free_list[pool_id]);88spin_unlock_bh(&dp->tx_desc_lock[pool_id]);89}9091static struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *dp,92u8 pool_id)93{94struct ath12k_tx_desc_info *desc;9596spin_lock_bh(&dp->tx_desc_lock[pool_id]);97desc = list_first_entry_or_null(&dp->tx_desc_free_list[pool_id],98struct ath12k_tx_desc_info,99list);100if (!desc) {101spin_unlock_bh(&dp->tx_desc_lock[pool_id]);102ath12k_warn(dp->ab, "failed to allocate data Tx buffer\n");103return NULL;104}105106list_move_tail(&desc->list, &dp->tx_desc_used_list[pool_id]);107spin_unlock_bh(&dp->tx_desc_lock[pool_id]);108109return desc;110}111112static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, void *cmd,113struct hal_tx_info *ti)114{115struct hal_tx_msdu_ext_desc *tcl_ext_cmd = (struct hal_tx_msdu_ext_desc *)cmd;116117tcl_ext_cmd->info0 = le32_encode_bits(ti->paddr,118HAL_TX_MSDU_EXT_INFO0_BUF_PTR_LO);119tcl_ext_cmd->info1 = le32_encode_bits(0x0,120HAL_TX_MSDU_EXT_INFO1_BUF_PTR_HI) |121le32_encode_bits(ti->data_len,122HAL_TX_MSDU_EXT_INFO1_BUF_LEN);123124tcl_ext_cmd->info1 = le32_encode_bits(1, HAL_TX_MSDU_EXT_INFO1_EXTN_OVERRIDE) |125le32_encode_bits(ti->encap_type,126HAL_TX_MSDU_EXT_INFO1_ENCAP_TYPE) |127le32_encode_bits(ti->encrypt_type,128HAL_TX_MSDU_EXT_INFO1_ENCRYPT_TYPE);129}130131int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,132struct sk_buff *skb)133{134struct ath12k_base *ab = ar->ab;135struct ath12k_dp *dp = &ab->dp;136struct hal_tx_info ti = {0};137struct ath12k_tx_desc_info *tx_desc;138struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);139struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb);140struct hal_tcl_data_cmd *hal_tcl_desc;141struct hal_tx_msdu_ext_desc *msg;142struct sk_buff *skb_ext_desc;143struct hal_srng *tcl_ring;144struct ieee80211_hdr *hdr = (void *)skb->data;145struct dp_tx_ring *tx_ring;146u8 pool_id;147u8 hal_ring_id;148int ret;149u8 ring_selector, ring_map = 0;150bool tcl_ring_retry;151bool msdu_ext_desc = false;152153if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))154return -ESHUTDOWN;155156if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&157!ieee80211_is_data(hdr->frame_control))158return -ENOTSUPP;159160pool_id = skb_get_queue_mapping(skb) & (ATH12K_HW_MAX_QUEUES - 1);161162/* Let the default ring selection be based on current processor163* number, where one of the 3 tcl rings are selected based on164* the smp_processor_id(). In case that ring165* is full/busy, we resort to other available rings.166* If all rings are full, we drop the packet.167* TODO: Add throttling logic when all rings are full168*/169ring_selector = ab->hw_params->hw_ops->get_ring_selector(skb);170171tcl_ring_sel:172tcl_ring_retry = false;173ti.ring_id = ring_selector % ab->hw_params->max_tx_ring;174175ring_map |= BIT(ti.ring_id);176ti.rbm_id = ab->hw_params->hal_ops->tcl_to_wbm_rbm_map[ti.ring_id].rbm_id;177178tx_ring = &dp->tx_ring[ti.ring_id];179180tx_desc = ath12k_dp_tx_assign_buffer(dp, pool_id);181if (!tx_desc)182return -ENOMEM;183184ti.bank_id = arvif->bank_id;185ti.meta_data_flags = arvif->tcl_metadata;186187if (arvif->tx_encap_type == HAL_TCL_ENCAP_TYPE_RAW &&188test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) {189if (skb_cb->flags & ATH12K_SKB_CIPHER_SET) {190ti.encrypt_type =191ath12k_dp_tx_get_encrypt_type(skb_cb->cipher);192193if (ieee80211_has_protected(hdr->frame_control))194skb_put(skb, IEEE80211_CCMP_MIC_LEN);195} else {196ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN;197}198199msdu_ext_desc = true;200}201202ti.encap_type = ath12k_dp_tx_get_encap_type(arvif, skb);203ti.addr_search_flags = arvif->hal_addr_search_flags;204ti.search_type = arvif->search_type;205ti.type = HAL_TCL_DESC_TYPE_BUFFER;206ti.pkt_offset = 0;207ti.lmac_id = ar->lmac_id;208ti.vdev_id = arvif->vdev_id;209ti.bss_ast_hash = arvif->ast_hash;210ti.bss_ast_idx = arvif->ast_idx;211ti.dscp_tid_tbl_idx = 0;212213if (skb->ip_summed == CHECKSUM_PARTIAL &&214ti.encap_type != HAL_TCL_ENCAP_TYPE_RAW) {215ti.flags0 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_IP4_CKSUM_EN) |216u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_UDP4_CKSUM_EN) |217u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_UDP6_CKSUM_EN) |218u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TCP4_CKSUM_EN) |219u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO2_TCP6_CKSUM_EN);220}221222ti.flags1 |= u32_encode_bits(1, HAL_TCL_DATA_CMD_INFO3_TID_OVERWRITE);223224ti.tid = ath12k_dp_tx_get_tid(skb);225226switch (ti.encap_type) {227case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI:228ath12k_dp_tx_encap_nwifi(skb);229break;230case HAL_TCL_ENCAP_TYPE_RAW:231if (!test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) {232ret = -EINVAL;233goto fail_remove_tx_buf;234}235break;236case HAL_TCL_ENCAP_TYPE_ETHERNET:237/* no need to encap */238break;239case HAL_TCL_ENCAP_TYPE_802_3:240default:241/* TODO: Take care of other encap modes as well */242ret = -EINVAL;243atomic_inc(&ab->soc_stats.tx_err.misc_fail);244goto fail_remove_tx_buf;245}246247ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE);248if (dma_mapping_error(ab->dev, ti.paddr)) {249atomic_inc(&ab->soc_stats.tx_err.misc_fail);250ath12k_warn(ab, "failed to DMA map data Tx buffer\n");251ret = -ENOMEM;252goto fail_remove_tx_buf;253}254255tx_desc->skb = skb;256tx_desc->mac_id = ar->pdev_idx;257ti.desc_id = tx_desc->desc_id;258ti.data_len = skb->len;259skb_cb->paddr = ti.paddr;260skb_cb->vif = arvif->vif;261skb_cb->ar = ar;262263if (msdu_ext_desc) {264skb_ext_desc = dev_alloc_skb(sizeof(struct hal_tx_msdu_ext_desc));265if (!skb_ext_desc) {266ret = -ENOMEM;267goto fail_unmap_dma;268}269270skb_put(skb_ext_desc, sizeof(struct hal_tx_msdu_ext_desc));271memset(skb_ext_desc->data, 0, skb_ext_desc->len);272273msg = (struct hal_tx_msdu_ext_desc *)skb_ext_desc->data;274ath12k_hal_tx_cmd_ext_desc_setup(ab, msg, &ti);275276ti.paddr = dma_map_single(ab->dev, skb_ext_desc->data,277skb_ext_desc->len, DMA_TO_DEVICE);278ret = dma_mapping_error(ab->dev, ti.paddr);279if (ret) {280kfree_skb(skb_ext_desc);281goto fail_unmap_dma;282}283284ti.data_len = skb_ext_desc->len;285ti.type = HAL_TCL_DESC_TYPE_EXT_DESC;286287skb_cb->paddr_ext_desc = ti.paddr;288}289290hal_ring_id = tx_ring->tcl_data_ring.ring_id;291tcl_ring = &ab->hal.srng_list[hal_ring_id];292293spin_lock_bh(&tcl_ring->lock);294295ath12k_hal_srng_access_begin(ab, tcl_ring);296297hal_tcl_desc = ath12k_hal_srng_src_get_next_entry(ab, tcl_ring);298if (!hal_tcl_desc) {299/* NOTE: It is highly unlikely we'll be running out of tcl_ring300* desc because the desc is directly enqueued onto hw queue.301*/302ath12k_hal_srng_access_end(ab, tcl_ring);303ab->soc_stats.tx_err.desc_na[ti.ring_id]++;304spin_unlock_bh(&tcl_ring->lock);305ret = -ENOMEM;306307/* Checking for available tcl descritors in another ring in308* case of failure due to full tcl ring now, is better than309* checking this ring earlier for each pkt tx.310* Restart ring selection if some rings are not checked yet.311*/312if (ring_map != (BIT(ab->hw_params->max_tx_ring) - 1) &&313ab->hw_params->tcl_ring_retry) {314tcl_ring_retry = true;315ring_selector++;316}317318goto fail_unmap_dma;319}320321ath12k_hal_tx_cmd_desc_setup(ab, hal_tcl_desc, &ti);322323ath12k_hal_srng_access_end(ab, tcl_ring);324325spin_unlock_bh(&tcl_ring->lock);326327ath12k_dbg_dump(ab, ATH12K_DBG_DP_TX, NULL, "dp tx msdu: ",328skb->data, skb->len);329330atomic_inc(&ar->dp.num_tx_pending);331332return 0;333334fail_unmap_dma:335dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE);336dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc,337sizeof(struct hal_tx_msdu_ext_desc), DMA_TO_DEVICE);338339fail_remove_tx_buf:340ath12k_dp_tx_release_txbuf(dp, tx_desc, pool_id);341if (tcl_ring_retry)342goto tcl_ring_sel;343344return ret;345}346347static void ath12k_dp_tx_free_txbuf(struct ath12k_base *ab,348struct sk_buff *msdu, u8 mac_id,349struct dp_tx_ring *tx_ring)350{351struct ath12k *ar;352struct ath12k_skb_cb *skb_cb;353u8 pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id);354355skb_cb = ATH12K_SKB_CB(msdu);356357dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);358if (skb_cb->paddr_ext_desc)359dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc,360sizeof(struct hal_tx_msdu_ext_desc), DMA_TO_DEVICE);361362dev_kfree_skb_any(msdu);363364ar = ab->pdevs[pdev_id].ar;365if (atomic_dec_and_test(&ar->dp.num_tx_pending))366wake_up(&ar->dp.tx_empty_waitq);367}368369static void370ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab,371struct sk_buff *msdu,372struct dp_tx_ring *tx_ring,373struct ath12k_dp_htt_wbm_tx_status *ts)374{375struct ieee80211_tx_info *info;376struct ath12k_skb_cb *skb_cb;377struct ath12k *ar;378379skb_cb = ATH12K_SKB_CB(msdu);380info = IEEE80211_SKB_CB(msdu);381382ar = skb_cb->ar;383384if (atomic_dec_and_test(&ar->dp.num_tx_pending))385wake_up(&ar->dp.tx_empty_waitq);386387dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);388if (skb_cb->paddr_ext_desc)389dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc,390sizeof(struct hal_tx_msdu_ext_desc), DMA_TO_DEVICE);391392memset(&info->status, 0, sizeof(info->status));393394if (ts->acked) {395if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {396info->flags |= IEEE80211_TX_STAT_ACK;397info->status.ack_signal = ATH12K_DEFAULT_NOISE_FLOOR +398ts->ack_rssi;399info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID;400} else {401info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;402}403}404405ieee80211_tx_status(ar->hw, msdu);406}407408static void409ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab,410void *desc, u8 mac_id,411struct sk_buff *msdu,412struct dp_tx_ring *tx_ring)413{414struct htt_tx_wbm_completion *status_desc;415struct ath12k_dp_htt_wbm_tx_status ts = {0};416enum hal_wbm_htt_tx_comp_status wbm_status;417418#if defined(__linux__)419status_desc = desc + HTT_TX_WBM_COMP_STATUS_OFFSET;420#elif defined(__FreeBSD__)421status_desc = (void *)((u8 *)desc + HTT_TX_WBM_COMP_STATUS_OFFSET);422#endif423424wbm_status = le32_get_bits(status_desc->info0,425HTT_TX_WBM_COMP_INFO0_STATUS);426427switch (wbm_status) {428case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK:429case HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP:430case HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL:431ts.acked = (wbm_status == HAL_WBM_REL_HTT_TX_COMP_STATUS_OK);432ts.ack_rssi = le32_get_bits(status_desc->info2,433HTT_TX_WBM_COMP_INFO2_ACK_RSSI);434ath12k_dp_tx_htt_tx_complete_buf(ab, msdu, tx_ring, &ts);435break;436case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ:437case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT:438ath12k_dp_tx_free_txbuf(ab, msdu, mac_id, tx_ring);439break;440case HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY:441/* This event is to be handled only when the driver decides to442* use WDS offload functionality.443*/444break;445default:446ath12k_warn(ab, "Unknown htt tx status %d\n", wbm_status);447break;448}449}450451static void ath12k_dp_tx_complete_msdu(struct ath12k *ar,452struct sk_buff *msdu,453struct hal_tx_status *ts)454{455struct ath12k_base *ab = ar->ab;456struct ieee80211_tx_info *info;457struct ath12k_skb_cb *skb_cb;458459if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) {460/* Must not happen */461return;462}463464skb_cb = ATH12K_SKB_CB(msdu);465466dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);467if (skb_cb->paddr_ext_desc)468dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc,469sizeof(struct hal_tx_msdu_ext_desc), DMA_TO_DEVICE);470471rcu_read_lock();472473if (!rcu_dereference(ab->pdevs_active[ar->pdev_idx])) {474dev_kfree_skb_any(msdu);475goto exit;476}477478if (!skb_cb->vif) {479dev_kfree_skb_any(msdu);480goto exit;481}482483info = IEEE80211_SKB_CB(msdu);484memset(&info->status, 0, sizeof(info->status));485486/* skip tx rate update from ieee80211_status*/487info->status.rates[0].idx = -1;488489if (ts->status == HAL_WBM_TQM_REL_REASON_FRAME_ACKED &&490!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {491info->flags |= IEEE80211_TX_STAT_ACK;492info->status.ack_signal = ATH12K_DEFAULT_NOISE_FLOOR +493ts->ack_rssi;494info->status.flags = IEEE80211_TX_STATUS_ACK_SIGNAL_VALID;495}496497if (ts->status == HAL_WBM_TQM_REL_REASON_CMD_REMOVE_TX &&498(info->flags & IEEE80211_TX_CTL_NO_ACK))499info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;500501/* NOTE: Tx rate status reporting. Tx completion status does not have502* necessary information (for example nss) to build the tx rate.503* Might end up reporting it out-of-band from HTT stats.504*/505506ieee80211_tx_status(ar->hw, msdu);507508exit:509rcu_read_unlock();510}511512static void ath12k_dp_tx_status_parse(struct ath12k_base *ab,513struct hal_wbm_completion_ring_tx *desc,514struct hal_tx_status *ts)515{516ts->buf_rel_source =517le32_get_bits(desc->info0, HAL_WBM_COMPL_TX_INFO0_REL_SRC_MODULE);518if (ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_FW &&519ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)520return;521522if (ts->buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW)523return;524525ts->status = le32_get_bits(desc->info0,526HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON);527528ts->ppdu_id = le32_get_bits(desc->info1,529HAL_WBM_COMPL_TX_INFO1_TQM_STATUS_NUMBER);530if (le32_to_cpu(desc->rate_stats.info0) & HAL_TX_RATE_STATS_INFO0_VALID)531ts->rate_stats = le32_to_cpu(desc->rate_stats.info0);532else533ts->rate_stats = 0;534}535536void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id)537{538struct ath12k *ar;539struct ath12k_dp *dp = &ab->dp;540int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id;541struct hal_srng *status_ring = &ab->hal.srng_list[hal_ring_id];542struct ath12k_tx_desc_info *tx_desc = NULL;543struct sk_buff *msdu;544struct hal_tx_status ts = { 0 };545struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id];546struct hal_wbm_release_ring *desc;547u8 mac_id, pdev_id;548u64 desc_va;549550spin_lock_bh(&status_ring->lock);551552ath12k_hal_srng_access_begin(ab, status_ring);553554while (ATH12K_TX_COMPL_NEXT(tx_ring->tx_status_head) != tx_ring->tx_status_tail) {555desc = ath12k_hal_srng_dst_get_next_entry(ab, status_ring);556if (!desc)557break;558559memcpy(&tx_ring->tx_status[tx_ring->tx_status_head],560desc, sizeof(*desc));561tx_ring->tx_status_head =562ATH12K_TX_COMPL_NEXT(tx_ring->tx_status_head);563}564565if (ath12k_hal_srng_dst_peek(ab, status_ring) &&566(ATH12K_TX_COMPL_NEXT(tx_ring->tx_status_head) == tx_ring->tx_status_tail)) {567/* TODO: Process pending tx_status messages when kfifo_is_full() */568ath12k_warn(ab, "Unable to process some of the tx_status ring desc because status_fifo is full\n");569}570571ath12k_hal_srng_access_end(ab, status_ring);572573spin_unlock_bh(&status_ring->lock);574575while (ATH12K_TX_COMPL_NEXT(tx_ring->tx_status_tail) != tx_ring->tx_status_head) {576struct hal_wbm_completion_ring_tx *tx_status;577u32 desc_id;578579tx_ring->tx_status_tail =580ATH12K_TX_COMPL_NEXT(tx_ring->tx_status_tail);581tx_status = &tx_ring->tx_status[tx_ring->tx_status_tail];582ath12k_dp_tx_status_parse(ab, tx_status, &ts);583584if (le32_get_bits(tx_status->info0, HAL_WBM_COMPL_TX_INFO0_CC_DONE)) {585/* HW done cookie conversion */586desc_va = ((u64)le32_to_cpu(tx_status->buf_va_hi) << 32 |587le32_to_cpu(tx_status->buf_va_lo));588tx_desc = (struct ath12k_tx_desc_info *)((unsigned long)desc_va);589} else {590/* SW does cookie conversion to VA */591desc_id = le32_get_bits(tx_status->buf_va_hi,592BUFFER_ADDR_INFO1_SW_COOKIE);593594tx_desc = ath12k_dp_get_tx_desc(ab, desc_id);595}596if (!tx_desc) {597ath12k_warn(ab, "unable to retrieve tx_desc!");598continue;599}600601msdu = tx_desc->skb;602mac_id = tx_desc->mac_id;603604/* Release descriptor as soon as extracting necessary info605* to reduce contention606*/607ath12k_dp_tx_release_txbuf(dp, tx_desc, tx_desc->pool_id);608if (ts.buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW) {609ath12k_dp_tx_process_htt_tx_complete(ab,610(void *)tx_status,611mac_id, msdu,612tx_ring);613continue;614}615616pdev_id = ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id);617ar = ab->pdevs[pdev_id].ar;618619if (atomic_dec_and_test(&ar->dp.num_tx_pending))620wake_up(&ar->dp.tx_empty_waitq);621622ath12k_dp_tx_complete_msdu(ar, msdu, &ts);623}624}625626static int627ath12k_dp_tx_get_ring_id_type(struct ath12k_base *ab,628int mac_id, u32 ring_id,629enum hal_ring_type ring_type,630enum htt_srng_ring_type *htt_ring_type,631enum htt_srng_ring_id *htt_ring_id)632{633int ret = 0;634635switch (ring_type) {636case HAL_RXDMA_BUF:637/* for some targets, host fills rx buffer to fw and fw fills to638* rxbuf ring for each rxdma639*/640if (!ab->hw_params->rx_mac_buf_ring) {641if (!(ring_id == HAL_SRNG_SW2RXDMA_BUF0 ||642ring_id == HAL_SRNG_SW2RXDMA_BUF1)) {643ret = -EINVAL;644}645*htt_ring_id = HTT_RXDMA_HOST_BUF_RING;646*htt_ring_type = HTT_SW_TO_HW_RING;647} else {648if (ring_id == HAL_SRNG_SW2RXDMA_BUF0) {649*htt_ring_id = HTT_HOST1_TO_FW_RXBUF_RING;650*htt_ring_type = HTT_SW_TO_SW_RING;651} else {652*htt_ring_id = HTT_RXDMA_HOST_BUF_RING;653*htt_ring_type = HTT_SW_TO_HW_RING;654}655}656break;657case HAL_RXDMA_DST:658*htt_ring_id = HTT_RXDMA_NON_MONITOR_DEST_RING;659*htt_ring_type = HTT_HW_TO_SW_RING;660break;661case HAL_RXDMA_MONITOR_BUF:662*htt_ring_id = HTT_RXDMA_MONITOR_BUF_RING;663*htt_ring_type = HTT_SW_TO_HW_RING;664break;665case HAL_RXDMA_MONITOR_STATUS:666*htt_ring_id = HTT_RXDMA_MONITOR_STATUS_RING;667*htt_ring_type = HTT_SW_TO_HW_RING;668break;669case HAL_RXDMA_MONITOR_DST:670*htt_ring_id = HTT_RXDMA_MONITOR_DEST_RING;671*htt_ring_type = HTT_HW_TO_SW_RING;672break;673case HAL_RXDMA_MONITOR_DESC:674*htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING;675*htt_ring_type = HTT_SW_TO_HW_RING;676break;677case HAL_TX_MONITOR_BUF:678*htt_ring_id = HTT_TX_MON_HOST2MON_BUF_RING;679*htt_ring_type = HTT_SW_TO_HW_RING;680break;681case HAL_TX_MONITOR_DST:682*htt_ring_id = HTT_TX_MON_MON2HOST_DEST_RING;683*htt_ring_type = HTT_HW_TO_SW_RING;684break;685default:686ath12k_warn(ab, "Unsupported ring type in DP :%d\n", ring_type);687ret = -EINVAL;688}689return ret;690}691692int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id,693int mac_id, enum hal_ring_type ring_type)694{695struct htt_srng_setup_cmd *cmd;696struct hal_srng *srng = &ab->hal.srng_list[ring_id];697struct hal_srng_params params;698struct sk_buff *skb;699u32 ring_entry_sz;700int len = sizeof(*cmd);701dma_addr_t hp_addr, tp_addr;702enum htt_srng_ring_type htt_ring_type;703enum htt_srng_ring_id htt_ring_id;704int ret;705706skb = ath12k_htc_alloc_skb(ab, len);707if (!skb)708return -ENOMEM;709710memset(¶ms, 0, sizeof(params));711ath12k_hal_srng_get_params(ab, srng, ¶ms);712713hp_addr = ath12k_hal_srng_get_hp_addr(ab, srng);714tp_addr = ath12k_hal_srng_get_tp_addr(ab, srng);715716ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id,717ring_type, &htt_ring_type,718&htt_ring_id);719if (ret)720goto err_free;721722skb_put(skb, len);723cmd = (struct htt_srng_setup_cmd *)skb->data;724cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_SRING_SETUP,725HTT_SRNG_SETUP_CMD_INFO0_MSG_TYPE);726if (htt_ring_type == HTT_SW_TO_HW_RING ||727htt_ring_type == HTT_HW_TO_SW_RING)728cmd->info0 |= le32_encode_bits(DP_SW2HW_MACID(mac_id),729HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID);730else731cmd->info0 |= le32_encode_bits(mac_id,732HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID);733cmd->info0 |= le32_encode_bits(htt_ring_type,734HTT_SRNG_SETUP_CMD_INFO0_RING_TYPE);735cmd->info0 |= le32_encode_bits(htt_ring_id,736HTT_SRNG_SETUP_CMD_INFO0_RING_ID);737738cmd->ring_base_addr_lo = cpu_to_le32(params.ring_base_paddr &739HAL_ADDR_LSB_REG_MASK);740741cmd->ring_base_addr_hi = cpu_to_le32((u64)params.ring_base_paddr >>742HAL_ADDR_MSB_REG_SHIFT);743744ret = ath12k_hal_srng_get_entrysize(ab, ring_type);745if (ret < 0)746goto err_free;747748ring_entry_sz = ret;749750ring_entry_sz >>= 2;751cmd->info1 = le32_encode_bits(ring_entry_sz,752HTT_SRNG_SETUP_CMD_INFO1_RING_ENTRY_SIZE);753cmd->info1 |= le32_encode_bits(params.num_entries * ring_entry_sz,754HTT_SRNG_SETUP_CMD_INFO1_RING_SIZE);755cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP),756HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_MSI_SWAP);757cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP),758HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_TLV_SWAP);759cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_RING_PTR_SWAP),760HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_HOST_FW_SWAP);761if (htt_ring_type == HTT_SW_TO_HW_RING)762cmd->info1 |= cpu_to_le32(HTT_SRNG_SETUP_CMD_INFO1_RING_LOOP_CNT_DIS);763764cmd->ring_head_off32_remote_addr_lo = cpu_to_le32(lower_32_bits(hp_addr));765cmd->ring_head_off32_remote_addr_hi = cpu_to_le32(upper_32_bits(hp_addr));766767cmd->ring_tail_off32_remote_addr_lo = cpu_to_le32(lower_32_bits(tp_addr));768cmd->ring_tail_off32_remote_addr_hi = cpu_to_le32(upper_32_bits(tp_addr));769770cmd->ring_msi_addr_lo = cpu_to_le32(lower_32_bits(params.msi_addr));771cmd->ring_msi_addr_hi = cpu_to_le32(upper_32_bits(params.msi_addr));772cmd->msi_data = cpu_to_le32(params.msi_data);773774cmd->intr_info =775le32_encode_bits(params.intr_batch_cntr_thres_entries * ring_entry_sz,776HTT_SRNG_SETUP_CMD_INTR_INFO_BATCH_COUNTER_THRESH);777cmd->intr_info |=778le32_encode_bits(params.intr_timer_thres_us >> 3,779HTT_SRNG_SETUP_CMD_INTR_INFO_INTR_TIMER_THRESH);780781cmd->info2 = 0;782if (params.flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) {783cmd->info2 = le32_encode_bits(params.low_threshold,784HTT_SRNG_SETUP_CMD_INFO2_INTR_LOW_THRESH);785}786787ath12k_dbg(ab, ATH12K_DBG_HAL,788"%s msi_addr_lo:0x%x, msi_addr_hi:0x%x, msi_data:0x%x\n",789__func__, cmd->ring_msi_addr_lo, cmd->ring_msi_addr_hi,790cmd->msi_data);791792ath12k_dbg(ab, ATH12K_DBG_HAL,793"ring_id:%d, ring_type:%d, intr_info:0x%x, flags:0x%x\n",794ring_id, ring_type, cmd->intr_info, cmd->info2);795796ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb);797if (ret)798goto err_free;799800return 0;801802err_free:803dev_kfree_skb_any(skb);804805return ret;806}807808#define HTT_TARGET_VERSION_TIMEOUT_HZ (3 * HZ)809810int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab)811{812struct ath12k_dp *dp = &ab->dp;813struct sk_buff *skb;814struct htt_ver_req_cmd *cmd;815int len = sizeof(*cmd);816int ret;817818init_completion(&dp->htt_tgt_version_received);819820skb = ath12k_htc_alloc_skb(ab, len);821if (!skb)822return -ENOMEM;823824skb_put(skb, len);825cmd = (struct htt_ver_req_cmd *)skb->data;826cmd->ver_reg_info = le32_encode_bits(HTT_H2T_MSG_TYPE_VERSION_REQ,827HTT_VER_REQ_INFO_MSG_ID);828829ret = ath12k_htc_send(&ab->htc, dp->eid, skb);830if (ret) {831dev_kfree_skb_any(skb);832return ret;833}834835ret = wait_for_completion_timeout(&dp->htt_tgt_version_received,836HTT_TARGET_VERSION_TIMEOUT_HZ);837if (ret == 0) {838ath12k_warn(ab, "htt target version request timed out\n");839return -ETIMEDOUT;840}841842if (dp->htt_tgt_ver_major != HTT_TARGET_VERSION_MAJOR) {843ath12k_err(ab, "unsupported htt major version %d supported version is %d\n",844dp->htt_tgt_ver_major, HTT_TARGET_VERSION_MAJOR);845return -ENOTSUPP;846}847848return 0;849}850851int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask)852{853struct ath12k_base *ab = ar->ab;854struct ath12k_dp *dp = &ab->dp;855struct sk_buff *skb;856struct htt_ppdu_stats_cfg_cmd *cmd;857int len = sizeof(*cmd);858u8 pdev_mask;859int ret;860int i;861862for (i = 0; i < ab->hw_params->num_rxmda_per_pdev; i++) {863skb = ath12k_htc_alloc_skb(ab, len);864if (!skb)865return -ENOMEM;866867skb_put(skb, len);868cmd = (struct htt_ppdu_stats_cfg_cmd *)skb->data;869cmd->msg = le32_encode_bits(HTT_H2T_MSG_TYPE_PPDU_STATS_CFG,870HTT_PPDU_STATS_CFG_MSG_TYPE);871872pdev_mask = 1 << (i + 1);873cmd->msg |= le32_encode_bits(pdev_mask, HTT_PPDU_STATS_CFG_PDEV_ID);874cmd->msg |= le32_encode_bits(mask, HTT_PPDU_STATS_CFG_TLV_TYPE_BITMASK);875876ret = ath12k_htc_send(&ab->htc, dp->eid, skb);877if (ret) {878dev_kfree_skb_any(skb);879return ret;880}881}882883return 0;884}885886int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id,887int mac_id, enum hal_ring_type ring_type,888int rx_buf_size,889struct htt_rx_ring_tlv_filter *tlv_filter)890{891struct htt_rx_ring_selection_cfg_cmd *cmd;892struct hal_srng *srng = &ab->hal.srng_list[ring_id];893struct hal_srng_params params;894struct sk_buff *skb;895int len = sizeof(*cmd);896enum htt_srng_ring_type htt_ring_type;897enum htt_srng_ring_id htt_ring_id;898int ret;899900skb = ath12k_htc_alloc_skb(ab, len);901if (!skb)902return -ENOMEM;903904memset(¶ms, 0, sizeof(params));905ath12k_hal_srng_get_params(ab, srng, ¶ms);906907ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id,908ring_type, &htt_ring_type,909&htt_ring_id);910if (ret)911goto err_free;912913skb_put(skb, len);914cmd = (struct htt_rx_ring_selection_cfg_cmd *)skb->data;915cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG,916HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE);917if (htt_ring_type == HTT_SW_TO_HW_RING ||918htt_ring_type == HTT_HW_TO_SW_RING)919cmd->info0 |=920le32_encode_bits(DP_SW2HW_MACID(mac_id),921HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID);922else923cmd->info0 |=924le32_encode_bits(mac_id,925HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID);926cmd->info0 |= le32_encode_bits(htt_ring_id,927HTT_RX_RING_SELECTION_CFG_CMD_INFO0_RING_ID);928cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP),929HTT_RX_RING_SELECTION_CFG_CMD_INFO0_SS);930cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP),931HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS);932cmd->info0 |= le32_encode_bits(tlv_filter->offset_valid,933HTT_RX_RING_SELECTION_CFG_CMD_OFFSET_VALID);934cmd->info1 = le32_encode_bits(rx_buf_size,935HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE);936cmd->pkt_type_en_flags0 = cpu_to_le32(tlv_filter->pkt_filter_flags0);937cmd->pkt_type_en_flags1 = cpu_to_le32(tlv_filter->pkt_filter_flags1);938cmd->pkt_type_en_flags2 = cpu_to_le32(tlv_filter->pkt_filter_flags2);939cmd->pkt_type_en_flags3 = cpu_to_le32(tlv_filter->pkt_filter_flags3);940cmd->rx_filter_tlv = cpu_to_le32(tlv_filter->rx_filter);941942if (tlv_filter->offset_valid) {943cmd->rx_packet_offset =944le32_encode_bits(tlv_filter->rx_packet_offset,945HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET);946947cmd->rx_packet_offset |=948le32_encode_bits(tlv_filter->rx_header_offset,949HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET);950951cmd->rx_mpdu_offset =952le32_encode_bits(tlv_filter->rx_mpdu_end_offset,953HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET);954955cmd->rx_mpdu_offset |=956le32_encode_bits(tlv_filter->rx_mpdu_start_offset,957HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET);958959cmd->rx_msdu_offset =960le32_encode_bits(tlv_filter->rx_msdu_end_offset,961HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET);962963cmd->rx_msdu_offset |=964le32_encode_bits(tlv_filter->rx_msdu_start_offset,965HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET);966967cmd->rx_attn_offset =968le32_encode_bits(tlv_filter->rx_attn_offset,969HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET);970}971972ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb);973if (ret)974goto err_free;975976return 0;977978err_free:979dev_kfree_skb_any(skb);980981return ret;982}983984int985ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type,986struct htt_ext_stats_cfg_params *cfg_params,987u64 cookie)988{989struct ath12k_base *ab = ar->ab;990struct ath12k_dp *dp = &ab->dp;991struct sk_buff *skb;992struct htt_ext_stats_cfg_cmd *cmd;993int len = sizeof(*cmd);994int ret;995996skb = ath12k_htc_alloc_skb(ab, len);997if (!skb)998return -ENOMEM;9991000skb_put(skb, len);10011002cmd = (struct htt_ext_stats_cfg_cmd *)skb->data;1003memset(cmd, 0, sizeof(*cmd));1004cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_EXT_STATS_CFG;10051006cmd->hdr.pdev_mask = 1 << ar->pdev->pdev_id;10071008cmd->hdr.stats_type = type;1009cmd->cfg_param0 = cpu_to_le32(cfg_params->cfg0);1010cmd->cfg_param1 = cpu_to_le32(cfg_params->cfg1);1011cmd->cfg_param2 = cpu_to_le32(cfg_params->cfg2);1012cmd->cfg_param3 = cpu_to_le32(cfg_params->cfg3);1013cmd->cookie_lsb = cpu_to_le32(lower_32_bits(cookie));1014cmd->cookie_msb = cpu_to_le32(upper_32_bits(cookie));10151016ret = ath12k_htc_send(&ab->htc, dp->eid, skb);1017if (ret) {1018ath12k_warn(ab, "failed to send htt type stats request: %d",1019ret);1020dev_kfree_skb_any(skb);1021return ret;1022}10231024return 0;1025}10261027int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset)1028{1029struct ath12k_base *ab = ar->ab;1030int ret;10311032ret = ath12k_dp_tx_htt_tx_monitor_mode_ring_config(ar, reset);1033if (ret) {1034ath12k_err(ab, "failed to setup tx monitor filter %d\n", ret);1035return ret;1036}10371038ret = ath12k_dp_tx_htt_tx_monitor_mode_ring_config(ar, reset);1039if (ret) {1040ath12k_err(ab, "failed to setup rx monitor filter %d\n", ret);1041return ret;1042}10431044return 0;1045}10461047int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset)1048{1049struct ath12k_base *ab = ar->ab;1050struct ath12k_dp *dp = &ab->dp;1051struct htt_rx_ring_tlv_filter tlv_filter = {0};1052int ret, ring_id;10531054ring_id = dp->rxdma_mon_buf_ring.refill_buf_ring.ring_id;1055tlv_filter.offset_valid = false;10561057if (!reset) {1058tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_BUF_RING;1059tlv_filter.pkt_filter_flags0 =1060HTT_RX_MON_FP_MGMT_FILTER_FLAGS0 |1061HTT_RX_MON_MO_MGMT_FILTER_FLAGS0;1062tlv_filter.pkt_filter_flags1 =1063HTT_RX_MON_FP_MGMT_FILTER_FLAGS1 |1064HTT_RX_MON_MO_MGMT_FILTER_FLAGS1;1065tlv_filter.pkt_filter_flags2 =1066HTT_RX_MON_FP_CTRL_FILTER_FLASG2 |1067HTT_RX_MON_MO_CTRL_FILTER_FLASG2;1068tlv_filter.pkt_filter_flags3 =1069HTT_RX_MON_FP_CTRL_FILTER_FLASG3 |1070HTT_RX_MON_MO_CTRL_FILTER_FLASG3 |1071HTT_RX_MON_FP_DATA_FILTER_FLASG3 |1072HTT_RX_MON_MO_DATA_FILTER_FLASG3;1073}10741075if (ab->hw_params->rxdma1_enable) {1076ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, 0,1077HAL_RXDMA_MONITOR_BUF,1078DP_RXDMA_REFILL_RING_SIZE,1079&tlv_filter);1080if (ret) {1081ath12k_err(ab,1082"failed to setup filter for monitor buf %d\n", ret);1083return ret;1084}1085}10861087return 0;1088}10891090int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id,1091int mac_id, enum hal_ring_type ring_type,1092int tx_buf_size,1093struct htt_tx_ring_tlv_filter *htt_tlv_filter)1094{1095struct htt_tx_ring_selection_cfg_cmd *cmd;1096struct hal_srng *srng = &ab->hal.srng_list[ring_id];1097struct hal_srng_params params;1098struct sk_buff *skb;1099int len = sizeof(*cmd);1100enum htt_srng_ring_type htt_ring_type;1101enum htt_srng_ring_id htt_ring_id;1102int ret;11031104skb = ath12k_htc_alloc_skb(ab, len);1105if (!skb)1106return -ENOMEM;11071108memset(¶ms, 0, sizeof(params));1109ath12k_hal_srng_get_params(ab, srng, ¶ms);11101111ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id,1112ring_type, &htt_ring_type,1113&htt_ring_id);11141115if (ret)1116goto err_free;11171118skb_put(skb, len);1119cmd = (struct htt_tx_ring_selection_cfg_cmd *)skb->data;1120cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_TX_MONITOR_CFG,1121HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE);1122if (htt_ring_type == HTT_SW_TO_HW_RING ||1123htt_ring_type == HTT_HW_TO_SW_RING)1124cmd->info0 |=1125le32_encode_bits(DP_SW2HW_MACID(mac_id),1126HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID);1127else1128cmd->info0 |=1129le32_encode_bits(mac_id,1130HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID);1131cmd->info0 |= le32_encode_bits(htt_ring_id,1132HTT_TX_RING_SELECTION_CFG_CMD_INFO0_RING_ID);1133cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP),1134HTT_TX_RING_SELECTION_CFG_CMD_INFO0_SS);1135cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP),1136HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PS);11371138cmd->info1 |=1139le32_encode_bits(tx_buf_size,1140HTT_TX_RING_SELECTION_CFG_CMD_INFO1_RING_BUFF_SIZE);11411142if (htt_tlv_filter->tx_mon_mgmt_filter) {1143cmd->info1 |=1144le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_MGMT,1145HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE);1146cmd->info1 |=1147le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len,1148HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT);1149cmd->info2 |=1150le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_MGMT,1151HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG);1152}11531154if (htt_tlv_filter->tx_mon_data_filter) {1155cmd->info1 |=1156le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_CTRL,1157HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE);1158cmd->info1 |=1159le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len,1160HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL);1161cmd->info2 |=1162le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_CTRL,1163HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG);1164}11651166if (htt_tlv_filter->tx_mon_ctrl_filter) {1167cmd->info1 |=1168le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_DATA,1169HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE);1170cmd->info1 |=1171le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len,1172HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA);1173cmd->info2 |=1174le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_DATA,1175HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG);1176}11771178cmd->tlv_filter_mask_in0 =1179cpu_to_le32(htt_tlv_filter->tx_mon_downstream_tlv_flags);1180cmd->tlv_filter_mask_in1 =1181cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags0);1182cmd->tlv_filter_mask_in2 =1183cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags1);1184cmd->tlv_filter_mask_in3 =1185cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags2);11861187ret = ath12k_htc_send(&ab->htc, ab->dp.eid, skb);1188if (ret)1189goto err_free;11901191return 0;11921193err_free:1194dev_kfree_skb_any(skb);1195return ret;1196}11971198int ath12k_dp_tx_htt_tx_monitor_mode_ring_config(struct ath12k *ar, bool reset)1199{1200struct ath12k_base *ab = ar->ab;1201struct ath12k_dp *dp = &ab->dp;1202struct htt_tx_ring_tlv_filter tlv_filter = {0};1203int ret, ring_id;12041205ring_id = dp->tx_mon_buf_ring.refill_buf_ring.ring_id;12061207/* TODO: Need to set upstream/downstream tlv filters1208* here1209*/12101211if (ab->hw_params->rxdma1_enable) {1212ret = ath12k_dp_tx_htt_tx_filter_setup(ar->ab, ring_id, 0,1213HAL_TX_MONITOR_BUF,1214DP_RXDMA_REFILL_RING_SIZE,1215&tlv_filter);1216if (ret) {1217ath12k_err(ab,1218"failed to setup filter for monitor buf %d\n", ret);1219return ret;1220}1221}12221223return 0;1224}122512261227