18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause-Clear 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include "debug.h" 78c2ecf20Sopenharmony_ci#include "hal.h" 88c2ecf20Sopenharmony_ci#include "hal_tx.h" 98c2ecf20Sopenharmony_ci#include "hal_rx.h" 108c2ecf20Sopenharmony_ci#include "hal_desc.h" 118c2ecf20Sopenharmony_ci#include "hif.h" 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_cistatic void ath11k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, 148c2ecf20Sopenharmony_ci u8 owner, u8 buffer_type, u32 magic) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci hdr->info0 = FIELD_PREP(HAL_DESC_HDR_INFO0_OWNER, owner) | 178c2ecf20Sopenharmony_ci FIELD_PREP(HAL_DESC_HDR_INFO0_BUF_TYPE, buffer_type); 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci /* Magic pattern in reserved bits for debugging */ 208c2ecf20Sopenharmony_ci hdr->info0 |= FIELD_PREP(HAL_DESC_HDR_INFO0_DBG_RESERVED, magic); 218c2ecf20Sopenharmony_ci} 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistatic int ath11k_hal_reo_cmd_queue_stats(struct hal_tlv_hdr *tlv, 248c2ecf20Sopenharmony_ci struct ath11k_hal_reo_cmd *cmd) 258c2ecf20Sopenharmony_ci{ 268c2ecf20Sopenharmony_ci struct hal_reo_get_queue_stats *desc; 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci tlv->tl = FIELD_PREP(HAL_TLV_HDR_TAG, HAL_REO_GET_QUEUE_STATS) | 298c2ecf20Sopenharmony_ci FIELD_PREP(HAL_TLV_HDR_LEN, sizeof(*desc)); 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci desc = (struct hal_reo_get_queue_stats *)tlv->value; 328c2ecf20Sopenharmony_ci memset(&desc->queue_addr_lo, 0, 338c2ecf20Sopenharmony_ci (sizeof(*desc) - sizeof(struct hal_reo_cmd_hdr))); 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci desc->cmd.info0 &= ~HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED; 368c2ecf20Sopenharmony_ci if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS) 378c2ecf20Sopenharmony_ci desc->cmd.info0 |= HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci desc->queue_addr_lo = cmd->addr_lo; 408c2ecf20Sopenharmony_ci desc->info0 = FIELD_PREP(HAL_REO_GET_QUEUE_STATS_INFO0_QUEUE_ADDR_HI, 418c2ecf20Sopenharmony_ci cmd->addr_hi); 428c2ecf20Sopenharmony_ci if (cmd->flag & HAL_REO_CMD_FLG_STATS_CLEAR) 438c2ecf20Sopenharmony_ci desc->info0 |= HAL_REO_GET_QUEUE_STATS_INFO0_CLEAR_STATS; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci return FIELD_GET(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, desc->cmd.info0); 468c2ecf20Sopenharmony_ci} 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_cistatic int ath11k_hal_reo_cmd_flush_cache(struct ath11k_hal *hal, struct hal_tlv_hdr *tlv, 498c2ecf20Sopenharmony_ci struct ath11k_hal_reo_cmd *cmd) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci struct hal_reo_flush_cache *desc; 528c2ecf20Sopenharmony_ci u8 avail_slot = ffz(hal->avail_blk_resource); 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER) { 558c2ecf20Sopenharmony_ci if (avail_slot >= HAL_MAX_AVAIL_BLK_RES) 568c2ecf20Sopenharmony_ci return -ENOSPC; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci hal->current_blk_index = avail_slot; 598c2ecf20Sopenharmony_ci } 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci tlv->tl = FIELD_PREP(HAL_TLV_HDR_TAG, HAL_REO_FLUSH_CACHE) | 628c2ecf20Sopenharmony_ci FIELD_PREP(HAL_TLV_HDR_LEN, sizeof(*desc)); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci desc = (struct hal_reo_flush_cache *)tlv->value; 658c2ecf20Sopenharmony_ci memset(&desc->cache_addr_lo, 0, 668c2ecf20Sopenharmony_ci (sizeof(*desc) - sizeof(struct hal_reo_cmd_hdr))); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci desc->cmd.info0 &= ~HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED; 698c2ecf20Sopenharmony_ci if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS) 708c2ecf20Sopenharmony_ci desc->cmd.info0 |= HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci desc->cache_addr_lo = cmd->addr_lo; 738c2ecf20Sopenharmony_ci desc->info0 = FIELD_PREP(HAL_REO_FLUSH_CACHE_INFO0_CACHE_ADDR_HI, 748c2ecf20Sopenharmony_ci cmd->addr_hi); 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS) 778c2ecf20Sopenharmony_ci desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_FWD_ALL_MPDUS; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER) { 808c2ecf20Sopenharmony_ci desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_BLOCK_CACHE_USAGE; 818c2ecf20Sopenharmony_ci desc->info0 |= 828c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_FLUSH_CACHE_INFO0_BLOCK_RESRC_IDX, 838c2ecf20Sopenharmony_ci avail_slot); 848c2ecf20Sopenharmony_ci } 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_NO_INVAL) 878c2ecf20Sopenharmony_ci desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_FLUSH_WO_INVALIDATE; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_ALL) 908c2ecf20Sopenharmony_ci desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_FLUSH_ALL; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci return FIELD_GET(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, desc->cmd.info0); 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_cistatic int ath11k_hal_reo_cmd_update_rx_queue(struct hal_tlv_hdr *tlv, 968c2ecf20Sopenharmony_ci struct ath11k_hal_reo_cmd *cmd) 978c2ecf20Sopenharmony_ci{ 988c2ecf20Sopenharmony_ci struct hal_reo_update_rx_queue *desc; 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci tlv->tl = FIELD_PREP(HAL_TLV_HDR_TAG, HAL_REO_UPDATE_RX_REO_QUEUE) | 1018c2ecf20Sopenharmony_ci FIELD_PREP(HAL_TLV_HDR_LEN, sizeof(*desc)); 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci desc = (struct hal_reo_update_rx_queue *)tlv->value; 1048c2ecf20Sopenharmony_ci memset(&desc->queue_addr_lo, 0, 1058c2ecf20Sopenharmony_ci (sizeof(*desc) - sizeof(struct hal_reo_cmd_hdr))); 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci desc->cmd.info0 &= ~HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED; 1088c2ecf20Sopenharmony_ci if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS) 1098c2ecf20Sopenharmony_ci desc->cmd.info0 |= HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci desc->queue_addr_lo = cmd->addr_lo; 1128c2ecf20Sopenharmony_ci desc->info0 = 1138c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_QUEUE_ADDR_HI, 1148c2ecf20Sopenharmony_ci cmd->addr_hi) | 1158c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_RX_QUEUE_NUM, 1168c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_RX_QUEUE_NUM)) | 1178c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_VLD, 1188c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_VLD)) | 1198c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_ASSOC_LNK_DESC_CNT, 1208c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_ALDC)) | 1218c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_DIS_DUP_DETECTION, 1228c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_DIS_DUP_DETECTION)) | 1238c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SOFT_REORDER_EN, 1248c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_SOFT_REORDER_EN)) | 1258c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_AC, 1268c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_AC)) | 1278c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_BAR, 1288c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_BAR)) | 1298c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_RETRY, 1308c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_RETRY)) | 1318c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_CHECK_2K_MODE, 1328c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_CHECK_2K_MODE)) | 1338c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_OOR_MODE, 1348c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_OOR_MODE)) | 1358c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_BA_WINDOW_SIZE, 1368c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_BA_WINDOW_SIZE)) | 1378c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_CHECK, 1388c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_CHECK)) | 1398c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_EVEN_PN, 1408c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_EVEN_PN)) | 1418c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_UNEVEN_PN, 1428c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_UNEVEN_PN)) | 1438c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_HANDLE_ENABLE, 1448c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_HANDLE_ENABLE)) | 1458c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_SIZE, 1468c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_SIZE)) | 1478c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_IGNORE_AMPDU_FLG, 1488c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_IGNORE_AMPDU_FLG)) | 1498c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SVLD, 1508c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_SVLD)) | 1518c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SSN, 1528c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_SSN)) | 1538c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SEQ_2K_ERR, 1548c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_SEQ_2K_ERR)) | 1558c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_VALID, 1568c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_VALID)) | 1578c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN, 1588c2ecf20Sopenharmony_ci !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN)); 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci desc->info1 = 1618c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_RX_QUEUE_NUMBER, 1628c2ecf20Sopenharmony_ci cmd->rx_queue_num) | 1638c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_VLD, 1648c2ecf20Sopenharmony_ci !!(cmd->upd1 & HAL_REO_CMD_UPD1_VLD)) | 1658c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_ASSOC_LNK_DESC_COUNTER, 1668c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_CMD_UPD1_ALDC, cmd->upd1)) | 1678c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_DIS_DUP_DETECTION, 1688c2ecf20Sopenharmony_ci !!(cmd->upd1 & HAL_REO_CMD_UPD1_DIS_DUP_DETECTION)) | 1698c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_SOFT_REORDER_EN, 1708c2ecf20Sopenharmony_ci !!(cmd->upd1 & HAL_REO_CMD_UPD1_SOFT_REORDER_EN)) | 1718c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_AC, 1728c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_CMD_UPD1_AC, cmd->upd1)) | 1738c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_BAR, 1748c2ecf20Sopenharmony_ci !!(cmd->upd1 & HAL_REO_CMD_UPD1_BAR)) | 1758c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_CHECK_2K_MODE, 1768c2ecf20Sopenharmony_ci !!(cmd->upd1 & HAL_REO_CMD_UPD1_CHECK_2K_MODE)) | 1778c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_RETRY, 1788c2ecf20Sopenharmony_ci !!(cmd->upd1 & HAL_REO_CMD_UPD1_RETRY)) | 1798c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_OOR_MODE, 1808c2ecf20Sopenharmony_ci !!(cmd->upd1 & HAL_REO_CMD_UPD1_OOR_MODE)) | 1818c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_PN_CHECK, 1828c2ecf20Sopenharmony_ci !!(cmd->upd1 & HAL_REO_CMD_UPD1_PN_CHECK)) | 1838c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_EVEN_PN, 1848c2ecf20Sopenharmony_ci !!(cmd->upd1 & HAL_REO_CMD_UPD1_EVEN_PN)) | 1858c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_UNEVEN_PN, 1868c2ecf20Sopenharmony_ci !!(cmd->upd1 & HAL_REO_CMD_UPD1_UNEVEN_PN)) | 1878c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_PN_HANDLE_ENABLE, 1888c2ecf20Sopenharmony_ci !!(cmd->upd1 & HAL_REO_CMD_UPD1_PN_HANDLE_ENABLE)) | 1898c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_IGNORE_AMPDU_FLG, 1908c2ecf20Sopenharmony_ci !!(cmd->upd1 & HAL_REO_CMD_UPD1_IGNORE_AMPDU_FLG)); 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci if (cmd->pn_size == 24) 1938c2ecf20Sopenharmony_ci cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_24; 1948c2ecf20Sopenharmony_ci else if (cmd->pn_size == 48) 1958c2ecf20Sopenharmony_ci cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_48; 1968c2ecf20Sopenharmony_ci else if (cmd->pn_size == 128) 1978c2ecf20Sopenharmony_ci cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_128; 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci if (cmd->ba_window_size < 1) 2008c2ecf20Sopenharmony_ci cmd->ba_window_size = 1; 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci if (cmd->ba_window_size == 1) 2038c2ecf20Sopenharmony_ci cmd->ba_window_size++; 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci desc->info2 = 2068c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_BA_WINDOW_SIZE, 2078c2ecf20Sopenharmony_ci cmd->ba_window_size - 1) | 2088c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_PN_SIZE, cmd->pn_size) | 2098c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_SVLD, 2108c2ecf20Sopenharmony_ci !!(cmd->upd2 & HAL_REO_CMD_UPD2_SVLD)) | 2118c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_SSN, 2128c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_CMD_UPD2_SSN, cmd->upd2)) | 2138c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_SEQ_2K_ERR, 2148c2ecf20Sopenharmony_ci !!(cmd->upd2 & HAL_REO_CMD_UPD2_SEQ_2K_ERR)) | 2158c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_PN_ERR, 2168c2ecf20Sopenharmony_ci !!(cmd->upd2 & HAL_REO_CMD_UPD2_PN_ERR)); 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci return FIELD_GET(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, desc->cmd.info0); 2198c2ecf20Sopenharmony_ci} 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ciint ath11k_hal_reo_cmd_send(struct ath11k_base *ab, struct hal_srng *srng, 2228c2ecf20Sopenharmony_ci enum hal_reo_cmd_type type, 2238c2ecf20Sopenharmony_ci struct ath11k_hal_reo_cmd *cmd) 2248c2ecf20Sopenharmony_ci{ 2258c2ecf20Sopenharmony_ci struct hal_tlv_hdr *reo_desc; 2268c2ecf20Sopenharmony_ci int ret; 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci spin_lock_bh(&srng->lock); 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci ath11k_hal_srng_access_begin(ab, srng); 2318c2ecf20Sopenharmony_ci reo_desc = (struct hal_tlv_hdr *)ath11k_hal_srng_src_get_next_entry(ab, srng); 2328c2ecf20Sopenharmony_ci if (!reo_desc) { 2338c2ecf20Sopenharmony_ci ret = -ENOBUFS; 2348c2ecf20Sopenharmony_ci goto out; 2358c2ecf20Sopenharmony_ci } 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci switch (type) { 2388c2ecf20Sopenharmony_ci case HAL_REO_CMD_GET_QUEUE_STATS: 2398c2ecf20Sopenharmony_ci ret = ath11k_hal_reo_cmd_queue_stats(reo_desc, cmd); 2408c2ecf20Sopenharmony_ci break; 2418c2ecf20Sopenharmony_ci case HAL_REO_CMD_FLUSH_CACHE: 2428c2ecf20Sopenharmony_ci ret = ath11k_hal_reo_cmd_flush_cache(&ab->hal, reo_desc, cmd); 2438c2ecf20Sopenharmony_ci break; 2448c2ecf20Sopenharmony_ci case HAL_REO_CMD_UPDATE_RX_QUEUE: 2458c2ecf20Sopenharmony_ci ret = ath11k_hal_reo_cmd_update_rx_queue(reo_desc, cmd); 2468c2ecf20Sopenharmony_ci break; 2478c2ecf20Sopenharmony_ci case HAL_REO_CMD_FLUSH_QUEUE: 2488c2ecf20Sopenharmony_ci case HAL_REO_CMD_UNBLOCK_CACHE: 2498c2ecf20Sopenharmony_ci case HAL_REO_CMD_FLUSH_TIMEOUT_LIST: 2508c2ecf20Sopenharmony_ci ath11k_warn(ab, "Unsupported reo command %d\n", type); 2518c2ecf20Sopenharmony_ci ret = -ENOTSUPP; 2528c2ecf20Sopenharmony_ci break; 2538c2ecf20Sopenharmony_ci default: 2548c2ecf20Sopenharmony_ci ath11k_warn(ab, "Unknown reo command %d\n", type); 2558c2ecf20Sopenharmony_ci ret = -EINVAL; 2568c2ecf20Sopenharmony_ci break; 2578c2ecf20Sopenharmony_ci } 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci ath11k_dp_shadow_start_timer(ab, srng, &ab->dp.reo_cmd_timer); 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ciout: 2628c2ecf20Sopenharmony_ci ath11k_hal_srng_access_end(ab, srng); 2638c2ecf20Sopenharmony_ci spin_unlock_bh(&srng->lock); 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci return ret; 2668c2ecf20Sopenharmony_ci} 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_civoid ath11k_hal_rx_buf_addr_info_set(void *desc, dma_addr_t paddr, 2698c2ecf20Sopenharmony_ci u32 cookie, u8 manager) 2708c2ecf20Sopenharmony_ci{ 2718c2ecf20Sopenharmony_ci struct ath11k_buffer_addr *binfo = (struct ath11k_buffer_addr *)desc; 2728c2ecf20Sopenharmony_ci u32 paddr_lo, paddr_hi; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci paddr_lo = lower_32_bits(paddr); 2758c2ecf20Sopenharmony_ci paddr_hi = upper_32_bits(paddr); 2768c2ecf20Sopenharmony_ci binfo->info0 = FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, paddr_lo); 2778c2ecf20Sopenharmony_ci binfo->info1 = FIELD_PREP(BUFFER_ADDR_INFO1_ADDR, paddr_hi) | 2788c2ecf20Sopenharmony_ci FIELD_PREP(BUFFER_ADDR_INFO1_SW_COOKIE, cookie) | 2798c2ecf20Sopenharmony_ci FIELD_PREP(BUFFER_ADDR_INFO1_RET_BUF_MGR, manager); 2808c2ecf20Sopenharmony_ci} 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_civoid ath11k_hal_rx_buf_addr_info_get(void *desc, dma_addr_t *paddr, 2838c2ecf20Sopenharmony_ci u32 *cookie, u8 *rbm) 2848c2ecf20Sopenharmony_ci{ 2858c2ecf20Sopenharmony_ci struct ath11k_buffer_addr *binfo = (struct ath11k_buffer_addr *)desc; 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci *paddr = 2888c2ecf20Sopenharmony_ci (((u64)FIELD_GET(BUFFER_ADDR_INFO1_ADDR, binfo->info1)) << 32) | 2898c2ecf20Sopenharmony_ci FIELD_GET(BUFFER_ADDR_INFO0_ADDR, binfo->info0); 2908c2ecf20Sopenharmony_ci *cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, binfo->info1); 2918c2ecf20Sopenharmony_ci *rbm = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, binfo->info1); 2928c2ecf20Sopenharmony_ci} 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_civoid ath11k_hal_rx_msdu_link_info_get(void *link_desc, u32 *num_msdus, 2958c2ecf20Sopenharmony_ci u32 *msdu_cookies, 2968c2ecf20Sopenharmony_ci enum hal_rx_buf_return_buf_manager *rbm) 2978c2ecf20Sopenharmony_ci{ 2988c2ecf20Sopenharmony_ci struct hal_rx_msdu_link *link = (struct hal_rx_msdu_link *)link_desc; 2998c2ecf20Sopenharmony_ci struct hal_rx_msdu_details *msdu; 3008c2ecf20Sopenharmony_ci int i; 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci *num_msdus = HAL_NUM_RX_MSDUS_PER_LINK_DESC; 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci msdu = &link->msdu_link[0]; 3058c2ecf20Sopenharmony_ci *rbm = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, 3068c2ecf20Sopenharmony_ci msdu->buf_addr_info.info1); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci for (i = 0; i < *num_msdus; i++) { 3098c2ecf20Sopenharmony_ci msdu = &link->msdu_link[i]; 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci if (!FIELD_GET(BUFFER_ADDR_INFO0_ADDR, 3128c2ecf20Sopenharmony_ci msdu->buf_addr_info.info0)) { 3138c2ecf20Sopenharmony_ci *num_msdus = i; 3148c2ecf20Sopenharmony_ci break; 3158c2ecf20Sopenharmony_ci } 3168c2ecf20Sopenharmony_ci *msdu_cookies = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, 3178c2ecf20Sopenharmony_ci msdu->buf_addr_info.info1); 3188c2ecf20Sopenharmony_ci msdu_cookies++; 3198c2ecf20Sopenharmony_ci } 3208c2ecf20Sopenharmony_ci} 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ciint ath11k_hal_desc_reo_parse_err(struct ath11k_base *ab, u32 *rx_desc, 3238c2ecf20Sopenharmony_ci dma_addr_t *paddr, u32 *desc_bank) 3248c2ecf20Sopenharmony_ci{ 3258c2ecf20Sopenharmony_ci struct hal_reo_dest_ring *desc = (struct hal_reo_dest_ring *)rx_desc; 3268c2ecf20Sopenharmony_ci enum hal_reo_dest_ring_push_reason push_reason; 3278c2ecf20Sopenharmony_ci enum hal_reo_dest_ring_error_code err_code; 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON, 3308c2ecf20Sopenharmony_ci desc->info0); 3318c2ecf20Sopenharmony_ci err_code = FIELD_GET(HAL_REO_DEST_RING_INFO0_ERROR_CODE, 3328c2ecf20Sopenharmony_ci desc->info0); 3338c2ecf20Sopenharmony_ci ab->soc_stats.reo_error[err_code]++; 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ci if (push_reason != HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED && 3368c2ecf20Sopenharmony_ci push_reason != HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) { 3378c2ecf20Sopenharmony_ci ath11k_warn(ab, "expected error push reason code, received %d\n", 3388c2ecf20Sopenharmony_ci push_reason); 3398c2ecf20Sopenharmony_ci return -EINVAL; 3408c2ecf20Sopenharmony_ci } 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci if (FIELD_GET(HAL_REO_DEST_RING_INFO0_BUFFER_TYPE, desc->info0) != 3438c2ecf20Sopenharmony_ci HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC) { 3448c2ecf20Sopenharmony_ci ath11k_warn(ab, "expected buffer type link_desc"); 3458c2ecf20Sopenharmony_ci return -EINVAL; 3468c2ecf20Sopenharmony_ci } 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci ath11k_hal_rx_reo_ent_paddr_get(ab, rx_desc, paddr, desc_bank); 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci return 0; 3518c2ecf20Sopenharmony_ci} 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_ciint ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc, 3548c2ecf20Sopenharmony_ci struct hal_rx_wbm_rel_info *rel_info) 3558c2ecf20Sopenharmony_ci{ 3568c2ecf20Sopenharmony_ci struct hal_wbm_release_ring *wbm_desc = desc; 3578c2ecf20Sopenharmony_ci enum hal_wbm_rel_desc_type type; 3588c2ecf20Sopenharmony_ci enum hal_wbm_rel_src_module rel_src; 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci type = FIELD_GET(HAL_WBM_RELEASE_INFO0_DESC_TYPE, 3618c2ecf20Sopenharmony_ci wbm_desc->info0); 3628c2ecf20Sopenharmony_ci /* We expect only WBM_REL buffer type */ 3638c2ecf20Sopenharmony_ci if (type != HAL_WBM_REL_DESC_TYPE_REL_MSDU) { 3648c2ecf20Sopenharmony_ci WARN_ON(1); 3658c2ecf20Sopenharmony_ci return -EINVAL; 3668c2ecf20Sopenharmony_ci } 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ci rel_src = FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, 3698c2ecf20Sopenharmony_ci wbm_desc->info0); 3708c2ecf20Sopenharmony_ci if (rel_src != HAL_WBM_REL_SRC_MODULE_RXDMA && 3718c2ecf20Sopenharmony_ci rel_src != HAL_WBM_REL_SRC_MODULE_REO) 3728c2ecf20Sopenharmony_ci return -EINVAL; 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_ci if (FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, 3758c2ecf20Sopenharmony_ci wbm_desc->buf_addr_info.info1) != HAL_RX_BUF_RBM_SW3_BM) { 3768c2ecf20Sopenharmony_ci ab->soc_stats.invalid_rbm++; 3778c2ecf20Sopenharmony_ci return -EINVAL; 3788c2ecf20Sopenharmony_ci } 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci rel_info->cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, 3818c2ecf20Sopenharmony_ci wbm_desc->buf_addr_info.info1); 3828c2ecf20Sopenharmony_ci rel_info->err_rel_src = rel_src; 3838c2ecf20Sopenharmony_ci if (rel_src == HAL_WBM_REL_SRC_MODULE_REO) { 3848c2ecf20Sopenharmony_ci rel_info->push_reason = 3858c2ecf20Sopenharmony_ci FIELD_GET(HAL_WBM_RELEASE_INFO0_REO_PUSH_REASON, 3868c2ecf20Sopenharmony_ci wbm_desc->info0); 3878c2ecf20Sopenharmony_ci rel_info->err_code = 3888c2ecf20Sopenharmony_ci FIELD_GET(HAL_WBM_RELEASE_INFO0_REO_ERROR_CODE, 3898c2ecf20Sopenharmony_ci wbm_desc->info0); 3908c2ecf20Sopenharmony_ci } else { 3918c2ecf20Sopenharmony_ci rel_info->push_reason = 3928c2ecf20Sopenharmony_ci FIELD_GET(HAL_WBM_RELEASE_INFO0_RXDMA_PUSH_REASON, 3938c2ecf20Sopenharmony_ci wbm_desc->info0); 3948c2ecf20Sopenharmony_ci rel_info->err_code = 3958c2ecf20Sopenharmony_ci FIELD_GET(HAL_WBM_RELEASE_INFO0_RXDMA_ERROR_CODE, 3968c2ecf20Sopenharmony_ci wbm_desc->info0); 3978c2ecf20Sopenharmony_ci } 3988c2ecf20Sopenharmony_ci 3998c2ecf20Sopenharmony_ci rel_info->first_msdu = FIELD_GET(HAL_WBM_RELEASE_INFO2_FIRST_MSDU, 4008c2ecf20Sopenharmony_ci wbm_desc->info2); 4018c2ecf20Sopenharmony_ci rel_info->last_msdu = FIELD_GET(HAL_WBM_RELEASE_INFO2_LAST_MSDU, 4028c2ecf20Sopenharmony_ci wbm_desc->info2); 4038c2ecf20Sopenharmony_ci return 0; 4048c2ecf20Sopenharmony_ci} 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_civoid ath11k_hal_rx_reo_ent_paddr_get(struct ath11k_base *ab, void *desc, 4078c2ecf20Sopenharmony_ci dma_addr_t *paddr, u32 *desc_bank) 4088c2ecf20Sopenharmony_ci{ 4098c2ecf20Sopenharmony_ci struct ath11k_buffer_addr *buff_addr = desc; 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ci *paddr = ((u64)(FIELD_GET(BUFFER_ADDR_INFO1_ADDR, buff_addr->info1)) << 32) | 4128c2ecf20Sopenharmony_ci FIELD_GET(BUFFER_ADDR_INFO0_ADDR, buff_addr->info0); 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci *desc_bank = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, buff_addr->info1); 4158c2ecf20Sopenharmony_ci} 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_civoid ath11k_hal_rx_msdu_link_desc_set(struct ath11k_base *ab, void *desc, 4188c2ecf20Sopenharmony_ci void *link_desc, 4198c2ecf20Sopenharmony_ci enum hal_wbm_rel_bm_act action) 4208c2ecf20Sopenharmony_ci{ 4218c2ecf20Sopenharmony_ci struct hal_wbm_release_ring *dst_desc = desc; 4228c2ecf20Sopenharmony_ci struct hal_wbm_release_ring *src_desc = link_desc; 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ci dst_desc->buf_addr_info = src_desc->buf_addr_info; 4258c2ecf20Sopenharmony_ci dst_desc->info0 |= FIELD_PREP(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, 4268c2ecf20Sopenharmony_ci HAL_WBM_REL_SRC_MODULE_SW) | 4278c2ecf20Sopenharmony_ci FIELD_PREP(HAL_WBM_RELEASE_INFO0_BM_ACTION, action) | 4288c2ecf20Sopenharmony_ci FIELD_PREP(HAL_WBM_RELEASE_INFO0_DESC_TYPE, 4298c2ecf20Sopenharmony_ci HAL_WBM_REL_DESC_TYPE_MSDU_LINK); 4308c2ecf20Sopenharmony_ci} 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_civoid ath11k_hal_reo_status_queue_stats(struct ath11k_base *ab, u32 *reo_desc, 4338c2ecf20Sopenharmony_ci struct hal_reo_status *status) 4348c2ecf20Sopenharmony_ci{ 4358c2ecf20Sopenharmony_ci struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; 4368c2ecf20Sopenharmony_ci struct hal_reo_get_queue_stats_status *desc = 4378c2ecf20Sopenharmony_ci (struct hal_reo_get_queue_stats_status *)tlv->value; 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_ci status->uniform_hdr.cmd_num = 4408c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, 4418c2ecf20Sopenharmony_ci desc->hdr.info0); 4428c2ecf20Sopenharmony_ci status->uniform_hdr.cmd_status = 4438c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, 4448c2ecf20Sopenharmony_ci desc->hdr.info0); 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci ath11k_dbg(ab, ATH11k_DBG_HAL, "Queue stats status:\n"); 4478c2ecf20Sopenharmony_ci ath11k_dbg(ab, ATH11k_DBG_HAL, "header: cmd_num %d status %d\n", 4488c2ecf20Sopenharmony_ci status->uniform_hdr.cmd_num, 4498c2ecf20Sopenharmony_ci status->uniform_hdr.cmd_status); 4508c2ecf20Sopenharmony_ci ath11k_dbg(ab, ATH11k_DBG_HAL, "ssn %ld cur_idx %ld\n", 4518c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO0_SSN, 4528c2ecf20Sopenharmony_ci desc->info0), 4538c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO0_CUR_IDX, 4548c2ecf20Sopenharmony_ci desc->info0)); 4558c2ecf20Sopenharmony_ci ath11k_dbg(ab, ATH11k_DBG_HAL, "pn = [%08x, %08x, %08x, %08x]\n", 4568c2ecf20Sopenharmony_ci desc->pn[0], desc->pn[1], desc->pn[2], desc->pn[3]); 4578c2ecf20Sopenharmony_ci ath11k_dbg(ab, ATH11k_DBG_HAL, "last_rx: enqueue_tstamp %08x dequeue_tstamp %08x\n", 4588c2ecf20Sopenharmony_ci desc->last_rx_enqueue_timestamp, 4598c2ecf20Sopenharmony_ci desc->last_rx_dequeue_timestamp); 4608c2ecf20Sopenharmony_ci ath11k_dbg(ab, ATH11k_DBG_HAL, "rx_bitmap [%08x %08x %08x %08x %08x %08x %08x %08x]\n", 4618c2ecf20Sopenharmony_ci desc->rx_bitmap[0], desc->rx_bitmap[1], desc->rx_bitmap[2], 4628c2ecf20Sopenharmony_ci desc->rx_bitmap[3], desc->rx_bitmap[4], desc->rx_bitmap[5], 4638c2ecf20Sopenharmony_ci desc->rx_bitmap[6], desc->rx_bitmap[7]); 4648c2ecf20Sopenharmony_ci ath11k_dbg(ab, ATH11k_DBG_HAL, "count: cur_mpdu %ld cur_msdu %ld\n", 4658c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO1_MPDU_COUNT, 4668c2ecf20Sopenharmony_ci desc->info1), 4678c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO1_MSDU_COUNT, 4688c2ecf20Sopenharmony_ci desc->info1)); 4698c2ecf20Sopenharmony_ci ath11k_dbg(ab, ATH11k_DBG_HAL, "fwd_timeout %ld fwd_bar %ld dup_count %ld\n", 4708c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_TIMEOUT_COUNT, 4718c2ecf20Sopenharmony_ci desc->info2), 4728c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_FDTB_COUNT, 4738c2ecf20Sopenharmony_ci desc->info2), 4748c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_DUPLICATE_COUNT, 4758c2ecf20Sopenharmony_ci desc->info2)); 4768c2ecf20Sopenharmony_ci ath11k_dbg(ab, ATH11k_DBG_HAL, "frames_in_order %ld bar_rcvd %ld\n", 4778c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO3_FIO_COUNT, 4788c2ecf20Sopenharmony_ci desc->info3), 4798c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO3_BAR_RCVD_CNT, 4808c2ecf20Sopenharmony_ci desc->info3)); 4818c2ecf20Sopenharmony_ci ath11k_dbg(ab, ATH11k_DBG_HAL, "num_mpdus %d num_msdus %d total_bytes %d\n", 4828c2ecf20Sopenharmony_ci desc->num_mpdu_frames, desc->num_msdu_frames, 4838c2ecf20Sopenharmony_ci desc->total_bytes); 4848c2ecf20Sopenharmony_ci ath11k_dbg(ab, ATH11k_DBG_HAL, "late_rcvd %ld win_jump_2k %ld hole_cnt %ld\n", 4858c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_LATE_RX_MPDU, 4868c2ecf20Sopenharmony_ci desc->info4), 4878c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_WINDOW_JMP2K, 4888c2ecf20Sopenharmony_ci desc->info4), 4898c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_HOLE_COUNT, 4908c2ecf20Sopenharmony_ci desc->info4)); 4918c2ecf20Sopenharmony_ci ath11k_dbg(ab, ATH11k_DBG_HAL, "looping count %ld\n", 4928c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO5_LOOPING_CNT, 4938c2ecf20Sopenharmony_ci desc->info5)); 4948c2ecf20Sopenharmony_ci} 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ciint ath11k_hal_reo_process_status(u8 *reo_desc, u8 *status) 4978c2ecf20Sopenharmony_ci{ 4988c2ecf20Sopenharmony_ci struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; 4998c2ecf20Sopenharmony_ci struct hal_reo_status_hdr *hdr; 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_ci hdr = (struct hal_reo_status_hdr *)tlv->value; 5028c2ecf20Sopenharmony_ci *status = FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, hdr->info0); 5038c2ecf20Sopenharmony_ci 5048c2ecf20Sopenharmony_ci return FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, hdr->info0); 5058c2ecf20Sopenharmony_ci} 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_civoid ath11k_hal_reo_flush_queue_status(struct ath11k_base *ab, u32 *reo_desc, 5088c2ecf20Sopenharmony_ci struct hal_reo_status *status) 5098c2ecf20Sopenharmony_ci{ 5108c2ecf20Sopenharmony_ci struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; 5118c2ecf20Sopenharmony_ci struct hal_reo_flush_queue_status *desc = 5128c2ecf20Sopenharmony_ci (struct hal_reo_flush_queue_status *)tlv->value; 5138c2ecf20Sopenharmony_ci 5148c2ecf20Sopenharmony_ci status->uniform_hdr.cmd_num = 5158c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, 5168c2ecf20Sopenharmony_ci desc->hdr.info0); 5178c2ecf20Sopenharmony_ci status->uniform_hdr.cmd_status = 5188c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, 5198c2ecf20Sopenharmony_ci desc->hdr.info0); 5208c2ecf20Sopenharmony_ci status->u.flush_queue.err_detected = 5218c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_FLUSH_QUEUE_INFO0_ERR_DETECTED, 5228c2ecf20Sopenharmony_ci desc->info0); 5238c2ecf20Sopenharmony_ci} 5248c2ecf20Sopenharmony_ci 5258c2ecf20Sopenharmony_civoid ath11k_hal_reo_flush_cache_status(struct ath11k_base *ab, u32 *reo_desc, 5268c2ecf20Sopenharmony_ci struct hal_reo_status *status) 5278c2ecf20Sopenharmony_ci{ 5288c2ecf20Sopenharmony_ci struct ath11k_hal *hal = &ab->hal; 5298c2ecf20Sopenharmony_ci struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; 5308c2ecf20Sopenharmony_ci struct hal_reo_flush_cache_status *desc = 5318c2ecf20Sopenharmony_ci (struct hal_reo_flush_cache_status *)tlv->value; 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_ci status->uniform_hdr.cmd_num = 5348c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, 5358c2ecf20Sopenharmony_ci desc->hdr.info0); 5368c2ecf20Sopenharmony_ci status->uniform_hdr.cmd_status = 5378c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, 5388c2ecf20Sopenharmony_ci desc->hdr.info0); 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ci status->u.flush_cache.err_detected = 5418c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_IS_ERR, 5428c2ecf20Sopenharmony_ci desc->info0); 5438c2ecf20Sopenharmony_ci status->u.flush_cache.err_code = 5448c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_BLOCK_ERR_CODE, 5458c2ecf20Sopenharmony_ci desc->info0); 5468c2ecf20Sopenharmony_ci if (!status->u.flush_cache.err_code) 5478c2ecf20Sopenharmony_ci hal->avail_blk_resource |= BIT(hal->current_blk_index); 5488c2ecf20Sopenharmony_ci 5498c2ecf20Sopenharmony_ci status->u.flush_cache.cache_controller_flush_status_hit = 5508c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_STATUS_HIT, 5518c2ecf20Sopenharmony_ci desc->info0); 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_ci status->u.flush_cache.cache_controller_flush_status_desc_type = 5548c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_DESC_TYPE, 5558c2ecf20Sopenharmony_ci desc->info0); 5568c2ecf20Sopenharmony_ci status->u.flush_cache.cache_controller_flush_status_client_id = 5578c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_CLIENT_ID, 5588c2ecf20Sopenharmony_ci desc->info0); 5598c2ecf20Sopenharmony_ci status->u.flush_cache.cache_controller_flush_status_err = 5608c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_ERR, 5618c2ecf20Sopenharmony_ci desc->info0); 5628c2ecf20Sopenharmony_ci status->u.flush_cache.cache_controller_flush_status_cnt = 5638c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_COUNT, 5648c2ecf20Sopenharmony_ci desc->info0); 5658c2ecf20Sopenharmony_ci} 5668c2ecf20Sopenharmony_ci 5678c2ecf20Sopenharmony_civoid ath11k_hal_reo_unblk_cache_status(struct ath11k_base *ab, u32 *reo_desc, 5688c2ecf20Sopenharmony_ci struct hal_reo_status *status) 5698c2ecf20Sopenharmony_ci{ 5708c2ecf20Sopenharmony_ci struct ath11k_hal *hal = &ab->hal; 5718c2ecf20Sopenharmony_ci struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; 5728c2ecf20Sopenharmony_ci struct hal_reo_unblock_cache_status *desc = 5738c2ecf20Sopenharmony_ci (struct hal_reo_unblock_cache_status *)tlv->value; 5748c2ecf20Sopenharmony_ci 5758c2ecf20Sopenharmony_ci status->uniform_hdr.cmd_num = 5768c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, 5778c2ecf20Sopenharmony_ci desc->hdr.info0); 5788c2ecf20Sopenharmony_ci status->uniform_hdr.cmd_status = 5798c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, 5808c2ecf20Sopenharmony_ci desc->hdr.info0); 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_ci status->u.unblock_cache.err_detected = 5838c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_UNBLOCK_CACHE_STATUS_INFO0_IS_ERR, 5848c2ecf20Sopenharmony_ci desc->info0); 5858c2ecf20Sopenharmony_ci status->u.unblock_cache.unblock_type = 5868c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_UNBLOCK_CACHE_STATUS_INFO0_TYPE, 5878c2ecf20Sopenharmony_ci desc->info0); 5888c2ecf20Sopenharmony_ci 5898c2ecf20Sopenharmony_ci if (!status->u.unblock_cache.err_detected && 5908c2ecf20Sopenharmony_ci status->u.unblock_cache.unblock_type == 5918c2ecf20Sopenharmony_ci HAL_REO_STATUS_UNBLOCK_BLOCKING_RESOURCE) 5928c2ecf20Sopenharmony_ci hal->avail_blk_resource &= ~BIT(hal->current_blk_index); 5938c2ecf20Sopenharmony_ci} 5948c2ecf20Sopenharmony_ci 5958c2ecf20Sopenharmony_civoid ath11k_hal_reo_flush_timeout_list_status(struct ath11k_base *ab, 5968c2ecf20Sopenharmony_ci u32 *reo_desc, 5978c2ecf20Sopenharmony_ci struct hal_reo_status *status) 5988c2ecf20Sopenharmony_ci{ 5998c2ecf20Sopenharmony_ci struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; 6008c2ecf20Sopenharmony_ci struct hal_reo_flush_timeout_list_status *desc = 6018c2ecf20Sopenharmony_ci (struct hal_reo_flush_timeout_list_status *)tlv->value; 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_ci status->uniform_hdr.cmd_num = 6048c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, 6058c2ecf20Sopenharmony_ci desc->hdr.info0); 6068c2ecf20Sopenharmony_ci status->uniform_hdr.cmd_status = 6078c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, 6088c2ecf20Sopenharmony_ci desc->hdr.info0); 6098c2ecf20Sopenharmony_ci 6108c2ecf20Sopenharmony_ci status->u.timeout_list.err_detected = 6118c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO0_IS_ERR, 6128c2ecf20Sopenharmony_ci desc->info0); 6138c2ecf20Sopenharmony_ci status->u.timeout_list.list_empty = 6148c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO0_LIST_EMPTY, 6158c2ecf20Sopenharmony_ci desc->info0); 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci status->u.timeout_list.release_desc_cnt = 6188c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO1_REL_DESC_COUNT, 6198c2ecf20Sopenharmony_ci desc->info1); 6208c2ecf20Sopenharmony_ci status->u.timeout_list.fwd_buf_cnt = 6218c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO1_FWD_BUF_COUNT, 6228c2ecf20Sopenharmony_ci desc->info1); 6238c2ecf20Sopenharmony_ci} 6248c2ecf20Sopenharmony_ci 6258c2ecf20Sopenharmony_civoid ath11k_hal_reo_desc_thresh_reached_status(struct ath11k_base *ab, 6268c2ecf20Sopenharmony_ci u32 *reo_desc, 6278c2ecf20Sopenharmony_ci struct hal_reo_status *status) 6288c2ecf20Sopenharmony_ci{ 6298c2ecf20Sopenharmony_ci struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; 6308c2ecf20Sopenharmony_ci struct hal_reo_desc_thresh_reached_status *desc = 6318c2ecf20Sopenharmony_ci (struct hal_reo_desc_thresh_reached_status *)tlv->value; 6328c2ecf20Sopenharmony_ci 6338c2ecf20Sopenharmony_ci status->uniform_hdr.cmd_num = 6348c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, 6358c2ecf20Sopenharmony_ci desc->hdr.info0); 6368c2ecf20Sopenharmony_ci status->uniform_hdr.cmd_status = 6378c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, 6388c2ecf20Sopenharmony_ci desc->hdr.info0); 6398c2ecf20Sopenharmony_ci 6408c2ecf20Sopenharmony_ci status->u.desc_thresh_reached.threshold_idx = 6418c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO0_THRESH_INDEX, 6428c2ecf20Sopenharmony_ci desc->info0); 6438c2ecf20Sopenharmony_ci 6448c2ecf20Sopenharmony_ci status->u.desc_thresh_reached.link_desc_counter0 = 6458c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO1_LINK_DESC_COUNTER0, 6468c2ecf20Sopenharmony_ci desc->info1); 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_ci status->u.desc_thresh_reached.link_desc_counter1 = 6498c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO2_LINK_DESC_COUNTER1, 6508c2ecf20Sopenharmony_ci desc->info2); 6518c2ecf20Sopenharmony_ci 6528c2ecf20Sopenharmony_ci status->u.desc_thresh_reached.link_desc_counter2 = 6538c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO3_LINK_DESC_COUNTER2, 6548c2ecf20Sopenharmony_ci desc->info3); 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ci status->u.desc_thresh_reached.link_desc_counter_sum = 6578c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO4_LINK_DESC_COUNTER_SUM, 6588c2ecf20Sopenharmony_ci desc->info4); 6598c2ecf20Sopenharmony_ci} 6608c2ecf20Sopenharmony_ci 6618c2ecf20Sopenharmony_civoid ath11k_hal_reo_update_rx_reo_queue_status(struct ath11k_base *ab, 6628c2ecf20Sopenharmony_ci u32 *reo_desc, 6638c2ecf20Sopenharmony_ci struct hal_reo_status *status) 6648c2ecf20Sopenharmony_ci{ 6658c2ecf20Sopenharmony_ci struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; 6668c2ecf20Sopenharmony_ci struct hal_reo_status_hdr *desc = 6678c2ecf20Sopenharmony_ci (struct hal_reo_status_hdr *)tlv->value; 6688c2ecf20Sopenharmony_ci 6698c2ecf20Sopenharmony_ci status->uniform_hdr.cmd_num = 6708c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, 6718c2ecf20Sopenharmony_ci desc->info0); 6728c2ecf20Sopenharmony_ci status->uniform_hdr.cmd_status = 6738c2ecf20Sopenharmony_ci FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, 6748c2ecf20Sopenharmony_ci desc->info0); 6758c2ecf20Sopenharmony_ci} 6768c2ecf20Sopenharmony_ci 6778c2ecf20Sopenharmony_ciu32 ath11k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid) 6788c2ecf20Sopenharmony_ci{ 6798c2ecf20Sopenharmony_ci u32 num_ext_desc; 6808c2ecf20Sopenharmony_ci 6818c2ecf20Sopenharmony_ci if (ba_window_size <= 1) { 6828c2ecf20Sopenharmony_ci if (tid != HAL_DESC_REO_NON_QOS_TID) 6838c2ecf20Sopenharmony_ci num_ext_desc = 1; 6848c2ecf20Sopenharmony_ci else 6858c2ecf20Sopenharmony_ci num_ext_desc = 0; 6868c2ecf20Sopenharmony_ci } else if (ba_window_size <= 105) { 6878c2ecf20Sopenharmony_ci num_ext_desc = 1; 6888c2ecf20Sopenharmony_ci } else if (ba_window_size <= 210) { 6898c2ecf20Sopenharmony_ci num_ext_desc = 2; 6908c2ecf20Sopenharmony_ci } else { 6918c2ecf20Sopenharmony_ci num_ext_desc = 3; 6928c2ecf20Sopenharmony_ci } 6938c2ecf20Sopenharmony_ci 6948c2ecf20Sopenharmony_ci return sizeof(struct hal_rx_reo_queue) + 6958c2ecf20Sopenharmony_ci (num_ext_desc * sizeof(struct hal_rx_reo_queue_ext)); 6968c2ecf20Sopenharmony_ci} 6978c2ecf20Sopenharmony_ci 6988c2ecf20Sopenharmony_civoid ath11k_hal_reo_qdesc_setup(void *vaddr, int tid, u32 ba_window_size, 6998c2ecf20Sopenharmony_ci u32 start_seq, enum hal_pn_type type) 7008c2ecf20Sopenharmony_ci{ 7018c2ecf20Sopenharmony_ci struct hal_rx_reo_queue *qdesc = (struct hal_rx_reo_queue *)vaddr; 7028c2ecf20Sopenharmony_ci struct hal_rx_reo_queue_ext *ext_desc; 7038c2ecf20Sopenharmony_ci 7048c2ecf20Sopenharmony_ci memset(qdesc, 0, sizeof(*qdesc)); 7058c2ecf20Sopenharmony_ci 7068c2ecf20Sopenharmony_ci ath11k_hal_reo_set_desc_hdr(&qdesc->desc_hdr, HAL_DESC_REO_OWNED, 7078c2ecf20Sopenharmony_ci HAL_DESC_REO_QUEUE_DESC, 7088c2ecf20Sopenharmony_ci REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_0); 7098c2ecf20Sopenharmony_ci 7108c2ecf20Sopenharmony_ci qdesc->rx_queue_num = FIELD_PREP(HAL_RX_REO_QUEUE_RX_QUEUE_NUMBER, tid); 7118c2ecf20Sopenharmony_ci 7128c2ecf20Sopenharmony_ci qdesc->info0 = 7138c2ecf20Sopenharmony_ci FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_VLD, 1) | 7148c2ecf20Sopenharmony_ci FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_ASSOC_LNK_DESC_COUNTER, 1) | 7158c2ecf20Sopenharmony_ci FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_AC, ath11k_tid_to_ac(tid)); 7168c2ecf20Sopenharmony_ci 7178c2ecf20Sopenharmony_ci if (ba_window_size < 1) 7188c2ecf20Sopenharmony_ci ba_window_size = 1; 7198c2ecf20Sopenharmony_ci 7208c2ecf20Sopenharmony_ci if (ba_window_size == 1 && tid != HAL_DESC_REO_NON_QOS_TID) 7218c2ecf20Sopenharmony_ci ba_window_size++; 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_ci if (ba_window_size == 1) 7248c2ecf20Sopenharmony_ci qdesc->info0 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_RETRY, 1); 7258c2ecf20Sopenharmony_ci 7268c2ecf20Sopenharmony_ci qdesc->info0 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_BA_WINDOW_SIZE, 7278c2ecf20Sopenharmony_ci ba_window_size - 1); 7288c2ecf20Sopenharmony_ci switch (type) { 7298c2ecf20Sopenharmony_ci case HAL_PN_TYPE_NONE: 7308c2ecf20Sopenharmony_ci case HAL_PN_TYPE_WAPI_EVEN: 7318c2ecf20Sopenharmony_ci case HAL_PN_TYPE_WAPI_UNEVEN: 7328c2ecf20Sopenharmony_ci break; 7338c2ecf20Sopenharmony_ci case HAL_PN_TYPE_WPA: 7348c2ecf20Sopenharmony_ci qdesc->info0 |= 7358c2ecf20Sopenharmony_ci FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_PN_CHECK, 1) | 7368c2ecf20Sopenharmony_ci FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_PN_SIZE, 7378c2ecf20Sopenharmony_ci HAL_RX_REO_QUEUE_PN_SIZE_48); 7388c2ecf20Sopenharmony_ci break; 7398c2ecf20Sopenharmony_ci } 7408c2ecf20Sopenharmony_ci 7418c2ecf20Sopenharmony_ci /* TODO: Set Ignore ampdu flags based on BA window size and/or 7428c2ecf20Sopenharmony_ci * AMPDU capabilities 7438c2ecf20Sopenharmony_ci */ 7448c2ecf20Sopenharmony_ci qdesc->info0 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_IGNORE_AMPDU_FLG, 1); 7458c2ecf20Sopenharmony_ci 7468c2ecf20Sopenharmony_ci qdesc->info1 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO1_SVLD, 0); 7478c2ecf20Sopenharmony_ci 7488c2ecf20Sopenharmony_ci if (start_seq <= 0xfff) 7498c2ecf20Sopenharmony_ci qdesc->info1 = FIELD_PREP(HAL_RX_REO_QUEUE_INFO1_SSN, 7508c2ecf20Sopenharmony_ci start_seq); 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_ci if (tid == HAL_DESC_REO_NON_QOS_TID) 7538c2ecf20Sopenharmony_ci return; 7548c2ecf20Sopenharmony_ci 7558c2ecf20Sopenharmony_ci ext_desc = qdesc->ext_desc; 7568c2ecf20Sopenharmony_ci 7578c2ecf20Sopenharmony_ci /* TODO: HW queue descriptors are currently allocated for max BA 7588c2ecf20Sopenharmony_ci * window size for all QOS TIDs so that same descriptor can be used 7598c2ecf20Sopenharmony_ci * later when ADDBA request is recevied. This should be changed to 7608c2ecf20Sopenharmony_ci * allocate HW queue descriptors based on BA window size being 7618c2ecf20Sopenharmony_ci * negotiated (0 for non BA cases), and reallocate when BA window 7628c2ecf20Sopenharmony_ci * size changes and also send WMI message to FW to change the REO 7638c2ecf20Sopenharmony_ci * queue descriptor in Rx peer entry as part of dp_rx_tid_update. 7648c2ecf20Sopenharmony_ci */ 7658c2ecf20Sopenharmony_ci memset(ext_desc, 0, 3 * sizeof(*ext_desc)); 7668c2ecf20Sopenharmony_ci ath11k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED, 7678c2ecf20Sopenharmony_ci HAL_DESC_REO_QUEUE_EXT_DESC, 7688c2ecf20Sopenharmony_ci REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_1); 7698c2ecf20Sopenharmony_ci ext_desc++; 7708c2ecf20Sopenharmony_ci ath11k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED, 7718c2ecf20Sopenharmony_ci HAL_DESC_REO_QUEUE_EXT_DESC, 7728c2ecf20Sopenharmony_ci REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2); 7738c2ecf20Sopenharmony_ci ext_desc++; 7748c2ecf20Sopenharmony_ci ath11k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED, 7758c2ecf20Sopenharmony_ci HAL_DESC_REO_QUEUE_EXT_DESC, 7768c2ecf20Sopenharmony_ci REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3); 7778c2ecf20Sopenharmony_ci} 7788c2ecf20Sopenharmony_ci 7798c2ecf20Sopenharmony_civoid ath11k_hal_reo_init_cmd_ring(struct ath11k_base *ab, 7808c2ecf20Sopenharmony_ci struct hal_srng *srng) 7818c2ecf20Sopenharmony_ci{ 7828c2ecf20Sopenharmony_ci struct hal_srng_params params; 7838c2ecf20Sopenharmony_ci struct hal_tlv_hdr *tlv; 7848c2ecf20Sopenharmony_ci struct hal_reo_get_queue_stats *desc; 7858c2ecf20Sopenharmony_ci int i, cmd_num = 1; 7868c2ecf20Sopenharmony_ci int entry_size; 7878c2ecf20Sopenharmony_ci u8 *entry; 7888c2ecf20Sopenharmony_ci 7898c2ecf20Sopenharmony_ci memset(¶ms, 0, sizeof(params)); 7908c2ecf20Sopenharmony_ci 7918c2ecf20Sopenharmony_ci entry_size = ath11k_hal_srng_get_entrysize(ab, HAL_REO_CMD); 7928c2ecf20Sopenharmony_ci ath11k_hal_srng_get_params(ab, srng, ¶ms); 7938c2ecf20Sopenharmony_ci entry = (u8 *)params.ring_base_vaddr; 7948c2ecf20Sopenharmony_ci 7958c2ecf20Sopenharmony_ci for (i = 0; i < params.num_entries; i++) { 7968c2ecf20Sopenharmony_ci tlv = (struct hal_tlv_hdr *)entry; 7978c2ecf20Sopenharmony_ci desc = (struct hal_reo_get_queue_stats *)tlv->value; 7988c2ecf20Sopenharmony_ci desc->cmd.info0 = 7998c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, cmd_num++); 8008c2ecf20Sopenharmony_ci entry += entry_size; 8018c2ecf20Sopenharmony_ci } 8028c2ecf20Sopenharmony_ci} 8038c2ecf20Sopenharmony_ci 8048c2ecf20Sopenharmony_civoid ath11k_hal_reo_hw_setup(struct ath11k_base *ab, u32 ring_hash_map) 8058c2ecf20Sopenharmony_ci{ 8068c2ecf20Sopenharmony_ci u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; 8078c2ecf20Sopenharmony_ci u32 val; 8088c2ecf20Sopenharmony_ci 8098c2ecf20Sopenharmony_ci val = ath11k_hif_read32(ab, reo_base + HAL_REO1_GEN_ENABLE); 8108c2ecf20Sopenharmony_ci 8118c2ecf20Sopenharmony_ci val &= ~HAL_REO1_GEN_ENABLE_FRAG_DST_RING; 8128c2ecf20Sopenharmony_ci val |= FIELD_PREP(HAL_REO1_GEN_ENABLE_FRAG_DST_RING, 8138c2ecf20Sopenharmony_ci HAL_SRNG_RING_ID_REO2SW1) | 8148c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE, 1) | 8158c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE, 1); 8168c2ecf20Sopenharmony_ci ath11k_hif_write32(ab, reo_base + HAL_REO1_GEN_ENABLE, val); 8178c2ecf20Sopenharmony_ci 8188c2ecf20Sopenharmony_ci ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_0(ab), 8198c2ecf20Sopenharmony_ci HAL_DEFAULT_REO_TIMEOUT_USEC); 8208c2ecf20Sopenharmony_ci ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_1(ab), 8218c2ecf20Sopenharmony_ci HAL_DEFAULT_REO_TIMEOUT_USEC); 8228c2ecf20Sopenharmony_ci ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_2(ab), 8238c2ecf20Sopenharmony_ci HAL_DEFAULT_REO_TIMEOUT_USEC); 8248c2ecf20Sopenharmony_ci ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3(ab), 8258c2ecf20Sopenharmony_ci HAL_DEFAULT_REO_TIMEOUT_USEC); 8268c2ecf20Sopenharmony_ci 8278c2ecf20Sopenharmony_ci ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_0, 8288c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, 8298c2ecf20Sopenharmony_ci ring_hash_map)); 8308c2ecf20Sopenharmony_ci ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_1, 8318c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, 8328c2ecf20Sopenharmony_ci ring_hash_map)); 8338c2ecf20Sopenharmony_ci ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_2, 8348c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, 8358c2ecf20Sopenharmony_ci ring_hash_map)); 8368c2ecf20Sopenharmony_ci ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_3, 8378c2ecf20Sopenharmony_ci FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, 8388c2ecf20Sopenharmony_ci ring_hash_map)); 8398c2ecf20Sopenharmony_ci} 8408c2ecf20Sopenharmony_ci 8418c2ecf20Sopenharmony_cistatic enum hal_rx_mon_status 8428c2ecf20Sopenharmony_ciath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab, 8438c2ecf20Sopenharmony_ci struct hal_rx_mon_ppdu_info *ppdu_info, 8448c2ecf20Sopenharmony_ci u32 tlv_tag, u8 *tlv_data) 8458c2ecf20Sopenharmony_ci{ 8468c2ecf20Sopenharmony_ci u32 info0, info1; 8478c2ecf20Sopenharmony_ci 8488c2ecf20Sopenharmony_ci switch (tlv_tag) { 8498c2ecf20Sopenharmony_ci case HAL_RX_PPDU_START: { 8508c2ecf20Sopenharmony_ci struct hal_rx_ppdu_start *ppdu_start = 8518c2ecf20Sopenharmony_ci (struct hal_rx_ppdu_start *)tlv_data; 8528c2ecf20Sopenharmony_ci 8538c2ecf20Sopenharmony_ci ppdu_info->ppdu_id = 8548c2ecf20Sopenharmony_ci FIELD_GET(HAL_RX_PPDU_START_INFO0_PPDU_ID, 8558c2ecf20Sopenharmony_ci __le32_to_cpu(ppdu_start->info0)); 8568c2ecf20Sopenharmony_ci ppdu_info->chan_num = __le32_to_cpu(ppdu_start->chan_num); 8578c2ecf20Sopenharmony_ci ppdu_info->ppdu_ts = __le32_to_cpu(ppdu_start->ppdu_start_ts); 8588c2ecf20Sopenharmony_ci break; 8598c2ecf20Sopenharmony_ci } 8608c2ecf20Sopenharmony_ci case HAL_RX_PPDU_END_USER_STATS: { 8618c2ecf20Sopenharmony_ci struct hal_rx_ppdu_end_user_stats *eu_stats = 8628c2ecf20Sopenharmony_ci (struct hal_rx_ppdu_end_user_stats *)tlv_data; 8638c2ecf20Sopenharmony_ci 8648c2ecf20Sopenharmony_ci info0 = __le32_to_cpu(eu_stats->info0); 8658c2ecf20Sopenharmony_ci info1 = __le32_to_cpu(eu_stats->info1); 8668c2ecf20Sopenharmony_ci 8678c2ecf20Sopenharmony_ci ppdu_info->tid = 8688c2ecf20Sopenharmony_ci ffs(FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP, 8698c2ecf20Sopenharmony_ci __le32_to_cpu(eu_stats->info6))) - 1; 8708c2ecf20Sopenharmony_ci ppdu_info->tcp_msdu_count = 8718c2ecf20Sopenharmony_ci FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT, 8728c2ecf20Sopenharmony_ci __le32_to_cpu(eu_stats->info4)); 8738c2ecf20Sopenharmony_ci ppdu_info->udp_msdu_count = 8748c2ecf20Sopenharmony_ci FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO4_UDP_MSDU_CNT, 8758c2ecf20Sopenharmony_ci __le32_to_cpu(eu_stats->info4)); 8768c2ecf20Sopenharmony_ci ppdu_info->other_msdu_count = 8778c2ecf20Sopenharmony_ci FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT, 8788c2ecf20Sopenharmony_ci __le32_to_cpu(eu_stats->info5)); 8798c2ecf20Sopenharmony_ci ppdu_info->tcp_ack_msdu_count = 8808c2ecf20Sopenharmony_ci FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT, 8818c2ecf20Sopenharmony_ci __le32_to_cpu(eu_stats->info5)); 8828c2ecf20Sopenharmony_ci ppdu_info->preamble_type = 8838c2ecf20Sopenharmony_ci FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO1_PKT_TYPE, info1); 8848c2ecf20Sopenharmony_ci ppdu_info->num_mpdu_fcs_ok = 8858c2ecf20Sopenharmony_ci FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO1_MPDU_CNT_FCS_OK, 8868c2ecf20Sopenharmony_ci info1); 8878c2ecf20Sopenharmony_ci ppdu_info->num_mpdu_fcs_err = 8888c2ecf20Sopenharmony_ci FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR, 8898c2ecf20Sopenharmony_ci info0); 8908c2ecf20Sopenharmony_ci break; 8918c2ecf20Sopenharmony_ci } 8928c2ecf20Sopenharmony_ci case HAL_PHYRX_HT_SIG: { 8938c2ecf20Sopenharmony_ci struct hal_rx_ht_sig_info *ht_sig = 8948c2ecf20Sopenharmony_ci (struct hal_rx_ht_sig_info *)tlv_data; 8958c2ecf20Sopenharmony_ci 8968c2ecf20Sopenharmony_ci info0 = __le32_to_cpu(ht_sig->info0); 8978c2ecf20Sopenharmony_ci info1 = __le32_to_cpu(ht_sig->info1); 8988c2ecf20Sopenharmony_ci 8998c2ecf20Sopenharmony_ci ppdu_info->mcs = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO0_MCS, info0); 9008c2ecf20Sopenharmony_ci ppdu_info->bw = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO0_BW, info0); 9018c2ecf20Sopenharmony_ci ppdu_info->is_stbc = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_STBC, 9028c2ecf20Sopenharmony_ci info1); 9038c2ecf20Sopenharmony_ci ppdu_info->ldpc = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING, info1); 9048c2ecf20Sopenharmony_ci ppdu_info->gi = info1 & HAL_RX_HT_SIG_INFO_INFO1_GI; 9058c2ecf20Sopenharmony_ci 9068c2ecf20Sopenharmony_ci switch (ppdu_info->mcs) { 9078c2ecf20Sopenharmony_ci case 0 ... 7: 9088c2ecf20Sopenharmony_ci ppdu_info->nss = 1; 9098c2ecf20Sopenharmony_ci break; 9108c2ecf20Sopenharmony_ci case 8 ... 15: 9118c2ecf20Sopenharmony_ci ppdu_info->nss = 2; 9128c2ecf20Sopenharmony_ci break; 9138c2ecf20Sopenharmony_ci case 16 ... 23: 9148c2ecf20Sopenharmony_ci ppdu_info->nss = 3; 9158c2ecf20Sopenharmony_ci break; 9168c2ecf20Sopenharmony_ci case 24 ... 31: 9178c2ecf20Sopenharmony_ci ppdu_info->nss = 4; 9188c2ecf20Sopenharmony_ci break; 9198c2ecf20Sopenharmony_ci } 9208c2ecf20Sopenharmony_ci 9218c2ecf20Sopenharmony_ci if (ppdu_info->nss > 1) 9228c2ecf20Sopenharmony_ci ppdu_info->mcs = ppdu_info->mcs % 8; 9238c2ecf20Sopenharmony_ci 9248c2ecf20Sopenharmony_ci ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; 9258c2ecf20Sopenharmony_ci break; 9268c2ecf20Sopenharmony_ci } 9278c2ecf20Sopenharmony_ci case HAL_PHYRX_L_SIG_B: { 9288c2ecf20Sopenharmony_ci struct hal_rx_lsig_b_info *lsigb = 9298c2ecf20Sopenharmony_ci (struct hal_rx_lsig_b_info *)tlv_data; 9308c2ecf20Sopenharmony_ci 9318c2ecf20Sopenharmony_ci ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_B_INFO_INFO0_RATE, 9328c2ecf20Sopenharmony_ci __le32_to_cpu(lsigb->info0)); 9338c2ecf20Sopenharmony_ci ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; 9348c2ecf20Sopenharmony_ci break; 9358c2ecf20Sopenharmony_ci } 9368c2ecf20Sopenharmony_ci case HAL_PHYRX_L_SIG_A: { 9378c2ecf20Sopenharmony_ci struct hal_rx_lsig_a_info *lsiga = 9388c2ecf20Sopenharmony_ci (struct hal_rx_lsig_a_info *)tlv_data; 9398c2ecf20Sopenharmony_ci 9408c2ecf20Sopenharmony_ci ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_A_INFO_INFO0_RATE, 9418c2ecf20Sopenharmony_ci __le32_to_cpu(lsiga->info0)); 9428c2ecf20Sopenharmony_ci ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; 9438c2ecf20Sopenharmony_ci break; 9448c2ecf20Sopenharmony_ci } 9458c2ecf20Sopenharmony_ci case HAL_PHYRX_VHT_SIG_A: { 9468c2ecf20Sopenharmony_ci struct hal_rx_vht_sig_a_info *vht_sig = 9478c2ecf20Sopenharmony_ci (struct hal_rx_vht_sig_a_info *)tlv_data; 9488c2ecf20Sopenharmony_ci u32 nsts; 9498c2ecf20Sopenharmony_ci u32 group_id; 9508c2ecf20Sopenharmony_ci u8 gi_setting; 9518c2ecf20Sopenharmony_ci 9528c2ecf20Sopenharmony_ci info0 = __le32_to_cpu(vht_sig->info0); 9538c2ecf20Sopenharmony_ci info1 = __le32_to_cpu(vht_sig->info1); 9548c2ecf20Sopenharmony_ci 9558c2ecf20Sopenharmony_ci ppdu_info->ldpc = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING, 9568c2ecf20Sopenharmony_ci info0); 9578c2ecf20Sopenharmony_ci ppdu_info->mcs = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_MCS, 9588c2ecf20Sopenharmony_ci info1); 9598c2ecf20Sopenharmony_ci gi_setting = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_GI_SETTING, 9608c2ecf20Sopenharmony_ci info1); 9618c2ecf20Sopenharmony_ci switch (gi_setting) { 9628c2ecf20Sopenharmony_ci case HAL_RX_VHT_SIG_A_NORMAL_GI: 9638c2ecf20Sopenharmony_ci ppdu_info->gi = HAL_RX_GI_0_8_US; 9648c2ecf20Sopenharmony_ci break; 9658c2ecf20Sopenharmony_ci case HAL_RX_VHT_SIG_A_SHORT_GI: 9668c2ecf20Sopenharmony_ci case HAL_RX_VHT_SIG_A_SHORT_GI_AMBIGUITY: 9678c2ecf20Sopenharmony_ci ppdu_info->gi = HAL_RX_GI_0_4_US; 9688c2ecf20Sopenharmony_ci break; 9698c2ecf20Sopenharmony_ci } 9708c2ecf20Sopenharmony_ci 9718c2ecf20Sopenharmony_ci ppdu_info->is_stbc = info0 & HAL_RX_VHT_SIG_A_INFO_INFO0_STBC; 9728c2ecf20Sopenharmony_ci nsts = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO0_NSTS, info0); 9738c2ecf20Sopenharmony_ci if (ppdu_info->is_stbc && nsts > 0) 9748c2ecf20Sopenharmony_ci nsts = ((nsts + 1) >> 1) - 1; 9758c2ecf20Sopenharmony_ci 9768c2ecf20Sopenharmony_ci ppdu_info->nss = (nsts & VHT_SIG_SU_NSS_MASK) + 1; 9778c2ecf20Sopenharmony_ci ppdu_info->bw = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO0_BW, 9788c2ecf20Sopenharmony_ci info0); 9798c2ecf20Sopenharmony_ci ppdu_info->beamformed = info1 & 9808c2ecf20Sopenharmony_ci HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED; 9818c2ecf20Sopenharmony_ci group_id = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO0_GROUP_ID, 9828c2ecf20Sopenharmony_ci info0); 9838c2ecf20Sopenharmony_ci if (group_id == 0 || group_id == 63) 9848c2ecf20Sopenharmony_ci ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; 9858c2ecf20Sopenharmony_ci else 9868c2ecf20Sopenharmony_ci ppdu_info->reception_type = 9878c2ecf20Sopenharmony_ci HAL_RX_RECEPTION_TYPE_MU_MIMO; 9888c2ecf20Sopenharmony_ci break; 9898c2ecf20Sopenharmony_ci } 9908c2ecf20Sopenharmony_ci case HAL_PHYRX_HE_SIG_A_SU: { 9918c2ecf20Sopenharmony_ci struct hal_rx_he_sig_a_su_info *he_sig_a = 9928c2ecf20Sopenharmony_ci (struct hal_rx_he_sig_a_su_info *)tlv_data; 9938c2ecf20Sopenharmony_ci u32 nsts, cp_ltf, dcm; 9948c2ecf20Sopenharmony_ci 9958c2ecf20Sopenharmony_ci info0 = __le32_to_cpu(he_sig_a->info0); 9968c2ecf20Sopenharmony_ci info1 = __le32_to_cpu(he_sig_a->info1); 9978c2ecf20Sopenharmony_ci 9988c2ecf20Sopenharmony_ci ppdu_info->mcs = 9998c2ecf20Sopenharmony_ci FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS, 10008c2ecf20Sopenharmony_ci info0); 10018c2ecf20Sopenharmony_ci ppdu_info->bw = 10028c2ecf20Sopenharmony_ci FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW, 10038c2ecf20Sopenharmony_ci info0); 10048c2ecf20Sopenharmony_ci ppdu_info->ldpc = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING, info0); 10058c2ecf20Sopenharmony_ci ppdu_info->is_stbc = info1 & 10068c2ecf20Sopenharmony_ci HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC; 10078c2ecf20Sopenharmony_ci ppdu_info->beamformed = info1 & 10088c2ecf20Sopenharmony_ci HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF; 10098c2ecf20Sopenharmony_ci dcm = info0 & HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM; 10108c2ecf20Sopenharmony_ci cp_ltf = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE, 10118c2ecf20Sopenharmony_ci info0); 10128c2ecf20Sopenharmony_ci nsts = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS, info0); 10138c2ecf20Sopenharmony_ci 10148c2ecf20Sopenharmony_ci switch (cp_ltf) { 10158c2ecf20Sopenharmony_ci case 0: 10168c2ecf20Sopenharmony_ci case 1: 10178c2ecf20Sopenharmony_ci ppdu_info->gi = HAL_RX_GI_0_8_US; 10188c2ecf20Sopenharmony_ci break; 10198c2ecf20Sopenharmony_ci case 2: 10208c2ecf20Sopenharmony_ci ppdu_info->gi = HAL_RX_GI_1_6_US; 10218c2ecf20Sopenharmony_ci break; 10228c2ecf20Sopenharmony_ci case 3: 10238c2ecf20Sopenharmony_ci if (dcm && ppdu_info->is_stbc) 10248c2ecf20Sopenharmony_ci ppdu_info->gi = HAL_RX_GI_0_8_US; 10258c2ecf20Sopenharmony_ci else 10268c2ecf20Sopenharmony_ci ppdu_info->gi = HAL_RX_GI_3_2_US; 10278c2ecf20Sopenharmony_ci break; 10288c2ecf20Sopenharmony_ci } 10298c2ecf20Sopenharmony_ci 10308c2ecf20Sopenharmony_ci ppdu_info->nss = nsts + 1; 10318c2ecf20Sopenharmony_ci ppdu_info->dcm = dcm; 10328c2ecf20Sopenharmony_ci ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; 10338c2ecf20Sopenharmony_ci break; 10348c2ecf20Sopenharmony_ci } 10358c2ecf20Sopenharmony_ci case HAL_PHYRX_HE_SIG_A_MU_DL: { 10368c2ecf20Sopenharmony_ci struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl = 10378c2ecf20Sopenharmony_ci (struct hal_rx_he_sig_a_mu_dl_info *)tlv_data; 10388c2ecf20Sopenharmony_ci 10398c2ecf20Sopenharmony_ci u32 cp_ltf; 10408c2ecf20Sopenharmony_ci 10418c2ecf20Sopenharmony_ci info0 = __le32_to_cpu(he_sig_a_mu_dl->info0); 10428c2ecf20Sopenharmony_ci info1 = __le32_to_cpu(he_sig_a_mu_dl->info1); 10438c2ecf20Sopenharmony_ci 10448c2ecf20Sopenharmony_ci ppdu_info->bw = 10458c2ecf20Sopenharmony_ci FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_TRANSMIT_BW, 10468c2ecf20Sopenharmony_ci info0); 10478c2ecf20Sopenharmony_ci cp_ltf = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_CP_LTF_SIZE, 10488c2ecf20Sopenharmony_ci info0); 10498c2ecf20Sopenharmony_ci 10508c2ecf20Sopenharmony_ci switch (cp_ltf) { 10518c2ecf20Sopenharmony_ci case 0: 10528c2ecf20Sopenharmony_ci case 1: 10538c2ecf20Sopenharmony_ci ppdu_info->gi = HAL_RX_GI_0_8_US; 10548c2ecf20Sopenharmony_ci break; 10558c2ecf20Sopenharmony_ci case 2: 10568c2ecf20Sopenharmony_ci ppdu_info->gi = HAL_RX_GI_1_6_US; 10578c2ecf20Sopenharmony_ci break; 10588c2ecf20Sopenharmony_ci case 3: 10598c2ecf20Sopenharmony_ci ppdu_info->gi = HAL_RX_GI_3_2_US; 10608c2ecf20Sopenharmony_ci break; 10618c2ecf20Sopenharmony_ci } 10628c2ecf20Sopenharmony_ci 10638c2ecf20Sopenharmony_ci ppdu_info->is_stbc = info1 & 10648c2ecf20Sopenharmony_ci HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_STBC; 10658c2ecf20Sopenharmony_ci ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO; 10668c2ecf20Sopenharmony_ci break; 10678c2ecf20Sopenharmony_ci } 10688c2ecf20Sopenharmony_ci case HAL_PHYRX_HE_SIG_B1_MU: { 10698c2ecf20Sopenharmony_ci struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu = 10708c2ecf20Sopenharmony_ci (struct hal_rx_he_sig_b1_mu_info *)tlv_data; 10718c2ecf20Sopenharmony_ci u16 ru_tones; 10728c2ecf20Sopenharmony_ci 10738c2ecf20Sopenharmony_ci info0 = __le32_to_cpu(he_sig_b1_mu->info0); 10748c2ecf20Sopenharmony_ci 10758c2ecf20Sopenharmony_ci ru_tones = FIELD_GET(HAL_RX_HE_SIG_B1_MU_INFO_INFO0_RU_ALLOCATION, 10768c2ecf20Sopenharmony_ci info0); 10778c2ecf20Sopenharmony_ci ppdu_info->ru_alloc = ath11k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones); 10788c2ecf20Sopenharmony_ci ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO; 10798c2ecf20Sopenharmony_ci break; 10808c2ecf20Sopenharmony_ci } 10818c2ecf20Sopenharmony_ci case HAL_PHYRX_HE_SIG_B2_MU: { 10828c2ecf20Sopenharmony_ci struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu = 10838c2ecf20Sopenharmony_ci (struct hal_rx_he_sig_b2_mu_info *)tlv_data; 10848c2ecf20Sopenharmony_ci 10858c2ecf20Sopenharmony_ci info0 = __le32_to_cpu(he_sig_b2_mu->info0); 10868c2ecf20Sopenharmony_ci 10878c2ecf20Sopenharmony_ci ppdu_info->mcs = 10888c2ecf20Sopenharmony_ci FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS, 10898c2ecf20Sopenharmony_ci info0); 10908c2ecf20Sopenharmony_ci ppdu_info->nss = 10918c2ecf20Sopenharmony_ci FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS, 10928c2ecf20Sopenharmony_ci info0) + 1; 10938c2ecf20Sopenharmony_ci ppdu_info->ldpc = FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING, 10948c2ecf20Sopenharmony_ci info0); 10958c2ecf20Sopenharmony_ci break; 10968c2ecf20Sopenharmony_ci } 10978c2ecf20Sopenharmony_ci case HAL_PHYRX_HE_SIG_B2_OFDMA: { 10988c2ecf20Sopenharmony_ci struct hal_rx_he_sig_b2_ofdma_info *he_sig_b2_ofdma = 10998c2ecf20Sopenharmony_ci (struct hal_rx_he_sig_b2_ofdma_info *)tlv_data; 11008c2ecf20Sopenharmony_ci 11018c2ecf20Sopenharmony_ci info0 = __le32_to_cpu(he_sig_b2_ofdma->info0); 11028c2ecf20Sopenharmony_ci 11038c2ecf20Sopenharmony_ci ppdu_info->mcs = 11048c2ecf20Sopenharmony_ci FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS, 11058c2ecf20Sopenharmony_ci info0); 11068c2ecf20Sopenharmony_ci ppdu_info->nss = 11078c2ecf20Sopenharmony_ci FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS, 11088c2ecf20Sopenharmony_ci info0) + 1; 11098c2ecf20Sopenharmony_ci ppdu_info->beamformed = 11108c2ecf20Sopenharmony_ci info0 & 11118c2ecf20Sopenharmony_ci HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF; 11128c2ecf20Sopenharmony_ci ppdu_info->ldpc = FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING, 11138c2ecf20Sopenharmony_ci info0); 11148c2ecf20Sopenharmony_ci ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA; 11158c2ecf20Sopenharmony_ci break; 11168c2ecf20Sopenharmony_ci } 11178c2ecf20Sopenharmony_ci case HAL_PHYRX_RSSI_LEGACY: { 11188c2ecf20Sopenharmony_ci struct hal_rx_phyrx_rssi_legacy_info *rssi = 11198c2ecf20Sopenharmony_ci (struct hal_rx_phyrx_rssi_legacy_info *)tlv_data; 11208c2ecf20Sopenharmony_ci 11218c2ecf20Sopenharmony_ci /* TODO: Please note that the combined rssi will not be accurate 11228c2ecf20Sopenharmony_ci * in MU case. Rssi in MU needs to be retrieved from 11238c2ecf20Sopenharmony_ci * PHYRX_OTHER_RECEIVE_INFO TLV. 11248c2ecf20Sopenharmony_ci */ 11258c2ecf20Sopenharmony_ci ppdu_info->rssi_comb = 11268c2ecf20Sopenharmony_ci FIELD_GET(HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO1_RSSI_COMB, 11278c2ecf20Sopenharmony_ci __le32_to_cpu(rssi->info0)); 11288c2ecf20Sopenharmony_ci break; 11298c2ecf20Sopenharmony_ci } 11308c2ecf20Sopenharmony_ci case HAL_RX_MPDU_START: { 11318c2ecf20Sopenharmony_ci struct hal_rx_mpdu_info *mpdu_info = 11328c2ecf20Sopenharmony_ci (struct hal_rx_mpdu_info *)tlv_data; 11338c2ecf20Sopenharmony_ci u16 peer_id; 11348c2ecf20Sopenharmony_ci 11358c2ecf20Sopenharmony_ci peer_id = FIELD_GET(HAL_RX_MPDU_INFO_INFO0_PEERID, 11368c2ecf20Sopenharmony_ci __le32_to_cpu(mpdu_info->info0)); 11378c2ecf20Sopenharmony_ci if (peer_id) 11388c2ecf20Sopenharmony_ci ppdu_info->peer_id = peer_id; 11398c2ecf20Sopenharmony_ci break; 11408c2ecf20Sopenharmony_ci } 11418c2ecf20Sopenharmony_ci case HAL_RXPCU_PPDU_END_INFO: { 11428c2ecf20Sopenharmony_ci struct hal_rx_ppdu_end_duration *ppdu_rx_duration = 11438c2ecf20Sopenharmony_ci (struct hal_rx_ppdu_end_duration *)tlv_data; 11448c2ecf20Sopenharmony_ci ppdu_info->rx_duration = 11458c2ecf20Sopenharmony_ci FIELD_GET(HAL_RX_PPDU_END_DURATION, 11468c2ecf20Sopenharmony_ci __le32_to_cpu(ppdu_rx_duration->info0)); 11478c2ecf20Sopenharmony_ci break; 11488c2ecf20Sopenharmony_ci } 11498c2ecf20Sopenharmony_ci case HAL_DUMMY: 11508c2ecf20Sopenharmony_ci return HAL_RX_MON_STATUS_BUF_DONE; 11518c2ecf20Sopenharmony_ci case HAL_RX_PPDU_END_STATUS_DONE: 11528c2ecf20Sopenharmony_ci case 0: 11538c2ecf20Sopenharmony_ci return HAL_RX_MON_STATUS_PPDU_DONE; 11548c2ecf20Sopenharmony_ci default: 11558c2ecf20Sopenharmony_ci break; 11568c2ecf20Sopenharmony_ci } 11578c2ecf20Sopenharmony_ci 11588c2ecf20Sopenharmony_ci return HAL_RX_MON_STATUS_PPDU_NOT_DONE; 11598c2ecf20Sopenharmony_ci} 11608c2ecf20Sopenharmony_ci 11618c2ecf20Sopenharmony_cienum hal_rx_mon_status 11628c2ecf20Sopenharmony_ciath11k_hal_rx_parse_mon_status(struct ath11k_base *ab, 11638c2ecf20Sopenharmony_ci struct hal_rx_mon_ppdu_info *ppdu_info, 11648c2ecf20Sopenharmony_ci struct sk_buff *skb) 11658c2ecf20Sopenharmony_ci{ 11668c2ecf20Sopenharmony_ci struct hal_tlv_hdr *tlv; 11678c2ecf20Sopenharmony_ci enum hal_rx_mon_status hal_status = HAL_RX_MON_STATUS_BUF_DONE; 11688c2ecf20Sopenharmony_ci u16 tlv_tag; 11698c2ecf20Sopenharmony_ci u16 tlv_len; 11708c2ecf20Sopenharmony_ci u8 *ptr = skb->data; 11718c2ecf20Sopenharmony_ci 11728c2ecf20Sopenharmony_ci do { 11738c2ecf20Sopenharmony_ci tlv = (struct hal_tlv_hdr *)ptr; 11748c2ecf20Sopenharmony_ci tlv_tag = FIELD_GET(HAL_TLV_HDR_TAG, tlv->tl); 11758c2ecf20Sopenharmony_ci tlv_len = FIELD_GET(HAL_TLV_HDR_LEN, tlv->tl); 11768c2ecf20Sopenharmony_ci ptr += sizeof(*tlv); 11778c2ecf20Sopenharmony_ci 11788c2ecf20Sopenharmony_ci /* The actual length of PPDU_END is the combined length of many PHY 11798c2ecf20Sopenharmony_ci * TLVs that follow. Skip the TLV header and 11808c2ecf20Sopenharmony_ci * rx_rxpcu_classification_overview that follows the header to get to 11818c2ecf20Sopenharmony_ci * next TLV. 11828c2ecf20Sopenharmony_ci */ 11838c2ecf20Sopenharmony_ci if (tlv_tag == HAL_RX_PPDU_END) 11848c2ecf20Sopenharmony_ci tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview); 11858c2ecf20Sopenharmony_ci 11868c2ecf20Sopenharmony_ci hal_status = ath11k_hal_rx_parse_mon_status_tlv(ab, ppdu_info, 11878c2ecf20Sopenharmony_ci tlv_tag, ptr); 11888c2ecf20Sopenharmony_ci ptr += tlv_len; 11898c2ecf20Sopenharmony_ci ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN); 11908c2ecf20Sopenharmony_ci 11918c2ecf20Sopenharmony_ci if ((ptr - skb->data) >= DP_RX_BUFFER_SIZE) 11928c2ecf20Sopenharmony_ci break; 11938c2ecf20Sopenharmony_ci } while (hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE); 11948c2ecf20Sopenharmony_ci 11958c2ecf20Sopenharmony_ci return hal_status; 11968c2ecf20Sopenharmony_ci} 11978c2ecf20Sopenharmony_ci 11988c2ecf20Sopenharmony_civoid ath11k_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr, 11998c2ecf20Sopenharmony_ci u32 *sw_cookie, void **pp_buf_addr, 12008c2ecf20Sopenharmony_ci u8 *rbm, u32 *msdu_cnt) 12018c2ecf20Sopenharmony_ci{ 12028c2ecf20Sopenharmony_ci struct hal_reo_entrance_ring *reo_ent_ring = 12038c2ecf20Sopenharmony_ci (struct hal_reo_entrance_ring *)rx_desc; 12048c2ecf20Sopenharmony_ci struct ath11k_buffer_addr *buf_addr_info; 12058c2ecf20Sopenharmony_ci struct rx_mpdu_desc *rx_mpdu_desc_info_details; 12068c2ecf20Sopenharmony_ci 12078c2ecf20Sopenharmony_ci rx_mpdu_desc_info_details = 12088c2ecf20Sopenharmony_ci (struct rx_mpdu_desc *)&reo_ent_ring->rx_mpdu_info; 12098c2ecf20Sopenharmony_ci 12108c2ecf20Sopenharmony_ci *msdu_cnt = FIELD_GET(RX_MPDU_DESC_INFO0_MSDU_COUNT, 12118c2ecf20Sopenharmony_ci rx_mpdu_desc_info_details->info0); 12128c2ecf20Sopenharmony_ci 12138c2ecf20Sopenharmony_ci buf_addr_info = (struct ath11k_buffer_addr *)&reo_ent_ring->buf_addr_info; 12148c2ecf20Sopenharmony_ci 12158c2ecf20Sopenharmony_ci *paddr = (((u64)FIELD_GET(BUFFER_ADDR_INFO1_ADDR, 12168c2ecf20Sopenharmony_ci buf_addr_info->info1)) << 32) | 12178c2ecf20Sopenharmony_ci FIELD_GET(BUFFER_ADDR_INFO0_ADDR, 12188c2ecf20Sopenharmony_ci buf_addr_info->info0); 12198c2ecf20Sopenharmony_ci 12208c2ecf20Sopenharmony_ci *sw_cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, 12218c2ecf20Sopenharmony_ci buf_addr_info->info1); 12228c2ecf20Sopenharmony_ci *rbm = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, 12238c2ecf20Sopenharmony_ci buf_addr_info->info1); 12248c2ecf20Sopenharmony_ci 12258c2ecf20Sopenharmony_ci *pp_buf_addr = (void *)buf_addr_info; 12268c2ecf20Sopenharmony_ci} 1227