xref: /wlan-dirver/qca-wifi-host-cmn/hal/wifi3.0/hal_api_mon.h (revision 92d87f51612f6c3b2285266215edee8911647c2f)
1 /*
2  * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #ifndef _HAL_API_MON_H_
20 #define _HAL_API_MON_H_
21 
22 #include "qdf_types.h"
23 #include "hal_internal.h"
24 
25 #define HAL_RX_OFFSET(block, field) block##_##field##_OFFSET
26 #define HAL_RX_LSB(block, field) block##_##field##_LSB
27 #define HAL_RX_MASk(block, field) block##_##field##_MASK
28 
29 #define HAL_RX_GET(_ptr, block, field) \
30 	(((*((volatile uint32_t *)_ptr + (HAL_RX_OFFSET(block, field)>>2))) & \
31 	HAL_RX_MASk(block, field)) >> \
32 	HAL_RX_LSB(block, field))
33 
34 #define HAL_RX_PHY_DATA_RADAR 0x01
35 #define HAL_SU_MU_CODING_LDPC 0x01
36 
37 #define HAL_RX_FCS_LEN (4)
38 #define KEY_EXTIV 0x20
39 
40 #define HAL_RX_USER_TLV32_TYPE_OFFSET		0x00000000
41 #define HAL_RX_USER_TLV32_TYPE_LSB		1
42 #define HAL_RX_USER_TLV32_TYPE_MASK		0x000003FE
43 
44 #define HAL_RX_USER_TLV32_LEN_OFFSET		0x00000000
45 #define HAL_RX_USER_TLV32_LEN_LSB		10
46 #define HAL_RX_USER_TLV32_LEN_MASK		0x003FFC00
47 
48 #define HAL_RX_USER_TLV32_USERID_OFFSET		0x00000000
49 #define HAL_RX_USER_TLV32_USERID_LSB		26
50 #define HAL_RX_USER_TLV32_USERID_MASK		0xFC000000
51 
52 #define HAL_ALIGN(x, a)				HAL_ALIGN_MASK(x, (a)-1)
53 #define HAL_ALIGN_MASK(x, mask)	(typeof(x))(((uint32)(x) + (mask)) & ~(mask))
54 
55 #define HAL_RX_TLV32_HDR_SIZE			4
56 
57 #define HAL_RX_GET_USER_TLV32_TYPE(rx_status_tlv_ptr) \
58 		((*((uint32_t *)(rx_status_tlv_ptr)) & \
59 		HAL_RX_USER_TLV32_TYPE_MASK) >> \
60 		HAL_RX_USER_TLV32_TYPE_LSB)
61 
62 #define HAL_RX_GET_USER_TLV32_LEN(rx_status_tlv_ptr) \
63 		((*((uint32_t *)(rx_status_tlv_ptr)) & \
64 		HAL_RX_USER_TLV32_LEN_MASK) >> \
65 		HAL_RX_USER_TLV32_LEN_LSB)
66 
67 #define HAL_RX_GET_USER_TLV32_USERID(rx_status_tlv_ptr) \
68 		((*((uint32_t *)(rx_status_tlv_ptr)) & \
69 		HAL_RX_USER_TLV32_USERID_MASK) >> \
70 		HAL_RX_USER_TLV32_USERID_LSB)
71 
72 #define HAL_TLV_STATUS_PPDU_NOT_DONE		0
73 #define HAL_TLV_STATUS_PPDU_DONE		1
74 #define HAL_TLV_STATUS_BUF_DONE			2
75 
76 #define HAL_MAX_UL_MU_USERS			8
77 
78 #define HAL_RX_PKT_TYPE_11A	0
79 #define HAL_RX_PKT_TYPE_11B	1
80 #define HAL_RX_PKT_TYPE_11N	2
81 #define HAL_RX_PKT_TYPE_11AC	3
82 #define HAL_RX_PKT_TYPE_11AX	4
83 
84 #define HAL_RX_RECEPTION_TYPE_SU	0
85 #define HAL_RX_RECEPTION_TYPE_MU_MIMO	1
86 #define HAL_RX_RECEPTION_TYPE_OFDMA	2
87 #define HAL_RX_RECEPTION_TYPE_MU_OFDMA	3
88 
89 /* Multiply rate by 2 to avoid float point
90  * and get rate in units of 500kbps
91  */
92 #define HAL_11B_RATE_0MCS	11*2
93 #define HAL_11B_RATE_1MCS	5.5*2
94 #define HAL_11B_RATE_2MCS	2*2
95 #define HAL_11B_RATE_3MCS	1*2
96 #define HAL_11B_RATE_4MCS	11*2
97 #define HAL_11B_RATE_5MCS	5.5*2
98 #define HAL_11B_RATE_6MCS	2*2
99 
100 #define HAL_11A_RATE_0MCS	48*2
101 #define HAL_11A_RATE_1MCS	24*2
102 #define HAL_11A_RATE_2MCS	12*2
103 #define HAL_11A_RATE_3MCS	6*2
104 #define HAL_11A_RATE_4MCS	54*2
105 #define HAL_11A_RATE_5MCS	36*2
106 #define HAL_11A_RATE_6MCS	18*2
107 #define HAL_11A_RATE_7MCS	9*2
108 
109 #define HE_GI_0_8 0
110 #define HE_GI_1_6 1
111 #define HE_GI_3_2 2
112 
113 #define HT_SGI_PRESENT 0x80
114 
115 #define HE_LTF_1_X 0
116 #define HE_LTF_2_X 1
117 #define HE_LTF_4_X 2
118 #define VHT_SIG_SU_NSS_MASK	0x7
119 
120 #define HAL_TID_INVALID 31
121 #define HAL_AST_IDX_INVALID 0xFFFF
122 
123 #ifdef GET_MSDU_AGGREGATION
124 #define HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs)\
125 {\
126 	struct rx_msdu_end *rx_msdu_end;\
127 	bool first_msdu, last_msdu; \
128 	rx_msdu_end = &rx_desc->msdu_end_tlv.rx_msdu_end;\
129 	first_msdu = HAL_RX_GET(rx_msdu_end, RX_MSDU_END_5, FIRST_MSDU);\
130 	last_msdu = HAL_RX_GET(rx_msdu_end, RX_MSDU_END_5, LAST_MSDU);\
131 	if (first_msdu && last_msdu)\
132 		rs->rs_flags &= (~IEEE80211_AMSDU_FLAG);\
133 	else\
134 		rs->rs_flags |= (IEEE80211_AMSDU_FLAG); \
135 } \
136 
137 #else
138 #define HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs)
139 #endif
140 
141 enum {
142 	HAL_HW_RX_DECAP_FORMAT_RAW = 0,
143 	HAL_HW_RX_DECAP_FORMAT_NWIFI,
144 	HAL_HW_RX_DECAP_FORMAT_ETH2,
145 	HAL_HW_RX_DECAP_FORMAT_8023,
146 };
147 
148 enum {
149 	DP_PPDU_STATUS_START,
150 	DP_PPDU_STATUS_DONE,
151 };
152 
153 static inline
154 uint32_t HAL_RX_MON_HW_RX_DESC_SIZE(void)
155 {
156 	/* return the HW_RX_DESC size */
157 	return sizeof(struct rx_pkt_tlvs);
158 }
159 
160 static inline
161 uint8_t *HAL_RX_MON_DEST_GET_DESC(uint8_t *data)
162 {
163 	return data;
164 }
165 
166 static inline
167 uint32_t HAL_RX_DESC_GET_MPDU_LENGTH_ERR(void *hw_desc_addr)
168 {
169 	struct rx_attention *rx_attn;
170 	struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr;
171 
172 	rx_attn = &rx_desc->attn_tlv.rx_attn;
173 
174 	return HAL_RX_GET(rx_attn, RX_ATTENTION_1, MPDU_LENGTH_ERR);
175 }
176 
177 static inline
178 uint32_t HAL_RX_DESC_GET_MPDU_FCS_ERR(void *hw_desc_addr)
179 {
180 	struct rx_attention *rx_attn;
181 	struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr;
182 
183 	rx_attn = &rx_desc->attn_tlv.rx_attn;
184 
185 	return HAL_RX_GET(rx_attn, RX_ATTENTION_1, FCS_ERR);
186 }
187 
188 static inline
189 uint32_t
190 HAL_RX_DESC_GET_DECAP_FORMAT(void *hw_desc_addr) {
191 	struct rx_msdu_start *rx_msdu_start;
192 	struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr;
193 
194 	rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start;
195 
196 	return HAL_RX_GET(rx_msdu_start, RX_MSDU_START_2, DECAP_FORMAT);
197 }
198 
199 static inline
200 uint8_t *
201 HAL_RX_DESC_GET_80211_HDR(void *hw_desc_addr) {
202 	uint8_t *rx_pkt_hdr;
203 	struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr;
204 
205 	rx_pkt_hdr = &rx_desc->pkt_hdr_tlv.rx_pkt_hdr[0];
206 
207 	return rx_pkt_hdr;
208 }
209 
210 static inline
211 uint32_t HAL_RX_HW_DESC_GET_PPDUID_GET(void *hw_desc_addr)
212 {
213 	struct rx_mpdu_info *rx_mpdu_info;
214 	struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr;
215 
216 	rx_mpdu_info =
217 		&rx_desc->mpdu_start_tlv.rx_mpdu_start.rx_mpdu_info_details;
218 
219 	return HAL_RX_GET(rx_mpdu_info, RX_MPDU_INFO_0, PHY_PPDU_ID);
220 }
221 
222 /* TODO: Move all Rx descriptor functions to hal_rx.h to avoid duplication */
223 static inline
224 uint32_t hal_rx_desc_is_first_msdu(void *hw_desc_addr)
225 {
226 	struct rx_pkt_tlvs *rx_tlvs = (struct rx_pkt_tlvs *)hw_desc_addr;
227 	struct rx_msdu_end *msdu_end = &rx_tlvs->msdu_end_tlv.rx_msdu_end;
228 
229 	return HAL_RX_GET(msdu_end, RX_MSDU_END_5, FIRST_MSDU);
230 }
231 
232 #define HAL_RX_BUFFER_ADDR_31_0_GET(buff_addr_info)		\
233 	(_HAL_MS((*_OFFSET_TO_WORD_PTR(buff_addr_info,		\
234 		BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_OFFSET)),	\
235 		BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_MASK,	\
236 		BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_LSB))
237 
238 #define HAL_RX_REO_ENT_BUFFER_ADDR_39_32_GET(reo_ent_desc)	\
239 	(HAL_RX_BUFFER_ADDR_39_32_GET(&				\
240 		(((struct reo_entrance_ring *)reo_ent_desc)	\
241 			->reo_level_mpdu_frame_info.msdu_link_desc_addr_info)))
242 
243 #define HAL_RX_REO_ENT_BUFFER_ADDR_31_0_GET(reo_ent_desc)	\
244 	(HAL_RX_BUFFER_ADDR_31_0_GET(&				\
245 		(((struct reo_entrance_ring *)reo_ent_desc)	\
246 			->reo_level_mpdu_frame_info.msdu_link_desc_addr_info)))
247 
248 #define HAL_RX_REO_ENT_BUF_COOKIE_GET(reo_ent_desc)		\
249 	(HAL_RX_BUF_COOKIE_GET(&					\
250 		(((struct reo_entrance_ring *)reo_ent_desc)	\
251 			->reo_level_mpdu_frame_info.msdu_link_desc_addr_info)))
252 
253 /**
254  * hal_rx_reo_ent_buf_paddr_get: Gets the physical address and
255  * cookie from the REO entrance ring element
256  *
257  * @ hal_rx_desc_cookie: Opaque cookie pointer used by HAL to get to
258  * the current descriptor
259  * @ buf_info: structure to return the buffer information
260  * @ msdu_cnt: pointer to msdu count in MPDU
261  * Return: void
262  */
263 static inline
264 void hal_rx_reo_ent_buf_paddr_get(void *rx_desc,
265 	struct hal_buf_info *buf_info,
266 	void **pp_buf_addr_info,
267 	uint32_t *msdu_cnt
268 )
269 {
270 	struct reo_entrance_ring *reo_ent_ring =
271 		(struct reo_entrance_ring *)rx_desc;
272 	struct buffer_addr_info *buf_addr_info;
273 	struct rx_mpdu_desc_info *rx_mpdu_desc_info_details;
274 	uint32_t loop_cnt;
275 
276 	rx_mpdu_desc_info_details =
277 	&reo_ent_ring->reo_level_mpdu_frame_info.rx_mpdu_desc_info_details;
278 
279 	*msdu_cnt = HAL_RX_GET(rx_mpdu_desc_info_details,
280 				RX_MPDU_DESC_INFO_0, MSDU_COUNT);
281 
282 	loop_cnt = HAL_RX_GET(reo_ent_ring, REO_ENTRANCE_RING_7, LOOPING_COUNT);
283 
284 	buf_addr_info =
285 	&reo_ent_ring->reo_level_mpdu_frame_info.msdu_link_desc_addr_info;
286 
287 	buf_info->paddr =
288 		(HAL_RX_BUFFER_ADDR_31_0_GET(buf_addr_info) |
289 		((uint64_t)
290 		(HAL_RX_BUFFER_ADDR_39_32_GET(buf_addr_info)) << 32));
291 
292 	buf_info->sw_cookie = HAL_RX_BUF_COOKIE_GET(buf_addr_info);
293 
294 	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
295 		"[%s][%d] ReoAddr=%pK, addrInfo=%pK, paddr=0x%llx, loopcnt=%d\n",
296 		__func__, __LINE__, reo_ent_ring, buf_addr_info,
297 	(unsigned long long)buf_info->paddr, loop_cnt);
298 
299 	*pp_buf_addr_info = (void *)buf_addr_info;
300 }
301 
302 static inline
303 void hal_rx_mon_next_link_desc_get(void *rx_msdu_link_desc,
304 	struct hal_buf_info *buf_info, void **pp_buf_addr_info)
305 {
306 	struct rx_msdu_link *msdu_link =
307 		(struct rx_msdu_link *)rx_msdu_link_desc;
308 	struct buffer_addr_info *buf_addr_info;
309 
310 	buf_addr_info = &msdu_link->next_msdu_link_desc_addr_info;
311 
312 	buf_info->paddr =
313 		(HAL_RX_BUFFER_ADDR_31_0_GET(buf_addr_info) |
314 		((uint64_t)
315 		(HAL_RX_BUFFER_ADDR_39_32_GET(buf_addr_info)) << 32));
316 
317 	buf_info->sw_cookie = HAL_RX_BUF_COOKIE_GET(buf_addr_info);
318 
319 	*pp_buf_addr_info = (void *)buf_addr_info;
320 }
321 
322 /**
323  * hal_rx_msdu_link_desc_set: Retrieves MSDU Link Descriptor to WBM
324  *
325  * @ soc		: HAL version of the SOC pointer
326  * @ src_srng_desc	: void pointer to the WBM Release Ring descriptor
327  * @ buf_addr_info	: void pointer to the buffer_addr_info
328  *
329  * Return: void
330  */
331 
332 static inline void hal_rx_mon_msdu_link_desc_set(struct hal_soc *soc,
333 			void *src_srng_desc, void *buf_addr_info)
334 {
335 	struct buffer_addr_info *wbm_srng_buffer_addr_info =
336 			(struct buffer_addr_info *)src_srng_desc;
337 	uint64_t paddr;
338 	struct buffer_addr_info *p_buffer_addr_info =
339 			(struct buffer_addr_info *)buf_addr_info;
340 
341 	paddr =
342 		(HAL_RX_BUFFER_ADDR_31_0_GET(buf_addr_info) |
343 		((uint64_t)
344 		(HAL_RX_BUFFER_ADDR_39_32_GET(buf_addr_info)) << 32));
345 
346 	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
347 		"[%s][%d] src_srng_desc=%pK, buf_addr=0x%llx, cookie=0x%llx\n",
348 		__func__, __LINE__, src_srng_desc, (unsigned long long)paddr,
349 		(unsigned long long)p_buffer_addr_info->sw_buffer_cookie);
350 
351 	/* Structure copy !!! */
352 	*wbm_srng_buffer_addr_info =
353 		*((struct buffer_addr_info *)buf_addr_info);
354 }
355 
356 static inline
357 uint32 hal_get_rx_msdu_link_desc_size(void)
358 {
359 	return sizeof(struct rx_msdu_link);
360 }
361 
362 enum {
363 	HAL_PKT_TYPE_OFDM = 0,
364 	HAL_PKT_TYPE_CCK,
365 	HAL_PKT_TYPE_HT,
366 	HAL_PKT_TYPE_VHT,
367 	HAL_PKT_TYPE_HE,
368 };
369 
370 enum {
371 	HAL_SGI_0_8_US,
372 	HAL_SGI_0_4_US,
373 	HAL_SGI_1_6_US,
374 	HAL_SGI_3_2_US,
375 };
376 
377 enum {
378 	HAL_FULL_RX_BW_20,
379 	HAL_FULL_RX_BW_40,
380 	HAL_FULL_RX_BW_80,
381 	HAL_FULL_RX_BW_160,
382 };
383 
384 enum {
385 	HAL_RX_TYPE_SU,
386 	HAL_RX_TYPE_MU_MIMO,
387 	HAL_RX_TYPE_MU_OFDMA,
388 	HAL_RX_TYPE_MU_OFDMA_MIMO,
389 };
390 
391 /**
392  * enum
393  * @HAL_RX_MON_PPDU_START: PPDU start TLV is decoded in HAL
394  * @HAL_RX_MON_PPDU_END: PPDU end TLV is decided in HAL
395  */
396 enum {
397 	HAL_RX_MON_PPDU_START = 0,
398 	HAL_RX_MON_PPDU_END,
399 };
400 
401 /**
402  * hal_rx_mon_hw_desc_get_mpdu_status: Retrieve MPDU status
403  *
404  * @ hw_desc_addr: Start address of Rx HW TLVs
405  * @ rs: Status for monitor mode
406  *
407  * Return: void
408  */
409 static inline
410 void hal_rx_mon_hw_desc_get_mpdu_status(void *hw_desc_addr,
411 		struct mon_rx_status *rs)
412 {
413 	struct rx_msdu_start *rx_msdu_start;
414 	struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr;
415 	uint32_t reg_value;
416 	static uint32_t sgi_hw_to_cdp[] = {
417 		CDP_SGI_0_8_US,
418 		CDP_SGI_0_4_US,
419 		CDP_SGI_1_6_US,
420 		CDP_SGI_3_2_US,
421 	};
422 
423 	rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start;
424 	HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs);
425 
426 	rs->ant_signal_db = HAL_RX_GET(rx_msdu_start,
427 					RX_MSDU_START_5, USER_RSSI);
428 	rs->is_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC);
429 
430 	reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI);
431 	rs->sgi = sgi_hw_to_cdp[reg_value];
432 #if !defined(QCA_WIFI_QCA6290_11AX)
433 	rs->nr_ant = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, NSS);
434 #endif
435 
436 	reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE);
437 	rs->beamformed = (reg_value == HAL_RX_RECEPTION_TYPE_MU_MIMO) ? 1 : 0;
438 	/* TODO: rs->beamformed should be set for SU beamforming also */
439 	hal_rx_dump_pkt_tlvs((uint8_t *)rx_desc, QDF_TRACE_LEVEL_DEBUG);
440 }
441 
442 struct hal_rx_ppdu_user_info {
443 
444 };
445 
446 struct hal_rx_ppdu_common_info {
447 	uint32_t ppdu_id;
448 	uint32_t last_ppdu_id;
449 	uint32_t ppdu_timestamp;
450 	uint32_t mpdu_cnt_fcs_ok;
451 	uint32_t mpdu_cnt_fcs_err;
452 };
453 
454 struct hal_rx_msdu_payload_info {
455 	uint8_t *first_msdu_payload;
456 	uint32_t payload_len;
457 };
458 
459 struct hal_rx_ppdu_info {
460 	struct hal_rx_ppdu_common_info com_info;
461 	struct hal_rx_ppdu_user_info user_info[HAL_MAX_UL_MU_USERS];
462 	struct mon_rx_status rx_status;
463 	struct hal_rx_msdu_payload_info msdu_info;
464 	/* status ring PPDU start and end state */
465 	uint32_t rx_state;
466 };
467 
468 static inline uint32_t
469 hal_get_rx_status_buf_size(void) {
470 	/* RX status buffer size is hard coded for now */
471 	return 2048;
472 }
473 
474 static inline uint8_t*
475 hal_rx_status_get_next_tlv(uint8_t *rx_tlv) {
476 	uint32_t tlv_len, tlv_tag;
477 
478 	tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv);
479 	tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv);
480 
481 	/* The actual length of PPDU_END is the combined length of many PHY
482 	 * TLVs that follow. Skip the TLV header and
483 	 * rx_rxpcu_classification_overview that follows the header to get to
484 	 * next TLV.
485 	 */
486 	if (tlv_tag == WIFIRX_PPDU_END_E)
487 		tlv_len = sizeof(struct rx_rxpcu_classification_overview);
488 
489 	return (uint8_t *)(((unsigned long)(rx_tlv + tlv_len +
490 			HAL_RX_TLV32_HDR_SIZE + 3)) & (~((unsigned long)3)));
491 }
492 
493 #ifdef QCA_WIFI_QCA6290_11AX
494 /**
495  * hal_rx_proc_phyrx_other_receive_info_tlv() - process other receive info TLV
496  * @rx_tlv_hdr: pointer to TLV header
497  * @ppdu_info: pointer to ppdu_info
498  *
499  * Return: None
500  */
501 static void hal_rx_proc_phyrx_other_receive_info_tlv(void *rx_tlv_hdr,
502 					     struct hal_rx_ppdu_info *ppdu_info)
503 {
504 	uint32_t tlv_tag, tlv_len;
505 	uint32_t temp_len, other_tlv_len, other_tlv_tag;
506 	void *rx_tlv = (uint8_t *)rx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE;
507 	void *other_tlv_hdr = NULL;
508 	void *other_tlv = NULL;
509 	uint32_t ru_details_channel_0;
510 
511 	tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv_hdr);
512 	tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv_hdr);
513 	temp_len = 0;
514 
515 	other_tlv_hdr = rx_tlv + HAL_RX_TLV32_HDR_SIZE;
516 
517 	other_tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(other_tlv_hdr);
518 	other_tlv_len = HAL_RX_GET_USER_TLV32_LEN(other_tlv_hdr);
519 	temp_len += other_tlv_len;
520 	other_tlv = other_tlv_hdr + HAL_RX_TLV32_HDR_SIZE;
521 
522 	switch (other_tlv_tag) {
523 	case WIFIPHYRX_OTHER_RECEIVE_INFO_RU_DETAILS_E:
524 		ru_details_channel_0 =
525 				HAL_RX_GET(other_tlv,
526 					  PHYRX_OTHER_RECEIVE_INFO_RU_DETAILS_0,
527 					  RU_DETAILS_CHANNEL_0);
528 
529 		qdf_mem_copy(ppdu_info->rx_status.he_RU,
530 			     &ru_details_channel_0,
531 			     sizeof(ppdu_info->rx_status.he_RU));
532 
533 		if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_20)
534 			ppdu_info->rx_status.he_sig_b_common_known |=
535 				QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0;
536 
537 		if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_40)
538 			ppdu_info->rx_status.he_sig_b_common_known |=
539 				QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU1;
540 
541 		if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_80)
542 			ppdu_info->rx_status.he_sig_b_common_known |=
543 				QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU2;
544 
545 		if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_160)
546 			ppdu_info->rx_status.he_sig_b_common_known |=
547 				QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU3;
548 			break;
549 	default:
550 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
551 			  "%s unhandled TLV type: %d, TLV len:%d",
552 			  __func__, other_tlv_tag, other_tlv_len);
553 		break;
554 	}
555 
556 }
557 #else
558 static inline void
559 hal_rx_proc_phyrx_other_receive_info_tlv(void *rx_tlv_hdr,
560 					 struct hal_rx_ppdu_info *ppdu_info)
561 {
562 }
563 #endif /* QCA_WIFI_QCA6290_11AX */
564 
565 /**
566  * hal_rx_status_get_tlv_info() - process receive info TLV
567  * @rx_tlv_hdr: pointer to TLV header
568  * @ppdu_info: pointer to ppdu_info
569  *
570  * Return: HAL_TLV_STATUS_PPDU_NOT_DONE or HAL_TLV_STATUS_PPDU_DONE from tlv
571  */
572 static inline uint32_t
573 hal_rx_status_get_tlv_info(void *rx_tlv_hdr, struct hal_rx_ppdu_info *ppdu_info)
574 {
575 	uint32_t tlv_tag, user_id, tlv_len, value;
576 	uint8_t group_id = 0;
577 	uint8_t he_dcm = 0;
578 	uint8_t he_stbc = 0;
579 	uint16_t he_gi = 0;
580 	uint16_t he_ltf = 0;
581 	void *rx_tlv;
582 	bool unhandled = false;
583 
584 
585 	tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv_hdr);
586 	user_id = HAL_RX_GET_USER_TLV32_USERID(rx_tlv_hdr);
587 	tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv_hdr);
588 
589 	rx_tlv = (uint8_t *)rx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE;
590 	switch (tlv_tag) {
591 
592 	case WIFIRX_PPDU_START_E:
593 		ppdu_info->com_info.ppdu_id =
594 			HAL_RX_GET(rx_tlv, RX_PPDU_START_0,
595 				PHY_PPDU_ID);
596 		/* channel number is set in PHY meta data */
597 		ppdu_info->rx_status.chan_num =
598 			HAL_RX_GET(rx_tlv, RX_PPDU_START_1,
599 				SW_PHY_META_DATA);
600 		ppdu_info->com_info.ppdu_timestamp =
601 			HAL_RX_GET(rx_tlv, RX_PPDU_START_2,
602 				PPDU_START_TIMESTAMP);
603 		ppdu_info->rx_state = HAL_RX_MON_PPDU_START;
604 		break;
605 
606 	case WIFIRX_PPDU_START_USER_INFO_E:
607 		break;
608 
609 	case WIFIRX_PPDU_END_E:
610 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
611 			"[%s][%d] ppdu_end_e len=%d",
612 				__func__, __LINE__, tlv_len);
613 		/* This is followed by sub-TLVs of PPDU_END */
614 		ppdu_info->rx_state = HAL_RX_MON_PPDU_END;
615 		break;
616 
617 	case WIFIRXPCU_PPDU_END_INFO_E:
618 		ppdu_info->rx_status.tsft =
619 			HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_1,
620 				WB_TIMESTAMP_UPPER_32);
621 		ppdu_info->rx_status.tsft = (ppdu_info->rx_status.tsft << 32) |
622 			HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_0,
623 				WB_TIMESTAMP_LOWER_32);
624 		ppdu_info->rx_status.duration =
625 			HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_8,
626 				RX_PPDU_DURATION);
627 		break;
628 
629 	case WIFIRX_PPDU_END_USER_STATS_E:
630 	{
631 		unsigned long tid = 0;
632 		uint16_t seq = 0;
633 
634 		ppdu_info->rx_status.ast_index =
635 				HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_4,
636 						AST_INDEX);
637 
638 		tid = HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_12,
639 				RECEIVED_QOS_DATA_TID_BITMAP);
640 		ppdu_info->rx_status.tid = qdf_find_first_bit(&tid, sizeof(tid)*8);
641 
642 		if (ppdu_info->rx_status.tid == (sizeof(tid) * 8))
643 			ppdu_info->rx_status.tid = HAL_TID_INVALID;
644 
645 		ppdu_info->rx_status.tcp_msdu_count =
646 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_9,
647 					TCP_MSDU_COUNT) +
648 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_10,
649 					TCP_ACK_MSDU_COUNT);
650 		ppdu_info->rx_status.udp_msdu_count =
651 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_9,
652 						UDP_MSDU_COUNT);
653 		ppdu_info->rx_status.other_msdu_count =
654 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_10,
655 					OTHER_MSDU_COUNT);
656 
657 		ppdu_info->rx_status.frame_control_info_valid =
658 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3,
659 					DATA_SEQUENCE_CONTROL_INFO_VALID);
660 
661 		seq = HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_5,
662 					FIRST_DATA_SEQ_CTRL);
663 		if (ppdu_info->rx_status.frame_control_info_valid)
664 			ppdu_info->rx_status.first_data_seq_ctrl = seq;
665 
666 		ppdu_info->rx_status.preamble_type =
667 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3,
668 						HT_CONTROL_FIELD_PKT_TYPE);
669 		switch (ppdu_info->rx_status.preamble_type) {
670 		case HAL_RX_PKT_TYPE_11N:
671 			ppdu_info->rx_status.ht_flags = 1;
672 			ppdu_info->rx_status.rtap_flags |= HT_SGI_PRESENT;
673 			break;
674 		case HAL_RX_PKT_TYPE_11AC:
675 			ppdu_info->rx_status.vht_flags = 1;
676 			break;
677 		case HAL_RX_PKT_TYPE_11AX:
678 			ppdu_info->rx_status.he_flags = 1;
679 			break;
680 		default:
681 			break;
682 		}
683 
684 		ppdu_info->com_info.mpdu_cnt_fcs_ok =
685 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3,
686 					MPDU_CNT_FCS_OK);
687 		ppdu_info->com_info.mpdu_cnt_fcs_err =
688 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_2,
689 					MPDU_CNT_FCS_ERR);
690 		if ((ppdu_info->com_info.mpdu_cnt_fcs_ok |
691 			ppdu_info->com_info.mpdu_cnt_fcs_err) > 1)
692 			ppdu_info->rx_status.rs_flags |= IEEE80211_AMPDU_FLAG;
693 		else
694 			ppdu_info->rx_status.rs_flags &=
695 				(~IEEE80211_AMPDU_FLAG);
696 		break;
697 	}
698 
699 	case WIFIRX_PPDU_END_USER_STATS_EXT_E:
700 		break;
701 
702 	case WIFIRX_PPDU_END_STATUS_DONE_E:
703 		return HAL_TLV_STATUS_PPDU_DONE;
704 
705 	case WIFIDUMMY_E:
706 		return HAL_TLV_STATUS_BUF_DONE;
707 
708 	case WIFIPHYRX_HT_SIG_E:
709 	{
710 		uint8_t *ht_sig_info = (uint8_t *)rx_tlv +
711 				HAL_RX_OFFSET(PHYRX_HT_SIG_0,
712 				HT_SIG_INFO_PHYRX_HT_SIG_INFO_DETAILS);
713 		value = HAL_RX_GET(ht_sig_info, HT_SIG_INFO_1,
714 				FEC_CODING);
715 		ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ?
716 			1 : 0;
717 		ppdu_info->rx_status.mcs = HAL_RX_GET(ht_sig_info,
718 				HT_SIG_INFO_0, MCS);
719 		ppdu_info->rx_status.bw = HAL_RX_GET(ht_sig_info,
720 				HT_SIG_INFO_0, CBW);
721 		ppdu_info->rx_status.sgi = HAL_RX_GET(ht_sig_info,
722 				HT_SIG_INFO_1, SHORT_GI);
723 		break;
724 	}
725 
726 	case WIFIPHYRX_L_SIG_B_E:
727 	{
728 		uint8_t *l_sig_b_info = (uint8_t *)rx_tlv +
729 				HAL_RX_OFFSET(PHYRX_L_SIG_B_0,
730 				L_SIG_B_INFO_PHYRX_L_SIG_B_INFO_DETAILS);
731 
732 		value = HAL_RX_GET(l_sig_b_info, L_SIG_B_INFO_0, RATE);
733 		switch (value) {
734 		case 1:
735 			ppdu_info->rx_status.rate = HAL_11B_RATE_3MCS;
736 			break;
737 		case 2:
738 			ppdu_info->rx_status.rate = HAL_11B_RATE_2MCS;
739 			break;
740 		case 3:
741 			ppdu_info->rx_status.rate = HAL_11B_RATE_1MCS;
742 			break;
743 		case 4:
744 			ppdu_info->rx_status.rate = HAL_11B_RATE_0MCS;
745 			break;
746 		case 5:
747 			ppdu_info->rx_status.rate = HAL_11B_RATE_6MCS;
748 			break;
749 		case 6:
750 			ppdu_info->rx_status.rate = HAL_11B_RATE_5MCS;
751 			break;
752 		case 7:
753 			ppdu_info->rx_status.rate = HAL_11B_RATE_4MCS;
754 			break;
755 		default:
756 			break;
757 		}
758 		ppdu_info->rx_status.cck_flag = 1;
759 	break;
760 	}
761 
762 	case WIFIPHYRX_L_SIG_A_E:
763 	{
764 		uint8_t *l_sig_a_info = (uint8_t *)rx_tlv +
765 				HAL_RX_OFFSET(PHYRX_L_SIG_A_0,
766 				L_SIG_A_INFO_PHYRX_L_SIG_A_INFO_DETAILS);
767 
768 		value = HAL_RX_GET(l_sig_a_info, L_SIG_A_INFO_0, RATE);
769 		switch (value) {
770 		case 8:
771 			ppdu_info->rx_status.rate = HAL_11A_RATE_0MCS;
772 			break;
773 		case 9:
774 			ppdu_info->rx_status.rate = HAL_11A_RATE_1MCS;
775 			break;
776 		case 10:
777 			ppdu_info->rx_status.rate = HAL_11A_RATE_2MCS;
778 			break;
779 		case 11:
780 			ppdu_info->rx_status.rate = HAL_11A_RATE_3MCS;
781 			break;
782 		case 12:
783 			ppdu_info->rx_status.rate = HAL_11A_RATE_4MCS;
784 			break;
785 		case 13:
786 			ppdu_info->rx_status.rate = HAL_11A_RATE_5MCS;
787 			break;
788 		case 14:
789 			ppdu_info->rx_status.rate = HAL_11A_RATE_6MCS;
790 			break;
791 		case 15:
792 			ppdu_info->rx_status.rate = HAL_11A_RATE_7MCS;
793 			break;
794 		default:
795 			break;
796 		}
797 		ppdu_info->rx_status.ofdm_flag = 1;
798 	break;
799 	}
800 
801 	case WIFIPHYRX_VHT_SIG_A_E:
802 	{
803 		uint8_t *vht_sig_a_info = (uint8_t *)rx_tlv +
804 				HAL_RX_OFFSET(PHYRX_VHT_SIG_A_0,
805 				VHT_SIG_A_INFO_PHYRX_VHT_SIG_A_INFO_DETAILS);
806 
807 		value = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_1,
808 				SU_MU_CODING);
809 		ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ?
810 			1 : 0;
811 		group_id = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_0, GROUP_ID);
812 		ppdu_info->rx_status.vht_flag_values5 = group_id;
813 		ppdu_info->rx_status.mcs = HAL_RX_GET(vht_sig_a_info,
814 				VHT_SIG_A_INFO_1, MCS);
815 		ppdu_info->rx_status.sgi = HAL_RX_GET(vht_sig_a_info,
816 				VHT_SIG_A_INFO_1, GI_SETTING);
817 #if !defined(QCA_WIFI_QCA6290_11AX)
818 		value =  HAL_RX_GET(vht_sig_a_info,
819 				VHT_SIG_A_INFO_0, N_STS);
820 		ppdu_info->rx_status.nss = ((value & VHT_SIG_SU_NSS_MASK) + 1);
821 #else
822 		ppdu_info->rx_status.nss = 0;
823 #endif
824 		ppdu_info->rx_status.vht_flag_values3[0] =
825 				(((ppdu_info->rx_status.mcs) << 4)
826 				| ppdu_info->rx_status.nss);
827 		ppdu_info->rx_status.bw = HAL_RX_GET(vht_sig_a_info,
828 				VHT_SIG_A_INFO_0, BANDWIDTH);
829 		ppdu_info->rx_status.vht_flag_values2 =
830 			ppdu_info->rx_status.bw;
831 		ppdu_info->rx_status.vht_flag_values4 =
832 			HAL_RX_GET(vht_sig_a_info,
833 				  VHT_SIG_A_INFO_1, SU_MU_CODING);
834 
835 		ppdu_info->rx_status.beamformed = HAL_RX_GET(vht_sig_a_info,
836 				VHT_SIG_A_INFO_1, BEAMFORMED);
837 
838 		break;
839 	}
840 	case WIFIPHYRX_HE_SIG_A_SU_E:
841 	{
842 		uint8_t *he_sig_a_su_info = (uint8_t *)rx_tlv +
843 			HAL_RX_OFFSET(PHYRX_HE_SIG_A_SU_0,
844 			HE_SIG_A_SU_INFO_PHYRX_HE_SIG_A_SU_INFO_DETAILS);
845 		ppdu_info->rx_status.he_flags = 1;
846 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0,
847 			FORMAT_INDICATION);
848 		if (value == 0) {
849 			ppdu_info->rx_status.he_data1 =
850 				QDF_MON_STATUS_HE_TRIG_FORMAT_TYPE;
851 		} else {
852 			 ppdu_info->rx_status.he_data1 =
853 				 QDF_MON_STATUS_HE_SU_FORMAT_TYPE;
854 		}
855 
856 		/* data1 */
857 		ppdu_info->rx_status.he_data1 |=
858 			QDF_MON_STATUS_HE_BSS_COLOR_KNOWN |
859 			QDF_MON_STATUS_HE_BEAM_CHANGE_KNOWN |
860 			QDF_MON_STATUS_HE_DL_UL_KNOWN |
861 			QDF_MON_STATUS_HE_MCS_KNOWN |
862 			QDF_MON_STATUS_HE_DCM_KNOWN |
863 			QDF_MON_STATUS_HE_CODING_KNOWN |
864 			QDF_MON_STATUS_HE_LDPC_EXTRA_SYMBOL_KNOWN |
865 			QDF_MON_STATUS_HE_STBC_KNOWN |
866 			QDF_MON_STATUS_HE_DATA_BW_RU_KNOWN |
867 			QDF_MON_STATUS_HE_DOPPLER_KNOWN;
868 
869 		/* data2 */
870 		ppdu_info->rx_status.he_data2 =
871 			QDF_MON_STATUS_HE_GI_KNOWN;
872 		ppdu_info->rx_status.he_data2 |=
873 			QDF_MON_STATUS_TXBF_KNOWN |
874 			QDF_MON_STATUS_PE_DISAMBIGUITY_KNOWN |
875 			QDF_MON_STATUS_TXOP_KNOWN |
876 			QDF_MON_STATUS_LTF_SYMBOLS_KNOWN |
877 			QDF_MON_STATUS_PRE_FEC_PADDING_KNOWN |
878 			QDF_MON_STATUS_MIDABLE_PERIODICITY_KNOWN;
879 
880 		/* data3 */
881 		value = HAL_RX_GET(he_sig_a_su_info,
882 				HE_SIG_A_SU_INFO_0, BSS_COLOR_ID);
883 		ppdu_info->rx_status.he_data3 = value;
884 		value = HAL_RX_GET(he_sig_a_su_info,
885 				HE_SIG_A_SU_INFO_0, BEAM_CHANGE);
886 		value = value << QDF_MON_STATUS_BEAM_CHANGE_SHIFT;
887 		ppdu_info->rx_status.he_data3 |= value;
888 		value = HAL_RX_GET(he_sig_a_su_info,
889 				HE_SIG_A_SU_INFO_0, DL_UL_FLAG);
890 		value = value << QDF_MON_STATUS_DL_UL_SHIFT;
891 		ppdu_info->rx_status.he_data3 |= value;
892 
893 		value = HAL_RX_GET(he_sig_a_su_info,
894 				HE_SIG_A_SU_INFO_0, TRANSMIT_MCS);
895 		ppdu_info->rx_status.mcs = value;
896 		value = value << QDF_MON_STATUS_TRANSMIT_MCS_SHIFT;
897 		ppdu_info->rx_status.he_data3 |= value;
898 
899 		value = HAL_RX_GET(he_sig_a_su_info,
900 				HE_SIG_A_SU_INFO_0, DCM);
901 		he_dcm = value;
902 		value = value << QDF_MON_STATUS_DCM_SHIFT;
903 		ppdu_info->rx_status.he_data3 |= value;
904 		value = HAL_RX_GET(he_sig_a_su_info,
905 				HE_SIG_A_SU_INFO_1, CODING);
906 		value = value << QDF_MON_STATUS_CODING_SHIFT;
907 		ppdu_info->rx_status.he_data3 |= value;
908 		value = HAL_RX_GET(he_sig_a_su_info,
909 				HE_SIG_A_SU_INFO_1,
910 				LDPC_EXTRA_SYMBOL);
911 		value = value << QDF_MON_STATUS_LDPC_EXTRA_SYMBOL_SHIFT;
912 		ppdu_info->rx_status.he_data3 |= value;
913 		value = HAL_RX_GET(he_sig_a_su_info,
914 				HE_SIG_A_SU_INFO_1, STBC);
915 		he_stbc = value;
916 		value = value << QDF_MON_STATUS_STBC_SHIFT;
917 		ppdu_info->rx_status.he_data3 |= value;
918 
919 		/* data4 */
920 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0,
921 							SPATIAL_REUSE);
922 		ppdu_info->rx_status.he_data4 = value;
923 
924 		/* data5 */
925 		value = HAL_RX_GET(he_sig_a_su_info,
926 				HE_SIG_A_SU_INFO_0, TRANSMIT_BW);
927 		ppdu_info->rx_status.he_data5 = value;
928 		ppdu_info->rx_status.bw = value;
929 		value = HAL_RX_GET(he_sig_a_su_info,
930 				HE_SIG_A_SU_INFO_0, CP_LTF_SIZE);
931 		switch (value) {
932 		case 0:
933 				he_gi = HE_GI_0_8;
934 				he_ltf = HE_LTF_1_X;
935 				break;
936 		case 1:
937 				he_gi = HE_GI_0_8;
938 				he_ltf = HE_LTF_2_X;
939 				break;
940 		case 2:
941 				he_gi = HE_GI_1_6;
942 				he_ltf = HE_LTF_2_X;
943 				break;
944 		case 3:
945 				if (he_dcm && he_stbc) {
946 					he_gi = HE_GI_0_8;
947 					he_ltf = HE_LTF_4_X;
948 				} else {
949 					he_gi = HE_GI_3_2;
950 					he_ltf = HE_LTF_4_X;
951 				}
952 				break;
953 		}
954 		ppdu_info->rx_status.sgi = he_gi;
955 		value = he_gi << QDF_MON_STATUS_GI_SHIFT;
956 		ppdu_info->rx_status.he_data5 |= value;
957 		value = he_ltf << QDF_MON_STATUS_HE_LTF_SHIFT;
958 		ppdu_info->rx_status.he_data5 |= value;
959 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1,
960 							PACKET_EXTENSION_A_FACTOR);
961 		value = value << QDF_MON_STATUS_PRE_FEC_PAD_SHIFT;
962 		ppdu_info->rx_status.he_data5 |= value;
963 
964 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1, TXBF);
965 		value = value << QDF_MON_STATUS_TXBF_SHIFT;
966 		ppdu_info->rx_status.he_data5 |= value;
967 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1,
968 							PACKET_EXTENSION_PE_DISAMBIGUITY);
969 		value = value << QDF_MON_STATUS_PE_DISAMBIGUITY_SHIFT;
970 		ppdu_info->rx_status.he_data5 |= value;
971 
972 		/* data6 */
973 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0, NSTS);
974 		value++;
975 		ppdu_info->rx_status.nss = value;
976 		ppdu_info->rx_status.he_data6 = value;
977 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1,
978 							DOPPLER_INDICATION);
979 		value = value << QDF_MON_STATUS_DOPPLER_SHIFT;
980 		ppdu_info->rx_status.he_data6 |= value;
981 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1,
982 							TXOP_DURATION);
983 		value = value << QDF_MON_STATUS_TXOP_SHIFT;
984 		ppdu_info->rx_status.he_data6 |= value;
985 
986 		ppdu_info->rx_status.beamformed = HAL_RX_GET(he_sig_a_su_info,
987 					HE_SIG_A_SU_INFO_1, TXBF);
988 		break;
989 	}
990 	case WIFIPHYRX_HE_SIG_A_MU_DL_E:
991 	{
992 		uint8_t *he_sig_a_mu_dl_info = (uint8_t *)rx_tlv +
993 			HAL_RX_OFFSET(PHYRX_HE_SIG_A_MU_DL_0,
994 			HE_SIG_A_MU_DL_INFO_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS);
995 
996 		ppdu_info->rx_status.he_mu_flags = 1;
997 
998 		/* HE Flags */
999 		/*data1*/
1000 		ppdu_info->rx_status.he_data1 =
1001 					QDF_MON_STATUS_HE_MU_FORMAT_TYPE;
1002 		ppdu_info->rx_status.he_data1 |=
1003 			QDF_MON_STATUS_HE_BSS_COLOR_KNOWN |
1004 			QDF_MON_STATUS_HE_DL_UL_KNOWN |
1005 			QDF_MON_STATUS_HE_LDPC_EXTRA_SYMBOL_KNOWN |
1006 			QDF_MON_STATUS_HE_STBC_KNOWN |
1007 			QDF_MON_STATUS_HE_DATA_BW_RU_KNOWN |
1008 			QDF_MON_STATUS_HE_DOPPLER_KNOWN;
1009 
1010 		/* data2 */
1011 		ppdu_info->rx_status.he_data2 =
1012 			QDF_MON_STATUS_HE_GI_KNOWN;
1013 		ppdu_info->rx_status.he_data2 |=
1014 			QDF_MON_STATUS_LTF_SYMBOLS_KNOWN |
1015 			QDF_MON_STATUS_PRE_FEC_PADDING_KNOWN |
1016 			QDF_MON_STATUS_PE_DISAMBIGUITY_KNOWN |
1017 			QDF_MON_STATUS_TXOP_KNOWN |
1018 			QDF_MON_STATUS_MIDABLE_PERIODICITY_KNOWN;
1019 
1020 		/*data3*/
1021 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1022 				HE_SIG_A_MU_DL_INFO_0, BSS_COLOR_ID);
1023 		ppdu_info->rx_status.he_data3 = value;
1024 
1025 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1026 				HE_SIG_A_MU_DL_INFO_0, DL_UL_FLAG);
1027 		value = value << QDF_MON_STATUS_DL_UL_SHIFT;
1028 		ppdu_info->rx_status.he_data3 |= value;
1029 
1030 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1031 				HE_SIG_A_MU_DL_INFO_1,
1032 				LDPC_EXTRA_SYMBOL);
1033 		value = value << QDF_MON_STATUS_LDPC_EXTRA_SYMBOL_SHIFT;
1034 		ppdu_info->rx_status.he_data3 |= value;
1035 
1036 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1037 				HE_SIG_A_MU_DL_INFO_1, STBC);
1038 		he_stbc = value;
1039 		value = value << QDF_MON_STATUS_STBC_SHIFT;
1040 		ppdu_info->rx_status.he_data3 |= value;
1041 
1042 		/*data4*/
1043 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_0,
1044 							SPATIAL_REUSE);
1045 		ppdu_info->rx_status.he_data4 = value;
1046 
1047 		/*data5*/
1048 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1049 				HE_SIG_A_MU_DL_INFO_0, TRANSMIT_BW);
1050 		ppdu_info->rx_status.he_data5 = value;
1051 		ppdu_info->rx_status.bw = value;
1052 
1053 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1054 				HE_SIG_A_MU_DL_INFO_0, CP_LTF_SIZE);
1055 		switch (value) {
1056 		case 0:
1057 			he_gi = HE_GI_0_8;
1058 			he_ltf = HE_LTF_4_X;
1059 			break;
1060 		case 1:
1061 			he_gi = HE_GI_0_8;
1062 			he_ltf = HE_LTF_2_X;
1063 			break;
1064 		case 2:
1065 			he_gi = HE_GI_1_6;
1066 			he_ltf = HE_LTF_2_X;
1067 			break;
1068 		case 3:
1069 			he_gi = HE_GI_3_2;
1070 			he_ltf = HE_LTF_4_X;
1071 			break;
1072 		}
1073 		ppdu_info->rx_status.sgi = he_gi;
1074 		value = he_gi << QDF_MON_STATUS_GI_SHIFT;
1075 		ppdu_info->rx_status.he_data5 |= value;
1076 
1077 		value = he_ltf << QDF_MON_STATUS_HE_LTF_SHIFT;
1078 		ppdu_info->rx_status.he_data5 |= value;
1079 
1080 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_1,
1081 				   PACKET_EXTENSION_A_FACTOR);
1082 		value = value << QDF_MON_STATUS_PRE_FEC_PAD_SHIFT;
1083 		ppdu_info->rx_status.he_data5 |= value;
1084 
1085 
1086 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_1,
1087 				   PACKET_EXTENSION_PE_DISAMBIGUITY);
1088 		value = value << QDF_MON_STATUS_PE_DISAMBIGUITY_SHIFT;
1089 		ppdu_info->rx_status.he_data5 |= value;
1090 
1091 		/*data6*/
1092 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_0,
1093 							DOPPLER_INDICATION);
1094 		value = value << QDF_MON_STATUS_DOPPLER_SHIFT;
1095 		ppdu_info->rx_status.he_data6 |= value;
1096 
1097 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_1,
1098 							TXOP_DURATION);
1099 		value = value << QDF_MON_STATUS_TXOP_SHIFT;
1100 		ppdu_info->rx_status.he_data6 |= value;
1101 
1102 		/* HE-MU Flags */
1103 		/* HE-MU-flags1 */
1104 		ppdu_info->rx_status.he_flags1 =
1105 			QDF_MON_STATUS_SIG_B_MCS_KNOWN |
1106 			QDF_MON_STATUS_SIG_B_DCM_KNOWN |
1107 			QDF_MON_STATUS_SIG_B_COMPRESSION_FLAG_1_KNOWN |
1108 			QDF_MON_STATUS_SIG_B_SYM_NUM_KNOWN |
1109 			QDF_MON_STATUS_RU_0_KNOWN;
1110 
1111 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1112 				HE_SIG_A_MU_DL_INFO_0, MCS_OF_SIG_B);
1113 		ppdu_info->rx_status.he_flags1 |= value;
1114 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1115 				HE_SIG_A_MU_DL_INFO_0, DCM_OF_SIG_B);
1116 		value = value << QDF_MON_STATUS_DCM_FLAG_1_SHIFT;
1117 		ppdu_info->rx_status.he_flags1 |= value;
1118 
1119 		/* HE-MU-flags2 */
1120 		ppdu_info->rx_status.he_flags2 =
1121 			QDF_MON_STATUS_BW_KNOWN;
1122 
1123 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1124 				HE_SIG_A_MU_DL_INFO_0, TRANSMIT_BW);
1125 		ppdu_info->rx_status.he_flags2 |= value;
1126 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1127 				HE_SIG_A_MU_DL_INFO_0, COMP_MODE_SIG_B);
1128 		value = value << QDF_MON_STATUS_SIG_B_COMPRESSION_FLAG_2_SHIFT;
1129 		ppdu_info->rx_status.he_flags2 |= value;
1130 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1131 				HE_SIG_A_MU_DL_INFO_0, NUM_SIG_B_SYMBOLS);
1132 		value = value - 1;
1133 		value = value << QDF_MON_STATUS_NUM_SIG_B_SYMBOLS_SHIFT;
1134 		ppdu_info->rx_status.he_flags2 |= value;
1135 		break;
1136 	}
1137 	case WIFIPHYRX_HE_SIG_B1_MU_E:
1138 	{
1139 
1140 		uint8_t *he_sig_b1_mu_info = (uint8_t *)rx_tlv +
1141 			HAL_RX_OFFSET(PHYRX_HE_SIG_B1_MU_0,
1142 			HE_SIG_B1_MU_INFO_PHYRX_HE_SIG_B1_MU_INFO_DETAILS);
1143 
1144 		ppdu_info->rx_status.he_sig_b_common_known |=
1145 			QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0;
1146 		/* TODO: Check on the availability of other fields in
1147 		 * sig_b_common
1148 		 */
1149 
1150 		value = HAL_RX_GET(he_sig_b1_mu_info,
1151 				HE_SIG_B1_MU_INFO_0, RU_ALLOCATION);
1152 		ppdu_info->rx_status.he_RU[0] = value;
1153 		break;
1154 	}
1155 	case WIFIPHYRX_HE_SIG_B2_MU_E:
1156 	{
1157 		uint8_t *he_sig_b2_mu_info = (uint8_t *)rx_tlv +
1158 			HAL_RX_OFFSET(PHYRX_HE_SIG_B2_MU_0,
1159 			HE_SIG_B2_MU_INFO_PHYRX_HE_SIG_B2_MU_INFO_DETAILS);
1160 		/*
1161 		 * Not all "HE" fields can be updated from
1162 		 * WIFIPHYRX_HE_SIG_A_MU_DL_E TLV. Use WIFIPHYRX_HE_SIG_B2_MU_E
1163 		 * to populate rest of the "HE" fields for MU scenarios.
1164 		 */
1165 
1166 		/* HE-data1 */
1167 		ppdu_info->rx_status.he_data1 |=
1168 			QDF_MON_STATUS_HE_MCS_KNOWN |
1169 			QDF_MON_STATUS_HE_CODING_KNOWN;
1170 
1171 		/* HE-data2 */
1172 
1173 		/* HE-data3 */
1174 		value = HAL_RX_GET(he_sig_b2_mu_info,
1175 				HE_SIG_B2_MU_INFO_0, STA_MCS);
1176 		ppdu_info->rx_status.mcs = value;
1177 		value = value << QDF_MON_STATUS_TRANSMIT_MCS_SHIFT;
1178 		ppdu_info->rx_status.he_data3 |= value;
1179 
1180 
1181 		value = HAL_RX_GET(he_sig_b2_mu_info,
1182 				HE_SIG_B2_MU_INFO_0, STA_CODING);
1183 		value = value << QDF_MON_STATUS_CODING_SHIFT;
1184 		ppdu_info->rx_status.he_data3 |= value;
1185 
1186 		/* HE-data4 */
1187 		value = HAL_RX_GET(he_sig_b2_mu_info,
1188 				HE_SIG_B2_MU_INFO_0, STA_ID);
1189 		value = value << QDF_MON_STATUS_STA_ID_SHIFT;
1190 		ppdu_info->rx_status.he_data4 |= value;
1191 
1192 		/* HE-data5 */
1193 
1194 		/* HE-data6 */
1195 		value = HAL_RX_GET(he_sig_b2_mu_info,
1196 				   HE_SIG_B2_MU_INFO_0, NSTS);
1197 		/* value n indicates n+1 spatial streams */
1198 		value++;
1199 		ppdu_info->rx_status.nss = value;
1200 		ppdu_info->rx_status.he_data6 |= value;
1201 
1202 		break;
1203 
1204 	}
1205 	case WIFIPHYRX_HE_SIG_B2_OFDMA_E:
1206 	{
1207 		uint8_t *he_sig_b2_ofdma_info =
1208 		(uint8_t *)rx_tlv +
1209 		HAL_RX_OFFSET(PHYRX_HE_SIG_B2_OFDMA_0,
1210 		HE_SIG_B2_OFDMA_INFO_PHYRX_HE_SIG_B2_OFDMA_INFO_DETAILS);
1211 
1212 		/*
1213 		 * Not all "HE" fields can be updated from
1214 		 * WIFIPHYRX_HE_SIG_A_MU_DL_E TLV. Use WIFIPHYRX_HE_SIG_B2_MU_E
1215 		 * to populate rest of "HE" fields for MU OFDMA scenarios.
1216 		 */
1217 
1218 		/* HE-data1 */
1219 		ppdu_info->rx_status.he_data1 |=
1220 			QDF_MON_STATUS_HE_MCS_KNOWN |
1221 			QDF_MON_STATUS_HE_DCM_KNOWN |
1222 			QDF_MON_STATUS_HE_CODING_KNOWN;
1223 
1224 		/* HE-data2 */
1225 		ppdu_info->rx_status.he_data2 |=
1226 					QDF_MON_STATUS_TXBF_KNOWN;
1227 
1228 		/* HE-data3 */
1229 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
1230 				HE_SIG_B2_OFDMA_INFO_0, STA_MCS);
1231 		ppdu_info->rx_status.mcs = value;
1232 		value = value << QDF_MON_STATUS_TRANSMIT_MCS_SHIFT;
1233 		ppdu_info->rx_status.he_data3 |= value;
1234 
1235 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
1236 				HE_SIG_B2_OFDMA_INFO_0, STA_DCM);
1237 		he_dcm = value;
1238 		value = value << QDF_MON_STATUS_DCM_SHIFT;
1239 		ppdu_info->rx_status.he_data3 |= value;
1240 
1241 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
1242 				HE_SIG_B2_OFDMA_INFO_0, STA_CODING);
1243 		value = value << QDF_MON_STATUS_CODING_SHIFT;
1244 		ppdu_info->rx_status.he_data3 |= value;
1245 
1246 		/* HE-data4 */
1247 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
1248 				HE_SIG_B2_OFDMA_INFO_0, STA_ID);
1249 		value = value << QDF_MON_STATUS_STA_ID_SHIFT;
1250 		ppdu_info->rx_status.he_data4 |= value;
1251 
1252 		/* HE-data5 */
1253 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
1254 				   HE_SIG_B2_OFDMA_INFO_0, TXBF);
1255 		value = value << QDF_MON_STATUS_TXBF_SHIFT;
1256 		ppdu_info->rx_status.he_data5 |= value;
1257 
1258 		/* HE-data6 */
1259 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
1260 				   HE_SIG_B2_OFDMA_INFO_0, NSTS);
1261 		/* value n indicates n+1 spatial streams */
1262 		value++;
1263 		ppdu_info->rx_status.nss = value;
1264 		ppdu_info->rx_status.he_data6 |= value;
1265 
1266 		break;
1267 	}
1268 	case WIFIPHYRX_RSSI_LEGACY_E:
1269 	{
1270 		uint8_t *rssi_info_tlv = (uint8_t *)rx_tlv +
1271 			HAL_RX_OFFSET(PHYRX_RSSI_LEGACY_3,
1272 			RECEIVE_RSSI_INFO_PRE_RSSI_INFO_DETAILS);
1273 
1274 		ppdu_info->rx_status.rssi_comb = HAL_RX_GET(rx_tlv,
1275 			PHYRX_RSSI_LEGACY_35, RSSI_COMB);
1276 		ppdu_info->rx_status.bw = HAL_RX_GET(rx_tlv,
1277 #if !defined(QCA_WIFI_QCA6290_11AX)
1278 			PHYRX_RSSI_LEGACY_35, RECEIVE_BANDWIDTH);
1279 #else
1280 			PHYRX_RSSI_LEGACY_0, RECEIVE_BANDWIDTH);
1281 #endif
1282 		ppdu_info->rx_status.he_re = 0;
1283 
1284 		ppdu_info->rx_status.reception_type = HAL_RX_GET(rx_tlv,
1285 				PHYRX_RSSI_LEGACY_0, RECEPTION_TYPE);
1286 
1287 		value = HAL_RX_GET(rssi_info_tlv,
1288 			RECEIVE_RSSI_INFO_0, RSSI_PRI20_CHAIN0);
1289 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1290 			"RSSI_PRI20_CHAIN0: %d\n", value);
1291 
1292 		value = HAL_RX_GET(rssi_info_tlv,
1293 			RECEIVE_RSSI_INFO_0, RSSI_EXT20_CHAIN0);
1294 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1295 			"RSSI_EXT20_CHAIN0: %d\n", value);
1296 
1297 		value = HAL_RX_GET(rssi_info_tlv,
1298 			RECEIVE_RSSI_INFO_0, RSSI_EXT40_LOW20_CHAIN0);
1299 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1300 			"RSSI_EXT40_LOW20_CHAIN0: %d\n", value);
1301 
1302 		value = HAL_RX_GET(rssi_info_tlv,
1303 			RECEIVE_RSSI_INFO_0, RSSI_EXT40_HIGH20_CHAIN0);
1304 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1305 			"RSSI_EXT40_HIGH20_CHAIN0: %d\n", value);
1306 
1307 		value = HAL_RX_GET(rssi_info_tlv,
1308 			RECEIVE_RSSI_INFO_1, RSSI_EXT80_LOW20_CHAIN0);
1309 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1310 			"RSSI_EXT80_LOW20_CHAIN0: %d\n", value);
1311 
1312 		value = HAL_RX_GET(rssi_info_tlv,
1313 			RECEIVE_RSSI_INFO_1, RSSI_EXT80_LOW_HIGH20_CHAIN0);
1314 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1315 			"RSSI_EXT80_LOW_HIGH20_CHAIN0: %d\n", value);
1316 
1317 		value = HAL_RX_GET(rssi_info_tlv,
1318 			RECEIVE_RSSI_INFO_1, RSSI_EXT80_HIGH_LOW20_CHAIN0);
1319 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1320 			"RSSI_EXT80_HIGH_LOW20_CHAIN0: %d\n", value);
1321 
1322 		value = HAL_RX_GET(rssi_info_tlv,
1323 			RECEIVE_RSSI_INFO_1, RSSI_EXT80_HIGH20_CHAIN0);
1324 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1325 			"RSSI_EXT80_HIGH20_CHAIN0: %d\n", value);
1326 		break;
1327 	}
1328 	case WIFIPHYRX_OTHER_RECEIVE_INFO_E:
1329 		hal_rx_proc_phyrx_other_receive_info_tlv(rx_tlv_hdr, ppdu_info);
1330 		break;
1331 	case WIFIRX_HEADER_E:
1332 		ppdu_info->msdu_info.first_msdu_payload = rx_tlv;
1333 		ppdu_info->msdu_info.payload_len = tlv_len;
1334 		break;
1335 	case WIFIRX_MPDU_START_E:
1336 	{
1337 		uint8_t *rx_mpdu_start =
1338 			(uint8_t *)rx_tlv + HAL_RX_OFFSET(RX_MPDU_START_0,
1339 					RX_MPDU_INFO_RX_MPDU_INFO_DETAILS);
1340 		uint32_t ppdu_id = HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0,
1341 					      PHY_PPDU_ID);
1342 
1343 		if (ppdu_info->rx_status.prev_ppdu_id != ppdu_id) {
1344 			ppdu_info->rx_status.prev_ppdu_id = ppdu_id;
1345 			ppdu_info->rx_status.ppdu_len =
1346 				HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_13,
1347 					   MPDU_LENGTH);
1348 		} else {
1349 			ppdu_info->rx_status.ppdu_len +=
1350 				HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_13,
1351 				MPDU_LENGTH);
1352 		}
1353 		break;
1354 	}
1355 	case 0:
1356 		return HAL_TLV_STATUS_PPDU_DONE;
1357 
1358 	default:
1359 		unhandled = true;
1360 		break;
1361 	}
1362 
1363 	if (!unhandled)
1364 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1365 			  "%s TLV type: %d, TLV len:%d %s",
1366 			  __func__, tlv_tag, tlv_len,
1367 			  unhandled == true ? "unhandled" : "");
1368 
1369 	qdf_trace_hex_dump(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, rx_tlv, tlv_len);
1370 
1371 	return HAL_TLV_STATUS_PPDU_NOT_DONE;
1372 }
1373 
1374 static inline
1375 uint32_t hal_get_rx_status_done_tlv_size(void *hal_soc)
1376 {
1377 	return HAL_RX_TLV32_HDR_SIZE;
1378 }
1379 
1380 static inline QDF_STATUS
1381 hal_get_rx_status_done(uint8_t *rx_tlv)
1382 {
1383 	uint32_t tlv_tag;
1384 
1385 	tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv);
1386 
1387 	if (tlv_tag == WIFIRX_STATUS_BUFFER_DONE_E)
1388 		return QDF_STATUS_SUCCESS;
1389 	else
1390 		return QDF_STATUS_E_EMPTY;
1391 }
1392 
1393 static inline QDF_STATUS
1394 hal_clear_rx_status_done(uint8_t *rx_tlv)
1395 {
1396 	*(uint32_t *)rx_tlv = 0;
1397 	return QDF_STATUS_SUCCESS;
1398 }
1399 
1400 #endif
1401