Path: blob/main/sys/contrib/dev/athk/ath11k/hal_rx.c
106180 views
// SPDX-License-Identifier: BSD-3-Clause-Clear1/*2* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.3* Copyright (c) 2021-2024 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 ath11k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr,14u8 owner, u8 buffer_type, u32 magic)15{16hdr->info0 = FIELD_PREP(HAL_DESC_HDR_INFO0_OWNER, owner) |17FIELD_PREP(HAL_DESC_HDR_INFO0_BUF_TYPE, buffer_type);1819/* Magic pattern in reserved bits for debugging */20hdr->info0 |= FIELD_PREP(HAL_DESC_HDR_INFO0_DBG_RESERVED, magic);21}2223static int ath11k_hal_reo_cmd_queue_stats(struct hal_tlv_hdr *tlv,24struct ath11k_hal_reo_cmd *cmd)25{26struct hal_reo_get_queue_stats *desc;2728tlv->tl = FIELD_PREP(HAL_TLV_HDR_TAG, HAL_REO_GET_QUEUE_STATS) |29FIELD_PREP(HAL_TLV_HDR_LEN, sizeof(*desc));3031desc = (struct hal_reo_get_queue_stats *)tlv->value;32memset_startat(desc, 0, queue_addr_lo);3334desc->cmd.info0 &= ~HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED;35if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS)36desc->cmd.info0 |= HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED;3738desc->queue_addr_lo = cmd->addr_lo;39desc->info0 = FIELD_PREP(HAL_REO_GET_QUEUE_STATS_INFO0_QUEUE_ADDR_HI,40cmd->addr_hi);41if (cmd->flag & HAL_REO_CMD_FLG_STATS_CLEAR)42desc->info0 |= HAL_REO_GET_QUEUE_STATS_INFO0_CLEAR_STATS;4344return FIELD_GET(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, desc->cmd.info0);45}4647static int ath11k_hal_reo_cmd_flush_cache(struct ath11k_hal *hal, struct hal_tlv_hdr *tlv,48struct ath11k_hal_reo_cmd *cmd)49{50struct hal_reo_flush_cache *desc;51u8 avail_slot = ffz(hal->avail_blk_resource);5253if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER) {54if (avail_slot >= HAL_MAX_AVAIL_BLK_RES)55return -ENOSPC;5657hal->current_blk_index = avail_slot;58}5960tlv->tl = FIELD_PREP(HAL_TLV_HDR_TAG, HAL_REO_FLUSH_CACHE) |61FIELD_PREP(HAL_TLV_HDR_LEN, sizeof(*desc));6263desc = (struct hal_reo_flush_cache *)tlv->value;64memset_startat(desc, 0, cache_addr_lo);6566desc->cmd.info0 &= ~HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED;67if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS)68desc->cmd.info0 |= HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED;6970desc->cache_addr_lo = cmd->addr_lo;71desc->info0 = FIELD_PREP(HAL_REO_FLUSH_CACHE_INFO0_CACHE_ADDR_HI,72cmd->addr_hi);7374if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS)75desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_FWD_ALL_MPDUS;7677if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER) {78desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_BLOCK_CACHE_USAGE;79desc->info0 |=80FIELD_PREP(HAL_REO_FLUSH_CACHE_INFO0_BLOCK_RESRC_IDX,81avail_slot);82}8384if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_NO_INVAL)85desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_FLUSH_WO_INVALIDATE;8687if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_ALL)88desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_FLUSH_ALL;8990return FIELD_GET(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, desc->cmd.info0);91}9293static int ath11k_hal_reo_cmd_update_rx_queue(struct hal_tlv_hdr *tlv,94struct ath11k_hal_reo_cmd *cmd)95{96struct hal_reo_update_rx_queue *desc;9798tlv->tl = FIELD_PREP(HAL_TLV_HDR_TAG, HAL_REO_UPDATE_RX_REO_QUEUE) |99FIELD_PREP(HAL_TLV_HDR_LEN, sizeof(*desc));100101desc = (struct hal_reo_update_rx_queue *)tlv->value;102memset_startat(desc, 0, queue_addr_lo);103104desc->cmd.info0 &= ~HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED;105if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS)106desc->cmd.info0 |= HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED;107108desc->queue_addr_lo = cmd->addr_lo;109desc->info0 =110FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_QUEUE_ADDR_HI,111cmd->addr_hi) |112FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_RX_QUEUE_NUM,113!!(cmd->upd0 & HAL_REO_CMD_UPD0_RX_QUEUE_NUM)) |114FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_VLD,115!!(cmd->upd0 & HAL_REO_CMD_UPD0_VLD)) |116FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_ASSOC_LNK_DESC_CNT,117!!(cmd->upd0 & HAL_REO_CMD_UPD0_ALDC)) |118FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_DIS_DUP_DETECTION,119!!(cmd->upd0 & HAL_REO_CMD_UPD0_DIS_DUP_DETECTION)) |120FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SOFT_REORDER_EN,121!!(cmd->upd0 & HAL_REO_CMD_UPD0_SOFT_REORDER_EN)) |122FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_AC,123!!(cmd->upd0 & HAL_REO_CMD_UPD0_AC)) |124FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_BAR,125!!(cmd->upd0 & HAL_REO_CMD_UPD0_BAR)) |126FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_RETRY,127!!(cmd->upd0 & HAL_REO_CMD_UPD0_RETRY)) |128FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_CHECK_2K_MODE,129!!(cmd->upd0 & HAL_REO_CMD_UPD0_CHECK_2K_MODE)) |130FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_OOR_MODE,131!!(cmd->upd0 & HAL_REO_CMD_UPD0_OOR_MODE)) |132FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_BA_WINDOW_SIZE,133!!(cmd->upd0 & HAL_REO_CMD_UPD0_BA_WINDOW_SIZE)) |134FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_CHECK,135!!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_CHECK)) |136FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_EVEN_PN,137!!(cmd->upd0 & HAL_REO_CMD_UPD0_EVEN_PN)) |138FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_UNEVEN_PN,139!!(cmd->upd0 & HAL_REO_CMD_UPD0_UNEVEN_PN)) |140FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_HANDLE_ENABLE,141!!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_HANDLE_ENABLE)) |142FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_SIZE,143!!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_SIZE)) |144FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_IGNORE_AMPDU_FLG,145!!(cmd->upd0 & HAL_REO_CMD_UPD0_IGNORE_AMPDU_FLG)) |146FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SVLD,147!!(cmd->upd0 & HAL_REO_CMD_UPD0_SVLD)) |148FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SSN,149!!(cmd->upd0 & HAL_REO_CMD_UPD0_SSN)) |150FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SEQ_2K_ERR,151!!(cmd->upd0 & HAL_REO_CMD_UPD0_SEQ_2K_ERR)) |152FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_VALID,153!!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_VALID)) |154FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN,155!!(cmd->upd0 & HAL_REO_CMD_UPD0_PN));156157desc->info1 =158FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_RX_QUEUE_NUMBER,159cmd->rx_queue_num) |160FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_VLD,161!!(cmd->upd1 & HAL_REO_CMD_UPD1_VLD)) |162FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_ASSOC_LNK_DESC_COUNTER,163FIELD_GET(HAL_REO_CMD_UPD1_ALDC, cmd->upd1)) |164FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_DIS_DUP_DETECTION,165!!(cmd->upd1 & HAL_REO_CMD_UPD1_DIS_DUP_DETECTION)) |166FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_SOFT_REORDER_EN,167!!(cmd->upd1 & HAL_REO_CMD_UPD1_SOFT_REORDER_EN)) |168FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_AC,169FIELD_GET(HAL_REO_CMD_UPD1_AC, cmd->upd1)) |170FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_BAR,171!!(cmd->upd1 & HAL_REO_CMD_UPD1_BAR)) |172FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_CHECK_2K_MODE,173!!(cmd->upd1 & HAL_REO_CMD_UPD1_CHECK_2K_MODE)) |174FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_RETRY,175!!(cmd->upd1 & HAL_REO_CMD_UPD1_RETRY)) |176FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_OOR_MODE,177!!(cmd->upd1 & HAL_REO_CMD_UPD1_OOR_MODE)) |178FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_PN_CHECK,179!!(cmd->upd1 & HAL_REO_CMD_UPD1_PN_CHECK)) |180FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_EVEN_PN,181!!(cmd->upd1 & HAL_REO_CMD_UPD1_EVEN_PN)) |182FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_UNEVEN_PN,183!!(cmd->upd1 & HAL_REO_CMD_UPD1_UNEVEN_PN)) |184FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_PN_HANDLE_ENABLE,185!!(cmd->upd1 & HAL_REO_CMD_UPD1_PN_HANDLE_ENABLE)) |186FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_IGNORE_AMPDU_FLG,187!!(cmd->upd1 & HAL_REO_CMD_UPD1_IGNORE_AMPDU_FLG));188189if (cmd->pn_size == 24)190cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_24;191else if (cmd->pn_size == 48)192cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_48;193else if (cmd->pn_size == 128)194cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_128;195196if (cmd->ba_window_size < 1)197cmd->ba_window_size = 1;198199if (cmd->ba_window_size == 1)200cmd->ba_window_size++;201202desc->info2 =203FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_BA_WINDOW_SIZE,204cmd->ba_window_size - 1) |205FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_PN_SIZE, cmd->pn_size) |206FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_SVLD,207!!(cmd->upd2 & HAL_REO_CMD_UPD2_SVLD)) |208FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_SSN,209FIELD_GET(HAL_REO_CMD_UPD2_SSN, cmd->upd2)) |210FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_SEQ_2K_ERR,211!!(cmd->upd2 & HAL_REO_CMD_UPD2_SEQ_2K_ERR)) |212FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_PN_ERR,213!!(cmd->upd2 & HAL_REO_CMD_UPD2_PN_ERR));214215return FIELD_GET(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, desc->cmd.info0);216}217218int ath11k_hal_reo_cmd_send(struct ath11k_base *ab, struct hal_srng *srng,219enum hal_reo_cmd_type type,220struct ath11k_hal_reo_cmd *cmd)221{222struct hal_tlv_hdr *reo_desc;223int ret;224225spin_lock_bh(&srng->lock);226227ath11k_hal_srng_access_begin(ab, srng);228reo_desc = (struct hal_tlv_hdr *)ath11k_hal_srng_src_get_next_entry(ab, srng);229if (!reo_desc) {230ret = -ENOBUFS;231goto out;232}233234switch (type) {235case HAL_REO_CMD_GET_QUEUE_STATS:236ret = ath11k_hal_reo_cmd_queue_stats(reo_desc, cmd);237break;238case HAL_REO_CMD_FLUSH_CACHE:239ret = ath11k_hal_reo_cmd_flush_cache(&ab->hal, reo_desc, cmd);240break;241case HAL_REO_CMD_UPDATE_RX_QUEUE:242ret = ath11k_hal_reo_cmd_update_rx_queue(reo_desc, cmd);243break;244case HAL_REO_CMD_FLUSH_QUEUE:245case HAL_REO_CMD_UNBLOCK_CACHE:246case HAL_REO_CMD_FLUSH_TIMEOUT_LIST:247ath11k_warn(ab, "Unsupported reo command %d\n", type);248ret = -EOPNOTSUPP;249break;250default:251ath11k_warn(ab, "Unknown reo command %d\n", type);252ret = -EINVAL;253break;254}255256ath11k_dp_shadow_start_timer(ab, srng, &ab->dp.reo_cmd_timer);257258out:259ath11k_hal_srng_access_end(ab, srng);260spin_unlock_bh(&srng->lock);261262return ret;263}264265void ath11k_hal_rx_buf_addr_info_set(void *desc, dma_addr_t paddr,266u32 cookie, u8 manager)267{268struct ath11k_buffer_addr *binfo = desc;269u32 paddr_lo, paddr_hi;270271paddr_lo = lower_32_bits(paddr);272paddr_hi = upper_32_bits(paddr);273binfo->info0 = FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, paddr_lo);274binfo->info1 = FIELD_PREP(BUFFER_ADDR_INFO1_ADDR, paddr_hi) |275FIELD_PREP(BUFFER_ADDR_INFO1_SW_COOKIE, cookie) |276FIELD_PREP(BUFFER_ADDR_INFO1_RET_BUF_MGR, manager);277}278279void ath11k_hal_rx_buf_addr_info_get(void *desc, dma_addr_t *paddr,280u32 *cookie, u8 *rbm)281{282struct ath11k_buffer_addr *binfo = desc;283284*paddr =285(((u64)FIELD_GET(BUFFER_ADDR_INFO1_ADDR, binfo->info1)) << 32) |286FIELD_GET(BUFFER_ADDR_INFO0_ADDR, binfo->info0);287*cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, binfo->info1);288*rbm = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, binfo->info1);289}290291void ath11k_hal_rx_msdu_link_info_get(void *link_desc, u32 *num_msdus,292u32 *msdu_cookies,293enum hal_rx_buf_return_buf_manager *rbm)294{295struct hal_rx_msdu_link *link = link_desc;296struct hal_rx_msdu_details *msdu;297int i;298299*num_msdus = HAL_NUM_RX_MSDUS_PER_LINK_DESC;300301msdu = &link->msdu_link[0];302*rbm = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR,303msdu->buf_addr_info.info1);304305for (i = 0; i < *num_msdus; i++) {306msdu = &link->msdu_link[i];307308if (!FIELD_GET(BUFFER_ADDR_INFO0_ADDR,309msdu->buf_addr_info.info0)) {310*num_msdus = i;311break;312}313*msdu_cookies = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,314msdu->buf_addr_info.info1);315msdu_cookies++;316}317}318319int ath11k_hal_desc_reo_parse_err(struct ath11k_base *ab, u32 *rx_desc,320dma_addr_t *paddr, u32 *desc_bank)321{322struct hal_reo_dest_ring *desc = (struct hal_reo_dest_ring *)rx_desc;323enum hal_reo_dest_ring_push_reason push_reason;324enum hal_reo_dest_ring_error_code err_code;325326push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON,327desc->info0);328err_code = FIELD_GET(HAL_REO_DEST_RING_INFO0_ERROR_CODE,329desc->info0);330ab->soc_stats.reo_error[err_code]++;331332if (push_reason != HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED &&333push_reason != HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) {334ath11k_warn(ab, "expected error push reason code, received %d\n",335push_reason);336return -EINVAL;337}338339if (FIELD_GET(HAL_REO_DEST_RING_INFO0_BUFFER_TYPE, desc->info0) !=340HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC) {341ath11k_warn(ab, "expected buffer type link_desc");342return -EINVAL;343}344345ath11k_hal_rx_reo_ent_paddr_get(ab, rx_desc, paddr, desc_bank);346347return 0;348}349350int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc,351struct hal_rx_wbm_rel_info *rel_info)352{353struct hal_wbm_release_ring *wbm_desc = desc;354enum hal_wbm_rel_desc_type type;355enum hal_wbm_rel_src_module rel_src;356enum hal_rx_buf_return_buf_manager ret_buf_mgr;357358type = FIELD_GET(HAL_WBM_RELEASE_INFO0_DESC_TYPE,359wbm_desc->info0);360/* We expect only WBM_REL buffer type */361if (type != HAL_WBM_REL_DESC_TYPE_REL_MSDU) {362WARN_ON(1);363return -EINVAL;364}365366rel_src = FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE,367wbm_desc->info0);368if (rel_src != HAL_WBM_REL_SRC_MODULE_RXDMA &&369rel_src != HAL_WBM_REL_SRC_MODULE_REO)370return -EINVAL;371372ret_buf_mgr = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR,373wbm_desc->buf_addr_info.info1);374if (ret_buf_mgr != HAL_RX_BUF_RBM_SW1_BM &&375ret_buf_mgr != HAL_RX_BUF_RBM_SW3_BM) {376ab->soc_stats.invalid_rbm++;377return -EINVAL;378}379380rel_info->cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,381wbm_desc->buf_addr_info.info1);382rel_info->err_rel_src = rel_src;383if (rel_src == HAL_WBM_REL_SRC_MODULE_REO) {384rel_info->push_reason =385FIELD_GET(HAL_WBM_RELEASE_INFO0_REO_PUSH_REASON,386wbm_desc->info0);387rel_info->err_code =388FIELD_GET(HAL_WBM_RELEASE_INFO0_REO_ERROR_CODE,389wbm_desc->info0);390} else {391rel_info->push_reason =392FIELD_GET(HAL_WBM_RELEASE_INFO0_RXDMA_PUSH_REASON,393wbm_desc->info0);394rel_info->err_code =395FIELD_GET(HAL_WBM_RELEASE_INFO0_RXDMA_ERROR_CODE,396wbm_desc->info0);397}398399rel_info->first_msdu = FIELD_GET(HAL_WBM_RELEASE_INFO2_FIRST_MSDU,400wbm_desc->info2);401rel_info->last_msdu = FIELD_GET(HAL_WBM_RELEASE_INFO2_LAST_MSDU,402wbm_desc->info2);403return 0;404}405406void ath11k_hal_rx_reo_ent_paddr_get(struct ath11k_base *ab, void *desc,407dma_addr_t *paddr, u32 *desc_bank)408{409struct ath11k_buffer_addr *buff_addr = desc;410411*paddr = ((u64)(FIELD_GET(BUFFER_ADDR_INFO1_ADDR, buff_addr->info1)) << 32) |412FIELD_GET(BUFFER_ADDR_INFO0_ADDR, buff_addr->info0);413414*desc_bank = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, buff_addr->info1);415}416417void ath11k_hal_rx_msdu_link_desc_set(struct ath11k_base *ab, void *desc,418void *link_desc,419enum hal_wbm_rel_bm_act action)420{421struct hal_wbm_release_ring *dst_desc = desc;422struct hal_wbm_release_ring *src_desc = link_desc;423424dst_desc->buf_addr_info = src_desc->buf_addr_info;425dst_desc->info0 |= FIELD_PREP(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE,426HAL_WBM_REL_SRC_MODULE_SW) |427FIELD_PREP(HAL_WBM_RELEASE_INFO0_BM_ACTION, action) |428FIELD_PREP(HAL_WBM_RELEASE_INFO0_DESC_TYPE,429HAL_WBM_REL_DESC_TYPE_MSDU_LINK);430}431432void ath11k_hal_reo_status_queue_stats(struct ath11k_base *ab, u32 *reo_desc,433struct hal_reo_status *status)434{435struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc;436struct hal_reo_get_queue_stats_status *desc =437(struct hal_reo_get_queue_stats_status *)tlv->value;438439status->uniform_hdr.cmd_num =440FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM,441desc->hdr.info0);442status->uniform_hdr.cmd_status =443FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS,444desc->hdr.info0);445446ath11k_dbg(ab, ATH11K_DBG_HAL, "Queue stats status:\n");447ath11k_dbg(ab, ATH11K_DBG_HAL, "header: cmd_num %d status %d\n",448status->uniform_hdr.cmd_num,449status->uniform_hdr.cmd_status);450ath11k_dbg(ab, ATH11K_DBG_HAL, "ssn %ld cur_idx %ld\n",451FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO0_SSN,452desc->info0),453FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO0_CUR_IDX,454desc->info0));455ath11k_dbg(ab, ATH11K_DBG_HAL, "pn = [%08x, %08x, %08x, %08x]\n",456desc->pn[0], desc->pn[1], desc->pn[2], desc->pn[3]);457ath11k_dbg(ab, ATH11K_DBG_HAL,458"last_rx: enqueue_tstamp %08x dequeue_tstamp %08x\n",459desc->last_rx_enqueue_timestamp,460desc->last_rx_dequeue_timestamp);461ath11k_dbg(ab, ATH11K_DBG_HAL,462"rx_bitmap [%08x %08x %08x %08x %08x %08x %08x %08x]\n",463desc->rx_bitmap[0], desc->rx_bitmap[1], desc->rx_bitmap[2],464desc->rx_bitmap[3], desc->rx_bitmap[4], desc->rx_bitmap[5],465desc->rx_bitmap[6], desc->rx_bitmap[7]);466ath11k_dbg(ab, ATH11K_DBG_HAL, "count: cur_mpdu %ld cur_msdu %ld\n",467FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO1_MPDU_COUNT,468desc->info1),469FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO1_MSDU_COUNT,470desc->info1));471ath11k_dbg(ab, ATH11K_DBG_HAL, "fwd_timeout %ld fwd_bar %ld dup_count %ld\n",472FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_TIMEOUT_COUNT,473desc->info2),474FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_FDTB_COUNT,475desc->info2),476FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_DUPLICATE_COUNT,477desc->info2));478ath11k_dbg(ab, ATH11K_DBG_HAL, "frames_in_order %ld bar_rcvd %ld\n",479FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO3_FIO_COUNT,480desc->info3),481FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO3_BAR_RCVD_CNT,482desc->info3));483ath11k_dbg(ab, ATH11K_DBG_HAL, "num_mpdus %d num_msdus %d total_bytes %d\n",484desc->num_mpdu_frames, desc->num_msdu_frames,485desc->total_bytes);486ath11k_dbg(ab, ATH11K_DBG_HAL, "late_rcvd %ld win_jump_2k %ld hole_cnt %ld\n",487FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_LATE_RX_MPDU,488desc->info4),489FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_WINDOW_JMP2K,490desc->info4),491FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_HOLE_COUNT,492desc->info4));493ath11k_dbg(ab, ATH11K_DBG_HAL, "looping count %ld\n",494FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO5_LOOPING_CNT,495desc->info5));496}497498int ath11k_hal_reo_process_status(u8 *reo_desc, u8 *status)499{500struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc;501struct hal_reo_status_hdr *hdr;502503hdr = (struct hal_reo_status_hdr *)tlv->value;504*status = FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, hdr->info0);505506return FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, hdr->info0);507}508509void ath11k_hal_reo_flush_queue_status(struct ath11k_base *ab, u32 *reo_desc,510struct hal_reo_status *status)511{512struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc;513struct hal_reo_flush_queue_status *desc =514(struct hal_reo_flush_queue_status *)tlv->value;515516status->uniform_hdr.cmd_num =517FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM,518desc->hdr.info0);519status->uniform_hdr.cmd_status =520FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS,521desc->hdr.info0);522status->u.flush_queue.err_detected =523FIELD_GET(HAL_REO_FLUSH_QUEUE_INFO0_ERR_DETECTED,524desc->info0);525}526527void ath11k_hal_reo_flush_cache_status(struct ath11k_base *ab, u32 *reo_desc,528struct hal_reo_status *status)529{530struct ath11k_hal *hal = &ab->hal;531struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc;532struct hal_reo_flush_cache_status *desc =533(struct hal_reo_flush_cache_status *)tlv->value;534535status->uniform_hdr.cmd_num =536FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM,537desc->hdr.info0);538status->uniform_hdr.cmd_status =539FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS,540desc->hdr.info0);541542status->u.flush_cache.err_detected =543FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_IS_ERR,544desc->info0);545status->u.flush_cache.err_code =546FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_BLOCK_ERR_CODE,547desc->info0);548if (!status->u.flush_cache.err_code)549hal->avail_blk_resource |= BIT(hal->current_blk_index);550551status->u.flush_cache.cache_controller_flush_status_hit =552FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_STATUS_HIT,553desc->info0);554555status->u.flush_cache.cache_controller_flush_status_desc_type =556FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_DESC_TYPE,557desc->info0);558status->u.flush_cache.cache_controller_flush_status_client_id =559FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_CLIENT_ID,560desc->info0);561status->u.flush_cache.cache_controller_flush_status_err =562FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_ERR,563desc->info0);564status->u.flush_cache.cache_controller_flush_status_cnt =565FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_COUNT,566desc->info0);567}568569void ath11k_hal_reo_unblk_cache_status(struct ath11k_base *ab, u32 *reo_desc,570struct hal_reo_status *status)571{572struct ath11k_hal *hal = &ab->hal;573struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc;574struct hal_reo_unblock_cache_status *desc =575(struct hal_reo_unblock_cache_status *)tlv->value;576577status->uniform_hdr.cmd_num =578FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM,579desc->hdr.info0);580status->uniform_hdr.cmd_status =581FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS,582desc->hdr.info0);583584status->u.unblock_cache.err_detected =585FIELD_GET(HAL_REO_UNBLOCK_CACHE_STATUS_INFO0_IS_ERR,586desc->info0);587status->u.unblock_cache.unblock_type =588FIELD_GET(HAL_REO_UNBLOCK_CACHE_STATUS_INFO0_TYPE,589desc->info0);590591if (!status->u.unblock_cache.err_detected &&592status->u.unblock_cache.unblock_type ==593HAL_REO_STATUS_UNBLOCK_BLOCKING_RESOURCE)594hal->avail_blk_resource &= ~BIT(hal->current_blk_index);595}596597void ath11k_hal_reo_flush_timeout_list_status(struct ath11k_base *ab,598u32 *reo_desc,599struct hal_reo_status *status)600{601struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc;602struct hal_reo_flush_timeout_list_status *desc =603(struct hal_reo_flush_timeout_list_status *)tlv->value;604605status->uniform_hdr.cmd_num =606FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM,607desc->hdr.info0);608status->uniform_hdr.cmd_status =609FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS,610desc->hdr.info0);611612status->u.timeout_list.err_detected =613FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO0_IS_ERR,614desc->info0);615status->u.timeout_list.list_empty =616FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO0_LIST_EMPTY,617desc->info0);618619status->u.timeout_list.release_desc_cnt =620FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO1_REL_DESC_COUNT,621desc->info1);622status->u.timeout_list.fwd_buf_cnt =623FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO1_FWD_BUF_COUNT,624desc->info1);625}626627void ath11k_hal_reo_desc_thresh_reached_status(struct ath11k_base *ab,628u32 *reo_desc,629struct hal_reo_status *status)630{631struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc;632struct hal_reo_desc_thresh_reached_status *desc =633(struct hal_reo_desc_thresh_reached_status *)tlv->value;634635status->uniform_hdr.cmd_num =636FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM,637desc->hdr.info0);638status->uniform_hdr.cmd_status =639FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS,640desc->hdr.info0);641642status->u.desc_thresh_reached.threshold_idx =643FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO0_THRESH_INDEX,644desc->info0);645646status->u.desc_thresh_reached.link_desc_counter0 =647FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO1_LINK_DESC_COUNTER0,648desc->info1);649650status->u.desc_thresh_reached.link_desc_counter1 =651FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO2_LINK_DESC_COUNTER1,652desc->info2);653654status->u.desc_thresh_reached.link_desc_counter2 =655FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO3_LINK_DESC_COUNTER2,656desc->info3);657658status->u.desc_thresh_reached.link_desc_counter_sum =659FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO4_LINK_DESC_COUNTER_SUM,660desc->info4);661}662663void ath11k_hal_reo_update_rx_reo_queue_status(struct ath11k_base *ab,664u32 *reo_desc,665struct hal_reo_status *status)666{667struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc;668struct hal_reo_status_hdr *desc =669(struct hal_reo_status_hdr *)tlv->value;670671status->uniform_hdr.cmd_num =672FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM,673desc->info0);674status->uniform_hdr.cmd_status =675FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS,676desc->info0);677}678679u32 ath11k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid)680{681u32 num_ext_desc;682683if (ba_window_size <= 1) {684if (tid != HAL_DESC_REO_NON_QOS_TID)685num_ext_desc = 1;686else687num_ext_desc = 0;688} else if (ba_window_size <= 105) {689num_ext_desc = 1;690} else if (ba_window_size <= 210) {691num_ext_desc = 2;692} else {693num_ext_desc = 3;694}695696return sizeof(struct hal_rx_reo_queue) +697(num_ext_desc * sizeof(struct hal_rx_reo_queue_ext));698}699700void ath11k_hal_reo_qdesc_setup(void *vaddr, int tid, u32 ba_window_size,701u32 start_seq, enum hal_pn_type type)702{703struct hal_rx_reo_queue *qdesc = vaddr;704struct hal_rx_reo_queue_ext *ext_desc;705706memset(qdesc, 0, sizeof(*qdesc));707708ath11k_hal_reo_set_desc_hdr(&qdesc->desc_hdr, HAL_DESC_REO_OWNED,709HAL_DESC_REO_QUEUE_DESC,710REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_0);711712qdesc->rx_queue_num = FIELD_PREP(HAL_RX_REO_QUEUE_RX_QUEUE_NUMBER, tid);713714qdesc->info0 =715FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_VLD, 1) |716FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_ASSOC_LNK_DESC_COUNTER, 1) |717FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_AC, ath11k_tid_to_ac(tid));718719if (ba_window_size < 1)720ba_window_size = 1;721722if (ba_window_size == 1 && tid != HAL_DESC_REO_NON_QOS_TID)723ba_window_size++;724725if (ba_window_size == 1)726qdesc->info0 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_RETRY, 1);727728qdesc->info0 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_BA_WINDOW_SIZE,729ba_window_size - 1);730switch (type) {731case HAL_PN_TYPE_NONE:732case HAL_PN_TYPE_WAPI_EVEN:733case HAL_PN_TYPE_WAPI_UNEVEN:734break;735case HAL_PN_TYPE_WPA:736qdesc->info0 |=737FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_PN_CHECK, 1) |738FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_PN_SIZE,739HAL_RX_REO_QUEUE_PN_SIZE_48);740break;741}742743/* TODO: Set Ignore ampdu flags based on BA window size and/or744* AMPDU capabilities745*/746qdesc->info0 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_IGNORE_AMPDU_FLG, 1);747748qdesc->info1 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO1_SVLD, 0);749750if (start_seq <= 0xfff)751qdesc->info1 = FIELD_PREP(HAL_RX_REO_QUEUE_INFO1_SSN,752start_seq);753754if (tid == HAL_DESC_REO_NON_QOS_TID)755return;756757ext_desc = qdesc->ext_desc;758759/* TODO: HW queue descriptors are currently allocated for max BA760* window size for all QOS TIDs so that same descriptor can be used761* later when ADDBA request is received. This should be changed to762* allocate HW queue descriptors based on BA window size being763* negotiated (0 for non BA cases), and reallocate when BA window764* size changes and also send WMI message to FW to change the REO765* queue descriptor in Rx peer entry as part of dp_rx_tid_update.766*/767memset(ext_desc, 0, sizeof(*ext_desc));768ath11k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED,769HAL_DESC_REO_QUEUE_EXT_DESC,770REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_1);771ext_desc++;772memset(ext_desc, 0, sizeof(*ext_desc));773ath11k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED,774HAL_DESC_REO_QUEUE_EXT_DESC,775REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2);776ext_desc++;777memset(ext_desc, 0, sizeof(*ext_desc));778ath11k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED,779HAL_DESC_REO_QUEUE_EXT_DESC,780REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3);781}782783void ath11k_hal_reo_init_cmd_ring(struct ath11k_base *ab,784struct hal_srng *srng)785{786struct hal_srng_params params;787struct hal_tlv_hdr *tlv;788struct hal_reo_get_queue_stats *desc;789int i, cmd_num = 1;790int entry_size;791u8 *entry;792793memset(¶ms, 0, sizeof(params));794795entry_size = ath11k_hal_srng_get_entrysize(ab, HAL_REO_CMD);796ath11k_hal_srng_get_params(ab, srng, ¶ms);797entry = (u8 *)params.ring_base_vaddr;798799for (i = 0; i < params.num_entries; i++) {800tlv = (struct hal_tlv_hdr *)entry;801desc = (struct hal_reo_get_queue_stats *)tlv->value;802desc->cmd.info0 =803FIELD_PREP(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, cmd_num++);804entry += entry_size;805}806}807808#define HAL_MAX_UL_MU_USERS 37809static inline void810ath11k_hal_rx_handle_ofdma_info(void *rx_tlv,811struct hal_rx_user_status *rx_user_status)812{813struct hal_rx_ppdu_end_user_stats *ppdu_end_user = rx_tlv;814815rx_user_status->ul_ofdma_user_v0_word0 = __le32_to_cpu(ppdu_end_user->info6);816817rx_user_status->ul_ofdma_user_v0_word1 = __le32_to_cpu(ppdu_end_user->info10);818}819820static inline void821ath11k_hal_rx_populate_byte_count(void *rx_tlv, void *ppduinfo,822struct hal_rx_user_status *rx_user_status)823{824struct hal_rx_ppdu_end_user_stats *ppdu_end_user = rx_tlv;825826rx_user_status->mpdu_ok_byte_count =827FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_OK_BYTE_COUNT,828__le32_to_cpu(ppdu_end_user->info8));829rx_user_status->mpdu_err_byte_count =830FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO9_MPDU_ERR_BYTE_COUNT,831__le32_to_cpu(ppdu_end_user->info9));832}833834static inline void835ath11k_hal_rx_populate_mu_user_info(void *rx_tlv, struct hal_rx_mon_ppdu_info *ppdu_info,836struct hal_rx_user_status *rx_user_status)837{838rx_user_status->ast_index = ppdu_info->ast_index;839rx_user_status->tid = ppdu_info->tid;840rx_user_status->tcp_msdu_count =841ppdu_info->tcp_msdu_count;842rx_user_status->udp_msdu_count =843ppdu_info->udp_msdu_count;844rx_user_status->other_msdu_count =845ppdu_info->other_msdu_count;846rx_user_status->frame_control = ppdu_info->frame_control;847rx_user_status->frame_control_info_valid =848ppdu_info->frame_control_info_valid;849rx_user_status->data_sequence_control_info_valid =850ppdu_info->data_sequence_control_info_valid;851rx_user_status->first_data_seq_ctrl =852ppdu_info->first_data_seq_ctrl;853rx_user_status->preamble_type = ppdu_info->preamble_type;854rx_user_status->ht_flags = ppdu_info->ht_flags;855rx_user_status->vht_flags = ppdu_info->vht_flags;856rx_user_status->he_flags = ppdu_info->he_flags;857rx_user_status->rs_flags = ppdu_info->rs_flags;858859rx_user_status->mpdu_cnt_fcs_ok =860ppdu_info->num_mpdu_fcs_ok;861rx_user_status->mpdu_cnt_fcs_err =862ppdu_info->num_mpdu_fcs_err;863864ath11k_hal_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status);865}866867static u16 ath11k_hal_rx_mpduinfo_get_peerid(struct ath11k_base *ab,868struct hal_rx_mpdu_info *mpdu_info)869{870return ab->hw_params.hw_ops->mpdu_info_get_peerid(mpdu_info);871}872873static enum hal_rx_mon_status874ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,875struct hal_rx_mon_ppdu_info *ppdu_info,876u32 tlv_tag, u8 *tlv_data, u32 userid)877{878u32 info0, info1, value;879u8 he_dcm = 0, he_stbc = 0;880u16 he_gi = 0, he_ltf = 0;881882switch (tlv_tag) {883case HAL_RX_PPDU_START: {884struct hal_rx_ppdu_start *ppdu_start =885(struct hal_rx_ppdu_start *)tlv_data;886887ppdu_info->ppdu_id =888FIELD_GET(HAL_RX_PPDU_START_INFO0_PPDU_ID,889__le32_to_cpu(ppdu_start->info0));890ppdu_info->chan_num = __le32_to_cpu(ppdu_start->chan_num);891ppdu_info->ppdu_ts = __le32_to_cpu(ppdu_start->ppdu_start_ts);892break;893}894case HAL_RX_PPDU_END_USER_STATS: {895struct hal_rx_ppdu_end_user_stats *eu_stats =896(struct hal_rx_ppdu_end_user_stats *)tlv_data;897898info0 = __le32_to_cpu(eu_stats->info0);899info1 = __le32_to_cpu(eu_stats->info1);900901ppdu_info->ast_index =902FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX,903__le32_to_cpu(eu_stats->info2));904ppdu_info->tid =905ffs(FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO7_TID_BITMAP,906__le32_to_cpu(eu_stats->info7))) - 1;907ppdu_info->tcp_msdu_count =908FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT,909__le32_to_cpu(eu_stats->info4));910ppdu_info->udp_msdu_count =911FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO4_UDP_MSDU_CNT,912__le32_to_cpu(eu_stats->info4));913ppdu_info->other_msdu_count =914FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT,915__le32_to_cpu(eu_stats->info5));916ppdu_info->tcp_ack_msdu_count =917FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT,918__le32_to_cpu(eu_stats->info5));919ppdu_info->preamble_type =920FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO1_PKT_TYPE, info1);921ppdu_info->num_mpdu_fcs_ok =922FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO1_MPDU_CNT_FCS_OK,923info1);924ppdu_info->num_mpdu_fcs_err =925FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR,926info0);927switch (ppdu_info->preamble_type) {928case HAL_RX_PREAMBLE_11N:929ppdu_info->ht_flags = 1;930break;931case HAL_RX_PREAMBLE_11AC:932ppdu_info->vht_flags = 1;933break;934case HAL_RX_PREAMBLE_11AX:935ppdu_info->he_flags = 1;936break;937default:938break;939}940941if (userid < HAL_MAX_UL_MU_USERS) {942struct hal_rx_user_status *rxuser_stats =943&ppdu_info->userstats;944945ath11k_hal_rx_handle_ofdma_info(tlv_data, rxuser_stats);946ath11k_hal_rx_populate_mu_user_info(tlv_data, ppdu_info,947rxuser_stats);948}949ppdu_info->userstats.mpdu_fcs_ok_bitmap[0] =950__le32_to_cpu(eu_stats->rsvd1[0]);951ppdu_info->userstats.mpdu_fcs_ok_bitmap[1] =952__le32_to_cpu(eu_stats->rsvd1[1]);953954break;955}956case HAL_RX_PPDU_END_USER_STATS_EXT: {957struct hal_rx_ppdu_end_user_stats_ext *eu_stats =958(struct hal_rx_ppdu_end_user_stats_ext *)tlv_data;959ppdu_info->userstats.mpdu_fcs_ok_bitmap[2] = eu_stats->info1;960ppdu_info->userstats.mpdu_fcs_ok_bitmap[3] = eu_stats->info2;961ppdu_info->userstats.mpdu_fcs_ok_bitmap[4] = eu_stats->info3;962ppdu_info->userstats.mpdu_fcs_ok_bitmap[5] = eu_stats->info4;963ppdu_info->userstats.mpdu_fcs_ok_bitmap[6] = eu_stats->info5;964ppdu_info->userstats.mpdu_fcs_ok_bitmap[7] = eu_stats->info6;965break;966}967case HAL_PHYRX_HT_SIG: {968struct hal_rx_ht_sig_info *ht_sig =969(struct hal_rx_ht_sig_info *)tlv_data;970971info0 = __le32_to_cpu(ht_sig->info0);972info1 = __le32_to_cpu(ht_sig->info1);973974ppdu_info->mcs = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO0_MCS, info0);975ppdu_info->bw = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO0_BW, info0);976ppdu_info->is_stbc = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_STBC,977info1);978ppdu_info->ldpc = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING, info1);979ppdu_info->gi = info1 & HAL_RX_HT_SIG_INFO_INFO1_GI;980981switch (ppdu_info->mcs) {982case 0 ... 7:983ppdu_info->nss = 1;984break;985case 8 ... 15:986ppdu_info->nss = 2;987break;988case 16 ... 23:989ppdu_info->nss = 3;990break;991case 24 ... 31:992ppdu_info->nss = 4;993break;994}995996if (ppdu_info->nss > 1)997ppdu_info->mcs = ppdu_info->mcs % 8;998999ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;1000break;1001}1002case HAL_PHYRX_L_SIG_B: {1003struct hal_rx_lsig_b_info *lsigb =1004(struct hal_rx_lsig_b_info *)tlv_data;10051006ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_B_INFO_INFO0_RATE,1007__le32_to_cpu(lsigb->info0));1008ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;1009break;1010}1011case HAL_PHYRX_L_SIG_A: {1012struct hal_rx_lsig_a_info *lsiga =1013(struct hal_rx_lsig_a_info *)tlv_data;10141015ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_A_INFO_INFO0_RATE,1016__le32_to_cpu(lsiga->info0));1017ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;1018break;1019}1020case HAL_PHYRX_VHT_SIG_A: {1021struct hal_rx_vht_sig_a_info *vht_sig =1022(struct hal_rx_vht_sig_a_info *)tlv_data;1023u32 nsts;1024u32 group_id;1025u8 gi_setting;10261027info0 = __le32_to_cpu(vht_sig->info0);1028info1 = __le32_to_cpu(vht_sig->info1);10291030ppdu_info->ldpc = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING,1031info1);1032ppdu_info->mcs = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_MCS,1033info1);1034gi_setting = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_GI_SETTING,1035info1);1036switch (gi_setting) {1037case HAL_RX_VHT_SIG_A_NORMAL_GI:1038ppdu_info->gi = HAL_RX_GI_0_8_US;1039break;1040case HAL_RX_VHT_SIG_A_SHORT_GI:1041case HAL_RX_VHT_SIG_A_SHORT_GI_AMBIGUITY:1042ppdu_info->gi = HAL_RX_GI_0_4_US;1043break;1044}10451046ppdu_info->is_stbc = info0 & HAL_RX_VHT_SIG_A_INFO_INFO0_STBC;1047nsts = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO0_NSTS, info0);1048if (ppdu_info->is_stbc && nsts > 0)1049nsts = ((nsts + 1) >> 1) - 1;10501051ppdu_info->nss = (nsts & VHT_SIG_SU_NSS_MASK) + 1;1052ppdu_info->bw = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO0_BW,1053info0);1054ppdu_info->beamformed = info1 &1055HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED;1056group_id = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO0_GROUP_ID,1057info0);1058if (group_id == 0 || group_id == 63)1059ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;1060else1061ppdu_info->reception_type =1062HAL_RX_RECEPTION_TYPE_MU_MIMO;1063ppdu_info->vht_flag_values5 = group_id;1064ppdu_info->vht_flag_values3[0] = (((ppdu_info->mcs) << 4) |1065ppdu_info->nss);1066ppdu_info->vht_flag_values2 = ppdu_info->bw;1067ppdu_info->vht_flag_values4 =1068FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING, info1);1069break;1070}1071case HAL_PHYRX_HE_SIG_A_SU: {1072struct hal_rx_he_sig_a_su_info *he_sig_a =1073(struct hal_rx_he_sig_a_su_info *)tlv_data;10741075ppdu_info->he_flags = 1;1076info0 = __le32_to_cpu(he_sig_a->info0);1077info1 = __le32_to_cpu(he_sig_a->info1);10781079value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_FORMAT_IND, info0);10801081if (value == 0)1082ppdu_info->he_data1 = IEEE80211_RADIOTAP_HE_DATA1_FORMAT_TRIG;1083else1084ppdu_info->he_data1 = IEEE80211_RADIOTAP_HE_DATA1_FORMAT_SU;10851086ppdu_info->he_data1 |=1087IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN |1088IEEE80211_RADIOTAP_HE_DATA1_BEAM_CHANGE_KNOWN |1089IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN |1090IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |1091IEEE80211_RADIOTAP_HE_DATA1_DATA_DCM_KNOWN |1092IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN |1093IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN |1094IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN |1095IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN |1096IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN;10971098ppdu_info->he_data2 |=1099IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN |1100IEEE80211_RADIOTAP_HE_DATA2_TXBF_KNOWN |1101IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN |1102IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN |1103IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN |1104IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN |1105IEEE80211_RADIOTAP_HE_DATA2_MIDAMBLE_KNOWN;11061107value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_BSS_COLOR, info0);1108ppdu_info->he_data3 =1109FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR, value);1110value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_BEAM_CHANGE, info0);1111ppdu_info->he_data3 |=1112FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_BEAM_CHANGE, value);1113value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_DL_UL_FLAG, info0);1114ppdu_info->he_data3 |=1115FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_UL_DL, value);1116value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS, info0);1117ppdu_info->mcs = value;1118ppdu_info->he_data3 |=1119FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_MCS, value);11201121he_dcm = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM, info0);1122ppdu_info->dcm = he_dcm;1123ppdu_info->he_data3 |=1124FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_DCM, he_dcm);1125value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING, info1);1126ppdu_info->ldpc = (value == HAL_RX_SU_MU_CODING_LDPC) ? 1 : 0;1127ppdu_info->he_data3 |=1128FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_CODING, value);1129value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_LDPC_EXTRA, info1);1130ppdu_info->he_data3 |=1131FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG, value);1132he_stbc = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC, info1);1133ppdu_info->is_stbc = he_stbc;1134ppdu_info->he_data3 |=1135FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_STBC, he_stbc);11361137/* data4 */1138value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_SPATIAL_REUSE, info0);1139ppdu_info->he_data4 =1140FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE, value);11411142/* data5 */1143value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW, info0);1144ppdu_info->bw = value;1145ppdu_info->he_data5 =1146FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC, value);1147value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE, info0);1148switch (value) {1149case 0:1150he_gi = HE_GI_0_8;1151he_ltf = HE_LTF_1_X;1152break;1153case 1:1154he_gi = HE_GI_0_8;1155he_ltf = HE_LTF_2_X;1156break;1157case 2:1158he_gi = HE_GI_1_6;1159he_ltf = HE_LTF_2_X;1160break;1161case 3:1162if (he_dcm && he_stbc) {1163he_gi = HE_GI_0_8;1164he_ltf = HE_LTF_4_X;1165} else {1166he_gi = HE_GI_3_2;1167he_ltf = HE_LTF_4_X;1168}1169break;1170}1171ppdu_info->gi = he_gi;1172he_gi = (he_gi != 0) ? he_gi - 1 : 0;1173ppdu_info->he_data5 |= FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_GI, he_gi);1174ppdu_info->ltf_size = he_ltf;1175ppdu_info->he_data5 |=1176FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE,1177(he_ltf == HE_LTF_4_X) ? he_ltf - 1 : he_ltf);11781179value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS, info0);1180ppdu_info->he_data5 |=1181FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS, value);11821183value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_FACTOR, info1);1184ppdu_info->he_data5 |=1185FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD, value);11861187value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF, info1);1188ppdu_info->beamformed = value;1189ppdu_info->he_data5 |=1190FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_TXBF, value);1191value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_PE_DISAM, info1);1192ppdu_info->he_data5 |=1193FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG, value);11941195/* data6 */1196value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS, info0);1197value++;1198ppdu_info->nss = value;1199ppdu_info->he_data6 =1200FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_NSTS, value);1201value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_DOPPLER_IND, info1);1202ppdu_info->he_data6 |=1203FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_DOPPLER, value);1204value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXOP_DURATION, info1);1205ppdu_info->he_data6 |=1206FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_TXOP, value);12071208ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;1209break;1210}1211case HAL_PHYRX_HE_SIG_A_MU_DL: {1212struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl =1213(struct hal_rx_he_sig_a_mu_dl_info *)tlv_data;12141215info0 = __le32_to_cpu(he_sig_a_mu_dl->info0);1216info1 = __le32_to_cpu(he_sig_a_mu_dl->info1);12171218ppdu_info->he_mu_flags = 1;12191220ppdu_info->he_data1 = IEEE80211_RADIOTAP_HE_DATA1_FORMAT_MU;1221ppdu_info->he_data1 |=1222IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN |1223IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN |1224IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN |1225IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN |1226IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN |1227IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN;12281229ppdu_info->he_data2 =1230IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN |1231IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN |1232IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN |1233IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN |1234IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN |1235IEEE80211_RADIOTAP_HE_DATA2_MIDAMBLE_KNOWN;12361237/*data3*/1238value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_BSS_COLOR, info0);1239ppdu_info->he_data3 =1240FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR, value);12411242value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_UL_FLAG, info0);1243ppdu_info->he_data3 |=1244FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_UL_DL, value);12451246value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_LDPC_EXTRA, info1);1247ppdu_info->he_data3 |=1248FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG, value);12491250value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_STBC, info1);1251he_stbc = value;1252ppdu_info->he_data3 |=1253FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_STBC, value);12541255/*data4*/1256value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_SPATIAL_REUSE, info0);1257ppdu_info->he_data4 =1258FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE, value);12591260/*data5*/1261value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_TRANSMIT_BW, info0);1262ppdu_info->bw = value;1263ppdu_info->he_data5 =1264FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC, value);12651266value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_CP_LTF_SIZE, info0);1267switch (value) {1268case 0:1269he_gi = HE_GI_0_8;1270he_ltf = HE_LTF_4_X;1271break;1272case 1:1273he_gi = HE_GI_0_8;1274he_ltf = HE_LTF_2_X;1275break;1276case 2:1277he_gi = HE_GI_1_6;1278he_ltf = HE_LTF_2_X;1279break;1280case 3:1281he_gi = HE_GI_3_2;1282he_ltf = HE_LTF_4_X;1283break;1284}1285ppdu_info->gi = he_gi;1286he_gi = (he_gi != 0) ? he_gi - 1 : 0;1287ppdu_info->he_data5 |= FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_GI, he_gi);1288ppdu_info->ltf_size = he_ltf;1289ppdu_info->he_data5 |=1290FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE,1291(he_ltf == HE_LTF_4_X) ? he_ltf - 1 : he_ltf);12921293value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_NUM_LTF_SYMB, info1);1294ppdu_info->he_data5 |=1295FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS, value);12961297value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_PKT_EXT_FACTOR,1298info1);1299ppdu_info->he_data5 |=1300FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD, value);13011302value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_PKT_EXT_PE_DISAM,1303info1);1304ppdu_info->he_data5 |=1305FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG, value);13061307/*data6*/1308value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_DOPPLER_INDICATION,1309info0);1310ppdu_info->he_data6 |=1311FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_DOPPLER, value);13121313value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_TXOP_DURATION, info1);1314ppdu_info->he_data6 |=1315FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_TXOP, value);13161317/* HE-MU Flags */1318/* HE-MU-flags1 */1319ppdu_info->he_flags1 =1320IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS_KNOWN |1321IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM_KNOWN |1322IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_COMP_KNOWN |1323IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN |1324IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_RU_KNOWN;13251326value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_MCS_OF_SIGB, info0);1327ppdu_info->he_flags1 |=1328FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS_KNOWN,1329value);1330value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_DCM_OF_SIGB, info0);1331ppdu_info->he_flags1 |=1332FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM_KNOWN,1333value);13341335/* HE-MU-flags2 */1336ppdu_info->he_flags2 =1337IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN;13381339value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_TRANSMIT_BW, info0);1340ppdu_info->he_flags2 |=1341FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW,1342value);1343value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_COMP_MODE_SIGB, info0);1344ppdu_info->he_flags2 |=1345FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP, value);1346value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_NUM_SIGB_SYMB, info0);1347value = value - 1;1348ppdu_info->he_flags2 |=1349FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS,1350value);13511352ppdu_info->is_stbc = info1 &1353HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_STBC;1354ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO;1355break;1356}1357case HAL_PHYRX_HE_SIG_B1_MU: {1358struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu =1359(struct hal_rx_he_sig_b1_mu_info *)tlv_data;1360u16 ru_tones;13611362info0 = __le32_to_cpu(he_sig_b1_mu->info0);13631364ru_tones = FIELD_GET(HAL_RX_HE_SIG_B1_MU_INFO_INFO0_RU_ALLOCATION,1365info0);1366ppdu_info->ru_alloc =1367ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(ru_tones);1368ppdu_info->he_RU[0] = ru_tones;1369ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO;1370break;1371}1372case HAL_PHYRX_HE_SIG_B2_MU: {1373struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu =1374(struct hal_rx_he_sig_b2_mu_info *)tlv_data;13751376info0 = __le32_to_cpu(he_sig_b2_mu->info0);13771378ppdu_info->he_data1 |= IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |1379IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN;13801381ppdu_info->mcs =1382FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS, info0);1383ppdu_info->he_data3 |=1384FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_MCS, ppdu_info->mcs);13851386value = FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING, info0);1387ppdu_info->ldpc = value;1388ppdu_info->he_data3 |=1389FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_CODING, value);13901391value = FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_ID, info0);1392ppdu_info->he_data4 |=1393FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA4_MU_STA_ID, value);13941395ppdu_info->nss =1396FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS, info0) + 1;1397break;1398}1399case HAL_PHYRX_HE_SIG_B2_OFDMA: {1400struct hal_rx_he_sig_b2_ofdma_info *he_sig_b2_ofdma =1401(struct hal_rx_he_sig_b2_ofdma_info *)tlv_data;14021403info0 = __le32_to_cpu(he_sig_b2_ofdma->info0);14041405ppdu_info->he_data1 |=1406IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |1407IEEE80211_RADIOTAP_HE_DATA1_DATA_DCM_KNOWN |1408IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN;14091410/* HE-data2 */1411ppdu_info->he_data2 |= IEEE80211_RADIOTAP_HE_DATA2_TXBF_KNOWN;14121413ppdu_info->mcs =1414FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS,1415info0);1416ppdu_info->he_data3 |=1417FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_MCS, ppdu_info->mcs);14181419value = FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_DCM, info0);1420he_dcm = value;1421ppdu_info->he_data3 |=1422FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_DCM, value);14231424value = FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING, info0);1425ppdu_info->ldpc = value;1426ppdu_info->he_data3 |=1427FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_CODING, value);14281429/* HE-data4 */1430value = FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_ID, info0);1431ppdu_info->he_data4 |=1432FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA4_MU_STA_ID, value);14331434ppdu_info->nss =1435FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS,1436info0) + 1;1437ppdu_info->beamformed =1438info0 & HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF;1439ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA;1440break;1441}1442case HAL_PHYRX_RSSI_LEGACY: {1443int i;1444bool db2dbm = test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT,1445ab->wmi_ab.svc_map);1446struct hal_rx_phyrx_rssi_legacy_info *rssi =1447(struct hal_rx_phyrx_rssi_legacy_info *)tlv_data;14481449/* TODO: Please note that the combined rssi will not be accurate1450* in MU case. Rssi in MU needs to be retrieved from1451* PHYRX_OTHER_RECEIVE_INFO TLV.1452*/1453ppdu_info->rssi_comb =1454FIELD_GET(HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RSSI_COMB,1455__le32_to_cpu(rssi->info0));14561457if (db2dbm) {1458for (i = 0; i < ARRAY_SIZE(rssi->preamble); i++) {1459ppdu_info->rssi_chain_pri20[i] =1460le32_get_bits(rssi->preamble[i].rssi_2040,1461HAL_RX_PHYRX_RSSI_PREAMBLE_PRI20);1462}1463}1464break;1465}1466case HAL_RX_MPDU_START: {1467struct hal_rx_mpdu_info *mpdu_info =1468(struct hal_rx_mpdu_info *)tlv_data;1469u16 peer_id;14701471peer_id = ath11k_hal_rx_mpduinfo_get_peerid(ab, mpdu_info);1472if (peer_id)1473ppdu_info->peer_id = peer_id;1474break;1475}1476case HAL_RXPCU_PPDU_END_INFO: {1477struct hal_rx_ppdu_end_duration *ppdu_rx_duration =1478(struct hal_rx_ppdu_end_duration *)tlv_data;1479ppdu_info->rx_duration =1480FIELD_GET(HAL_RX_PPDU_END_DURATION,1481__le32_to_cpu(ppdu_rx_duration->info0));1482ppdu_info->tsft = __le32_to_cpu(ppdu_rx_duration->rsvd0[1]);1483ppdu_info->tsft = (ppdu_info->tsft << 32) |1484__le32_to_cpu(ppdu_rx_duration->rsvd0[0]);1485break;1486}1487case HAL_DUMMY:1488return HAL_RX_MON_STATUS_BUF_DONE;1489case HAL_RX_PPDU_END_STATUS_DONE:1490case 0:1491return HAL_RX_MON_STATUS_PPDU_DONE;1492default:1493break;1494}14951496return HAL_RX_MON_STATUS_PPDU_NOT_DONE;1497}14981499enum hal_rx_mon_status1500ath11k_hal_rx_parse_mon_status(struct ath11k_base *ab,1501struct hal_rx_mon_ppdu_info *ppdu_info,1502struct sk_buff *skb)1503{1504struct hal_tlv_hdr *tlv;1505enum hal_rx_mon_status hal_status = HAL_RX_MON_STATUS_BUF_DONE;1506u16 tlv_tag;1507u16 tlv_len;1508u32 tlv_userid = 0;1509u8 *ptr = skb->data;15101511do {1512tlv = (struct hal_tlv_hdr *)ptr;1513tlv_tag = FIELD_GET(HAL_TLV_HDR_TAG, tlv->tl);1514tlv_len = FIELD_GET(HAL_TLV_HDR_LEN, tlv->tl);1515tlv_userid = FIELD_GET(HAL_TLV_USR_ID, tlv->tl);1516ptr += sizeof(*tlv);15171518/* The actual length of PPDU_END is the combined length of many PHY1519* TLVs that follow. Skip the TLV header and1520* rx_rxpcu_classification_overview that follows the header to get to1521* next TLV.1522*/1523if (tlv_tag == HAL_RX_PPDU_END)1524tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview);15251526hal_status = ath11k_hal_rx_parse_mon_status_tlv(ab, ppdu_info,1527tlv_tag, ptr, tlv_userid);1528ptr += tlv_len;1529ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN);15301531if ((ptr - skb->data) >= DP_RX_BUFFER_SIZE)1532break;1533} while (hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE);15341535return hal_status;1536}15371538void ath11k_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr,1539u32 *sw_cookie, void **pp_buf_addr,1540u8 *rbm, u32 *msdu_cnt)1541{1542struct hal_reo_entrance_ring *reo_ent_ring = rx_desc;1543struct ath11k_buffer_addr *buf_addr_info;1544struct rx_mpdu_desc *rx_mpdu_desc_info_details;15451546rx_mpdu_desc_info_details =1547(struct rx_mpdu_desc *)&reo_ent_ring->rx_mpdu_info;15481549*msdu_cnt = FIELD_GET(RX_MPDU_DESC_INFO0_MSDU_COUNT,1550rx_mpdu_desc_info_details->info0);15511552buf_addr_info = (struct ath11k_buffer_addr *)&reo_ent_ring->buf_addr_info;15531554*paddr = (((u64)FIELD_GET(BUFFER_ADDR_INFO1_ADDR,1555buf_addr_info->info1)) << 32) |1556FIELD_GET(BUFFER_ADDR_INFO0_ADDR,1557buf_addr_info->info0);15581559*sw_cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,1560buf_addr_info->info1);1561*rbm = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR,1562buf_addr_info->info1);15631564*pp_buf_addr = (void *)buf_addr_info;1565}15661567void1568ath11k_hal_rx_sw_mon_ring_buf_paddr_get(void *rx_desc,1569struct hal_sw_mon_ring_entries *sw_mon_entries)1570{1571struct hal_sw_monitor_ring *sw_mon_ring = rx_desc;1572struct ath11k_buffer_addr *buf_addr_info;1573struct ath11k_buffer_addr *status_buf_addr_info;1574struct rx_mpdu_desc *rx_mpdu_desc_info_details;15751576rx_mpdu_desc_info_details = &sw_mon_ring->rx_mpdu_info;15771578sw_mon_entries->msdu_cnt = FIELD_GET(RX_MPDU_DESC_INFO0_MSDU_COUNT,1579rx_mpdu_desc_info_details->info0);15801581buf_addr_info = &sw_mon_ring->buf_addr_info;1582status_buf_addr_info = &sw_mon_ring->status_buf_addr_info;15831584sw_mon_entries->mon_dst_paddr = (((u64)FIELD_GET(BUFFER_ADDR_INFO1_ADDR,1585buf_addr_info->info1)) << 32) |1586FIELD_GET(BUFFER_ADDR_INFO0_ADDR,1587buf_addr_info->info0);15881589sw_mon_entries->mon_status_paddr =1590(((u64)FIELD_GET(BUFFER_ADDR_INFO1_ADDR,1591status_buf_addr_info->info1)) << 32) |1592FIELD_GET(BUFFER_ADDR_INFO0_ADDR,1593status_buf_addr_info->info0);15941595sw_mon_entries->mon_dst_sw_cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,1596buf_addr_info->info1);15971598sw_mon_entries->mon_status_sw_cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,1599status_buf_addr_info->info1);16001601sw_mon_entries->status_buf_count = FIELD_GET(HAL_SW_MON_RING_INFO0_STATUS_BUF_CNT,1602sw_mon_ring->info0);16031604sw_mon_entries->dst_buf_addr_info = buf_addr_info;1605sw_mon_entries->status_buf_addr_info = status_buf_addr_info;16061607sw_mon_entries->ppdu_id =1608FIELD_GET(HAL_SW_MON_RING_INFO1_PHY_PPDU_ID, sw_mon_ring->info1);1609}161016111612