Linux Audio

Check our new training course

Yocto / OpenEmbedded training

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