Path: blob/main/sys/contrib/dev/athk/ath12k/hal_rx.c
48378 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 "debug.h"7#include "hal.h"8#include "hal_tx.h"9#include "hal_rx.h"10#include "hal_desc.h"11#include "hif.h"1213static void ath12k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr,14u8 owner, u8 buffer_type, u32 magic)15{16hdr->info0 = le32_encode_bits(owner, HAL_DESC_HDR_INFO0_OWNER) |17le32_encode_bits(buffer_type, HAL_DESC_HDR_INFO0_BUF_TYPE);1819/* Magic pattern in reserved bits for debugging */20hdr->info0 |= le32_encode_bits(magic, HAL_DESC_HDR_INFO0_DBG_RESERVED);21}2223static int ath12k_hal_reo_cmd_queue_stats(struct hal_tlv_64_hdr *tlv,24struct ath12k_hal_reo_cmd *cmd)25{26struct hal_reo_get_queue_stats *desc;2728tlv->tl = u32_encode_bits(HAL_REO_GET_QUEUE_STATS, HAL_TLV_HDR_TAG) |29u32_encode_bits(sizeof(*desc), HAL_TLV_HDR_LEN);3031desc = (struct hal_reo_get_queue_stats *)tlv->value;32memset_startat(desc, 0, queue_addr_lo);3334desc->cmd.info0 &= ~cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED);35if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS)36desc->cmd.info0 |= cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED);3738desc->queue_addr_lo = cpu_to_le32(cmd->addr_lo);39desc->info0 = le32_encode_bits(cmd->addr_hi,40HAL_REO_GET_QUEUE_STATS_INFO0_QUEUE_ADDR_HI);41if (cmd->flag & HAL_REO_CMD_FLG_STATS_CLEAR)42desc->info0 |= cpu_to_le32(HAL_REO_GET_QUEUE_STATS_INFO0_CLEAR_STATS);4344return le32_get_bits(desc->cmd.info0, HAL_REO_CMD_HDR_INFO0_CMD_NUMBER);45}4647static int ath12k_hal_reo_cmd_flush_cache(struct ath12k_hal *hal,48struct hal_tlv_64_hdr *tlv,49struct ath12k_hal_reo_cmd *cmd)50{51struct hal_reo_flush_cache *desc;52u8 avail_slot = ffz(hal->avail_blk_resource);5354if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER) {55if (avail_slot >= HAL_MAX_AVAIL_BLK_RES)56return -ENOSPC;5758hal->current_blk_index = avail_slot;59}6061tlv->tl = u32_encode_bits(HAL_REO_FLUSH_CACHE, HAL_TLV_HDR_TAG) |62u32_encode_bits(sizeof(*desc), HAL_TLV_HDR_LEN);6364desc = (struct hal_reo_flush_cache *)tlv->value;65memset_startat(desc, 0, cache_addr_lo);6667desc->cmd.info0 &= ~cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED);68if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS)69desc->cmd.info0 |= cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED);7071desc->cache_addr_lo = cpu_to_le32(cmd->addr_lo);72desc->info0 = le32_encode_bits(cmd->addr_hi,73HAL_REO_FLUSH_CACHE_INFO0_CACHE_ADDR_HI);7475if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS)76desc->info0 |= cpu_to_le32(HAL_REO_FLUSH_CACHE_INFO0_FWD_ALL_MPDUS);7778if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER) {79desc->info0 |= cpu_to_le32(HAL_REO_FLUSH_CACHE_INFO0_BLOCK_CACHE_USAGE);80desc->info0 |=81le32_encode_bits(avail_slot,82HAL_REO_FLUSH_CACHE_INFO0_BLOCK_RESRC_IDX);83}8485if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_NO_INVAL)86desc->info0 |= cpu_to_le32(HAL_REO_FLUSH_CACHE_INFO0_FLUSH_WO_INVALIDATE);8788if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_ALL)89desc->info0 |= cpu_to_le32(HAL_REO_FLUSH_CACHE_INFO0_FLUSH_ALL);9091return le32_get_bits(desc->cmd.info0, HAL_REO_CMD_HDR_INFO0_CMD_NUMBER);92}9394static int ath12k_hal_reo_cmd_update_rx_queue(struct hal_tlv_64_hdr *tlv,95struct ath12k_hal_reo_cmd *cmd)96{97struct hal_reo_update_rx_queue *desc;9899tlv->tl = u32_encode_bits(HAL_REO_UPDATE_RX_REO_QUEUE, HAL_TLV_HDR_TAG) |100u32_encode_bits(sizeof(*desc), HAL_TLV_HDR_LEN);101102desc = (struct hal_reo_update_rx_queue *)tlv->value;103memset_startat(desc, 0, queue_addr_lo);104105desc->cmd.info0 &= ~cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED);106if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS)107desc->cmd.info0 |= cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED);108109desc->queue_addr_lo = cpu_to_le32(cmd->addr_lo);110desc->info0 =111le32_encode_bits(cmd->addr_hi,112HAL_REO_UPD_RX_QUEUE_INFO0_QUEUE_ADDR_HI) |113le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_RX_QUEUE_NUM),114HAL_REO_UPD_RX_QUEUE_INFO0_UPD_RX_QUEUE_NUM) |115le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_VLD),116HAL_REO_UPD_RX_QUEUE_INFO0_UPD_VLD) |117le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_ALDC),118HAL_REO_UPD_RX_QUEUE_INFO0_UPD_ASSOC_LNK_DESC_CNT) |119le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_DIS_DUP_DETECTION),120HAL_REO_UPD_RX_QUEUE_INFO0_UPD_DIS_DUP_DETECTION) |121le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_SOFT_REORDER_EN),122HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SOFT_REORDER_EN) |123le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_AC),124HAL_REO_UPD_RX_QUEUE_INFO0_UPD_AC) |125le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_BAR),126HAL_REO_UPD_RX_QUEUE_INFO0_UPD_BAR) |127le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_RETRY),128HAL_REO_UPD_RX_QUEUE_INFO0_UPD_RETRY) |129le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_CHECK_2K_MODE),130HAL_REO_UPD_RX_QUEUE_INFO0_UPD_CHECK_2K_MODE) |131le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_OOR_MODE),132HAL_REO_UPD_RX_QUEUE_INFO0_UPD_OOR_MODE) |133le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_BA_WINDOW_SIZE),134HAL_REO_UPD_RX_QUEUE_INFO0_UPD_BA_WINDOW_SIZE) |135le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_CHECK),136HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_CHECK) |137le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_EVEN_PN),138HAL_REO_UPD_RX_QUEUE_INFO0_UPD_EVEN_PN) |139le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_UNEVEN_PN),140HAL_REO_UPD_RX_QUEUE_INFO0_UPD_UNEVEN_PN) |141le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_HANDLE_ENABLE),142HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_HANDLE_ENABLE) |143le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_SIZE),144HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_SIZE) |145le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_IGNORE_AMPDU_FLG),146HAL_REO_UPD_RX_QUEUE_INFO0_UPD_IGNORE_AMPDU_FLG) |147le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_SVLD),148HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SVLD) |149le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_SSN),150HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SSN) |151le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_SEQ_2K_ERR),152HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SEQ_2K_ERR) |153le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_VALID),154HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_VALID) |155le32_encode_bits(!!(cmd->upd0 & HAL_REO_CMD_UPD0_PN),156HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN);157158desc->info1 =159le32_encode_bits(cmd->rx_queue_num,160HAL_REO_UPD_RX_QUEUE_INFO1_RX_QUEUE_NUMBER) |161le32_encode_bits(!!(cmd->upd1 & HAL_REO_CMD_UPD1_VLD),162HAL_REO_UPD_RX_QUEUE_INFO1_VLD) |163le32_encode_bits(u32_get_bits(cmd->upd1, HAL_REO_CMD_UPD1_ALDC),164HAL_REO_UPD_RX_QUEUE_INFO1_ASSOC_LNK_DESC_COUNTER) |165le32_encode_bits(!!(cmd->upd1 & HAL_REO_CMD_UPD1_DIS_DUP_DETECTION),166HAL_REO_UPD_RX_QUEUE_INFO1_DIS_DUP_DETECTION) |167le32_encode_bits(!!(cmd->upd1 & HAL_REO_CMD_UPD1_SOFT_REORDER_EN),168HAL_REO_UPD_RX_QUEUE_INFO1_SOFT_REORDER_EN) |169le32_encode_bits(u32_get_bits(cmd->upd1, HAL_REO_CMD_UPD1_AC),170HAL_REO_UPD_RX_QUEUE_INFO1_AC) |171le32_encode_bits(!!(cmd->upd1 & HAL_REO_CMD_UPD1_BAR),172HAL_REO_UPD_RX_QUEUE_INFO1_BAR) |173le32_encode_bits(!!(cmd->upd1 & HAL_REO_CMD_UPD1_CHECK_2K_MODE),174HAL_REO_UPD_RX_QUEUE_INFO1_CHECK_2K_MODE) |175le32_encode_bits(!!(cmd->upd1 & HAL_REO_CMD_UPD1_RETRY),176HAL_REO_UPD_RX_QUEUE_INFO1_RETRY) |177le32_encode_bits(!!(cmd->upd1 & HAL_REO_CMD_UPD1_OOR_MODE),178HAL_REO_UPD_RX_QUEUE_INFO1_OOR_MODE) |179le32_encode_bits(!!(cmd->upd1 & HAL_REO_CMD_UPD1_PN_CHECK),180HAL_REO_UPD_RX_QUEUE_INFO1_PN_CHECK) |181le32_encode_bits(!!(cmd->upd1 & HAL_REO_CMD_UPD1_EVEN_PN),182HAL_REO_UPD_RX_QUEUE_INFO1_EVEN_PN) |183le32_encode_bits(!!(cmd->upd1 & HAL_REO_CMD_UPD1_UNEVEN_PN),184HAL_REO_UPD_RX_QUEUE_INFO1_UNEVEN_PN) |185le32_encode_bits(!!(cmd->upd1 & HAL_REO_CMD_UPD1_PN_HANDLE_ENABLE),186HAL_REO_UPD_RX_QUEUE_INFO1_PN_HANDLE_ENABLE) |187le32_encode_bits(!!(cmd->upd1 & HAL_REO_CMD_UPD1_IGNORE_AMPDU_FLG),188HAL_REO_UPD_RX_QUEUE_INFO1_IGNORE_AMPDU_FLG);189190if (cmd->pn_size == 24)191cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_24;192else if (cmd->pn_size == 48)193cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_48;194else if (cmd->pn_size == 128)195cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_128;196197if (cmd->ba_window_size < 1)198cmd->ba_window_size = 1;199200if (cmd->ba_window_size == 1)201cmd->ba_window_size++;202203desc->info2 =204le32_encode_bits(cmd->ba_window_size - 1,205HAL_REO_UPD_RX_QUEUE_INFO2_BA_WINDOW_SIZE) |206le32_encode_bits(cmd->pn_size, HAL_REO_UPD_RX_QUEUE_INFO2_PN_SIZE) |207le32_encode_bits(!!(cmd->upd2 & HAL_REO_CMD_UPD2_SVLD),208HAL_REO_UPD_RX_QUEUE_INFO2_SVLD) |209le32_encode_bits(u32_get_bits(cmd->upd2, HAL_REO_CMD_UPD2_SSN),210HAL_REO_UPD_RX_QUEUE_INFO2_SSN) |211le32_encode_bits(!!(cmd->upd2 & HAL_REO_CMD_UPD2_SEQ_2K_ERR),212HAL_REO_UPD_RX_QUEUE_INFO2_SEQ_2K_ERR) |213le32_encode_bits(!!(cmd->upd2 & HAL_REO_CMD_UPD2_PN_ERR),214HAL_REO_UPD_RX_QUEUE_INFO2_PN_ERR);215216return le32_get_bits(desc->cmd.info0, HAL_REO_CMD_HDR_INFO0_CMD_NUMBER);217}218219int ath12k_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng,220enum hal_reo_cmd_type type,221struct ath12k_hal_reo_cmd *cmd)222{223struct hal_tlv_64_hdr *reo_desc;224int ret;225226spin_lock_bh(&srng->lock);227228ath12k_hal_srng_access_begin(ab, srng);229reo_desc = ath12k_hal_srng_src_get_next_entry(ab, srng);230if (!reo_desc) {231ret = -ENOBUFS;232goto out;233}234235switch (type) {236case HAL_REO_CMD_GET_QUEUE_STATS:237ret = ath12k_hal_reo_cmd_queue_stats(reo_desc, cmd);238break;239case HAL_REO_CMD_FLUSH_CACHE:240ret = ath12k_hal_reo_cmd_flush_cache(&ab->hal, reo_desc, cmd);241break;242case HAL_REO_CMD_UPDATE_RX_QUEUE:243ret = ath12k_hal_reo_cmd_update_rx_queue(reo_desc, cmd);244break;245case HAL_REO_CMD_FLUSH_QUEUE:246case HAL_REO_CMD_UNBLOCK_CACHE:247case HAL_REO_CMD_FLUSH_TIMEOUT_LIST:248ath12k_warn(ab, "Unsupported reo command %d\n", type);249ret = -ENOTSUPP;250break;251default:252ath12k_warn(ab, "Unknown reo command %d\n", type);253ret = -EINVAL;254break;255}256257out:258ath12k_hal_srng_access_end(ab, srng);259spin_unlock_bh(&srng->lock);260261return ret;262}263264void ath12k_hal_rx_buf_addr_info_set(struct ath12k_buffer_addr *binfo,265dma_addr_t paddr, u32 cookie, u8 manager)266{267u32 paddr_lo, paddr_hi;268269paddr_lo = lower_32_bits(paddr);270paddr_hi = upper_32_bits(paddr);271binfo->info0 = le32_encode_bits(paddr_lo, BUFFER_ADDR_INFO0_ADDR);272binfo->info1 = le32_encode_bits(paddr_hi, BUFFER_ADDR_INFO1_ADDR) |273le32_encode_bits(cookie, BUFFER_ADDR_INFO1_SW_COOKIE) |274le32_encode_bits(manager, BUFFER_ADDR_INFO1_RET_BUF_MGR);275}276277void ath12k_hal_rx_buf_addr_info_get(struct ath12k_buffer_addr *binfo,278dma_addr_t *paddr,279u32 *cookie, u8 *rbm)280{281*paddr = (((u64)le32_get_bits(binfo->info1, BUFFER_ADDR_INFO1_ADDR)) << 32) |282le32_get_bits(binfo->info0, BUFFER_ADDR_INFO0_ADDR);283*cookie = le32_get_bits(binfo->info1, BUFFER_ADDR_INFO1_SW_COOKIE);284*rbm = le32_get_bits(binfo->info1, BUFFER_ADDR_INFO1_RET_BUF_MGR);285}286287void ath12k_hal_rx_msdu_link_info_get(struct hal_rx_msdu_link *link, u32 *num_msdus,288u32 *msdu_cookies,289enum hal_rx_buf_return_buf_manager *rbm)290{291struct hal_rx_msdu_details *msdu;292u32 val;293int i;294295*num_msdus = HAL_NUM_RX_MSDUS_PER_LINK_DESC;296297msdu = &link->msdu_link[0];298*rbm = le32_get_bits(msdu->buf_addr_info.info1,299BUFFER_ADDR_INFO1_RET_BUF_MGR);300301for (i = 0; i < *num_msdus; i++) {302msdu = &link->msdu_link[i];303304val = le32_get_bits(msdu->buf_addr_info.info0,305BUFFER_ADDR_INFO0_ADDR);306if (val == 0) {307*num_msdus = i;308break;309}310*msdu_cookies = le32_get_bits(msdu->buf_addr_info.info1,311BUFFER_ADDR_INFO1_SW_COOKIE);312msdu_cookies++;313}314}315316int ath12k_hal_desc_reo_parse_err(struct ath12k_base *ab,317struct hal_reo_dest_ring *desc,318dma_addr_t *paddr, u32 *desc_bank)319{320enum hal_reo_dest_ring_push_reason push_reason;321enum hal_reo_dest_ring_error_code err_code;322u32 cookie, val;323324push_reason = le32_get_bits(desc->info0,325HAL_REO_DEST_RING_INFO0_PUSH_REASON);326err_code = le32_get_bits(desc->info0,327HAL_REO_DEST_RING_INFO0_ERROR_CODE);328ab->soc_stats.reo_error[err_code]++;329330if (push_reason != HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED &&331push_reason != HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) {332ath12k_warn(ab, "expected error push reason code, received %d\n",333push_reason);334return -EINVAL;335}336337val = le32_get_bits(desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE);338if (val != HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC) {339ath12k_warn(ab, "expected buffer type link_desc");340return -EINVAL;341}342343ath12k_hal_rx_reo_ent_paddr_get(ab, &desc->buf_addr_info, paddr, &cookie);344*desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK);345346return 0;347}348349int ath12k_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc,350struct hal_rx_wbm_rel_info *rel_info)351{352struct hal_wbm_release_ring *wbm_desc = desc;353struct hal_wbm_release_ring_cc_rx *wbm_cc_desc = desc;354enum hal_wbm_rel_desc_type type;355enum hal_wbm_rel_src_module rel_src;356bool hw_cc_done;357u64 desc_va;358u32 val;359360type = le32_get_bits(wbm_desc->info0, HAL_WBM_RELEASE_INFO0_DESC_TYPE);361/* We expect only WBM_REL buffer type */362if (type != HAL_WBM_REL_DESC_TYPE_REL_MSDU) {363WARN_ON(1);364return -EINVAL;365}366367rel_src = le32_get_bits(wbm_desc->info0,368HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE);369if (rel_src != HAL_WBM_REL_SRC_MODULE_RXDMA &&370rel_src != HAL_WBM_REL_SRC_MODULE_REO)371return -EINVAL;372373/* The format of wbm rel ring desc changes based on the374* hw cookie conversion status375*/376hw_cc_done = le32_get_bits(wbm_desc->info0,377HAL_WBM_RELEASE_RX_INFO0_CC_STATUS);378379if (!hw_cc_done) {380val = le32_get_bits(wbm_desc->buf_addr_info.info1,381BUFFER_ADDR_INFO1_RET_BUF_MGR);382if (val != HAL_RX_BUF_RBM_SW3_BM) {383ab->soc_stats.invalid_rbm++;384return -EINVAL;385}386387rel_info->cookie = le32_get_bits(wbm_desc->buf_addr_info.info1,388BUFFER_ADDR_INFO1_SW_COOKIE);389390rel_info->rx_desc = NULL;391} else {392val = le32_get_bits(wbm_cc_desc->info0,393HAL_WBM_RELEASE_RX_CC_INFO0_RBM);394if (val != HAL_RX_BUF_RBM_SW3_BM) {395ab->soc_stats.invalid_rbm++;396return -EINVAL;397}398399rel_info->cookie = le32_get_bits(wbm_cc_desc->info1,400HAL_WBM_RELEASE_RX_CC_INFO1_COOKIE);401402desc_va = ((u64)le32_to_cpu(wbm_cc_desc->buf_va_hi) << 32 |403le32_to_cpu(wbm_cc_desc->buf_va_lo));404rel_info->rx_desc =405(struct ath12k_rx_desc_info *)((unsigned long)desc_va);406}407408rel_info->err_rel_src = rel_src;409rel_info->hw_cc_done = hw_cc_done;410411rel_info->first_msdu = le32_get_bits(wbm_desc->info3,412HAL_WBM_RELEASE_INFO3_FIRST_MSDU);413rel_info->last_msdu = le32_get_bits(wbm_desc->info3,414HAL_WBM_RELEASE_INFO3_LAST_MSDU);415rel_info->continuation = le32_get_bits(wbm_desc->info3,416HAL_WBM_RELEASE_INFO3_CONTINUATION);417418if (rel_info->err_rel_src == HAL_WBM_REL_SRC_MODULE_REO) {419rel_info->push_reason =420le32_get_bits(wbm_desc->info0,421HAL_WBM_RELEASE_INFO0_REO_PUSH_REASON);422rel_info->err_code =423le32_get_bits(wbm_desc->info0,424HAL_WBM_RELEASE_INFO0_REO_ERROR_CODE);425} else {426rel_info->push_reason =427le32_get_bits(wbm_desc->info0,428HAL_WBM_RELEASE_INFO0_RXDMA_PUSH_REASON);429rel_info->err_code =430le32_get_bits(wbm_desc->info0,431HAL_WBM_RELEASE_INFO0_RXDMA_ERROR_CODE);432}433434return 0;435}436437void ath12k_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab,438struct ath12k_buffer_addr *buff_addr,439dma_addr_t *paddr, u32 *cookie)440{441*paddr = ((u64)(le32_get_bits(buff_addr->info1,442BUFFER_ADDR_INFO1_ADDR)) << 32) |443le32_get_bits(buff_addr->info0, BUFFER_ADDR_INFO0_ADDR);444445*cookie = le32_get_bits(buff_addr->info1, BUFFER_ADDR_INFO1_SW_COOKIE);446}447448void ath12k_hal_rx_msdu_link_desc_set(struct ath12k_base *ab,449struct hal_wbm_release_ring *dst_desc,450struct hal_wbm_release_ring *src_desc,451enum hal_wbm_rel_bm_act action)452{453dst_desc->buf_addr_info = src_desc->buf_addr_info;454dst_desc->info0 |= le32_encode_bits(HAL_WBM_REL_SRC_MODULE_SW,455HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE) |456le32_encode_bits(action, HAL_WBM_RELEASE_INFO0_BM_ACTION) |457le32_encode_bits(HAL_WBM_REL_DESC_TYPE_MSDU_LINK,458HAL_WBM_RELEASE_INFO0_DESC_TYPE);459}460461void ath12k_hal_reo_status_queue_stats(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv,462struct hal_reo_status *status)463{464struct hal_reo_get_queue_stats_status *desc =465(struct hal_reo_get_queue_stats_status *)tlv->value;466467status->uniform_hdr.cmd_num =468le32_get_bits(desc->hdr.info0,469HAL_REO_STATUS_HDR_INFO0_STATUS_NUM);470status->uniform_hdr.cmd_status =471le32_get_bits(desc->hdr.info0,472HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS);473474ath12k_dbg(ab, ATH12K_DBG_HAL, "Queue stats status:\n");475ath12k_dbg(ab, ATH12K_DBG_HAL, "header: cmd_num %d status %d\n",476status->uniform_hdr.cmd_num,477status->uniform_hdr.cmd_status);478ath12k_dbg(ab, ATH12K_DBG_HAL, "ssn %u cur_idx %u\n",479le32_get_bits(desc->info0,480HAL_REO_GET_QUEUE_STATS_STATUS_INFO0_SSN),481le32_get_bits(desc->info0,482HAL_REO_GET_QUEUE_STATS_STATUS_INFO0_CUR_IDX));483ath12k_dbg(ab, ATH12K_DBG_HAL, "pn = [%08x, %08x, %08x, %08x]\n",484desc->pn[0], desc->pn[1], desc->pn[2], desc->pn[3]);485ath12k_dbg(ab, ATH12K_DBG_HAL, "last_rx: enqueue_tstamp %08x dequeue_tstamp %08x\n",486desc->last_rx_enqueue_timestamp,487desc->last_rx_dequeue_timestamp);488ath12k_dbg(ab, ATH12K_DBG_HAL, "rx_bitmap [%08x %08x %08x %08x %08x %08x %08x %08x]\n",489desc->rx_bitmap[0], desc->rx_bitmap[1], desc->rx_bitmap[2],490desc->rx_bitmap[3], desc->rx_bitmap[4], desc->rx_bitmap[5],491desc->rx_bitmap[6], desc->rx_bitmap[7]);492ath12k_dbg(ab, ATH12K_DBG_HAL, "count: cur_mpdu %u cur_msdu %u\n",493le32_get_bits(desc->info1,494HAL_REO_GET_QUEUE_STATS_STATUS_INFO1_MPDU_COUNT),495le32_get_bits(desc->info1,496HAL_REO_GET_QUEUE_STATS_STATUS_INFO1_MSDU_COUNT));497ath12k_dbg(ab, ATH12K_DBG_HAL, "fwd_timeout %u fwd_bar %u dup_count %u\n",498le32_get_bits(desc->info2,499HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_TIMEOUT_COUNT),500le32_get_bits(desc->info2,501HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_FDTB_COUNT),502le32_get_bits(desc->info2,503HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_DUPLICATE_COUNT));504ath12k_dbg(ab, ATH12K_DBG_HAL, "frames_in_order %u bar_rcvd %u\n",505le32_get_bits(desc->info3,506HAL_REO_GET_QUEUE_STATS_STATUS_INFO3_FIO_COUNT),507le32_get_bits(desc->info3,508HAL_REO_GET_QUEUE_STATS_STATUS_INFO3_BAR_RCVD_CNT));509ath12k_dbg(ab, ATH12K_DBG_HAL, "num_mpdus %d num_msdus %d total_bytes %d\n",510desc->num_mpdu_frames, desc->num_msdu_frames,511desc->total_bytes);512ath12k_dbg(ab, ATH12K_DBG_HAL, "late_rcvd %u win_jump_2k %u hole_cnt %u\n",513le32_get_bits(desc->info4,514HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_LATE_RX_MPDU),515le32_get_bits(desc->info2,516HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_WINDOW_JMP2K),517le32_get_bits(desc->info4,518HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_HOLE_COUNT));519ath12k_dbg(ab, ATH12K_DBG_HAL, "looping count %u\n",520le32_get_bits(desc->info5,521HAL_REO_GET_QUEUE_STATS_STATUS_INFO5_LOOPING_CNT));522}523524void ath12k_hal_reo_flush_queue_status(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv,525struct hal_reo_status *status)526{527struct hal_reo_flush_queue_status *desc =528(struct hal_reo_flush_queue_status *)tlv->value;529530status->uniform_hdr.cmd_num =531le32_get_bits(desc->hdr.info0,532HAL_REO_STATUS_HDR_INFO0_STATUS_NUM);533status->uniform_hdr.cmd_status =534le32_get_bits(desc->hdr.info0,535HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS);536status->u.flush_queue.err_detected =537le32_get_bits(desc->info0,538HAL_REO_FLUSH_QUEUE_INFO0_ERR_DETECTED);539}540541void ath12k_hal_reo_flush_cache_status(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv,542struct hal_reo_status *status)543{544struct ath12k_hal *hal = &ab->hal;545struct hal_reo_flush_cache_status *desc =546(struct hal_reo_flush_cache_status *)tlv->value;547548status->uniform_hdr.cmd_num =549le32_get_bits(desc->hdr.info0,550HAL_REO_STATUS_HDR_INFO0_STATUS_NUM);551status->uniform_hdr.cmd_status =552le32_get_bits(desc->hdr.info0,553HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS);554555status->u.flush_cache.err_detected =556le32_get_bits(desc->info0,557HAL_REO_FLUSH_CACHE_STATUS_INFO0_IS_ERR);558status->u.flush_cache.err_code =559le32_get_bits(desc->info0,560HAL_REO_FLUSH_CACHE_STATUS_INFO0_BLOCK_ERR_CODE);561if (!status->u.flush_cache.err_code)562hal->avail_blk_resource |= BIT(hal->current_blk_index);563564status->u.flush_cache.cache_controller_flush_status_hit =565le32_get_bits(desc->info0,566HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_STATUS_HIT);567568status->u.flush_cache.cache_controller_flush_status_desc_type =569le32_get_bits(desc->info0,570HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_DESC_TYPE);571status->u.flush_cache.cache_controller_flush_status_client_id =572le32_get_bits(desc->info0,573HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_CLIENT_ID);574status->u.flush_cache.cache_controller_flush_status_err =575le32_get_bits(desc->info0,576HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_ERR);577status->u.flush_cache.cache_controller_flush_status_cnt =578le32_get_bits(desc->info0,579HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_COUNT);580}581582void ath12k_hal_reo_unblk_cache_status(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv,583struct hal_reo_status *status)584{585struct ath12k_hal *hal = &ab->hal;586struct hal_reo_unblock_cache_status *desc =587(struct hal_reo_unblock_cache_status *)tlv->value;588589status->uniform_hdr.cmd_num =590le32_get_bits(desc->hdr.info0,591HAL_REO_STATUS_HDR_INFO0_STATUS_NUM);592status->uniform_hdr.cmd_status =593le32_get_bits(desc->hdr.info0,594HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS);595596status->u.unblock_cache.err_detected =597le32_get_bits(desc->info0,598HAL_REO_UNBLOCK_CACHE_STATUS_INFO0_IS_ERR);599status->u.unblock_cache.unblock_type =600le32_get_bits(desc->info0,601HAL_REO_UNBLOCK_CACHE_STATUS_INFO0_TYPE);602603if (!status->u.unblock_cache.err_detected &&604status->u.unblock_cache.unblock_type ==605HAL_REO_STATUS_UNBLOCK_BLOCKING_RESOURCE)606hal->avail_blk_resource &= ~BIT(hal->current_blk_index);607}608609void ath12k_hal_reo_flush_timeout_list_status(struct ath12k_base *ab,610struct hal_tlv_64_hdr *tlv,611struct hal_reo_status *status)612{613struct hal_reo_flush_timeout_list_status *desc =614(struct hal_reo_flush_timeout_list_status *)tlv->value;615616status->uniform_hdr.cmd_num =617le32_get_bits(desc->hdr.info0,618HAL_REO_STATUS_HDR_INFO0_STATUS_NUM);619status->uniform_hdr.cmd_status =620le32_get_bits(desc->hdr.info0,621HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS);622623status->u.timeout_list.err_detected =624le32_get_bits(desc->info0,625HAL_REO_FLUSH_TIMEOUT_STATUS_INFO0_IS_ERR);626status->u.timeout_list.list_empty =627le32_get_bits(desc->info0,628HAL_REO_FLUSH_TIMEOUT_STATUS_INFO0_LIST_EMPTY);629630status->u.timeout_list.release_desc_cnt =631le32_get_bits(desc->info1,632HAL_REO_FLUSH_TIMEOUT_STATUS_INFO1_REL_DESC_COUNT);633status->u.timeout_list.fwd_buf_cnt =634le32_get_bits(desc->info0,635HAL_REO_FLUSH_TIMEOUT_STATUS_INFO1_FWD_BUF_COUNT);636}637638void ath12k_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab,639struct hal_tlv_64_hdr *tlv,640struct hal_reo_status *status)641{642struct hal_reo_desc_thresh_reached_status *desc =643(struct hal_reo_desc_thresh_reached_status *)tlv->value;644645status->uniform_hdr.cmd_num =646le32_get_bits(desc->hdr.info0,647HAL_REO_STATUS_HDR_INFO0_STATUS_NUM);648status->uniform_hdr.cmd_status =649le32_get_bits(desc->hdr.info0,650HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS);651652status->u.desc_thresh_reached.threshold_idx =653le32_get_bits(desc->info0,654HAL_REO_DESC_THRESH_STATUS_INFO0_THRESH_INDEX);655656status->u.desc_thresh_reached.link_desc_counter0 =657le32_get_bits(desc->info1,658HAL_REO_DESC_THRESH_STATUS_INFO1_LINK_DESC_COUNTER0);659660status->u.desc_thresh_reached.link_desc_counter1 =661le32_get_bits(desc->info2,662HAL_REO_DESC_THRESH_STATUS_INFO2_LINK_DESC_COUNTER1);663664status->u.desc_thresh_reached.link_desc_counter2 =665le32_get_bits(desc->info3,666HAL_REO_DESC_THRESH_STATUS_INFO3_LINK_DESC_COUNTER2);667668status->u.desc_thresh_reached.link_desc_counter_sum =669le32_get_bits(desc->info4,670HAL_REO_DESC_THRESH_STATUS_INFO4_LINK_DESC_COUNTER_SUM);671}672673void ath12k_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab,674struct hal_tlv_64_hdr *tlv,675struct hal_reo_status *status)676{677struct hal_reo_status_hdr *desc =678(struct hal_reo_status_hdr *)tlv->value;679680status->uniform_hdr.cmd_num =681le32_get_bits(desc->info0,682HAL_REO_STATUS_HDR_INFO0_STATUS_NUM);683status->uniform_hdr.cmd_status =684le32_get_bits(desc->info0,685HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS);686}687688u32 ath12k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid)689{690u32 num_ext_desc;691692if (ba_window_size <= 1) {693if (tid != HAL_DESC_REO_NON_QOS_TID)694num_ext_desc = 1;695else696num_ext_desc = 0;697} else if (ba_window_size <= 105) {698num_ext_desc = 1;699} else if (ba_window_size <= 210) {700num_ext_desc = 2;701} else {702num_ext_desc = 3;703}704705return sizeof(struct hal_rx_reo_queue) +706(num_ext_desc * sizeof(struct hal_rx_reo_queue_ext));707}708709void ath12k_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc,710int tid, u32 ba_window_size,711u32 start_seq, enum hal_pn_type type)712{713struct hal_rx_reo_queue_ext *ext_desc;714715memset(qdesc, 0, sizeof(*qdesc));716717ath12k_hal_reo_set_desc_hdr(&qdesc->desc_hdr, HAL_DESC_REO_OWNED,718HAL_DESC_REO_QUEUE_DESC,719REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_0);720721qdesc->rx_queue_num = le32_encode_bits(tid, HAL_RX_REO_QUEUE_RX_QUEUE_NUMBER);722723qdesc->info0 =724le32_encode_bits(1, HAL_RX_REO_QUEUE_INFO0_VLD) |725le32_encode_bits(1, HAL_RX_REO_QUEUE_INFO0_ASSOC_LNK_DESC_COUNTER) |726le32_encode_bits(ath12k_tid_to_ac(tid), HAL_RX_REO_QUEUE_INFO0_AC);727728if (ba_window_size < 1)729ba_window_size = 1;730731if (ba_window_size == 1 && tid != HAL_DESC_REO_NON_QOS_TID)732ba_window_size++;733734if (ba_window_size == 1)735qdesc->info0 |= le32_encode_bits(1, HAL_RX_REO_QUEUE_INFO0_RETRY);736737qdesc->info0 |= le32_encode_bits(ba_window_size - 1,738HAL_RX_REO_QUEUE_INFO0_BA_WINDOW_SIZE);739switch (type) {740case HAL_PN_TYPE_NONE:741case HAL_PN_TYPE_WAPI_EVEN:742case HAL_PN_TYPE_WAPI_UNEVEN:743break;744case HAL_PN_TYPE_WPA:745qdesc->info0 |=746le32_encode_bits(1, HAL_RX_REO_QUEUE_INFO0_PN_CHECK) |747le32_encode_bits(HAL_RX_REO_QUEUE_PN_SIZE_48,748HAL_RX_REO_QUEUE_INFO0_PN_SIZE);749break;750}751752/* TODO: Set Ignore ampdu flags based on BA window size and/or753* AMPDU capabilities754*/755qdesc->info0 |= le32_encode_bits(1, HAL_RX_REO_QUEUE_INFO0_IGNORE_AMPDU_FLG);756757qdesc->info1 |= le32_encode_bits(0, HAL_RX_REO_QUEUE_INFO1_SVLD);758759if (start_seq <= 0xfff)760qdesc->info1 = le32_encode_bits(start_seq,761HAL_RX_REO_QUEUE_INFO1_SSN);762763if (tid == HAL_DESC_REO_NON_QOS_TID)764return;765766ext_desc = qdesc->ext_desc;767768/* TODO: HW queue descriptors are currently allocated for max BA769* window size for all QOS TIDs so that same descriptor can be used770* later when ADDBA request is received. This should be changed to771* allocate HW queue descriptors based on BA window size being772* negotiated (0 for non BA cases), and reallocate when BA window773* size changes and also send WMI message to FW to change the REO774* queue descriptor in Rx peer entry as part of dp_rx_tid_update.775*/776memset(ext_desc, 0, 3 * sizeof(*ext_desc));777ath12k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED,778HAL_DESC_REO_QUEUE_EXT_DESC,779REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_1);780ext_desc++;781ath12k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED,782HAL_DESC_REO_QUEUE_EXT_DESC,783REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2);784ext_desc++;785ath12k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED,786HAL_DESC_REO_QUEUE_EXT_DESC,787REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3);788}789790void ath12k_hal_reo_init_cmd_ring(struct ath12k_base *ab,791struct hal_srng *srng)792{793struct hal_srng_params params;794struct hal_tlv_64_hdr *tlv;795struct hal_reo_get_queue_stats *desc;796int i, cmd_num = 1;797int entry_size;798u8 *entry;799800memset(¶ms, 0, sizeof(params));801802entry_size = ath12k_hal_srng_get_entrysize(ab, HAL_REO_CMD);803ath12k_hal_srng_get_params(ab, srng, ¶ms);804entry = (u8 *)params.ring_base_vaddr;805806for (i = 0; i < params.num_entries; i++) {807tlv = (struct hal_tlv_64_hdr *)entry;808desc = (struct hal_reo_get_queue_stats *)tlv->value;809desc->cmd.info0 = le32_encode_bits(cmd_num++,810HAL_REO_CMD_HDR_INFO0_CMD_NUMBER);811entry += entry_size;812}813}814815void ath12k_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map)816{817u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG;818u32 val;819820val = ath12k_hif_read32(ab, reo_base + HAL_REO1_GEN_ENABLE);821822val |= u32_encode_bits(1, HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE) |823u32_encode_bits(1, HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE);824ath12k_hif_write32(ab, reo_base + HAL_REO1_GEN_ENABLE, val);825826val = ath12k_hif_read32(ab, reo_base + HAL_REO1_MISC_CTRL_ADDR(ab));827828val &= ~(HAL_REO1_MISC_CTL_FRAG_DST_RING |829HAL_REO1_MISC_CTL_BAR_DST_RING);830val |= u32_encode_bits(HAL_SRNG_RING_ID_REO2SW0,831HAL_REO1_MISC_CTL_FRAG_DST_RING);832val |= u32_encode_bits(HAL_SRNG_RING_ID_REO2SW0,833HAL_REO1_MISC_CTL_BAR_DST_RING);834ath12k_hif_write32(ab, reo_base + HAL_REO1_MISC_CTRL_ADDR(ab), val);835836ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_0(ab),837HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC);838ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_1(ab),839HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC);840ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_2(ab),841HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC);842ath12k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3(ab),843HAL_DEFAULT_VO_REO_TIMEOUT_USEC);844845ath12k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_2,846ring_hash_map);847ath12k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_3,848ring_hash_map);849}850851852