1d5c65159SKalle Valo // SPDX-License-Identifier: BSD-3-Clause-Clear 2d5c65159SKalle Valo /* 3d5c65159SKalle Valo * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4d5c65159SKalle Valo */ 5d5c65159SKalle Valo 6d5c65159SKalle Valo #include "ahb.h" 7d5c65159SKalle Valo #include "debug.h" 8d5c65159SKalle Valo #include "hal.h" 9d5c65159SKalle Valo #include "hal_tx.h" 10d5c65159SKalle Valo #include "hal_rx.h" 11d5c65159SKalle Valo #include "hal_desc.h" 12d5c65159SKalle Valo 13d5c65159SKalle Valo static void ath11k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, 14d5c65159SKalle Valo u8 owner, u8 buffer_type, u32 magic) 15d5c65159SKalle Valo { 16d5c65159SKalle Valo hdr->info0 = FIELD_PREP(HAL_DESC_HDR_INFO0_OWNER, owner) | 17d5c65159SKalle Valo FIELD_PREP(HAL_DESC_HDR_INFO0_BUF_TYPE, buffer_type); 18d5c65159SKalle Valo 19d5c65159SKalle Valo /* Magic pattern in reserved bits for debugging */ 20d5c65159SKalle Valo hdr->info0 |= FIELD_PREP(HAL_DESC_HDR_INFO0_DBG_RESERVED, magic); 21d5c65159SKalle Valo } 22d5c65159SKalle Valo 23d5c65159SKalle Valo static int ath11k_hal_reo_cmd_queue_stats(struct hal_tlv_hdr *tlv, 24d5c65159SKalle Valo struct ath11k_hal_reo_cmd *cmd) 25d5c65159SKalle Valo { 26d5c65159SKalle Valo struct hal_reo_get_queue_stats *desc; 27d5c65159SKalle Valo 28d5c65159SKalle Valo tlv->tl = FIELD_PREP(HAL_TLV_HDR_TAG, HAL_REO_GET_QUEUE_STATS) | 29d5c65159SKalle Valo FIELD_PREP(HAL_TLV_HDR_LEN, sizeof(*desc)); 30d5c65159SKalle Valo 31d5c65159SKalle Valo desc = (struct hal_reo_get_queue_stats *)tlv->value; 32d5c65159SKalle Valo memset(&desc->queue_addr_lo, 0, 33d5c65159SKalle Valo (sizeof(*desc) - sizeof(struct hal_reo_cmd_hdr))); 34d5c65159SKalle Valo 35d5c65159SKalle Valo desc->cmd.info0 &= ~HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED; 36d5c65159SKalle Valo if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS) 37d5c65159SKalle Valo desc->cmd.info0 |= HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED; 38d5c65159SKalle Valo 39d5c65159SKalle Valo desc->queue_addr_lo = cmd->addr_lo; 40d5c65159SKalle Valo desc->info0 = FIELD_PREP(HAL_REO_GET_QUEUE_STATS_INFO0_QUEUE_ADDR_HI, 41d5c65159SKalle Valo cmd->addr_hi); 42d5c65159SKalle Valo if (cmd->flag & HAL_REO_CMD_FLG_STATS_CLEAR) 43d5c65159SKalle Valo desc->info0 |= HAL_REO_GET_QUEUE_STATS_INFO0_CLEAR_STATS; 44d5c65159SKalle Valo 45d5c65159SKalle Valo return FIELD_GET(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, desc->cmd.info0); 46d5c65159SKalle Valo } 47d5c65159SKalle Valo 48d5c65159SKalle Valo static int ath11k_hal_reo_cmd_flush_cache(struct ath11k_hal *hal, struct hal_tlv_hdr *tlv, 49d5c65159SKalle Valo struct ath11k_hal_reo_cmd *cmd) 50d5c65159SKalle Valo { 51d5c65159SKalle Valo struct hal_reo_flush_cache *desc; 52d5c65159SKalle Valo u8 avail_slot = ffz(hal->avail_blk_resource); 53d5c65159SKalle Valo 54d5c65159SKalle Valo if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER) { 55d5c65159SKalle Valo if (avail_slot >= HAL_MAX_AVAIL_BLK_RES) 56d5c65159SKalle Valo return -ENOSPC; 57d5c65159SKalle Valo 58d5c65159SKalle Valo hal->current_blk_index = avail_slot; 59d5c65159SKalle Valo } 60d5c65159SKalle Valo 61d5c65159SKalle Valo tlv->tl = FIELD_PREP(HAL_TLV_HDR_TAG, HAL_REO_FLUSH_CACHE) | 62d5c65159SKalle Valo FIELD_PREP(HAL_TLV_HDR_LEN, sizeof(*desc)); 63d5c65159SKalle Valo 64d5c65159SKalle Valo desc = (struct hal_reo_flush_cache *)tlv->value; 65d5c65159SKalle Valo memset(&desc->cache_addr_lo, 0, 66d5c65159SKalle Valo (sizeof(*desc) - sizeof(struct hal_reo_cmd_hdr))); 67d5c65159SKalle Valo 68d5c65159SKalle Valo desc->cmd.info0 &= ~HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED; 69d5c65159SKalle Valo if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS) 70d5c65159SKalle Valo desc->cmd.info0 |= HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED; 71d5c65159SKalle Valo 72d5c65159SKalle Valo desc->cache_addr_lo = cmd->addr_lo; 73d5c65159SKalle Valo desc->info0 = FIELD_PREP(HAL_REO_FLUSH_CACHE_INFO0_CACHE_ADDR_HI, 74d5c65159SKalle Valo cmd->addr_hi); 75d5c65159SKalle Valo 76d5c65159SKalle Valo if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS) 77d5c65159SKalle Valo desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_FWD_ALL_MPDUS; 78d5c65159SKalle Valo 79d5c65159SKalle Valo if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER) { 80d5c65159SKalle Valo desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_BLOCK_CACHE_USAGE; 81d5c65159SKalle Valo desc->info0 |= 82d5c65159SKalle Valo FIELD_PREP(HAL_REO_FLUSH_CACHE_INFO0_BLOCK_RESRC_IDX, 83d5c65159SKalle Valo avail_slot); 84d5c65159SKalle Valo } 85d5c65159SKalle Valo 86d5c65159SKalle Valo if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_NO_INVAL) 87d5c65159SKalle Valo desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_FLUSH_WO_INVALIDATE; 88d5c65159SKalle Valo 89d5c65159SKalle Valo if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_ALL) 90d5c65159SKalle Valo desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_FLUSH_ALL; 91d5c65159SKalle Valo 92d5c65159SKalle Valo return FIELD_GET(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, desc->cmd.info0); 93d5c65159SKalle Valo } 94d5c65159SKalle Valo 95d5c65159SKalle Valo static int ath11k_hal_reo_cmd_update_rx_queue(struct hal_tlv_hdr *tlv, 96d5c65159SKalle Valo struct ath11k_hal_reo_cmd *cmd) 97d5c65159SKalle Valo { 98d5c65159SKalle Valo struct hal_reo_update_rx_queue *desc; 99d5c65159SKalle Valo 100d5c65159SKalle Valo tlv->tl = FIELD_PREP(HAL_TLV_HDR_TAG, HAL_REO_UPDATE_RX_REO_QUEUE) | 101d5c65159SKalle Valo FIELD_PREP(HAL_TLV_HDR_LEN, sizeof(*desc)); 102d5c65159SKalle Valo 103d5c65159SKalle Valo desc = (struct hal_reo_update_rx_queue *)tlv->value; 104d5c65159SKalle Valo memset(&desc->queue_addr_lo, 0, 105d5c65159SKalle Valo (sizeof(*desc) - sizeof(struct hal_reo_cmd_hdr))); 106d5c65159SKalle Valo 107d5c65159SKalle Valo desc->cmd.info0 &= ~HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED; 108d5c65159SKalle Valo if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS) 109d5c65159SKalle Valo desc->cmd.info0 |= HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED; 110d5c65159SKalle Valo 111d5c65159SKalle Valo desc->queue_addr_lo = cmd->addr_lo; 112d5c65159SKalle Valo desc->info0 = 113d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_QUEUE_ADDR_HI, 114d5c65159SKalle Valo cmd->addr_hi) | 115d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_RX_QUEUE_NUM, 116d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_RX_QUEUE_NUM)) | 117d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_VLD, 118d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_VLD)) | 119d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_ASSOC_LNK_DESC_CNT, 120d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_ALDC)) | 121d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_DIS_DUP_DETECTION, 122d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_DIS_DUP_DETECTION)) | 123d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SOFT_REORDER_EN, 124d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_SOFT_REORDER_EN)) | 125d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_AC, 126d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_AC)) | 127d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_BAR, 128d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_BAR)) | 129d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_RETRY, 130d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_RETRY)) | 131d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_CHECK_2K_MODE, 132d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_CHECK_2K_MODE)) | 133d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_OOR_MODE, 134d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_OOR_MODE)) | 135d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_BA_WINDOW_SIZE, 136d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_BA_WINDOW_SIZE)) | 137d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_CHECK, 138d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_CHECK)) | 139d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_EVEN_PN, 140d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_EVEN_PN)) | 141d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_UNEVEN_PN, 142d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_UNEVEN_PN)) | 143d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_HANDLE_ENABLE, 144d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_HANDLE_ENABLE)) | 145d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_SIZE, 146d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_SIZE)) | 147d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_IGNORE_AMPDU_FLG, 148d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_IGNORE_AMPDU_FLG)) | 149d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SVLD, 150d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_SVLD)) | 151d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SSN, 152d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_SSN)) | 153d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SEQ_2K_ERR, 154d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_SEQ_2K_ERR)) | 155d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_VALID, 156d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_VALID)) | 157d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN, 158d5c65159SKalle Valo !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN)); 159d5c65159SKalle Valo 160d5c65159SKalle Valo desc->info1 = 161d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_RX_QUEUE_NUMBER, 162d5c65159SKalle Valo cmd->rx_queue_num) | 163d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_VLD, 164d5c65159SKalle Valo !!(cmd->upd1 & HAL_REO_CMD_UPD1_VLD)) | 165d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_ASSOC_LNK_DESC_COUNTER, 166d5c65159SKalle Valo FIELD_GET(HAL_REO_CMD_UPD1_ALDC, cmd->upd1)) | 167d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_DIS_DUP_DETECTION, 168d5c65159SKalle Valo !!(cmd->upd1 & HAL_REO_CMD_UPD1_DIS_DUP_DETECTION)) | 169d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_SOFT_REORDER_EN, 170d5c65159SKalle Valo !!(cmd->upd1 & HAL_REO_CMD_UPD1_SOFT_REORDER_EN)) | 171d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_AC, 172d5c65159SKalle Valo FIELD_GET(HAL_REO_CMD_UPD1_AC, cmd->upd1)) | 173d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_BAR, 174d5c65159SKalle Valo !!(cmd->upd1 & HAL_REO_CMD_UPD1_BAR)) | 175d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_CHECK_2K_MODE, 176d5c65159SKalle Valo !!(cmd->upd1 & HAL_REO_CMD_UPD1_CHECK_2K_MODE)) | 177d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_RETRY, 178d5c65159SKalle Valo !!(cmd->upd1 & HAL_REO_CMD_UPD1_RETRY)) | 179d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_OOR_MODE, 180d5c65159SKalle Valo !!(cmd->upd1 & HAL_REO_CMD_UPD1_OOR_MODE)) | 181d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_PN_CHECK, 182d5c65159SKalle Valo !!(cmd->upd1 & HAL_REO_CMD_UPD1_PN_CHECK)) | 183d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_EVEN_PN, 184d5c65159SKalle Valo !!(cmd->upd1 & HAL_REO_CMD_UPD1_EVEN_PN)) | 185d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_UNEVEN_PN, 186d5c65159SKalle Valo !!(cmd->upd1 & HAL_REO_CMD_UPD1_UNEVEN_PN)) | 187d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_PN_HANDLE_ENABLE, 188d5c65159SKalle Valo !!(cmd->upd1 & HAL_REO_CMD_UPD1_PN_HANDLE_ENABLE)) | 189d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_IGNORE_AMPDU_FLG, 190d5c65159SKalle Valo !!(cmd->upd1 & HAL_REO_CMD_UPD1_IGNORE_AMPDU_FLG)); 191d5c65159SKalle Valo 192d5c65159SKalle Valo if (cmd->pn_size == 24) 193d5c65159SKalle Valo cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_24; 194d5c65159SKalle Valo else if (cmd->pn_size == 48) 195d5c65159SKalle Valo cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_48; 196d5c65159SKalle Valo else if (cmd->pn_size == 128) 197d5c65159SKalle Valo cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_128; 198d5c65159SKalle Valo 199d5c65159SKalle Valo if (cmd->ba_window_size < 1) 200d5c65159SKalle Valo cmd->ba_window_size = 1; 201d5c65159SKalle Valo 202d5c65159SKalle Valo if (cmd->ba_window_size == 1) 203d5c65159SKalle Valo cmd->ba_window_size++; 204d5c65159SKalle Valo 205d5c65159SKalle Valo desc->info2 = 206d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_BA_WINDOW_SIZE, 207d5c65159SKalle Valo cmd->ba_window_size - 1) | 208d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_PN_SIZE, cmd->pn_size) | 209d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_SVLD, 210d5c65159SKalle Valo !!(cmd->upd2 & HAL_REO_CMD_UPD2_SVLD)) | 211d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_SSN, 212d5c65159SKalle Valo FIELD_GET(HAL_REO_CMD_UPD2_SSN, cmd->upd2)) | 213d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_SEQ_2K_ERR, 214d5c65159SKalle Valo !!(cmd->upd2 & HAL_REO_CMD_UPD2_SEQ_2K_ERR)) | 215d5c65159SKalle Valo FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_PN_ERR, 216d5c65159SKalle Valo !!(cmd->upd2 & HAL_REO_CMD_UPD2_PN_ERR)); 217d5c65159SKalle Valo 218d5c65159SKalle Valo return FIELD_GET(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, desc->cmd.info0); 219d5c65159SKalle Valo } 220d5c65159SKalle Valo 221d5c65159SKalle Valo int ath11k_hal_reo_cmd_send(struct ath11k_base *ab, struct hal_srng *srng, 222d5c65159SKalle Valo enum hal_reo_cmd_type type, 223d5c65159SKalle Valo struct ath11k_hal_reo_cmd *cmd) 224d5c65159SKalle Valo { 225d5c65159SKalle Valo struct hal_tlv_hdr *reo_desc; 226d5c65159SKalle Valo int ret; 227d5c65159SKalle Valo 228d5c65159SKalle Valo spin_lock_bh(&srng->lock); 229d5c65159SKalle Valo 230d5c65159SKalle Valo ath11k_hal_srng_access_begin(ab, srng); 231d5c65159SKalle Valo reo_desc = (struct hal_tlv_hdr *)ath11k_hal_srng_src_get_next_entry(ab, srng); 232d5c65159SKalle Valo if (!reo_desc) { 233d5c65159SKalle Valo ret = -ENOBUFS; 234d5c65159SKalle Valo goto out; 235d5c65159SKalle Valo } 236d5c65159SKalle Valo 237d5c65159SKalle Valo switch (type) { 238d5c65159SKalle Valo case HAL_REO_CMD_GET_QUEUE_STATS: 239d5c65159SKalle Valo ret = ath11k_hal_reo_cmd_queue_stats(reo_desc, cmd); 240d5c65159SKalle Valo break; 241d5c65159SKalle Valo case HAL_REO_CMD_FLUSH_CACHE: 242d5c65159SKalle Valo ret = ath11k_hal_reo_cmd_flush_cache(&ab->hal, reo_desc, cmd); 243d5c65159SKalle Valo break; 244d5c65159SKalle Valo case HAL_REO_CMD_UPDATE_RX_QUEUE: 245d5c65159SKalle Valo ret = ath11k_hal_reo_cmd_update_rx_queue(reo_desc, cmd); 246d5c65159SKalle Valo break; 247d5c65159SKalle Valo case HAL_REO_CMD_FLUSH_QUEUE: 248d5c65159SKalle Valo case HAL_REO_CMD_UNBLOCK_CACHE: 249d5c65159SKalle Valo case HAL_REO_CMD_FLUSH_TIMEOUT_LIST: 250d5c65159SKalle Valo ath11k_warn(ab, "Unsupported reo command %d\n", type); 251d5c65159SKalle Valo ret = -ENOTSUPP; 252d5c65159SKalle Valo break; 253d5c65159SKalle Valo default: 254d5c65159SKalle Valo ath11k_warn(ab, "Unknown reo command %d\n", type); 255d5c65159SKalle Valo ret = -EINVAL; 256d5c65159SKalle Valo break; 257d5c65159SKalle Valo } 258d5c65159SKalle Valo 259d5c65159SKalle Valo out: 260d5c65159SKalle Valo ath11k_hal_srng_access_end(ab, srng); 261d5c65159SKalle Valo spin_unlock_bh(&srng->lock); 262d5c65159SKalle Valo 263d5c65159SKalle Valo return ret; 264d5c65159SKalle Valo } 265d5c65159SKalle Valo 266d5c65159SKalle Valo void ath11k_hal_rx_buf_addr_info_set(void *desc, dma_addr_t paddr, 267d5c65159SKalle Valo u32 cookie, u8 manager) 268d5c65159SKalle Valo { 269d5c65159SKalle Valo struct ath11k_buffer_addr *binfo = (struct ath11k_buffer_addr *)desc; 270d5c65159SKalle Valo u32 paddr_lo, paddr_hi; 271d5c65159SKalle Valo 272d5c65159SKalle Valo paddr_lo = lower_32_bits(paddr); 273d5c65159SKalle Valo paddr_hi = upper_32_bits(paddr); 274d5c65159SKalle Valo binfo->info0 = FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, paddr_lo); 275d5c65159SKalle Valo binfo->info1 = FIELD_PREP(BUFFER_ADDR_INFO1_ADDR, paddr_hi) | 276d5c65159SKalle Valo FIELD_PREP(BUFFER_ADDR_INFO1_SW_COOKIE, cookie) | 277d5c65159SKalle Valo FIELD_PREP(BUFFER_ADDR_INFO1_RET_BUF_MGR, manager); 278d5c65159SKalle Valo } 279d5c65159SKalle Valo 280d5c65159SKalle Valo void ath11k_hal_rx_buf_addr_info_get(void *desc, dma_addr_t *paddr, 281d5c65159SKalle Valo u32 *cookie, u8 *rbm) 282d5c65159SKalle Valo { 283d5c65159SKalle Valo struct ath11k_buffer_addr *binfo = (struct ath11k_buffer_addr *)desc; 284d5c65159SKalle Valo 285d5c65159SKalle Valo *paddr = 286d5c65159SKalle Valo (((u64)FIELD_GET(BUFFER_ADDR_INFO1_ADDR, binfo->info1)) << 32) | 287d5c65159SKalle Valo FIELD_GET(BUFFER_ADDR_INFO0_ADDR, binfo->info0); 288d5c65159SKalle Valo *cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, binfo->info1); 289d5c65159SKalle Valo *rbm = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, binfo->info1); 290d5c65159SKalle Valo } 291d5c65159SKalle Valo 292d5c65159SKalle Valo void ath11k_hal_rx_msdu_link_info_get(void *link_desc, u32 *num_msdus, 293293cb583SJohn Crispin u32 *msdu_cookies, 294d5c65159SKalle Valo enum hal_rx_buf_return_buf_manager *rbm) 295d5c65159SKalle Valo { 296d5c65159SKalle Valo struct hal_rx_msdu_link *link = (struct hal_rx_msdu_link *)link_desc; 297d5c65159SKalle Valo struct hal_rx_msdu_details *msdu; 298d5c65159SKalle Valo int i; 299d5c65159SKalle Valo 300d5c65159SKalle Valo *num_msdus = HAL_NUM_RX_MSDUS_PER_LINK_DESC; 301d5c65159SKalle Valo 302d5c65159SKalle Valo msdu = &link->msdu_link[0]; 303d5c65159SKalle Valo *rbm = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, 304d5c65159SKalle Valo msdu->buf_addr_info.info1); 305d5c65159SKalle Valo 306d5c65159SKalle Valo for (i = 0; i < *num_msdus; i++) { 307d5c65159SKalle Valo msdu = &link->msdu_link[i]; 308d5c65159SKalle Valo 309d5c65159SKalle Valo if (!FIELD_GET(BUFFER_ADDR_INFO0_ADDR, 310d5c65159SKalle Valo msdu->buf_addr_info.info0)) { 311d5c65159SKalle Valo *num_msdus = i; 312d5c65159SKalle Valo break; 313d5c65159SKalle Valo } 314293cb583SJohn Crispin *msdu_cookies = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, 315d5c65159SKalle Valo msdu->buf_addr_info.info1); 316293cb583SJohn Crispin msdu_cookies++; 317d5c65159SKalle Valo } 318d5c65159SKalle Valo } 319d5c65159SKalle Valo 320d5c65159SKalle Valo int ath11k_hal_desc_reo_parse_err(struct ath11k_base *ab, u32 *rx_desc, 321d5c65159SKalle Valo dma_addr_t *paddr, u32 *desc_bank) 322d5c65159SKalle Valo { 323d5c65159SKalle Valo struct hal_reo_dest_ring *desc = (struct hal_reo_dest_ring *)rx_desc; 324d5c65159SKalle Valo enum hal_reo_dest_ring_push_reason push_reason; 325d5c65159SKalle Valo enum hal_reo_dest_ring_error_code err_code; 326d5c65159SKalle Valo 327d5c65159SKalle Valo push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON, 328d5c65159SKalle Valo desc->info0); 329d5c65159SKalle Valo err_code = FIELD_GET(HAL_REO_DEST_RING_INFO0_ERROR_CODE, 330d5c65159SKalle Valo desc->info0); 331d5c65159SKalle Valo ab->soc_stats.reo_error[err_code]++; 332d5c65159SKalle Valo 333d5c65159SKalle Valo if (push_reason != HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED && 334d5c65159SKalle Valo push_reason != HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) { 335d5c65159SKalle Valo ath11k_warn(ab, "expected error push reason code, received %d\n", 336d5c65159SKalle Valo push_reason); 337d5c65159SKalle Valo return -EINVAL; 338d5c65159SKalle Valo } 339d5c65159SKalle Valo 340d5c65159SKalle Valo if (FIELD_GET(HAL_REO_DEST_RING_INFO0_BUFFER_TYPE, desc->info0) != 341d5c65159SKalle Valo HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC) { 342d5c65159SKalle Valo ath11k_warn(ab, "expected buffer type link_desc"); 343d5c65159SKalle Valo return -EINVAL; 344d5c65159SKalle Valo } 345d5c65159SKalle Valo 346d5c65159SKalle Valo ath11k_hal_rx_reo_ent_paddr_get(ab, rx_desc, paddr, desc_bank); 347d5c65159SKalle Valo 348d5c65159SKalle Valo return 0; 349d5c65159SKalle Valo } 350d5c65159SKalle Valo 351d5c65159SKalle Valo int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc, 352d5c65159SKalle Valo struct hal_rx_wbm_rel_info *rel_info) 353d5c65159SKalle Valo { 354d5c65159SKalle Valo struct hal_wbm_release_ring *wbm_desc = desc; 355d5c65159SKalle Valo enum hal_wbm_rel_desc_type type; 356d5c65159SKalle Valo enum hal_wbm_rel_src_module rel_src; 357d5c65159SKalle Valo 358d5c65159SKalle Valo type = FIELD_GET(HAL_WBM_RELEASE_INFO0_DESC_TYPE, 359d5c65159SKalle Valo wbm_desc->info0); 360d5c65159SKalle Valo /* We expect only WBM_REL buffer type */ 361d5c65159SKalle Valo if (type != HAL_WBM_REL_DESC_TYPE_REL_MSDU) { 362d5c65159SKalle Valo WARN_ON(1); 363d5c65159SKalle Valo return -EINVAL; 364d5c65159SKalle Valo } 365d5c65159SKalle Valo 366d5c65159SKalle Valo rel_src = FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, 367d5c65159SKalle Valo wbm_desc->info0); 368d5c65159SKalle Valo if (rel_src != HAL_WBM_REL_SRC_MODULE_RXDMA && 369d5c65159SKalle Valo rel_src != HAL_WBM_REL_SRC_MODULE_REO) 370d5c65159SKalle Valo return -EINVAL; 371d5c65159SKalle Valo 372d5c65159SKalle Valo if (FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, 373d5c65159SKalle Valo wbm_desc->buf_addr_info.info1) != HAL_RX_BUF_RBM_SW3_BM) { 374d5c65159SKalle Valo ab->soc_stats.invalid_rbm++; 375d5c65159SKalle Valo return -EINVAL; 376d5c65159SKalle Valo } 377d5c65159SKalle Valo 378d5c65159SKalle Valo rel_info->cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, 379d5c65159SKalle Valo wbm_desc->buf_addr_info.info1); 380d5c65159SKalle Valo rel_info->err_rel_src = rel_src; 381d5c65159SKalle Valo if (rel_src == HAL_WBM_REL_SRC_MODULE_REO) { 382d5c65159SKalle Valo rel_info->push_reason = 383d5c65159SKalle Valo FIELD_GET(HAL_WBM_RELEASE_INFO0_REO_PUSH_REASON, 384d5c65159SKalle Valo wbm_desc->info0); 385d5c65159SKalle Valo rel_info->err_code = 386d5c65159SKalle Valo FIELD_GET(HAL_WBM_RELEASE_INFO0_REO_ERROR_CODE, 387d5c65159SKalle Valo wbm_desc->info0); 388d5c65159SKalle Valo } else { 389d5c65159SKalle Valo rel_info->push_reason = 390d5c65159SKalle Valo FIELD_GET(HAL_WBM_RELEASE_INFO0_RXDMA_PUSH_REASON, 391d5c65159SKalle Valo wbm_desc->info0); 392d5c65159SKalle Valo rel_info->err_code = 393d5c65159SKalle Valo FIELD_GET(HAL_WBM_RELEASE_INFO0_RXDMA_ERROR_CODE, 394d5c65159SKalle Valo wbm_desc->info0); 395d5c65159SKalle Valo } 396d5c65159SKalle Valo 397d5c65159SKalle Valo rel_info->first_msdu = FIELD_GET(HAL_WBM_RELEASE_INFO2_FIRST_MSDU, 398d5c65159SKalle Valo wbm_desc->info2); 399d5c65159SKalle Valo rel_info->last_msdu = FIELD_GET(HAL_WBM_RELEASE_INFO2_LAST_MSDU, 400d5c65159SKalle Valo wbm_desc->info2); 401d5c65159SKalle Valo return 0; 402d5c65159SKalle Valo } 403d5c65159SKalle Valo 404d5c65159SKalle Valo void ath11k_hal_rx_reo_ent_paddr_get(struct ath11k_base *ab, void *desc, 405d5c65159SKalle Valo dma_addr_t *paddr, u32 *desc_bank) 406d5c65159SKalle Valo { 407d5c65159SKalle Valo struct ath11k_buffer_addr *buff_addr = desc; 408d5c65159SKalle Valo 409d5c65159SKalle Valo *paddr = ((u64)(FIELD_GET(BUFFER_ADDR_INFO1_ADDR, buff_addr->info1)) << 32) | 410d5c65159SKalle Valo FIELD_GET(BUFFER_ADDR_INFO0_ADDR, buff_addr->info0); 411d5c65159SKalle Valo 412d5c65159SKalle Valo *desc_bank = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, buff_addr->info1); 413d5c65159SKalle Valo } 414d5c65159SKalle Valo 415d5c65159SKalle Valo void ath11k_hal_rx_msdu_link_desc_set(struct ath11k_base *ab, void *desc, 416d5c65159SKalle Valo void *link_desc, 417d5c65159SKalle Valo enum hal_wbm_rel_bm_act action) 418d5c65159SKalle Valo { 419d5c65159SKalle Valo struct hal_wbm_release_ring *dst_desc = desc; 420d5c65159SKalle Valo struct hal_wbm_release_ring *src_desc = link_desc; 421d5c65159SKalle Valo 422d5c65159SKalle Valo dst_desc->buf_addr_info = src_desc->buf_addr_info; 423d5c65159SKalle Valo dst_desc->info0 |= FIELD_PREP(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, 424d5c65159SKalle Valo HAL_WBM_REL_SRC_MODULE_SW) | 425d5c65159SKalle Valo FIELD_PREP(HAL_WBM_RELEASE_INFO0_BM_ACTION, action) | 426d5c65159SKalle Valo FIELD_PREP(HAL_WBM_RELEASE_INFO0_DESC_TYPE, 427d5c65159SKalle Valo HAL_WBM_REL_DESC_TYPE_MSDU_LINK); 428d5c65159SKalle Valo } 429d5c65159SKalle Valo 430d5c65159SKalle Valo void ath11k_hal_reo_status_queue_stats(struct ath11k_base *ab, u32 *reo_desc, 431d5c65159SKalle Valo struct hal_reo_status *status) 432d5c65159SKalle Valo { 433d5c65159SKalle Valo struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; 434d5c65159SKalle Valo struct hal_reo_get_queue_stats_status *desc = 435d5c65159SKalle Valo (struct hal_reo_get_queue_stats_status *)tlv->value; 436d5c65159SKalle Valo 437d5c65159SKalle Valo status->uniform_hdr.cmd_num = 438d5c65159SKalle Valo FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, 439d5c65159SKalle Valo desc->hdr.info0); 440d5c65159SKalle Valo status->uniform_hdr.cmd_status = 441d5c65159SKalle Valo FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, 442d5c65159SKalle Valo desc->hdr.info0); 443d5c65159SKalle Valo 444d5c65159SKalle Valo ath11k_dbg(ab, ATH11k_DBG_HAL, "Queue stats status:\n"); 445d5c65159SKalle Valo ath11k_dbg(ab, ATH11k_DBG_HAL, "header: cmd_num %d status %d\n", 446d5c65159SKalle Valo status->uniform_hdr.cmd_num, 447d5c65159SKalle Valo status->uniform_hdr.cmd_status); 448d5c65159SKalle Valo ath11k_dbg(ab, ATH11k_DBG_HAL, "ssn %ld cur_idx %ld\n", 449d5c65159SKalle Valo FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO0_SSN, 450d5c65159SKalle Valo desc->info0), 451d5c65159SKalle Valo FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO0_CUR_IDX, 452d5c65159SKalle Valo desc->info0)); 453d5c65159SKalle Valo ath11k_dbg(ab, ATH11k_DBG_HAL, "pn = [%08x, %08x, %08x, %08x]\n", 454d5c65159SKalle Valo desc->pn[0], desc->pn[1], desc->pn[2], desc->pn[3]); 455d5c65159SKalle Valo ath11k_dbg(ab, ATH11k_DBG_HAL, "last_rx: enqueue_tstamp %08x dequeue_tstamp %08x\n", 456d5c65159SKalle Valo desc->last_rx_enqueue_timestamp, 457d5c65159SKalle Valo desc->last_rx_dequeue_timestamp); 458d5c65159SKalle Valo ath11k_dbg(ab, ATH11k_DBG_HAL, "rx_bitmap [%08x %08x %08x %08x %08x %08x %08x %08x]\n", 459d5c65159SKalle Valo desc->rx_bitmap[0], desc->rx_bitmap[1], desc->rx_bitmap[2], 460d5c65159SKalle Valo desc->rx_bitmap[3], desc->rx_bitmap[4], desc->rx_bitmap[5], 461d5c65159SKalle Valo desc->rx_bitmap[6], desc->rx_bitmap[7]); 462d5c65159SKalle Valo ath11k_dbg(ab, ATH11k_DBG_HAL, "count: cur_mpdu %ld cur_msdu %ld\n", 463d5c65159SKalle Valo FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO1_MPDU_COUNT, 464d5c65159SKalle Valo desc->info1), 465d5c65159SKalle Valo FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO1_MSDU_COUNT, 466d5c65159SKalle Valo desc->info1)); 467d5c65159SKalle Valo ath11k_dbg(ab, ATH11k_DBG_HAL, "fwd_timeout %ld fwd_bar %ld dup_count %ld\n", 468d5c65159SKalle Valo FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_TIMEOUT_COUNT, 469d5c65159SKalle Valo desc->info2), 470d5c65159SKalle Valo FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_FDTB_COUNT, 471d5c65159SKalle Valo desc->info2), 472d5c65159SKalle Valo FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_DUPLICATE_COUNT, 473d5c65159SKalle Valo desc->info2)); 474d5c65159SKalle Valo ath11k_dbg(ab, ATH11k_DBG_HAL, "frames_in_order %ld bar_rcvd %ld\n", 475d5c65159SKalle Valo FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO3_FIO_COUNT, 476d5c65159SKalle Valo desc->info3), 477d5c65159SKalle Valo FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO3_BAR_RCVD_CNT, 478d5c65159SKalle Valo desc->info3)); 479d5c65159SKalle Valo ath11k_dbg(ab, ATH11k_DBG_HAL, "num_mpdus %d num_msdus %d total_bytes %d\n", 480d5c65159SKalle Valo desc->num_mpdu_frames, desc->num_msdu_frames, 481d5c65159SKalle Valo desc->total_bytes); 482d5c65159SKalle Valo ath11k_dbg(ab, ATH11k_DBG_HAL, "late_rcvd %ld win_jump_2k %ld hole_cnt %ld\n", 483d5c65159SKalle Valo FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_LATE_RX_MPDU, 484d5c65159SKalle Valo desc->info4), 485d5c65159SKalle Valo FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_WINDOW_JMP2K, 486d5c65159SKalle Valo desc->info4), 487d5c65159SKalle Valo FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_HOLE_COUNT, 488d5c65159SKalle Valo desc->info4)); 489d5c65159SKalle Valo ath11k_dbg(ab, ATH11k_DBG_HAL, "looping count %ld\n", 490d5c65159SKalle Valo FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO5_LOOPING_CNT, 491d5c65159SKalle Valo desc->info5)); 492d5c65159SKalle Valo } 493d5c65159SKalle Valo 494d5c65159SKalle Valo int ath11k_hal_reo_process_status(u8 *reo_desc, u8 *status) 495d5c65159SKalle Valo { 496d5c65159SKalle Valo struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; 497d5c65159SKalle Valo struct hal_reo_status_hdr *hdr; 498d5c65159SKalle Valo 499d5c65159SKalle Valo hdr = (struct hal_reo_status_hdr *)tlv->value; 500d5c65159SKalle Valo *status = FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, hdr->info0); 501d5c65159SKalle Valo 502d5c65159SKalle Valo return FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, hdr->info0); 503d5c65159SKalle Valo } 504d5c65159SKalle Valo 505d5c65159SKalle Valo void ath11k_hal_reo_flush_queue_status(struct ath11k_base *ab, u32 *reo_desc, 506d5c65159SKalle Valo struct hal_reo_status *status) 507d5c65159SKalle Valo { 508d5c65159SKalle Valo struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; 509d5c65159SKalle Valo struct hal_reo_flush_queue_status *desc = 510d5c65159SKalle Valo (struct hal_reo_flush_queue_status *)tlv->value; 511d5c65159SKalle Valo 512d5c65159SKalle Valo status->uniform_hdr.cmd_num = 513d5c65159SKalle Valo FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, 514d5c65159SKalle Valo desc->hdr.info0); 515d5c65159SKalle Valo status->uniform_hdr.cmd_status = 516d5c65159SKalle Valo FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, 517d5c65159SKalle Valo desc->hdr.info0); 518d5c65159SKalle Valo status->u.flush_queue.err_detected = 519d5c65159SKalle Valo FIELD_GET(HAL_REO_FLUSH_QUEUE_INFO0_ERR_DETECTED, 520d5c65159SKalle Valo desc->info0); 521d5c65159SKalle Valo } 522d5c65159SKalle Valo 523d5c65159SKalle Valo void ath11k_hal_reo_flush_cache_status(struct ath11k_base *ab, u32 *reo_desc, 524d5c65159SKalle Valo struct hal_reo_status *status) 525d5c65159SKalle Valo { 526d5c65159SKalle Valo struct ath11k_hal *hal = &ab->hal; 527d5c65159SKalle Valo struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; 528d5c65159SKalle Valo struct hal_reo_flush_cache_status *desc = 529d5c65159SKalle Valo (struct hal_reo_flush_cache_status *)tlv->value; 530d5c65159SKalle Valo 531d5c65159SKalle Valo status->uniform_hdr.cmd_num = 532d5c65159SKalle Valo FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, 533d5c65159SKalle Valo desc->hdr.info0); 534d5c65159SKalle Valo status->uniform_hdr.cmd_status = 535d5c65159SKalle Valo FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, 536d5c65159SKalle Valo desc->hdr.info0); 537d5c65159SKalle Valo 538d5c65159SKalle Valo status->u.flush_cache.err_detected = 539d5c65159SKalle Valo FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_IS_ERR, 540d5c65159SKalle Valo desc->info0); 541d5c65159SKalle Valo status->u.flush_cache.err_code = 542d5c65159SKalle Valo FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_BLOCK_ERR_CODE, 543d5c65159SKalle Valo desc->info0); 544d5c65159SKalle Valo if (!status->u.flush_cache.err_code) 545d5c65159SKalle Valo hal->avail_blk_resource |= BIT(hal->current_blk_index); 546d5c65159SKalle Valo 547d5c65159SKalle Valo status->u.flush_cache.cache_controller_flush_status_hit = 548d5c65159SKalle Valo FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_STATUS_HIT, 549d5c65159SKalle Valo desc->info0); 550d5c65159SKalle Valo 551d5c65159SKalle Valo status->u.flush_cache.cache_controller_flush_status_desc_type = 552d5c65159SKalle Valo FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_DESC_TYPE, 553d5c65159SKalle Valo desc->info0); 554d5c65159SKalle Valo status->u.flush_cache.cache_controller_flush_status_client_id = 555d5c65159SKalle Valo FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_CLIENT_ID, 556d5c65159SKalle Valo desc->info0); 557d5c65159SKalle Valo status->u.flush_cache.cache_controller_flush_status_err = 558d5c65159SKalle Valo FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_ERR, 559d5c65159SKalle Valo desc->info0); 560d5c65159SKalle Valo status->u.flush_cache.cache_controller_flush_status_cnt = 561d5c65159SKalle Valo FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_COUNT, 562d5c65159SKalle Valo desc->info0); 563d5c65159SKalle Valo } 564d5c65159SKalle Valo 565d5c65159SKalle Valo void ath11k_hal_reo_unblk_cache_status(struct ath11k_base *ab, u32 *reo_desc, 566d5c65159SKalle Valo struct hal_reo_status *status) 567d5c65159SKalle Valo { 568d5c65159SKalle Valo struct ath11k_hal *hal = &ab->hal; 569d5c65159SKalle Valo struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; 570d5c65159SKalle Valo struct hal_reo_unblock_cache_status *desc = 571d5c65159SKalle Valo (struct hal_reo_unblock_cache_status *)tlv->value; 572d5c65159SKalle Valo 573d5c65159SKalle Valo status->uniform_hdr.cmd_num = 574d5c65159SKalle Valo FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, 575d5c65159SKalle Valo desc->hdr.info0); 576d5c65159SKalle Valo status->uniform_hdr.cmd_status = 577d5c65159SKalle Valo FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, 578d5c65159SKalle Valo desc->hdr.info0); 579d5c65159SKalle Valo 580d5c65159SKalle Valo status->u.unblock_cache.err_detected = 581d5c65159SKalle Valo FIELD_GET(HAL_REO_UNBLOCK_CACHE_STATUS_INFO0_IS_ERR, 582d5c65159SKalle Valo desc->info0); 583d5c65159SKalle Valo status->u.unblock_cache.unblock_type = 584d5c65159SKalle Valo FIELD_GET(HAL_REO_UNBLOCK_CACHE_STATUS_INFO0_TYPE, 585d5c65159SKalle Valo desc->info0); 586d5c65159SKalle Valo 587d5c65159SKalle Valo if (!status->u.unblock_cache.err_detected && 588d5c65159SKalle Valo status->u.unblock_cache.unblock_type == 589d5c65159SKalle Valo HAL_REO_STATUS_UNBLOCK_BLOCKING_RESOURCE) 590d5c65159SKalle Valo hal->avail_blk_resource &= ~BIT(hal->current_blk_index); 591d5c65159SKalle Valo } 592d5c65159SKalle Valo 593d5c65159SKalle Valo void ath11k_hal_reo_flush_timeout_list_status(struct ath11k_base *ab, 594d5c65159SKalle Valo u32 *reo_desc, 595d5c65159SKalle Valo struct hal_reo_status *status) 596d5c65159SKalle Valo { 597d5c65159SKalle Valo struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; 598d5c65159SKalle Valo struct hal_reo_flush_timeout_list_status *desc = 599d5c65159SKalle Valo (struct hal_reo_flush_timeout_list_status *)tlv->value; 600d5c65159SKalle Valo 601d5c65159SKalle Valo status->uniform_hdr.cmd_num = 602d5c65159SKalle Valo FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, 603d5c65159SKalle Valo desc->hdr.info0); 604d5c65159SKalle Valo status->uniform_hdr.cmd_status = 605d5c65159SKalle Valo FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, 606d5c65159SKalle Valo desc->hdr.info0); 607d5c65159SKalle Valo 608d5c65159SKalle Valo status->u.timeout_list.err_detected = 609d5c65159SKalle Valo FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO0_IS_ERR, 610d5c65159SKalle Valo desc->info0); 611d5c65159SKalle Valo status->u.timeout_list.list_empty = 612d5c65159SKalle Valo FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO0_LIST_EMPTY, 613d5c65159SKalle Valo desc->info0); 614d5c65159SKalle Valo 615d5c65159SKalle Valo status->u.timeout_list.release_desc_cnt = 616d5c65159SKalle Valo FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO1_REL_DESC_COUNT, 617d5c65159SKalle Valo desc->info1); 618d5c65159SKalle Valo status->u.timeout_list.fwd_buf_cnt = 619d5c65159SKalle Valo FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO1_FWD_BUF_COUNT, 620d5c65159SKalle Valo desc->info1); 621d5c65159SKalle Valo } 622d5c65159SKalle Valo 623d5c65159SKalle Valo void ath11k_hal_reo_desc_thresh_reached_status(struct ath11k_base *ab, 624d5c65159SKalle Valo u32 *reo_desc, 625d5c65159SKalle Valo struct hal_reo_status *status) 626d5c65159SKalle Valo { 627d5c65159SKalle Valo struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; 628d5c65159SKalle Valo struct hal_reo_desc_thresh_reached_status *desc = 629d5c65159SKalle Valo (struct hal_reo_desc_thresh_reached_status *)tlv->value; 630d5c65159SKalle Valo 631d5c65159SKalle Valo status->uniform_hdr.cmd_num = 632d5c65159SKalle Valo FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, 633d5c65159SKalle Valo desc->hdr.info0); 634d5c65159SKalle Valo status->uniform_hdr.cmd_status = 635d5c65159SKalle Valo FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, 636d5c65159SKalle Valo desc->hdr.info0); 637d5c65159SKalle Valo 638d5c65159SKalle Valo status->u.desc_thresh_reached.threshold_idx = 639d5c65159SKalle Valo FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO0_THRESH_INDEX, 640d5c65159SKalle Valo desc->info0); 641d5c65159SKalle Valo 642d5c65159SKalle Valo status->u.desc_thresh_reached.link_desc_counter0 = 643d5c65159SKalle Valo FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO1_LINK_DESC_COUNTER0, 644d5c65159SKalle Valo desc->info1); 645d5c65159SKalle Valo 646d5c65159SKalle Valo status->u.desc_thresh_reached.link_desc_counter1 = 647d5c65159SKalle Valo FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO2_LINK_DESC_COUNTER1, 648d5c65159SKalle Valo desc->info2); 649d5c65159SKalle Valo 650d5c65159SKalle Valo status->u.desc_thresh_reached.link_desc_counter2 = 651d5c65159SKalle Valo FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO3_LINK_DESC_COUNTER2, 652d5c65159SKalle Valo desc->info3); 653d5c65159SKalle Valo 654d5c65159SKalle Valo status->u.desc_thresh_reached.link_desc_counter_sum = 655d5c65159SKalle Valo FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO4_LINK_DESC_COUNTER_SUM, 656d5c65159SKalle Valo desc->info4); 657d5c65159SKalle Valo } 658d5c65159SKalle Valo 659d5c65159SKalle Valo void ath11k_hal_reo_update_rx_reo_queue_status(struct ath11k_base *ab, 660d5c65159SKalle Valo u32 *reo_desc, 661d5c65159SKalle Valo struct hal_reo_status *status) 662d5c65159SKalle Valo { 663d5c65159SKalle Valo struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; 664d5c65159SKalle Valo struct hal_reo_status_hdr *desc = 665d5c65159SKalle Valo (struct hal_reo_status_hdr *)tlv->value; 666d5c65159SKalle Valo 667d5c65159SKalle Valo status->uniform_hdr.cmd_num = 668d5c65159SKalle Valo FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, 669d5c65159SKalle Valo desc->info0); 670d5c65159SKalle Valo status->uniform_hdr.cmd_status = 671d5c65159SKalle Valo FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, 672d5c65159SKalle Valo desc->info0); 673d5c65159SKalle Valo } 674d5c65159SKalle Valo 675d5c65159SKalle Valo u32 ath11k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid) 676d5c65159SKalle Valo { 677d5c65159SKalle Valo u32 num_ext_desc; 678d5c65159SKalle Valo 679d5c65159SKalle Valo if (ba_window_size <= 1) { 680d5c65159SKalle Valo if (tid != HAL_DESC_REO_NON_QOS_TID) 681d5c65159SKalle Valo num_ext_desc = 1; 682d5c65159SKalle Valo else 683d5c65159SKalle Valo num_ext_desc = 0; 684d5c65159SKalle Valo } else if (ba_window_size <= 105) { 685d5c65159SKalle Valo num_ext_desc = 1; 686d5c65159SKalle Valo } else if (ba_window_size <= 210) { 687d5c65159SKalle Valo num_ext_desc = 2; 688d5c65159SKalle Valo } else { 689d5c65159SKalle Valo num_ext_desc = 3; 690d5c65159SKalle Valo } 691d5c65159SKalle Valo 692d5c65159SKalle Valo return sizeof(struct hal_rx_reo_queue) + 693d5c65159SKalle Valo (num_ext_desc * sizeof(struct hal_rx_reo_queue_ext)); 694d5c65159SKalle Valo } 695d5c65159SKalle Valo 696d5c65159SKalle Valo void ath11k_hal_reo_qdesc_setup(void *vaddr, int tid, u32 ba_window_size, 697d5c65159SKalle Valo u32 start_seq) 698d5c65159SKalle Valo { 699d5c65159SKalle Valo struct hal_rx_reo_queue *qdesc = (struct hal_rx_reo_queue *)vaddr; 700d5c65159SKalle Valo struct hal_rx_reo_queue_ext *ext_desc; 701d5c65159SKalle Valo 702d5c65159SKalle Valo memset(qdesc, 0, sizeof(*qdesc)); 703d5c65159SKalle Valo 704d5c65159SKalle Valo ath11k_hal_reo_set_desc_hdr(&qdesc->desc_hdr, HAL_DESC_REO_OWNED, 705d5c65159SKalle Valo HAL_DESC_REO_QUEUE_DESC, 706d5c65159SKalle Valo REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_0); 707d5c65159SKalle Valo 708d5c65159SKalle Valo qdesc->rx_queue_num = FIELD_PREP(HAL_RX_REO_QUEUE_RX_QUEUE_NUMBER, tid); 709d5c65159SKalle Valo 710d5c65159SKalle Valo qdesc->info0 = 711d5c65159SKalle Valo FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_VLD, 1) | 712d5c65159SKalle Valo FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_ASSOC_LNK_DESC_COUNTER, 1) | 713d5c65159SKalle Valo FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_AC, ath11k_tid_to_ac(tid)); 714d5c65159SKalle Valo 715d5c65159SKalle Valo if (ba_window_size < 1) 716d5c65159SKalle Valo ba_window_size = 1; 717d5c65159SKalle Valo 718d5c65159SKalle Valo if (ba_window_size == 1 && tid != HAL_DESC_REO_NON_QOS_TID) 719d5c65159SKalle Valo ba_window_size++; 720d5c65159SKalle Valo 721d5c65159SKalle Valo if (ba_window_size == 1) 722d5c65159SKalle Valo qdesc->info0 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_RETRY, 1); 723d5c65159SKalle Valo 724d5c65159SKalle Valo qdesc->info0 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_BA_WINDOW_SIZE, 725d5c65159SKalle Valo ba_window_size - 1); 726d5c65159SKalle Valo 727d5c65159SKalle Valo /* TODO: Set Ignore ampdu flags based on BA window size and/or 728d5c65159SKalle Valo * AMPDU capabilities 729d5c65159SKalle Valo */ 730d5c65159SKalle Valo qdesc->info0 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_IGNORE_AMPDU_FLG, 1); 731d5c65159SKalle Valo 732d5c65159SKalle Valo qdesc->info1 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO1_SVLD, 0); 733d5c65159SKalle Valo 734d5c65159SKalle Valo if (start_seq <= 0xfff) 735d5c65159SKalle Valo qdesc->info1 = FIELD_PREP(HAL_RX_REO_QUEUE_INFO1_SSN, 736d5c65159SKalle Valo start_seq); 737d5c65159SKalle Valo 738d5c65159SKalle Valo if (tid == HAL_DESC_REO_NON_QOS_TID) 739d5c65159SKalle Valo return; 740d5c65159SKalle Valo 741d5c65159SKalle Valo ext_desc = qdesc->ext_desc; 742d5c65159SKalle Valo 743d5c65159SKalle Valo /* TODO: HW queue descriptors are currently allocated for max BA 744d5c65159SKalle Valo * window size for all QOS TIDs so that same descriptor can be used 745d5c65159SKalle Valo * later when ADDBA request is recevied. This should be changed to 746d5c65159SKalle Valo * allocate HW queue descriptors based on BA window size being 747d5c65159SKalle Valo * negotiated (0 for non BA cases), and reallocate when BA window 748d5c65159SKalle Valo * size changes and also send WMI message to FW to change the REO 749d5c65159SKalle Valo * queue descriptor in Rx peer entry as part of dp_rx_tid_update. 750d5c65159SKalle Valo */ 751d5c65159SKalle Valo memset(ext_desc, 0, 3 * sizeof(*ext_desc)); 752d5c65159SKalle Valo ath11k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED, 753d5c65159SKalle Valo HAL_DESC_REO_QUEUE_EXT_DESC, 754d5c65159SKalle Valo REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_1); 755d5c65159SKalle Valo ext_desc++; 756d5c65159SKalle Valo ath11k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED, 757d5c65159SKalle Valo HAL_DESC_REO_QUEUE_EXT_DESC, 758d5c65159SKalle Valo REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2); 759d5c65159SKalle Valo ext_desc++; 760d5c65159SKalle Valo ath11k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED, 761d5c65159SKalle Valo HAL_DESC_REO_QUEUE_EXT_DESC, 762d5c65159SKalle Valo REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3); 763d5c65159SKalle Valo } 764d5c65159SKalle Valo 765d5c65159SKalle Valo void ath11k_hal_reo_init_cmd_ring(struct ath11k_base *ab, 766d5c65159SKalle Valo struct hal_srng *srng) 767d5c65159SKalle Valo { 768d5c65159SKalle Valo struct hal_srng_params params; 769d5c65159SKalle Valo struct hal_tlv_hdr *tlv; 770d5c65159SKalle Valo struct hal_reo_get_queue_stats *desc; 771d5c65159SKalle Valo int i, cmd_num = 1; 772d5c65159SKalle Valo int entry_size; 773d5c65159SKalle Valo u8 *entry; 774d5c65159SKalle Valo 775d5c65159SKalle Valo memset(¶ms, 0, sizeof(params)); 776d5c65159SKalle Valo 777d5c65159SKalle Valo entry_size = ath11k_hal_srng_get_entrysize(HAL_REO_CMD); 778d5c65159SKalle Valo ath11k_hal_srng_get_params(ab, srng, ¶ms); 779d5c65159SKalle Valo entry = (u8 *)params.ring_base_vaddr; 780d5c65159SKalle Valo 781d5c65159SKalle Valo for (i = 0; i < params.num_entries; i++) { 782d5c65159SKalle Valo tlv = (struct hal_tlv_hdr *)entry; 783d5c65159SKalle Valo desc = (struct hal_reo_get_queue_stats *)tlv->value; 784d5c65159SKalle Valo desc->cmd.info0 = 785d5c65159SKalle Valo FIELD_PREP(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, cmd_num++); 786d5c65159SKalle Valo entry += entry_size; 787d5c65159SKalle Valo } 788d5c65159SKalle Valo } 789d5c65159SKalle Valo 790d5c65159SKalle Valo void ath11k_hal_reo_hw_setup(struct ath11k_base *ab) 791d5c65159SKalle Valo { 792d5c65159SKalle Valo u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; 793d5c65159SKalle Valo u32 val; 794d5c65159SKalle Valo 795d5c65159SKalle Valo val = ath11k_ahb_read32(ab, reo_base + HAL_REO1_GEN_ENABLE); 796d5c65159SKalle Valo 797d5c65159SKalle Valo val &= ~HAL_REO1_GEN_ENABLE_FRAG_DST_RING; 798d5c65159SKalle Valo val |= FIELD_PREP(HAL_REO1_GEN_ENABLE_FRAG_DST_RING, 799d5c65159SKalle Valo HAL_SRNG_RING_ID_REO2SW1) | 800d5c65159SKalle Valo FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE, 1) | 801d5c65159SKalle Valo FIELD_PREP(HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE, 1); 802d5c65159SKalle Valo ath11k_ahb_write32(ab, reo_base + HAL_REO1_GEN_ENABLE, val); 803d5c65159SKalle Valo 804d5c65159SKalle Valo ath11k_ahb_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_0, 805d5c65159SKalle Valo HAL_DEFAULT_REO_TIMEOUT_USEC); 806d5c65159SKalle Valo ath11k_ahb_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_1, 807d5c65159SKalle Valo HAL_DEFAULT_REO_TIMEOUT_USEC); 808d5c65159SKalle Valo ath11k_ahb_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_2, 809d5c65159SKalle Valo HAL_DEFAULT_REO_TIMEOUT_USEC); 810d5c65159SKalle Valo ath11k_ahb_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3, 811d5c65159SKalle Valo HAL_DEFAULT_REO_TIMEOUT_USEC); 812d5c65159SKalle Valo } 813d5c65159SKalle Valo 814d5c65159SKalle Valo static enum hal_rx_mon_status 815d5c65159SKalle Valo ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab, 816d5c65159SKalle Valo struct hal_rx_mon_ppdu_info *ppdu_info, 817d5c65159SKalle Valo u32 tlv_tag, u8 *tlv_data) 818d5c65159SKalle Valo { 819d5c65159SKalle Valo u32 info0, info1; 820d5c65159SKalle Valo 821d5c65159SKalle Valo switch (tlv_tag) { 822d5c65159SKalle Valo case HAL_RX_PPDU_START: { 823d5c65159SKalle Valo struct hal_rx_ppdu_start *ppdu_start = 824d5c65159SKalle Valo (struct hal_rx_ppdu_start *)tlv_data; 825d5c65159SKalle Valo 826d5c65159SKalle Valo ppdu_info->ppdu_id = 827d5c65159SKalle Valo FIELD_GET(HAL_RX_PPDU_START_INFO0_PPDU_ID, 828d5c65159SKalle Valo __le32_to_cpu(ppdu_start->info0)); 829d5c65159SKalle Valo ppdu_info->chan_num = __le32_to_cpu(ppdu_start->chan_num); 830d5c65159SKalle Valo ppdu_info->ppdu_ts = __le32_to_cpu(ppdu_start->ppdu_start_ts); 831d5c65159SKalle Valo break; 832d5c65159SKalle Valo } 833d5c65159SKalle Valo case HAL_RX_PPDU_END_USER_STATS: { 834d5c65159SKalle Valo struct hal_rx_ppdu_end_user_stats *eu_stats = 835d5c65159SKalle Valo (struct hal_rx_ppdu_end_user_stats *)tlv_data; 836d5c65159SKalle Valo 837d5c65159SKalle Valo info0 = __le32_to_cpu(eu_stats->info0); 838d5c65159SKalle Valo info1 = __le32_to_cpu(eu_stats->info1); 839d5c65159SKalle Valo 840d5c65159SKalle Valo ppdu_info->tid = 841d5c65159SKalle Valo ffs(FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP, 842d5c65159SKalle Valo __le32_to_cpu(eu_stats->info6))) - 1; 843d5c65159SKalle Valo ppdu_info->tcp_msdu_count = 844d5c65159SKalle Valo FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT, 845d5c65159SKalle Valo __le32_to_cpu(eu_stats->info4)); 846d5c65159SKalle Valo ppdu_info->udp_msdu_count = 847d5c65159SKalle Valo FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO4_UDP_MSDU_CNT, 848d5c65159SKalle Valo __le32_to_cpu(eu_stats->info4)); 849d5c65159SKalle Valo ppdu_info->other_msdu_count = 850d5c65159SKalle Valo FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT, 851d5c65159SKalle Valo __le32_to_cpu(eu_stats->info5)); 852d5c65159SKalle Valo ppdu_info->tcp_ack_msdu_count = 853d5c65159SKalle Valo FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT, 854d5c65159SKalle Valo __le32_to_cpu(eu_stats->info5)); 855d5c65159SKalle Valo ppdu_info->preamble_type = 856d5c65159SKalle Valo FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO1_PKT_TYPE, info1); 857d5c65159SKalle Valo ppdu_info->num_mpdu_fcs_ok = 858d5c65159SKalle Valo FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO1_MPDU_CNT_FCS_OK, 859d5c65159SKalle Valo info1); 860d5c65159SKalle Valo ppdu_info->num_mpdu_fcs_err = 861d5c65159SKalle Valo FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR, 862d5c65159SKalle Valo info0); 863d5c65159SKalle Valo break; 864d5c65159SKalle Valo } 865d5c65159SKalle Valo case HAL_PHYRX_HT_SIG: { 866d5c65159SKalle Valo struct hal_rx_ht_sig_info *ht_sig = 867d5c65159SKalle Valo (struct hal_rx_ht_sig_info *)tlv_data; 868d5c65159SKalle Valo 869d5c65159SKalle Valo info0 = __le32_to_cpu(ht_sig->info0); 870d5c65159SKalle Valo info1 = __le32_to_cpu(ht_sig->info1); 871d5c65159SKalle Valo 872d5c65159SKalle Valo ppdu_info->mcs = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO0_MCS, info0); 873d5c65159SKalle Valo ppdu_info->bw = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO0_BW, info0); 874d5c65159SKalle Valo ppdu_info->is_stbc = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_STBC, 875d5c65159SKalle Valo info1); 876d5c65159SKalle Valo ppdu_info->ldpc = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING, info1); 877d5c65159SKalle Valo ppdu_info->gi = info1 & HAL_RX_HT_SIG_INFO_INFO1_GI; 878d5c65159SKalle Valo 879d5c65159SKalle Valo switch (ppdu_info->mcs) { 880d5c65159SKalle Valo case 0 ... 7: 881d5c65159SKalle Valo ppdu_info->nss = 1; 882d5c65159SKalle Valo break; 883d5c65159SKalle Valo case 8 ... 15: 884d5c65159SKalle Valo ppdu_info->nss = 2; 885d5c65159SKalle Valo break; 886d5c65159SKalle Valo case 16 ... 23: 887d5c65159SKalle Valo ppdu_info->nss = 3; 888d5c65159SKalle Valo break; 889d5c65159SKalle Valo case 24 ... 31: 890d5c65159SKalle Valo ppdu_info->nss = 4; 891d5c65159SKalle Valo break; 892d5c65159SKalle Valo } 893d5c65159SKalle Valo 894d5c65159SKalle Valo if (ppdu_info->nss > 1) 895d5c65159SKalle Valo ppdu_info->mcs = ppdu_info->mcs % 8; 896d5c65159SKalle Valo 897d5c65159SKalle Valo ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; 898d5c65159SKalle Valo break; 899d5c65159SKalle Valo } 900d5c65159SKalle Valo case HAL_PHYRX_L_SIG_B: { 901d5c65159SKalle Valo struct hal_rx_lsig_b_info *lsigb = 902d5c65159SKalle Valo (struct hal_rx_lsig_b_info *)tlv_data; 903d5c65159SKalle Valo 904d5c65159SKalle Valo ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_B_INFO_INFO0_RATE, 905d5c65159SKalle Valo __le32_to_cpu(lsigb->info0)); 906d5c65159SKalle Valo ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; 907d5c65159SKalle Valo break; 908d5c65159SKalle Valo } 909d5c65159SKalle Valo case HAL_PHYRX_L_SIG_A: { 910d5c65159SKalle Valo struct hal_rx_lsig_a_info *lsiga = 911d5c65159SKalle Valo (struct hal_rx_lsig_a_info *)tlv_data; 912d5c65159SKalle Valo 913d5c65159SKalle Valo ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_A_INFO_INFO0_RATE, 914d5c65159SKalle Valo __le32_to_cpu(lsiga->info0)); 915d5c65159SKalle Valo ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; 916d5c65159SKalle Valo break; 917d5c65159SKalle Valo } 918d5c65159SKalle Valo case HAL_PHYRX_VHT_SIG_A: { 919d5c65159SKalle Valo struct hal_rx_vht_sig_a_info *vht_sig = 920d5c65159SKalle Valo (struct hal_rx_vht_sig_a_info *)tlv_data; 921d5c65159SKalle Valo u32 nsts; 922d5c65159SKalle Valo u32 group_id; 923*28dee8efSManikanta Pubbisetty u8 gi_setting; 924d5c65159SKalle Valo 925d5c65159SKalle Valo info0 = __le32_to_cpu(vht_sig->info0); 926d5c65159SKalle Valo info1 = __le32_to_cpu(vht_sig->info1); 927d5c65159SKalle Valo 928d5c65159SKalle Valo ppdu_info->ldpc = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING, 929d5c65159SKalle Valo info0); 930d5c65159SKalle Valo ppdu_info->mcs = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_MCS, 931d5c65159SKalle Valo info1); 932*28dee8efSManikanta Pubbisetty gi_setting = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_GI_SETTING, 933d5c65159SKalle Valo info1); 934*28dee8efSManikanta Pubbisetty switch (gi_setting) { 935*28dee8efSManikanta Pubbisetty case HAL_RX_VHT_SIG_A_NORMAL_GI: 936*28dee8efSManikanta Pubbisetty ppdu_info->gi = HAL_RX_GI_0_8_US; 937*28dee8efSManikanta Pubbisetty break; 938*28dee8efSManikanta Pubbisetty case HAL_RX_VHT_SIG_A_SHORT_GI: 939*28dee8efSManikanta Pubbisetty case HAL_RX_VHT_SIG_A_SHORT_GI_AMBIGUITY: 940*28dee8efSManikanta Pubbisetty ppdu_info->gi = HAL_RX_GI_0_4_US; 941*28dee8efSManikanta Pubbisetty break; 942*28dee8efSManikanta Pubbisetty } 943*28dee8efSManikanta Pubbisetty 944d5c65159SKalle Valo ppdu_info->is_stbc = info0 & HAL_RX_VHT_SIG_A_INFO_INFO0_STBC; 945d5c65159SKalle Valo nsts = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO0_NSTS, info0); 946d5c65159SKalle Valo if (ppdu_info->is_stbc && nsts > 0) 947d5c65159SKalle Valo nsts = ((nsts + 1) >> 1) - 1; 948d5c65159SKalle Valo 949d5c65159SKalle Valo ppdu_info->nss = (nsts & VHT_SIG_SU_NSS_MASK) + 1; 950d5c65159SKalle Valo ppdu_info->bw = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO0_BW, 951d5c65159SKalle Valo info0); 952d5c65159SKalle Valo ppdu_info->beamformed = info1 & 953d5c65159SKalle Valo HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED; 954d5c65159SKalle Valo group_id = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO0_GROUP_ID, 955d5c65159SKalle Valo info0); 956d5c65159SKalle Valo if (group_id == 0 || group_id == 63) 957d5c65159SKalle Valo ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; 958d5c65159SKalle Valo else 959d5c65159SKalle Valo ppdu_info->reception_type = 960d5c65159SKalle Valo HAL_RX_RECEPTION_TYPE_MU_MIMO; 961d5c65159SKalle Valo break; 962d5c65159SKalle Valo } 963d5c65159SKalle Valo case HAL_PHYRX_HE_SIG_A_SU: { 964d5c65159SKalle Valo struct hal_rx_he_sig_a_su_info *he_sig_a = 965d5c65159SKalle Valo (struct hal_rx_he_sig_a_su_info *)tlv_data; 966d5c65159SKalle Valo u32 nsts, cp_ltf, dcm; 967d5c65159SKalle Valo 968d5c65159SKalle Valo info0 = __le32_to_cpu(he_sig_a->info0); 969d5c65159SKalle Valo info1 = __le32_to_cpu(he_sig_a->info1); 970d5c65159SKalle Valo 971d5c65159SKalle Valo ppdu_info->mcs = 972d5c65159SKalle Valo FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS, 973d5c65159SKalle Valo info0); 974d5c65159SKalle Valo ppdu_info->bw = 975d5c65159SKalle Valo FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW, 976d5c65159SKalle Valo info0); 977d5c65159SKalle Valo ppdu_info->ldpc = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING, info0); 978d5c65159SKalle Valo ppdu_info->is_stbc = info1 & 979d5c65159SKalle Valo HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC; 980d5c65159SKalle Valo ppdu_info->beamformed = info1 & 981d5c65159SKalle Valo HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF; 982d5c65159SKalle Valo dcm = info0 & HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM; 983d5c65159SKalle Valo cp_ltf = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE, 984d5c65159SKalle Valo info0); 985d5c65159SKalle Valo nsts = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS, info0); 986d5c65159SKalle Valo 987d5c65159SKalle Valo switch (cp_ltf) { 988d5c65159SKalle Valo case 0: 989d5c65159SKalle Valo case 1: 990d5c65159SKalle Valo ppdu_info->gi = HAL_RX_GI_0_8_US; 991d5c65159SKalle Valo break; 992d5c65159SKalle Valo case 2: 993d5c65159SKalle Valo ppdu_info->gi = HAL_RX_GI_1_6_US; 994d5c65159SKalle Valo break; 995d5c65159SKalle Valo case 3: 996d5c65159SKalle Valo if (dcm && ppdu_info->is_stbc) 997d5c65159SKalle Valo ppdu_info->gi = HAL_RX_GI_0_8_US; 998d5c65159SKalle Valo else 999d5c65159SKalle Valo ppdu_info->gi = HAL_RX_GI_3_2_US; 1000d5c65159SKalle Valo break; 1001d5c65159SKalle Valo } 1002d5c65159SKalle Valo 1003d5c65159SKalle Valo ppdu_info->nss = nsts + 1; 1004d5c65159SKalle Valo ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; 1005d5c65159SKalle Valo break; 1006d5c65159SKalle Valo } 1007d5c65159SKalle Valo case HAL_PHYRX_HE_SIG_A_MU_DL: { 1008d5c65159SKalle Valo struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl = 1009d5c65159SKalle Valo (struct hal_rx_he_sig_a_mu_dl_info *)tlv_data; 1010d5c65159SKalle Valo 1011d5c65159SKalle Valo u32 cp_ltf; 1012d5c65159SKalle Valo 1013d5c65159SKalle Valo info0 = __le32_to_cpu(he_sig_a_mu_dl->info0); 1014d5c65159SKalle Valo info1 = __le32_to_cpu(he_sig_a_mu_dl->info1); 1015d5c65159SKalle Valo 1016d5c65159SKalle Valo ppdu_info->bw = 1017d5c65159SKalle Valo FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_TRANSMIT_BW, 1018d5c65159SKalle Valo info0); 1019d5c65159SKalle Valo cp_ltf = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_CP_LTF_SIZE, 1020d5c65159SKalle Valo info0); 1021d5c65159SKalle Valo 1022d5c65159SKalle Valo switch (cp_ltf) { 1023d5c65159SKalle Valo case 0: 1024d5c65159SKalle Valo case 1: 1025d5c65159SKalle Valo ppdu_info->gi = HAL_RX_GI_0_8_US; 1026d5c65159SKalle Valo break; 1027d5c65159SKalle Valo case 2: 1028d5c65159SKalle Valo ppdu_info->gi = HAL_RX_GI_1_6_US; 1029d5c65159SKalle Valo break; 1030d5c65159SKalle Valo case 3: 1031d5c65159SKalle Valo ppdu_info->gi = HAL_RX_GI_3_2_US; 1032d5c65159SKalle Valo break; 1033d5c65159SKalle Valo } 1034d5c65159SKalle Valo 1035d5c65159SKalle Valo ppdu_info->is_stbc = info1 & 1036d5c65159SKalle Valo HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_STBC; 1037d5c65159SKalle Valo ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO; 1038d5c65159SKalle Valo break; 1039d5c65159SKalle Valo } 1040d5c65159SKalle Valo case HAL_PHYRX_HE_SIG_B1_MU: { 1041d5c65159SKalle Valo /* TODO: Check if resource unit(RU) allocation stats 1042d5c65159SKalle Valo * are required 1043d5c65159SKalle Valo */ 1044d5c65159SKalle Valo ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO; 1045d5c65159SKalle Valo break; 1046d5c65159SKalle Valo } 1047d5c65159SKalle Valo case HAL_PHYRX_HE_SIG_B2_MU: { 1048d5c65159SKalle Valo struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu = 1049d5c65159SKalle Valo (struct hal_rx_he_sig_b2_mu_info *)tlv_data; 1050d5c65159SKalle Valo 1051d5c65159SKalle Valo info0 = __le32_to_cpu(he_sig_b2_mu->info0); 1052d5c65159SKalle Valo 1053d5c65159SKalle Valo ppdu_info->mcs = 1054d5c65159SKalle Valo FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS, 1055d5c65159SKalle Valo info0); 1056d5c65159SKalle Valo ppdu_info->nss = 1057d5c65159SKalle Valo FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS, 1058d5c65159SKalle Valo info0) + 1; 1059d5c65159SKalle Valo ppdu_info->ldpc = FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING, 1060d5c65159SKalle Valo info0); 1061d5c65159SKalle Valo break; 1062d5c65159SKalle Valo } 1063d5c65159SKalle Valo case HAL_PHYRX_HE_SIG_B2_OFDMA: { 1064d5c65159SKalle Valo struct hal_rx_he_sig_b2_ofdma_info *he_sig_b2_ofdma = 1065d5c65159SKalle Valo (struct hal_rx_he_sig_b2_ofdma_info *)tlv_data; 1066d5c65159SKalle Valo 1067d5c65159SKalle Valo info0 = __le32_to_cpu(he_sig_b2_ofdma->info0); 1068d5c65159SKalle Valo 1069d5c65159SKalle Valo ppdu_info->mcs = 1070d5c65159SKalle Valo FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS, 1071d5c65159SKalle Valo info0); 1072d5c65159SKalle Valo ppdu_info->nss = 1073d5c65159SKalle Valo FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS, 1074d5c65159SKalle Valo info0) + 1; 1075d5c65159SKalle Valo ppdu_info->beamformed = 1076d5c65159SKalle Valo info0 & 1077d5c65159SKalle Valo HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF; 1078d5c65159SKalle Valo ppdu_info->ldpc = FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING, 1079d5c65159SKalle Valo info0); 1080d5c65159SKalle Valo ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA; 1081d5c65159SKalle Valo break; 1082d5c65159SKalle Valo } 1083d5c65159SKalle Valo case HAL_PHYRX_RSSI_LEGACY: { 1084d5c65159SKalle Valo struct hal_rx_phyrx_rssi_legacy_info *rssi = 1085d5c65159SKalle Valo (struct hal_rx_phyrx_rssi_legacy_info *)tlv_data; 1086d5c65159SKalle Valo 1087d5c65159SKalle Valo /* TODO: Please note that the combined rssi will not be accurate 1088d5c65159SKalle Valo * in MU case. Rssi in MU needs to be retrieved from 1089d5c65159SKalle Valo * PHYRX_OTHER_RECEIVE_INFO TLV. 1090d5c65159SKalle Valo */ 1091d5c65159SKalle Valo ppdu_info->rssi_comb = 1092d5c65159SKalle Valo FIELD_GET(HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO1_RSSI_COMB, 1093d5c65159SKalle Valo __le32_to_cpu(rssi->info0)); 1094d5c65159SKalle Valo break; 1095d5c65159SKalle Valo } 1096d5c65159SKalle Valo case HAL_RX_MPDU_START: { 1097d5c65159SKalle Valo struct hal_rx_mpdu_info *mpdu_info = 1098d5c65159SKalle Valo (struct hal_rx_mpdu_info *)tlv_data; 1099d5c65159SKalle Valo u16 peer_id; 1100d5c65159SKalle Valo 1101d5c65159SKalle Valo peer_id = FIELD_GET(HAL_RX_MPDU_INFO_INFO0_PEERID, 1102d5c65159SKalle Valo __le32_to_cpu(mpdu_info->info0)); 1103d5c65159SKalle Valo if (peer_id) 1104d5c65159SKalle Valo ppdu_info->peer_id = peer_id; 1105d5c65159SKalle Valo break; 1106d5c65159SKalle Valo } 1107d5c65159SKalle Valo case HAL_RXPCU_PPDU_END_INFO: { 1108d5c65159SKalle Valo struct hal_rx_ppdu_end_duration *ppdu_rx_duration = 1109d5c65159SKalle Valo (struct hal_rx_ppdu_end_duration *)tlv_data; 1110d5c65159SKalle Valo ppdu_info->rx_duration = 1111d5c65159SKalle Valo FIELD_GET(HAL_RX_PPDU_END_DURATION, 1112d5c65159SKalle Valo __le32_to_cpu(ppdu_rx_duration->info0)); 1113d5c65159SKalle Valo break; 1114d5c65159SKalle Valo } 1115d5c65159SKalle Valo case HAL_DUMMY: 1116d5c65159SKalle Valo return HAL_RX_MON_STATUS_BUF_DONE; 1117d5c65159SKalle Valo case HAL_RX_PPDU_END_STATUS_DONE: 1118d5c65159SKalle Valo case 0: 1119d5c65159SKalle Valo return HAL_RX_MON_STATUS_PPDU_DONE; 1120d5c65159SKalle Valo default: 1121d5c65159SKalle Valo break; 1122d5c65159SKalle Valo } 1123d5c65159SKalle Valo 1124d5c65159SKalle Valo return HAL_RX_MON_STATUS_PPDU_NOT_DONE; 1125d5c65159SKalle Valo } 1126d5c65159SKalle Valo 1127d5c65159SKalle Valo enum hal_rx_mon_status 1128d5c65159SKalle Valo ath11k_hal_rx_parse_mon_status(struct ath11k_base *ab, 1129d5c65159SKalle Valo struct hal_rx_mon_ppdu_info *ppdu_info, 1130d5c65159SKalle Valo struct sk_buff *skb) 1131d5c65159SKalle Valo { 1132d5c65159SKalle Valo struct hal_tlv_hdr *tlv; 1133d5c65159SKalle Valo enum hal_rx_mon_status hal_status = HAL_RX_MON_STATUS_BUF_DONE; 1134d5c65159SKalle Valo u16 tlv_tag; 1135d5c65159SKalle Valo u16 tlv_len; 1136d5c65159SKalle Valo u8 *ptr = skb->data; 1137d5c65159SKalle Valo 1138d5c65159SKalle Valo do { 1139d5c65159SKalle Valo tlv = (struct hal_tlv_hdr *)ptr; 1140d5c65159SKalle Valo tlv_tag = FIELD_GET(HAL_TLV_HDR_TAG, tlv->tl); 1141d5c65159SKalle Valo tlv_len = FIELD_GET(HAL_TLV_HDR_LEN, tlv->tl); 1142d5c65159SKalle Valo ptr += sizeof(*tlv); 1143d5c65159SKalle Valo 1144d5c65159SKalle Valo /* The actual length of PPDU_END is the combined length of many PHY 1145d5c65159SKalle Valo * TLVs that follow. Skip the TLV header and 1146d5c65159SKalle Valo * rx_rxpcu_classification_overview that follows the header to get to 1147d5c65159SKalle Valo * next TLV. 1148d5c65159SKalle Valo */ 1149d5c65159SKalle Valo if (tlv_tag == HAL_RX_PPDU_END) 1150d5c65159SKalle Valo tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview); 1151d5c65159SKalle Valo 1152d5c65159SKalle Valo hal_status = ath11k_hal_rx_parse_mon_status_tlv(ab, ppdu_info, 1153d5c65159SKalle Valo tlv_tag, ptr); 1154d5c65159SKalle Valo ptr += tlv_len; 1155d5c65159SKalle Valo ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN); 1156d5c65159SKalle Valo 1157d5c65159SKalle Valo if ((ptr - skb->data) >= DP_RX_BUFFER_SIZE) 1158d5c65159SKalle Valo break; 1159d5c65159SKalle Valo } while (hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE); 1160d5c65159SKalle Valo 1161d5c65159SKalle Valo return hal_status; 1162d5c65159SKalle Valo } 1163d5c65159SKalle Valo 1164d5c65159SKalle Valo void ath11k_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr, 1165d5c65159SKalle Valo u32 *sw_cookie, void **pp_buf_addr, 1166d5c65159SKalle Valo u32 *msdu_cnt) 1167d5c65159SKalle Valo { 1168d5c65159SKalle Valo struct hal_reo_entrance_ring *reo_ent_ring = 1169d5c65159SKalle Valo (struct hal_reo_entrance_ring *)rx_desc; 1170d5c65159SKalle Valo struct ath11k_buffer_addr *buf_addr_info; 1171d5c65159SKalle Valo struct rx_mpdu_desc *rx_mpdu_desc_info_details; 1172d5c65159SKalle Valo 1173d5c65159SKalle Valo rx_mpdu_desc_info_details = 1174d5c65159SKalle Valo (struct rx_mpdu_desc *)&reo_ent_ring->rx_mpdu_info; 1175d5c65159SKalle Valo 1176d5c65159SKalle Valo *msdu_cnt = FIELD_GET(RX_MPDU_DESC_INFO0_MSDU_COUNT, 1177d5c65159SKalle Valo rx_mpdu_desc_info_details->info0); 1178d5c65159SKalle Valo 1179d5c65159SKalle Valo buf_addr_info = (struct ath11k_buffer_addr *)&reo_ent_ring->buf_addr_info; 1180d5c65159SKalle Valo 1181d5c65159SKalle Valo *paddr = (((u64)FIELD_GET(BUFFER_ADDR_INFO1_ADDR, 1182d5c65159SKalle Valo buf_addr_info->info1)) << 32) | 1183d5c65159SKalle Valo FIELD_GET(BUFFER_ADDR_INFO0_ADDR, 1184d5c65159SKalle Valo buf_addr_info->info0); 1185d5c65159SKalle Valo 1186d5c65159SKalle Valo *sw_cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, 1187d5c65159SKalle Valo buf_addr_info->info1); 1188d5c65159SKalle Valo 1189d5c65159SKalle Valo *pp_buf_addr = (void *)buf_addr_info; 1190d5c65159SKalle Valo } 1191