xref: /wlan-dirver/qca-wifi-host-cmn/hal/wifi3.0/be/hal_be_reo.c (revision d97cfce6b43cb886e37296da37840d170c8ea179)
1 /*
2  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "qdf_module.h"
21 #include "hal_hw_headers.h"
22 #include "hal_be_hw_headers.h"
23 #include "hal_reo.h"
24 #include "hal_be_reo.h"
25 #include "hal_be_api.h"
26 
27 uint32_t hal_get_reo_reg_base_offset_be(void)
28 {
29 	return REO_REG_REG_BASE;
30 }
31 
32 void hal_reo_qdesc_setup_be(hal_soc_handle_t hal_soc_hdl, int tid,
33 			    uint32_t ba_window_size,
34 			    uint32_t start_seq, void *hw_qdesc_vaddr,
35 			    qdf_dma_addr_t hw_qdesc_paddr,
36 			    int pn_type, uint8_t vdev_stats_id)
37 {
38 	uint32_t *reo_queue_desc = (uint32_t *)hw_qdesc_vaddr;
39 	uint32_t *reo_queue_ext_desc;
40 	uint32_t reg_val;
41 	uint32_t pn_enable;
42 	uint32_t pn_size = 0;
43 
44 	qdf_mem_zero(hw_qdesc_vaddr, sizeof(struct rx_reo_queue));
45 
46 	hal_uniform_desc_hdr_setup(reo_queue_desc, HAL_DESC_REO_OWNED,
47 				   HAL_REO_QUEUE_DESC);
48 	/* Fixed pattern in reserved bits for debugging */
49 	HAL_DESC_SET_FIELD(reo_queue_desc, UNIFORM_DESCRIPTOR_HEADER,
50 			   RESERVED_0A, 0xDDBEEF);
51 
52 	/* This a just a SW meta data and will be copied to REO destination
53 	 * descriptors indicated by hardware.
54 	 * TODO: Setting TID in this field. See if we should set something else.
55 	 */
56 	HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE,
57 			   RECEIVE_QUEUE_NUMBER, tid);
58 	HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE,
59 			   VLD, 1);
60 	HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE,
61 			   ASSOCIATED_LINK_DESCRIPTOR_COUNTER,
62 			   HAL_RX_LINK_DESC_CNTR);
63 
64 	/*
65 	 * Fields DISABLE_DUPLICATE_DETECTION and SOFT_REORDER_ENABLE will be 0
66 	 */
67 
68 	reg_val = TID_TO_WME_AC(tid);
69 	HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE, AC, reg_val);
70 
71 	if (ba_window_size < 1)
72 		ba_window_size = 1;
73 
74 	/* WAR to get 2k exception in Non BA case.
75 	 * Setting window size to 2 to get 2k jump exception
76 	 * when we receive aggregates in Non BA case
77 	 */
78 	ba_window_size = hal_update_non_ba_win_size(tid, ba_window_size);
79 
80 	/* Set RTY bit for non-BA case. Duplicate detection is currently not
81 	 * done by HW in non-BA case if RTY bit is not set.
82 	 * TODO: This is a temporary War and should be removed once HW fix is
83 	 * made to check and discard duplicates even if RTY bit is not set.
84 	 */
85 	if (ba_window_size == 1)
86 		HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE, RTY, 1);
87 
88 	HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE, BA_WINDOW_SIZE,
89 			   ba_window_size - 1);
90 
91 	switch (pn_type) {
92 	case HAL_PN_WPA:
93 		pn_enable = 1;
94 		pn_size = PN_SIZE_48;
95 		break;
96 	case HAL_PN_WAPI_EVEN:
97 	case HAL_PN_WAPI_UNEVEN:
98 		pn_enable = 1;
99 		pn_size = PN_SIZE_128;
100 		break;
101 	default:
102 		pn_enable = 0;
103 		break;
104 	}
105 
106 	HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE, PN_CHECK_NEEDED,
107 			   pn_enable);
108 
109 	if (pn_type == HAL_PN_WAPI_EVEN)
110 		HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE,
111 				   PN_SHALL_BE_EVEN, 1);
112 	else if (pn_type == HAL_PN_WAPI_UNEVEN)
113 		HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE,
114 				   PN_SHALL_BE_UNEVEN, 1);
115 
116 	/*
117 	 *  TODO: Need to check if PN handling in SW needs to be enabled
118 	 *  So far this is not a requirement
119 	 */
120 
121 	HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE, PN_SIZE,
122 			   pn_size);
123 
124 	/* TODO: Check if RX_REO_QUEUE_IGNORE_AMPDU_FLAG need to be set
125 	 * based on BA window size and/or AMPDU capabilities
126 	 */
127 	HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE,
128 			   IGNORE_AMPDU_FLAG, 1);
129 
130 	if (start_seq <= 0xfff)
131 		HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE, SSN,
132 				   start_seq);
133 
134 	/* TODO: SVLD should be set to 1 if a valid SSN is received in ADDBA,
135 	 * but REO is not delivering packets if we set it to 1. Need to enable
136 	 * this once the issue is resolved
137 	 */
138 	HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE, SVLD, 0);
139 
140 	hal_update_stats_counter_index(reo_queue_desc, vdev_stats_id);
141 
142 	/* TODO: Check if we should set start PN for WAPI */
143 
144 	/* TODO: HW queue descriptors are currently allocated for max BA
145 	 * window size for all QOS TIDs so that same descriptor can be used
146 	 * later when ADDBA request is received. This should be changed to
147 	 * allocate HW queue descriptors based on BA window size being
148 	 * negotiated (0 for non BA cases), and reallocate when BA window
149 	 * size changes and also send WMI message to FW to change the REO
150 	 * queue descriptor in Rx peer entry as part of dp_rx_tid_update.
151 	 */
152 	if (tid == HAL_NON_QOS_TID)
153 		return;
154 
155 	reo_queue_ext_desc = (uint32_t *)
156 		(((struct rx_reo_queue *)reo_queue_desc) + 1);
157 	qdf_mem_zero(reo_queue_ext_desc, 3 *
158 		     sizeof(struct rx_reo_queue_ext));
159 	/* Initialize first reo queue extension descriptor */
160 	hal_uniform_desc_hdr_setup(reo_queue_ext_desc,
161 				   HAL_DESC_REO_OWNED,
162 				   HAL_REO_QUEUE_EXT_DESC);
163 	/* Fixed pattern in reserved bits for debugging */
164 	HAL_DESC_SET_FIELD(reo_queue_ext_desc,
165 			   UNIFORM_DESCRIPTOR_HEADER, RESERVED_0A,
166 			   0xADBEEF);
167 	/* Initialize second reo queue extension descriptor */
168 	reo_queue_ext_desc = (uint32_t *)
169 		(((struct rx_reo_queue_ext *)reo_queue_ext_desc) + 1);
170 	hal_uniform_desc_hdr_setup(reo_queue_ext_desc,
171 				   HAL_DESC_REO_OWNED,
172 				   HAL_REO_QUEUE_EXT_DESC);
173 	/* Fixed pattern in reserved bits for debugging */
174 	HAL_DESC_SET_FIELD(reo_queue_ext_desc,
175 			   UNIFORM_DESCRIPTOR_HEADER, RESERVED_0A,
176 			   0xBDBEEF);
177 	/* Initialize third reo queue extension descriptor */
178 	reo_queue_ext_desc = (uint32_t *)
179 		(((struct rx_reo_queue_ext *)reo_queue_ext_desc) + 1);
180 	hal_uniform_desc_hdr_setup(reo_queue_ext_desc,
181 				   HAL_DESC_REO_OWNED,
182 				   HAL_REO_QUEUE_EXT_DESC);
183 	/* Fixed pattern in reserved bits for debugging */
184 	HAL_DESC_SET_FIELD(reo_queue_ext_desc,
185 			   UNIFORM_DESCRIPTOR_HEADER, RESERVED_0A,
186 			   0xCDBEEF);
187 }
188 
189 qdf_export_symbol(hal_reo_qdesc_setup_be);
190 
191 static void
192 hal_reo_cmd_set_descr_addr_be(uint32_t *reo_desc,
193 			      enum hal_reo_cmd_type type,
194 			      uint32_t paddr_lo,
195 			      uint8_t paddr_hi)
196 {
197 	struct reo_get_queue_stats *reo_get_queue_stats;
198 	struct reo_flush_queue *reo_flush_queue;
199 	struct reo_flush_cache *reo_flush_cache;
200 	struct reo_update_rx_reo_queue *reo_update_rx_reo_queue;
201 
202 	switch (type) {
203 	case CMD_GET_QUEUE_STATS:
204 		reo_get_queue_stats = (struct reo_get_queue_stats *)reo_desc;
205 		reo_get_queue_stats->rx_reo_queue_desc_addr_31_0 = paddr_lo;
206 		reo_get_queue_stats->rx_reo_queue_desc_addr_39_32 = paddr_hi;
207 		break;
208 	case CMD_FLUSH_QUEUE:
209 		reo_flush_queue = (struct reo_flush_queue *)reo_desc;
210 		reo_flush_queue->flush_desc_addr_31_0 = paddr_lo;
211 		reo_flush_queue->flush_desc_addr_39_32 = paddr_hi;
212 		break;
213 	case CMD_FLUSH_CACHE:
214 		reo_flush_cache = (struct reo_flush_cache *)reo_desc;
215 		reo_flush_cache->flush_addr_31_0 = paddr_lo;
216 		reo_flush_cache->flush_addr_39_32 = paddr_hi;
217 		break;
218 	case CMD_UPDATE_RX_REO_QUEUE:
219 		reo_update_rx_reo_queue =
220 				(struct reo_update_rx_reo_queue *)reo_desc;
221 		reo_update_rx_reo_queue->rx_reo_queue_desc_addr_31_0 = paddr_lo;
222 		reo_update_rx_reo_queue->rx_reo_queue_desc_addr_39_32 =
223 								paddr_hi;
224 		break;
225 	default:
226 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
227 			  "%s: Invalid REO command type", __func__);
228 		break;
229 	}
230 }
231 
232 static int
233 hal_reo_cmd_queue_stats_be(hal_ring_handle_t  hal_ring_hdl,
234 			   hal_soc_handle_t hal_soc_hdl,
235 			   struct hal_reo_cmd_params *cmd)
236 {
237 	uint32_t *reo_desc, val;
238 	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
239 	struct reo_get_queue_stats *reo_get_queue_stats;
240 
241 	hal_srng_access_start(hal_soc_hdl, hal_ring_hdl);
242 	reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
243 	if (!reo_desc) {
244 		hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
245 		hal_warn_rl("Out of cmd ring entries");
246 		return -EBUSY;
247 	}
248 
249 	HAL_SET_TLV_HDR(reo_desc, WIFIREO_GET_QUEUE_STATS_E,
250 			sizeof(struct reo_get_queue_stats));
251 
252 	/*
253 	 * Offsets of descriptor fields defined in HW headers start from
254 	 * the field after TLV header
255 	 */
256 	reo_desc += (sizeof(struct tlv_32_hdr) >> 2);
257 	qdf_mem_zero((reo_desc + NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER),
258 		     sizeof(struct reo_get_queue_stats) -
259 		     (NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER << 2));
260 
261 	reo_get_queue_stats = (struct reo_get_queue_stats *)reo_desc;
262 	reo_get_queue_stats->cmd_header.reo_status_required =
263 							cmd->std.need_status;
264 
265 	hal_reo_cmd_set_descr_addr_be(reo_desc, CMD_GET_QUEUE_STATS,
266 				      cmd->std.addr_lo,
267 				      cmd->std.addr_hi);
268 
269 	reo_get_queue_stats->clear_stats = cmd->u.stats_params.clear;
270 
271 	hal_srng_access_end_v1(hal_soc_hdl, hal_ring_hdl,
272 			       HIF_RTPM_ID_HAL_REO_CMD);
273 
274 	val = reo_desc[CMD_HEADER_DW_OFFSET];
275 	return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER, REO_CMD_NUMBER,
276 				     val);
277 }
278 
279 static int
280 hal_reo_cmd_flush_queue_be(hal_ring_handle_t hal_ring_hdl,
281 			   hal_soc_handle_t hal_soc_hdl,
282 			   struct hal_reo_cmd_params *cmd)
283 {
284 	uint32_t *reo_desc, val;
285 	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
286 	struct reo_flush_queue *reo_flush_queue;
287 
288 	hal_srng_access_start(hal_soc_hdl, hal_ring_hdl);
289 	reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
290 	if (!reo_desc) {
291 		hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
292 		hal_warn_rl("Out of cmd ring entries");
293 		return -EBUSY;
294 	}
295 
296 	HAL_SET_TLV_HDR(reo_desc, WIFIREO_FLUSH_QUEUE_E,
297 			sizeof(struct reo_flush_queue));
298 
299 	/*
300 	 * Offsets of descriptor fields defined in HW headers start from
301 	 * the field after TLV header
302 	 */
303 	reo_desc += (sizeof(struct tlv_32_hdr) >> 2);
304 	qdf_mem_zero((reo_desc + NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER),
305 		     sizeof(struct reo_flush_queue) -
306 		     (NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER << 2));
307 
308 	reo_flush_queue = (struct reo_flush_queue *)reo_desc;
309 	reo_flush_queue->cmd_header.reo_status_required = cmd->std.need_status;
310 
311 	hal_reo_cmd_set_descr_addr_be(reo_desc, CMD_FLUSH_QUEUE,
312 				      cmd->std.addr_lo, cmd->std.addr_hi);
313 
314 	reo_flush_queue->block_desc_addr_usage_after_flush =
315 				cmd->u.fl_queue_params.block_use_after_flush;
316 
317 	if (cmd->u.fl_queue_params.block_use_after_flush)
318 		reo_flush_queue->block_resource_index =
319 						cmd->u.fl_queue_params.index;
320 
321 	hal_srng_access_end_v1(hal_soc_hdl, hal_ring_hdl,
322 			       HIF_RTPM_ID_HAL_REO_CMD);
323 
324 	val = reo_desc[CMD_HEADER_DW_OFFSET];
325 	return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER, REO_CMD_NUMBER,
326 				     val);
327 }
328 
329 static int
330 hal_reo_cmd_flush_cache_be(hal_ring_handle_t hal_ring_hdl,
331 			   hal_soc_handle_t hal_soc_hdl,
332 			   struct hal_reo_cmd_params *cmd)
333 {
334 	uint32_t *reo_desc, val;
335 	struct hal_reo_cmd_flush_cache_params *cp;
336 	uint8_t index = 0;
337 	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
338 	struct reo_flush_cache *reo_flush_cache;
339 
340 	cp = &cmd->u.fl_cache_params;
341 
342 	hal_srng_access_start(hal_soc_hdl, hal_ring_hdl);
343 
344 	/* We need a cache block resource for this operation, and REO HW has
345 	 * only 4 such blocking resources. These resources are managed using
346 	 * reo_res_bitmap, and we return failure if none is available.
347 	 */
348 	if (cp->block_use_after_flush) {
349 		index = hal_find_zero_bit(hal_soc->reo_res_bitmap);
350 		if (index > 3) {
351 			hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
352 			hal_warn_rl("No blocking resource available!");
353 			return -EBUSY;
354 		}
355 		hal_soc->index = index;
356 	}
357 
358 	reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
359 	if (!reo_desc) {
360 		hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
361 		hal_srng_dump(hal_ring_handle_to_hal_srng(hal_ring_hdl));
362 		return -EBUSY;
363 	}
364 
365 	HAL_SET_TLV_HDR(reo_desc, WIFIREO_FLUSH_CACHE_E,
366 			sizeof(struct reo_flush_cache));
367 
368 	/*
369 	 * Offsets of descriptor fields defined in HW headers start from
370 	 * the field after TLV header
371 	 */
372 	reo_desc += (sizeof(struct tlv_32_hdr) >> 2);
373 	qdf_mem_zero((reo_desc + NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER),
374 		     sizeof(struct reo_flush_cache) -
375 		     (NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER << 2));
376 
377 	reo_flush_cache = (struct reo_flush_cache *)reo_desc;
378 	reo_flush_cache->cmd_header.reo_status_required = cmd->std.need_status;
379 
380 	hal_reo_cmd_set_descr_addr_be(reo_desc, CMD_FLUSH_CACHE,
381 				      cmd->std.addr_lo, cmd->std.addr_hi);
382 
383 	reo_flush_cache->forward_all_mpdus_in_queue = cp->fwd_mpdus_in_queue;
384 
385 	/* set it to 0 for now */
386 	cp->rel_block_index = 0;
387 	reo_flush_cache->release_cache_block_index = cp->rel_block_index;
388 
389 	if (cp->block_use_after_flush) {
390 		reo_flush_cache->cache_block_resource_index = index;
391 	}
392 
393 	reo_flush_cache->flush_without_invalidate = cp->flush_no_inval;
394 	reo_flush_cache->flush_queue_1k_desc = cp->flush_q_1k_desc;
395 	reo_flush_cache->block_cache_usage_after_flush =
396 						cp->block_use_after_flush;
397 	reo_flush_cache->flush_entire_cache = cp->flush_entire_cache;
398 
399 	hal_srng_access_end_v1(hal_soc_hdl, hal_ring_hdl,
400 			       HIF_RTPM_ID_HAL_REO_CMD);
401 
402 	val = reo_desc[CMD_HEADER_DW_OFFSET];
403 	return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER, REO_CMD_NUMBER,
404 				     val);
405 }
406 
407 static int
408 hal_reo_cmd_unblock_cache_be(hal_ring_handle_t hal_ring_hdl,
409 			     hal_soc_handle_t hal_soc_hdl,
410 			     struct hal_reo_cmd_params *cmd)
411 
412 {
413 	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
414 	uint32_t *reo_desc, val;
415 	uint8_t index = 0;
416 	struct reo_unblock_cache *reo_unblock_cache;
417 
418 	hal_srng_access_start(hal_soc_hdl, hal_ring_hdl);
419 
420 	if (cmd->u.unblk_cache_params.type == UNBLOCK_RES_INDEX) {
421 		index = hal_find_one_bit(hal_soc->reo_res_bitmap);
422 		if (index > 3) {
423 			hal_srng_access_end(hal_soc, hal_ring_hdl);
424 			qdf_print("No blocking resource to unblock!");
425 			return -EBUSY;
426 		}
427 	}
428 
429 	reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
430 	if (!reo_desc) {
431 		hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
432 		hal_warn_rl("Out of cmd ring entries");
433 		return -EBUSY;
434 	}
435 
436 	HAL_SET_TLV_HDR(reo_desc, WIFIREO_UNBLOCK_CACHE_E,
437 			sizeof(struct reo_unblock_cache));
438 
439 	/*
440 	 * Offsets of descriptor fields defined in HW headers start from
441 	 * the field after TLV header
442 	 */
443 	reo_desc += (sizeof(struct tlv_32_hdr) >> 2);
444 	qdf_mem_zero((reo_desc + NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER),
445 		     sizeof(struct reo_unblock_cache) -
446 		     (NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER << 2));
447 
448 	reo_unblock_cache = (struct reo_unblock_cache *)reo_desc;
449 	reo_unblock_cache->cmd_header.reo_status_required =
450 							cmd->std.need_status;
451 	reo_unblock_cache->unblock_type = cmd->u.unblk_cache_params.type;
452 
453 	if (cmd->u.unblk_cache_params.type == UNBLOCK_RES_INDEX)
454 		reo_unblock_cache->cache_block_resource_index =
455 						cmd->u.unblk_cache_params.index;
456 
457 	hal_srng_access_end(hal_soc, hal_ring_hdl);
458 	val = reo_desc[CMD_HEADER_DW_OFFSET];
459 	return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER, REO_CMD_NUMBER,
460 				     val);
461 }
462 
463 static int
464 hal_reo_cmd_flush_timeout_list_be(hal_ring_handle_t hal_ring_hdl,
465 				  hal_soc_handle_t hal_soc_hdl,
466 				  struct hal_reo_cmd_params *cmd)
467 {
468 	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
469 	uint32_t *reo_desc, val;
470 	struct reo_flush_timeout_list *reo_flush_timeout_list;
471 
472 	hal_srng_access_start(hal_soc_hdl, hal_ring_hdl);
473 	reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
474 	if (!reo_desc) {
475 		hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
476 		hal_warn_rl("Out of cmd ring entries");
477 		return -EBUSY;
478 	}
479 
480 	HAL_SET_TLV_HDR(reo_desc, WIFIREO_FLUSH_TIMEOUT_LIST_E,
481 			sizeof(struct reo_flush_timeout_list));
482 
483 	/*
484 	 * Offsets of descriptor fields defined in HW headers start from
485 	 * the field after TLV header
486 	 */
487 	reo_desc += (sizeof(struct tlv_32_hdr) >> 2);
488 	qdf_mem_zero((reo_desc + NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER),
489 		     sizeof(struct reo_flush_timeout_list) -
490 		     (NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER << 2));
491 
492 	reo_flush_timeout_list = (struct reo_flush_timeout_list *)reo_desc;
493 	reo_flush_timeout_list->cmd_header.reo_status_required =
494 							cmd->std.need_status;
495 	reo_flush_timeout_list->ac_timout_list =
496 					cmd->u.fl_tim_list_params.ac_list;
497 	reo_flush_timeout_list->minimum_release_desc_count =
498 					cmd->u.fl_tim_list_params.min_rel_desc;
499 	reo_flush_timeout_list->minimum_forward_buf_count =
500 					cmd->u.fl_tim_list_params.min_fwd_buf;
501 
502 	hal_srng_access_end(hal_soc, hal_ring_hdl);
503 	val = reo_desc[CMD_HEADER_DW_OFFSET];
504 	return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER, REO_CMD_NUMBER,
505 				     val);
506 }
507 
508 static int
509 hal_reo_cmd_update_rx_queue_be(hal_ring_handle_t hal_ring_hdl,
510 			       hal_soc_handle_t hal_soc_hdl,
511 			       struct hal_reo_cmd_params *cmd)
512 {
513 	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
514 	uint32_t *reo_desc, val;
515 	struct hal_reo_cmd_update_queue_params *p;
516 	struct reo_update_rx_reo_queue *reo_update_rx_reo_queue;
517 
518 	p = &cmd->u.upd_queue_params;
519 
520 	hal_srng_access_start(hal_soc_hdl, hal_ring_hdl);
521 	reo_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
522 	if (!reo_desc) {
523 		hal_srng_access_end_reap(hal_soc, hal_ring_hdl);
524 		hal_warn_rl("Out of cmd ring entries");
525 		return -EBUSY;
526 	}
527 
528 	HAL_SET_TLV_HDR(reo_desc, WIFIREO_UPDATE_RX_REO_QUEUE_E,
529 			sizeof(struct reo_update_rx_reo_queue));
530 
531 	/*
532 	 * Offsets of descriptor fields defined in HW headers start from
533 	 * the field after TLV header
534 	 */
535 	reo_desc += (sizeof(struct tlv_32_hdr) >> 2);
536 	qdf_mem_zero((reo_desc + NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER),
537 		     sizeof(struct reo_update_rx_reo_queue) -
538 		     (NUM_OF_DWORDS_UNIFORM_REO_CMD_HEADER << 2));
539 
540 	reo_update_rx_reo_queue = (struct reo_update_rx_reo_queue *)reo_desc;
541 	reo_update_rx_reo_queue->cmd_header.reo_status_required =
542 							cmd->std.need_status;
543 
544 	hal_reo_cmd_set_descr_addr_be(reo_desc, CMD_UPDATE_RX_REO_QUEUE,
545 				      cmd->std.addr_lo, cmd->std.addr_hi);
546 
547 	reo_update_rx_reo_queue->update_receive_queue_number =
548 							p->update_rx_queue_num;
549 	reo_update_rx_reo_queue->update_vld = p->update_vld;
550 	reo_update_rx_reo_queue->update_associated_link_descriptor_counter =
551 						p->update_assoc_link_desc;
552 	reo_update_rx_reo_queue->update_disable_duplicate_detection =
553 						p->update_disable_dup_detect;
554 	reo_update_rx_reo_queue->update_soft_reorder_enable =
555 						p->update_soft_reorder_enab;
556 	reo_update_rx_reo_queue->update_ac = p->update_ac;
557 	reo_update_rx_reo_queue->update_bar = p->update_bar;
558 	reo_update_rx_reo_queue->update_rty = p->update_rty;
559 	reo_update_rx_reo_queue->update_chk_2k_mode = p->update_chk_2k_mode;
560 	reo_update_rx_reo_queue->update_oor_mode = p->update_oor_mode;
561 	reo_update_rx_reo_queue->update_ba_window_size =
562 						p->update_ba_window_size;
563 	reo_update_rx_reo_queue->update_pn_check_needed =
564 						p->update_pn_check_needed;
565 	reo_update_rx_reo_queue->update_pn_shall_be_even = p->update_pn_even;
566 	reo_update_rx_reo_queue->update_pn_shall_be_uneven =
567 							p->update_pn_uneven;
568 	reo_update_rx_reo_queue->update_pn_handling_enable =
569 							p->update_pn_hand_enab;
570 	reo_update_rx_reo_queue->update_pn_size = p->update_pn_size;
571 	reo_update_rx_reo_queue->update_ignore_ampdu_flag =
572 							p->update_ignore_ampdu;
573 	reo_update_rx_reo_queue->update_svld = p->update_svld;
574 	reo_update_rx_reo_queue->update_ssn = p->update_ssn;
575 	reo_update_rx_reo_queue->update_seq_2k_error_detected_flag =
576 						p->update_seq_2k_err_detect;
577 	reo_update_rx_reo_queue->update_pn_valid = p->update_pn_valid;
578 	reo_update_rx_reo_queue->update_pn = p->update_pn;
579 	reo_update_rx_reo_queue->receive_queue_number = p->rx_queue_num;
580 	reo_update_rx_reo_queue->vld = p->vld;
581 	reo_update_rx_reo_queue->associated_link_descriptor_counter =
582 							p->assoc_link_desc;
583 	reo_update_rx_reo_queue->disable_duplicate_detection =
584 							p->disable_dup_detect;
585 	reo_update_rx_reo_queue->soft_reorder_enable = p->soft_reorder_enab;
586 	reo_update_rx_reo_queue->ac = p->ac;
587 	reo_update_rx_reo_queue->bar = p->bar;
588 	reo_update_rx_reo_queue->chk_2k_mode = p->chk_2k_mode;
589 	reo_update_rx_reo_queue->rty = p->rty;
590 	reo_update_rx_reo_queue->oor_mode = p->oor_mode;
591 	reo_update_rx_reo_queue->pn_check_needed = p->pn_check_needed;
592 	reo_update_rx_reo_queue->pn_shall_be_even = p->pn_even;
593 	reo_update_rx_reo_queue->pn_shall_be_uneven = p->pn_uneven;
594 	reo_update_rx_reo_queue->pn_handling_enable = p->pn_hand_enab;
595 	reo_update_rx_reo_queue->ignore_ampdu_flag = p->ignore_ampdu;
596 
597 	if (p->ba_window_size < 1)
598 		p->ba_window_size = 1;
599 	/*
600 	 * WAR to get 2k exception in Non BA case.
601 	 * Setting window size to 2 to get 2k jump exception
602 	 * when we receive aggregates in Non BA case
603 	 */
604 	if (p->ba_window_size == 1)
605 		p->ba_window_size++;
606 
607 	reo_update_rx_reo_queue->ba_window_size = p->ba_window_size - 1;
608 	reo_update_rx_reo_queue->pn_size = p->pn_size;
609 	reo_update_rx_reo_queue->svld = p->svld;
610 	reo_update_rx_reo_queue->ssn = p->ssn;
611 	reo_update_rx_reo_queue->seq_2k_error_detected_flag =
612 							p->seq_2k_err_detect;
613 	reo_update_rx_reo_queue->pn_error_detected_flag = p->pn_err_detect;
614 	reo_update_rx_reo_queue->pn_31_0 = p->pn_31_0;
615 	reo_update_rx_reo_queue->pn_63_32 = p->pn_63_32;
616 	reo_update_rx_reo_queue->pn_95_64 = p->pn_95_64;
617 	reo_update_rx_reo_queue->pn_127_96 = p->pn_127_96;
618 
619 	hal_srng_access_end_v1(hal_soc_hdl, hal_ring_hdl,
620 			       HIF_RTPM_ID_HAL_REO_CMD);
621 
622 	val = reo_desc[CMD_HEADER_DW_OFFSET];
623 	return HAL_GET_FIELD(UNIFORM_REO_CMD_HEADER, REO_CMD_NUMBER,
624 				     val);
625 }
626 
627 int hal_reo_send_cmd_be(hal_soc_handle_t hal_soc_hdl,
628 			hal_ring_handle_t  hal_ring_hdl,
629 			enum hal_reo_cmd_type cmd,
630 			void *params)
631 {
632 	struct hal_reo_cmd_params *cmd_params =
633 			(struct hal_reo_cmd_params *)params;
634 	int num = 0;
635 
636 	switch (cmd) {
637 	case CMD_GET_QUEUE_STATS:
638 		num = hal_reo_cmd_queue_stats_be(hal_ring_hdl,
639 						 hal_soc_hdl, cmd_params);
640 		break;
641 	case CMD_FLUSH_QUEUE:
642 		num = hal_reo_cmd_flush_queue_be(hal_ring_hdl,
643 						 hal_soc_hdl, cmd_params);
644 		break;
645 	case CMD_FLUSH_CACHE:
646 		num = hal_reo_cmd_flush_cache_be(hal_ring_hdl,
647 						 hal_soc_hdl, cmd_params);
648 		break;
649 	case CMD_UNBLOCK_CACHE:
650 		num = hal_reo_cmd_unblock_cache_be(hal_ring_hdl,
651 						   hal_soc_hdl, cmd_params);
652 		break;
653 	case CMD_FLUSH_TIMEOUT_LIST:
654 		num = hal_reo_cmd_flush_timeout_list_be(hal_ring_hdl,
655 							hal_soc_hdl,
656 							cmd_params);
657 		break;
658 	case CMD_UPDATE_RX_REO_QUEUE:
659 		num = hal_reo_cmd_update_rx_queue_be(hal_ring_hdl,
660 						     hal_soc_hdl, cmd_params);
661 		break;
662 	default:
663 		hal_err("Invalid REO command type: %d", cmd);
664 		return -EINVAL;
665 	};
666 
667 	return num;
668 }
669 
670 void
671 hal_reo_queue_stats_status_be(hal_ring_desc_t ring_desc,
672 			      void *st_handle,
673 			      hal_soc_handle_t hal_soc_hdl)
674 {
675 	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
676 	struct hal_reo_queue_status *st =
677 		(struct hal_reo_queue_status *)st_handle;
678 	uint64_t *reo_desc = (uint64_t *)ring_desc;
679 	uint64_t val;
680 
681 	/*
682 	 * Offsets of descriptor fields defined in HW headers start
683 	 * from the field after TLV header
684 	 */
685 	reo_desc += HAL_GET_NUM_QWORDS(sizeof(struct tlv_32_hdr));
686 
687 	/* header */
688 	hal_reo_status_get_header(ring_desc, HAL_REO_QUEUE_STATS_STATUS_TLV,
689 				  &(st->header), hal_soc);
690 
691 	/* SSN */
692 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS, SSN)];
693 	st->ssn = HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS, SSN, val);
694 
695 	/* current index */
696 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
697 					 CURRENT_INDEX)];
698 	st->curr_idx =
699 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
700 			      CURRENT_INDEX, val);
701 
702 	/* PN bits */
703 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
704 					 PN_31_0)];
705 	st->pn_31_0 =
706 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
707 			      PN_31_0, val);
708 
709 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
710 					 PN_63_32)];
711 	st->pn_63_32 =
712 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
713 			      PN_63_32, val);
714 
715 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
716 					 PN_95_64)];
717 	st->pn_95_64 =
718 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
719 			      PN_95_64, val);
720 
721 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
722 					 PN_127_96)];
723 	st->pn_127_96 =
724 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
725 			      PN_127_96, val);
726 
727 	/* timestamps */
728 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
729 					 LAST_RX_ENQUEUE_TIMESTAMP)];
730 	st->last_rx_enq_tstamp =
731 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
732 			      LAST_RX_ENQUEUE_TIMESTAMP, val);
733 
734 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
735 					 LAST_RX_DEQUEUE_TIMESTAMP)];
736 	st->last_rx_deq_tstamp =
737 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
738 			      LAST_RX_DEQUEUE_TIMESTAMP, val);
739 
740 	/* rx bitmap */
741 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
742 					 RX_BITMAP_31_0)];
743 	st->rx_bitmap_31_0 =
744 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
745 			      RX_BITMAP_31_0, val);
746 
747 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
748 					 RX_BITMAP_63_32)];
749 	st->rx_bitmap_63_32 =
750 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
751 			      RX_BITMAP_63_32, val);
752 
753 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
754 					 RX_BITMAP_95_64)];
755 	st->rx_bitmap_95_64 =
756 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
757 			      RX_BITMAP_95_64, val);
758 
759 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
760 					 RX_BITMAP_127_96)];
761 	st->rx_bitmap_127_96 =
762 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
763 			      RX_BITMAP_127_96, val);
764 
765 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
766 					 RX_BITMAP_159_128)];
767 	st->rx_bitmap_159_128 =
768 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
769 			      RX_BITMAP_159_128, val);
770 
771 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
772 					 RX_BITMAP_191_160)];
773 	st->rx_bitmap_191_160 =
774 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
775 			      RX_BITMAP_191_160, val);
776 
777 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
778 					 RX_BITMAP_223_192)];
779 	st->rx_bitmap_223_192 =
780 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
781 			      RX_BITMAP_223_192, val);
782 
783 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
784 					 RX_BITMAP_255_224)];
785 	st->rx_bitmap_255_224 =
786 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
787 			      RX_BITMAP_255_224, val);
788 
789 	/* various counts */
790 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
791 					 CURRENT_MPDU_COUNT)];
792 	st->curr_mpdu_cnt =
793 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
794 			      CURRENT_MPDU_COUNT, val);
795 
796 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
797 					 CURRENT_MSDU_COUNT)];
798 	st->curr_msdu_cnt =
799 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
800 			      CURRENT_MSDU_COUNT, val);
801 
802 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
803 					 TIMEOUT_COUNT)];
804 	st->fwd_timeout_cnt =
805 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
806 			      TIMEOUT_COUNT, val);
807 
808 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
809 					 FORWARD_DUE_TO_BAR_COUNT)];
810 	st->fwd_bar_cnt =
811 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
812 			      FORWARD_DUE_TO_BAR_COUNT, val);
813 
814 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
815 					 DUPLICATE_COUNT)];
816 	st->dup_cnt =
817 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
818 			      DUPLICATE_COUNT, val);
819 
820 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
821 					 FRAMES_IN_ORDER_COUNT)];
822 	st->frms_in_order_cnt =
823 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
824 			      FRAMES_IN_ORDER_COUNT, val);
825 
826 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
827 					 BAR_RECEIVED_COUNT)];
828 	st->bar_rcvd_cnt =
829 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
830 			      BAR_RECEIVED_COUNT, val);
831 
832 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
833 					 MPDU_FRAMES_PROCESSED_COUNT)];
834 	st->mpdu_frms_cnt =
835 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
836 			      MPDU_FRAMES_PROCESSED_COUNT, val);
837 
838 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
839 					 MSDU_FRAMES_PROCESSED_COUNT)];
840 	st->msdu_frms_cnt =
841 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
842 			      MSDU_FRAMES_PROCESSED_COUNT, val);
843 
844 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
845 					 TOTAL_PROCESSED_BYTE_COUNT)];
846 	st->total_cnt =
847 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
848 			      TOTAL_PROCESSED_BYTE_COUNT, val);
849 
850 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
851 					 LATE_RECEIVE_MPDU_COUNT)];
852 	st->late_recv_mpdu_cnt =
853 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
854 			      LATE_RECEIVE_MPDU_COUNT, val);
855 
856 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
857 					 WINDOW_JUMP_2K)];
858 	st->win_jump_2k =
859 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
860 			      WINDOW_JUMP_2K, val);
861 
862 	val = reo_desc[HAL_OFFSET_QW(REO_GET_QUEUE_STATS_STATUS,
863 					 HOLE_COUNT)];
864 	st->hole_cnt =
865 		HAL_GET_FIELD(REO_GET_QUEUE_STATS_STATUS,
866 			      HOLE_COUNT, val);
867 }
868 
869 void
870 hal_reo_flush_queue_status_be(hal_ring_desc_t ring_desc,
871 			      void *st_handle,
872 			      hal_soc_handle_t hal_soc_hdl)
873 {
874 	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
875 	struct hal_reo_flush_queue_status *st =
876 			(struct hal_reo_flush_queue_status *)st_handle;
877 	uint64_t *reo_desc = (uint64_t *)ring_desc;
878 	uint64_t val;
879 
880 	/*
881 	 * Offsets of descriptor fields defined in HW headers start
882 	 * from the field after TLV header
883 	 */
884 	reo_desc += HAL_GET_NUM_QWORDS(sizeof(struct tlv_32_hdr));
885 
886 	/* header */
887 	hal_reo_status_get_header(ring_desc, HAL_REO_FLUSH_QUEUE_STATUS_TLV,
888 				  &(st->header), hal_soc);
889 
890 	/* error bit */
891 	val = reo_desc[HAL_OFFSET(REO_FLUSH_QUEUE_STATUS,
892 					 ERROR_DETECTED)];
893 	st->error = HAL_GET_FIELD(REO_FLUSH_QUEUE_STATUS, ERROR_DETECTED,
894 				  val);
895 }
896 
897 void
898 hal_reo_flush_cache_status_be(hal_ring_desc_t ring_desc,
899 			      void *st_handle,
900 			      hal_soc_handle_t hal_soc_hdl)
901 {
902 	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
903 	struct hal_reo_flush_cache_status *st =
904 			(struct hal_reo_flush_cache_status *)st_handle;
905 	uint64_t *reo_desc = (uint64_t *)ring_desc;
906 	uint64_t val;
907 
908 	/*
909 	 * Offsets of descriptor fields defined in HW headers start
910 	 * from the field after TLV header
911 	 */
912 	reo_desc += HAL_GET_NUM_QWORDS(sizeof(struct tlv_32_hdr));
913 
914 	/* header */
915 	hal_reo_status_get_header(ring_desc, HAL_REO_FLUSH_CACHE_STATUS_TLV,
916 				  &(st->header), hal_soc);
917 
918 	/* error bit */
919 	val = reo_desc[HAL_OFFSET_QW(REO_FLUSH_CACHE_STATUS,
920 					 ERROR_DETECTED)];
921 	st->error = HAL_GET_FIELD(REO_FLUSH_QUEUE_STATUS, ERROR_DETECTED,
922 				  val);
923 
924 	/* block error */
925 	val = reo_desc[HAL_OFFSET_QW(REO_FLUSH_CACHE_STATUS,
926 					 BLOCK_ERROR_DETAILS)];
927 	st->block_error = HAL_GET_FIELD(REO_FLUSH_CACHE_STATUS,
928 					BLOCK_ERROR_DETAILS,
929 					val);
930 	if (!st->block_error)
931 		qdf_set_bit(hal_soc->index,
932 			    (unsigned long *)&hal_soc->reo_res_bitmap);
933 
934 	/* cache flush status */
935 	val = reo_desc[HAL_OFFSET_QW(REO_FLUSH_CACHE_STATUS,
936 					 CACHE_CONTROLLER_FLUSH_STATUS_HIT)];
937 	st->cache_flush_status = HAL_GET_FIELD(REO_FLUSH_CACHE_STATUS,
938 					CACHE_CONTROLLER_FLUSH_STATUS_HIT,
939 					val);
940 
941 	/* cache flush descriptor type */
942 	val = reo_desc[HAL_OFFSET_QW(REO_FLUSH_CACHE_STATUS,
943 				  CACHE_CONTROLLER_FLUSH_STATUS_DESC_TYPE)];
944 	st->cache_flush_status_desc_type =
945 		HAL_GET_FIELD(REO_FLUSH_CACHE_STATUS,
946 			      CACHE_CONTROLLER_FLUSH_STATUS_DESC_TYPE,
947 			      val);
948 
949 	/* cache flush count */
950 	val = reo_desc[HAL_OFFSET_QW(REO_FLUSH_CACHE_STATUS,
951 				  CACHE_CONTROLLER_FLUSH_COUNT)];
952 	st->cache_flush_cnt =
953 		HAL_GET_FIELD(REO_FLUSH_CACHE_STATUS,
954 			      CACHE_CONTROLLER_FLUSH_COUNT,
955 			      val);
956 }
957 
958 void
959 hal_reo_unblock_cache_status_be(hal_ring_desc_t ring_desc,
960 				hal_soc_handle_t hal_soc_hdl,
961 				void *st_handle)
962 {
963 	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
964 	struct hal_reo_unblk_cache_status *st =
965 			(struct hal_reo_unblk_cache_status *)st_handle;
966 	uint64_t *reo_desc = (uint64_t *)ring_desc;
967 	uint64_t val;
968 
969 	/*
970 	 * Offsets of descriptor fields defined in HW headers start
971 	 * from the field after TLV header
972 	 */
973 	reo_desc += HAL_GET_NUM_QWORDS(sizeof(struct tlv_32_hdr));
974 
975 	/* header */
976 	hal_reo_status_get_header(ring_desc, HAL_REO_UNBLK_CACHE_STATUS_TLV,
977 				  &st->header, hal_soc);
978 
979 	/* error bit */
980 	val = reo_desc[HAL_OFFSET_QW(REO_UNBLOCK_CACHE_STATUS,
981 				  ERROR_DETECTED)];
982 	st->error = HAL_GET_FIELD(REO_UNBLOCK_CACHE_STATUS,
983 				  ERROR_DETECTED,
984 				  val);
985 
986 	/* unblock type */
987 	val = reo_desc[HAL_OFFSET_QW(REO_UNBLOCK_CACHE_STATUS,
988 				  UNBLOCK_TYPE)];
989 	st->unblock_type = HAL_GET_FIELD(REO_UNBLOCK_CACHE_STATUS,
990 					 UNBLOCK_TYPE,
991 					 val);
992 
993 	if (!st->error && (st->unblock_type == UNBLOCK_RES_INDEX))
994 		qdf_clear_bit(hal_soc->index,
995 			      (unsigned long *)&hal_soc->reo_res_bitmap);
996 }
997 
998 void hal_reo_flush_timeout_list_status_be(hal_ring_desc_t ring_desc,
999 					  void *st_handle,
1000 					  hal_soc_handle_t hal_soc_hdl)
1001 {
1002 	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
1003 	struct hal_reo_flush_timeout_list_status *st =
1004 			(struct hal_reo_flush_timeout_list_status *)st_handle;
1005 	uint64_t *reo_desc = (uint64_t *)ring_desc;
1006 	uint64_t val;
1007 
1008 	/*
1009 	 * Offsets of descriptor fields defined in HW headers start
1010 	 * from the field after TLV header
1011 	 */
1012 	reo_desc += HAL_GET_NUM_QWORDS(sizeof(struct tlv_32_hdr));
1013 
1014 	/* header */
1015 	hal_reo_status_get_header(ring_desc, HAL_REO_TIMOUT_LIST_STATUS_TLV,
1016 				  &(st->header), hal_soc);
1017 
1018 	/* error bit */
1019 	val = reo_desc[HAL_OFFSET_QW(REO_FLUSH_TIMEOUT_LIST_STATUS,
1020 					 ERROR_DETECTED)];
1021 	st->error = HAL_GET_FIELD(REO_FLUSH_TIMEOUT_LIST_STATUS,
1022 				  ERROR_DETECTED,
1023 				  val);
1024 
1025 	/* list empty */
1026 	val = reo_desc[HAL_OFFSET_QW(REO_FLUSH_TIMEOUT_LIST_STATUS,
1027 					 TIMOUT_LIST_EMPTY)];
1028 	st->list_empty = HAL_GET_FIELD(REO_FLUSH_TIMEOUT_LIST_STATUS,
1029 				       TIMOUT_LIST_EMPTY,
1030 				       val);
1031 
1032 	/* release descriptor count */
1033 	val = reo_desc[HAL_OFFSET_QW(REO_FLUSH_TIMEOUT_LIST_STATUS,
1034 					 RELEASE_DESC_COUNT)];
1035 	st->rel_desc_cnt = HAL_GET_FIELD(REO_FLUSH_TIMEOUT_LIST_STATUS,
1036 					 RELEASE_DESC_COUNT,
1037 					 val);
1038 
1039 	/* forward buf count */
1040 	val = reo_desc[HAL_OFFSET_QW(REO_FLUSH_TIMEOUT_LIST_STATUS,
1041 					 FORWARD_BUF_COUNT)];
1042 	st->fwd_buf_cnt = HAL_GET_FIELD(REO_FLUSH_TIMEOUT_LIST_STATUS,
1043 					FORWARD_BUF_COUNT,
1044 					val);
1045 }
1046 
1047 void hal_reo_desc_thres_reached_status_be(hal_ring_desc_t ring_desc,
1048 					  void *st_handle,
1049 					  hal_soc_handle_t hal_soc_hdl)
1050 {
1051 	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
1052 	struct hal_reo_desc_thres_reached_status *st =
1053 			(struct hal_reo_desc_thres_reached_status *)st_handle;
1054 	uint64_t *reo_desc = (uint64_t *)ring_desc;
1055 	uint64_t val;
1056 
1057 	/*
1058 	 * Offsets of descriptor fields defined in HW headers start
1059 	 * from the field after TLV header
1060 	 */
1061 	reo_desc += HAL_GET_NUM_QWORDS(sizeof(struct tlv_32_hdr));
1062 
1063 	/* header */
1064 	hal_reo_status_get_header(ring_desc,
1065 				  HAL_REO_DESC_THRES_STATUS_TLV,
1066 				  &(st->header), hal_soc);
1067 
1068 	/* threshold index */
1069 	val = reo_desc[HAL_OFFSET_QW(
1070 				 REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS,
1071 				 THRESHOLD_INDEX)];
1072 	st->thres_index = HAL_GET_FIELD(
1073 				REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS,
1074 				THRESHOLD_INDEX,
1075 				val);
1076 
1077 	/* link desc counters */
1078 	val = reo_desc[HAL_OFFSET_QW(
1079 				 REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS,
1080 				 LINK_DESCRIPTOR_COUNTER0)];
1081 	st->link_desc_counter0 = HAL_GET_FIELD(
1082 				REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS,
1083 				LINK_DESCRIPTOR_COUNTER0,
1084 				val);
1085 
1086 	val = reo_desc[HAL_OFFSET_QW(
1087 				 REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS,
1088 				 LINK_DESCRIPTOR_COUNTER1)];
1089 	st->link_desc_counter1 = HAL_GET_FIELD(
1090 				REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS,
1091 				LINK_DESCRIPTOR_COUNTER1,
1092 				val);
1093 
1094 	val = reo_desc[HAL_OFFSET_QW(
1095 				 REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS,
1096 				 LINK_DESCRIPTOR_COUNTER2)];
1097 	st->link_desc_counter2 = HAL_GET_FIELD(
1098 				REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS,
1099 				LINK_DESCRIPTOR_COUNTER2,
1100 				val);
1101 
1102 	val = reo_desc[HAL_OFFSET_QW(
1103 				 REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS,
1104 				 LINK_DESCRIPTOR_COUNTER_SUM)];
1105 	st->link_desc_counter_sum = HAL_GET_FIELD(
1106 				REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS,
1107 				LINK_DESCRIPTOR_COUNTER_SUM,
1108 				val);
1109 }
1110 
1111 void
1112 hal_reo_rx_update_queue_status_be(hal_ring_desc_t ring_desc,
1113 				  void *st_handle,
1114 				  hal_soc_handle_t hal_soc_hdl)
1115 {
1116 	struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
1117 	struct hal_reo_update_rx_queue_status *st =
1118 			(struct hal_reo_update_rx_queue_status *)st_handle;
1119 	uint64_t *reo_desc = (uint64_t *)ring_desc;
1120 
1121 	/*
1122 	 * Offsets of descriptor fields defined in HW headers start
1123 	 * from the field after TLV header
1124 	 */
1125 	reo_desc += HAL_GET_NUM_QWORDS(sizeof(struct tlv_32_hdr));
1126 
1127 	/* header */
1128 	hal_reo_status_get_header(ring_desc,
1129 				  HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV,
1130 				  &(st->header), hal_soc);
1131 }
1132 
1133 uint8_t hal_get_tlv_hdr_size_be(void)
1134 {
1135 	return sizeof(struct tlv_32_hdr);
1136 }
1137