xref: /wlan-dirver/qca-wifi-host-cmn/hal/wifi3.0/hal_api_mon.h (revision 1c6bb03362248b5f27a0b2ed30e5c0af99dfd2b9)
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 }
440 
441 struct hal_rx_ppdu_user_info {
442 
443 };
444 
445 struct hal_rx_ppdu_common_info {
446 	uint32_t ppdu_id;
447 	uint32_t last_ppdu_id;
448 	uint32_t ppdu_timestamp;
449 	uint32_t mpdu_cnt_fcs_ok;
450 	uint32_t mpdu_cnt_fcs_err;
451 };
452 
453 struct hal_rx_msdu_payload_info {
454 	uint8_t *first_msdu_payload;
455 	uint32_t payload_len;
456 };
457 
458 struct hal_rx_ppdu_info {
459 	struct hal_rx_ppdu_common_info com_info;
460 	struct hal_rx_ppdu_user_info user_info[HAL_MAX_UL_MU_USERS];
461 	struct mon_rx_status rx_status;
462 	struct hal_rx_msdu_payload_info msdu_info;
463 	/* status ring PPDU start and end state */
464 	uint32_t rx_state;
465 };
466 
467 static inline uint32_t
468 hal_get_rx_status_buf_size(void) {
469 	/* RX status buffer size is hard coded for now */
470 	return 2048;
471 }
472 
473 static inline uint8_t*
474 hal_rx_status_get_next_tlv(uint8_t *rx_tlv) {
475 	uint32_t tlv_len, tlv_tag;
476 
477 	tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv);
478 	tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv);
479 
480 	/* The actual length of PPDU_END is the combined length of many PHY
481 	 * TLVs that follow. Skip the TLV header and
482 	 * rx_rxpcu_classification_overview that follows the header to get to
483 	 * next TLV.
484 	 */
485 	if (tlv_tag == WIFIRX_PPDU_END_E)
486 		tlv_len = sizeof(struct rx_rxpcu_classification_overview);
487 
488 	return (uint8_t *)(((unsigned long)(rx_tlv + tlv_len +
489 			HAL_RX_TLV32_HDR_SIZE + 3)) & (~((unsigned long)3)));
490 }
491 
492 static inline uint32_t
493 hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info)
494 {
495 	uint32_t tlv_tag, user_id, tlv_len, value;
496 	uint8_t group_id = 0;
497 	uint8_t he_dcm = 0;
498 	uint8_t he_stbc = 0;
499 	uint16_t he_gi = 0;
500 	uint16_t he_ltf = 0;
501 
502 	tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv);
503 	user_id = HAL_RX_GET_USER_TLV32_USERID(rx_tlv);
504 	tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv);
505 
506 	rx_tlv = (uint8_t *) rx_tlv + HAL_RX_TLV32_HDR_SIZE;
507 	switch (tlv_tag) {
508 
509 	case WIFIRX_PPDU_START_E:
510 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
511 				  "[%s][%d] ppdu_start_e len=%d",
512 					__func__, __LINE__, tlv_len);
513 		ppdu_info->com_info.ppdu_id =
514 			HAL_RX_GET(rx_tlv, RX_PPDU_START_0,
515 				PHY_PPDU_ID);
516 		/* channel number is set in PHY meta data */
517 		ppdu_info->rx_status.chan_num =
518 			HAL_RX_GET(rx_tlv, RX_PPDU_START_1,
519 				SW_PHY_META_DATA);
520 		ppdu_info->com_info.ppdu_timestamp =
521 			HAL_RX_GET(rx_tlv, RX_PPDU_START_2,
522 				PPDU_START_TIMESTAMP);
523 		ppdu_info->rx_state = HAL_RX_MON_PPDU_START;
524 		break;
525 
526 	case WIFIRX_PPDU_START_USER_INFO_E:
527 		break;
528 
529 	case WIFIRX_PPDU_END_E:
530 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
531 			"[%s][%d] ppdu_end_e len=%d",
532 				__func__, __LINE__, tlv_len);
533 		/* This is followed by sub-TLVs of PPDU_END */
534 		ppdu_info->rx_state = HAL_RX_MON_PPDU_END;
535 		break;
536 
537 	case WIFIRXPCU_PPDU_END_INFO_E:
538 		ppdu_info->rx_status.tsft =
539 			HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_1,
540 				WB_TIMESTAMP_UPPER_32);
541 		ppdu_info->rx_status.tsft = (ppdu_info->rx_status.tsft << 32) |
542 			HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_0,
543 				WB_TIMESTAMP_LOWER_32);
544 		ppdu_info->rx_status.duration =
545 			HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_8,
546 				RX_PPDU_DURATION);
547 		break;
548 
549 	case WIFIRX_PPDU_END_USER_STATS_E:
550 	{
551 		unsigned long tid = 0;
552 		uint16_t seq = 0;
553 
554 		ppdu_info->rx_status.ast_index =
555 				HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_4,
556 						AST_INDEX);
557 
558 		tid = HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_12,
559 				RECEIVED_QOS_DATA_TID_BITMAP);
560 		ppdu_info->rx_status.tid = qdf_find_first_bit(&tid, sizeof(tid)*8);
561 
562 		if (ppdu_info->rx_status.tid == (sizeof(tid) * 8))
563 			ppdu_info->rx_status.tid = HAL_TID_INVALID;
564 
565 		ppdu_info->rx_status.tcp_msdu_count =
566 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_9,
567 					TCP_MSDU_COUNT) +
568 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_10,
569 					TCP_ACK_MSDU_COUNT);
570 		ppdu_info->rx_status.udp_msdu_count =
571 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_9,
572 						UDP_MSDU_COUNT);
573 		ppdu_info->rx_status.other_msdu_count =
574 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_10,
575 					OTHER_MSDU_COUNT);
576 
577 		ppdu_info->rx_status.frame_control_info_valid =
578 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3,
579 					DATA_SEQUENCE_CONTROL_INFO_VALID);
580 
581 		seq = HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_5,
582 					FIRST_DATA_SEQ_CTRL);
583 		if (ppdu_info->rx_status.frame_control_info_valid)
584 			ppdu_info->rx_status.first_data_seq_ctrl = seq;
585 
586 		ppdu_info->rx_status.preamble_type =
587 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3,
588 						HT_CONTROL_FIELD_PKT_TYPE);
589 		switch (ppdu_info->rx_status.preamble_type) {
590 		case HAL_RX_PKT_TYPE_11N:
591 			ppdu_info->rx_status.ht_flags = 1;
592 			ppdu_info->rx_status.rtap_flags |= HT_SGI_PRESENT;
593 			break;
594 		case HAL_RX_PKT_TYPE_11AC:
595 			ppdu_info->rx_status.vht_flags = 1;
596 			break;
597 		case HAL_RX_PKT_TYPE_11AX:
598 			ppdu_info->rx_status.he_flags = 1;
599 			break;
600 		default:
601 			break;
602 		}
603 
604 		ppdu_info->com_info.mpdu_cnt_fcs_ok =
605 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3,
606 					MPDU_CNT_FCS_OK);
607 		ppdu_info->com_info.mpdu_cnt_fcs_err =
608 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_2,
609 					MPDU_CNT_FCS_ERR);
610 		if ((ppdu_info->com_info.mpdu_cnt_fcs_ok |
611 			ppdu_info->com_info.mpdu_cnt_fcs_err) > 1)
612 			ppdu_info->rx_status.rs_flags |= IEEE80211_AMPDU_FLAG;
613 		else
614 			ppdu_info->rx_status.rs_flags &=
615 				(~IEEE80211_AMPDU_FLAG);
616 		break;
617 	}
618 
619 	case WIFIRX_PPDU_END_USER_STATS_EXT_E:
620 		break;
621 
622 	case WIFIRX_PPDU_END_STATUS_DONE_E:
623 		return HAL_TLV_STATUS_PPDU_DONE;
624 
625 	case WIFIDUMMY_E:
626 		return HAL_TLV_STATUS_BUF_DONE;
627 
628 	case WIFIPHYRX_HT_SIG_E:
629 	{
630 		uint8_t *ht_sig_info = (uint8_t *)rx_tlv +
631 				HAL_RX_OFFSET(PHYRX_HT_SIG_0,
632 				HT_SIG_INFO_PHYRX_HT_SIG_INFO_DETAILS);
633 		value = HAL_RX_GET(ht_sig_info, HT_SIG_INFO_1,
634 				FEC_CODING);
635 		ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ?
636 			1 : 0;
637 		ppdu_info->rx_status.mcs = HAL_RX_GET(ht_sig_info,
638 				HT_SIG_INFO_0, MCS);
639 		ppdu_info->rx_status.bw = HAL_RX_GET(ht_sig_info,
640 				HT_SIG_INFO_0, CBW);
641 		ppdu_info->rx_status.sgi = HAL_RX_GET(ht_sig_info,
642 				HT_SIG_INFO_1, SHORT_GI);
643 		break;
644 	}
645 
646 	case WIFIPHYRX_L_SIG_B_E:
647 	{
648 		uint8_t *l_sig_b_info = (uint8_t *)rx_tlv +
649 				HAL_RX_OFFSET(PHYRX_L_SIG_B_0,
650 				L_SIG_B_INFO_PHYRX_L_SIG_B_INFO_DETAILS);
651 
652 		value = HAL_RX_GET(l_sig_b_info, L_SIG_B_INFO_0, RATE);
653 		switch (value) {
654 		case 1:
655 			ppdu_info->rx_status.rate = HAL_11B_RATE_3MCS;
656 			break;
657 		case 2:
658 			ppdu_info->rx_status.rate = HAL_11B_RATE_2MCS;
659 			break;
660 		case 3:
661 			ppdu_info->rx_status.rate = HAL_11B_RATE_1MCS;
662 			break;
663 		case 4:
664 			ppdu_info->rx_status.rate = HAL_11B_RATE_0MCS;
665 			break;
666 		case 5:
667 			ppdu_info->rx_status.rate = HAL_11B_RATE_6MCS;
668 			break;
669 		case 6:
670 			ppdu_info->rx_status.rate = HAL_11B_RATE_5MCS;
671 			break;
672 		case 7:
673 			ppdu_info->rx_status.rate = HAL_11B_RATE_4MCS;
674 			break;
675 		default:
676 			break;
677 		}
678 		ppdu_info->rx_status.cck_flag = 1;
679 	break;
680 	}
681 
682 	case WIFIPHYRX_L_SIG_A_E:
683 	{
684 		uint8_t *l_sig_a_info = (uint8_t *)rx_tlv +
685 				HAL_RX_OFFSET(PHYRX_L_SIG_A_0,
686 				L_SIG_A_INFO_PHYRX_L_SIG_A_INFO_DETAILS);
687 
688 		value = HAL_RX_GET(l_sig_a_info, L_SIG_A_INFO_0, RATE);
689 		switch (value) {
690 		case 8:
691 			ppdu_info->rx_status.rate = HAL_11A_RATE_0MCS;
692 			break;
693 		case 9:
694 			ppdu_info->rx_status.rate = HAL_11A_RATE_1MCS;
695 			break;
696 		case 10:
697 			ppdu_info->rx_status.rate = HAL_11A_RATE_2MCS;
698 			break;
699 		case 11:
700 			ppdu_info->rx_status.rate = HAL_11A_RATE_3MCS;
701 			break;
702 		case 12:
703 			ppdu_info->rx_status.rate = HAL_11A_RATE_4MCS;
704 			break;
705 		case 13:
706 			ppdu_info->rx_status.rate = HAL_11A_RATE_5MCS;
707 			break;
708 		case 14:
709 			ppdu_info->rx_status.rate = HAL_11A_RATE_6MCS;
710 			break;
711 		case 15:
712 			ppdu_info->rx_status.rate = HAL_11A_RATE_7MCS;
713 			break;
714 		default:
715 			break;
716 		}
717 		ppdu_info->rx_status.ofdm_flag = 1;
718 	break;
719 	}
720 
721 	case WIFIPHYRX_VHT_SIG_A_E:
722 	{
723 		uint8_t *vht_sig_a_info = (uint8_t *)rx_tlv +
724 				HAL_RX_OFFSET(PHYRX_VHT_SIG_A_0,
725 				VHT_SIG_A_INFO_PHYRX_VHT_SIG_A_INFO_DETAILS);
726 
727 		value = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_1,
728 				SU_MU_CODING);
729 		ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ?
730 			1 : 0;
731 		group_id = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_0, GROUP_ID);
732 		ppdu_info->rx_status.vht_flag_values5 = group_id;
733 		ppdu_info->rx_status.mcs = HAL_RX_GET(vht_sig_a_info,
734 				VHT_SIG_A_INFO_1, MCS);
735 		ppdu_info->rx_status.sgi = HAL_RX_GET(vht_sig_a_info,
736 				VHT_SIG_A_INFO_1, GI_SETTING);
737 #if !defined(QCA_WIFI_QCA6290_11AX)
738 		value =  HAL_RX_GET(vht_sig_a_info,
739 				VHT_SIG_A_INFO_0, N_STS);
740 		ppdu_info->rx_status.nss = ((value & VHT_SIG_SU_NSS_MASK) + 1);
741 #else
742 		ppdu_info->rx_status.nss = 0;
743 #endif
744 		ppdu_info->rx_status.vht_flag_values3[0] =
745 				(((ppdu_info->rx_status.mcs) << 4)
746 				| ppdu_info->rx_status.nss);
747 		ppdu_info->rx_status.bw = HAL_RX_GET(vht_sig_a_info,
748 				VHT_SIG_A_INFO_0, BANDWIDTH);
749 		ppdu_info->rx_status.vht_flag_values2 =
750 			ppdu_info->rx_status.bw;
751 		ppdu_info->rx_status.vht_flag_values4 =
752 			HAL_RX_GET(vht_sig_a_info,
753 				  VHT_SIG_A_INFO_1, SU_MU_CODING);
754 
755 		ppdu_info->rx_status.beamformed = HAL_RX_GET(vht_sig_a_info,
756 				VHT_SIG_A_INFO_1, BEAMFORMED);
757 
758 		break;
759 	}
760 	case WIFIPHYRX_HE_SIG_A_SU_E:
761 	{
762 		uint8_t *he_sig_a_su_info = (uint8_t *)rx_tlv +
763 			HAL_RX_OFFSET(PHYRX_HE_SIG_A_SU_0,
764 			HE_SIG_A_SU_INFO_PHYRX_HE_SIG_A_SU_INFO_DETAILS);
765 		ppdu_info->rx_status.he_flags = 1;
766 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0,
767 			FORMAT_INDICATION);
768 		if (value == 0) {
769 			ppdu_info->rx_status.he_data1 =
770 				QDF_MON_STATUS_HE_TRIG_FORMAT_TYPE;
771 		} else {
772 			 ppdu_info->rx_status.he_data1 =
773 				 QDF_MON_STATUS_HE_SU_FORMAT_TYPE;
774 		}
775 
776 		/* data1 */
777 		ppdu_info->rx_status.he_data1 |=
778 			QDF_MON_STATUS_HE_BSS_COLOR_KNOWN |
779 			QDF_MON_STATUS_HE_BEAM_CHANGE_KNOWN |
780 			QDF_MON_STATUS_HE_DL_UL_KNOWN |
781 			QDF_MON_STATUS_HE_MCS_KNOWN |
782 			QDF_MON_STATUS_HE_DCM_KNOWN |
783 			QDF_MON_STATUS_HE_CODING_KNOWN |
784 			QDF_MON_STATUS_HE_LDPC_EXTRA_SYMBOL_KNOWN |
785 			QDF_MON_STATUS_HE_STBC_KNOWN |
786 			QDF_MON_STATUS_HE_DATA_BW_RU_KNOWN |
787 			QDF_MON_STATUS_HE_DOPPLER_KNOWN;
788 
789 		/* data2 */
790 		ppdu_info->rx_status.he_data2 =
791 			QDF_MON_STATUS_HE_GI_KNOWN;
792 		ppdu_info->rx_status.he_data2 |=
793 			QDF_MON_STATUS_TXBF_KNOWN |
794 			QDF_MON_STATUS_PE_DISAMBIGUITY_KNOWN |
795 			QDF_MON_STATUS_TXOP_KNOWN |
796 			QDF_MON_STATUS_LTF_SYMBOLS_KNOWN |
797 			QDF_MON_STATUS_PRE_FEC_PADDING_KNOWN |
798 			QDF_MON_STATUS_MIDABLE_PERIODICITY_KNOWN;
799 
800 		/* data3 */
801 		value = HAL_RX_GET(he_sig_a_su_info,
802 				HE_SIG_A_SU_INFO_0, BSS_COLOR_ID);
803 		ppdu_info->rx_status.he_data3 = value;
804 		value = HAL_RX_GET(he_sig_a_su_info,
805 				HE_SIG_A_SU_INFO_0, BEAM_CHANGE);
806 		value = value << QDF_MON_STATUS_BEAM_CHANGE_SHIFT;
807 		ppdu_info->rx_status.he_data3 |= value;
808 		value = HAL_RX_GET(he_sig_a_su_info,
809 				HE_SIG_A_SU_INFO_0, DL_UL_FLAG);
810 		value = value << QDF_MON_STATUS_DL_UL_SHIFT;
811 		ppdu_info->rx_status.he_data3 |= value;
812 
813 		value = HAL_RX_GET(he_sig_a_su_info,
814 				HE_SIG_A_SU_INFO_0, TRANSMIT_MCS);
815 		ppdu_info->rx_status.mcs = value;
816 		value = value << QDF_MON_STATUS_TRANSMIT_MCS_SHIFT;
817 		ppdu_info->rx_status.he_data3 |= value;
818 
819 		value = HAL_RX_GET(he_sig_a_su_info,
820 				HE_SIG_A_SU_INFO_0, DCM);
821 		he_dcm = value;
822 		value = value << QDF_MON_STATUS_DCM_SHIFT;
823 		ppdu_info->rx_status.he_data3 |= value;
824 		value = HAL_RX_GET(he_sig_a_su_info,
825 				HE_SIG_A_SU_INFO_1, CODING);
826 		value = value << QDF_MON_STATUS_CODING_SHIFT;
827 		ppdu_info->rx_status.he_data3 |= value;
828 		value = HAL_RX_GET(he_sig_a_su_info,
829 				HE_SIG_A_SU_INFO_1,
830 				LDPC_EXTRA_SYMBOL);
831 		value = value << QDF_MON_STATUS_LDPC_EXTRA_SYMBOL_SHIFT;
832 		ppdu_info->rx_status.he_data3 |= value;
833 		value = HAL_RX_GET(he_sig_a_su_info,
834 				HE_SIG_A_SU_INFO_1, STBC);
835 		he_stbc = value;
836 		value = value << QDF_MON_STATUS_STBC_SHIFT;
837 		ppdu_info->rx_status.he_data3 |= value;
838 
839 		/* data4 */
840 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0,
841 							SPATIAL_REUSE);
842 		ppdu_info->rx_status.he_data4 = value;
843 
844 		/* data5 */
845 		value = HAL_RX_GET(he_sig_a_su_info,
846 				HE_SIG_A_SU_INFO_0, TRANSMIT_BW);
847 		ppdu_info->rx_status.he_data5 = value;
848 		ppdu_info->rx_status.bw = value;
849 		value = HAL_RX_GET(he_sig_a_su_info,
850 				HE_SIG_A_SU_INFO_0, CP_LTF_SIZE);
851 		switch (value) {
852 		case 0:
853 				he_gi = HE_GI_0_8;
854 				he_ltf = HE_LTF_1_X;
855 				break;
856 		case 1:
857 				he_gi = HE_GI_0_8;
858 				he_ltf = HE_LTF_2_X;
859 				break;
860 		case 2:
861 				he_gi = HE_GI_1_6;
862 				he_ltf = HE_LTF_2_X;
863 				break;
864 		case 3:
865 				if (he_dcm && he_stbc) {
866 					he_gi = HE_GI_0_8;
867 					he_ltf = HE_LTF_4_X;
868 				} else {
869 					he_gi = HE_GI_3_2;
870 					he_ltf = HE_LTF_4_X;
871 				}
872 				break;
873 		}
874 		ppdu_info->rx_status.sgi = he_gi;
875 		value = he_gi << QDF_MON_STATUS_GI_SHIFT;
876 		ppdu_info->rx_status.he_data5 |= value;
877 		value = he_ltf << QDF_MON_STATUS_HE_LTF_SHIFT;
878 		ppdu_info->rx_status.he_data5 |= value;
879 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1,
880 							PACKET_EXTENSION_A_FACTOR);
881 		value = value << QDF_MON_STATUS_PRE_FEC_PAD_SHIFT;
882 		ppdu_info->rx_status.he_data5 |= value;
883 
884 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1, TXBF);
885 		value = value << QDF_MON_STATUS_TXBF_SHIFT;
886 		ppdu_info->rx_status.he_data5 |= value;
887 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1,
888 							PACKET_EXTENSION_PE_DISAMBIGUITY);
889 		value = value << QDF_MON_STATUS_PE_DISAMBIGUITY_SHIFT;
890 		ppdu_info->rx_status.he_data5 |= value;
891 
892 		/* data6 */
893 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0, NSTS);
894 		value++;
895 		ppdu_info->rx_status.nss = value;
896 		ppdu_info->rx_status.he_data6 = value;
897 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1,
898 							DOPPLER_INDICATION);
899 		value = value << QDF_MON_STATUS_DOPPLER_SHIFT;
900 		ppdu_info->rx_status.he_data6 |= value;
901 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1,
902 							TXOP_DURATION);
903 		value = value << QDF_MON_STATUS_TXOP_SHIFT;
904 		ppdu_info->rx_status.he_data6 |= value;
905 
906 		ppdu_info->rx_status.beamformed = HAL_RX_GET(he_sig_a_su_info,
907 					HE_SIG_A_SU_INFO_1, TXBF);
908 		break;
909 	}
910 	case WIFIPHYRX_HE_SIG_A_MU_DL_E:
911 	{
912 		uint8_t *he_sig_a_mu_dl_info = (uint8_t *)rx_tlv +
913 			HAL_RX_OFFSET(PHYRX_HE_SIG_A_MU_DL_0,
914 			HE_SIG_A_MU_DL_INFO_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS);
915 
916 		ppdu_info->rx_status.he_mu_flags = 1;
917 
918 		/* HE Flags */
919 		/*data1*/
920 		ppdu_info->rx_status.he_data1 =
921 					QDF_MON_STATUS_HE_MU_FORMAT_TYPE;
922 		ppdu_info->rx_status.he_data1 |=
923 			QDF_MON_STATUS_HE_BSS_COLOR_KNOWN |
924 			QDF_MON_STATUS_HE_DL_UL_KNOWN |
925 			QDF_MON_STATUS_HE_LDPC_EXTRA_SYMBOL_KNOWN |
926 			QDF_MON_STATUS_HE_STBC_KNOWN |
927 			QDF_MON_STATUS_HE_DATA_BW_RU_KNOWN |
928 			QDF_MON_STATUS_HE_DOPPLER_KNOWN;
929 
930 		/* data2 */
931 		ppdu_info->rx_status.he_data2 =
932 			QDF_MON_STATUS_HE_GI_KNOWN;
933 		ppdu_info->rx_status.he_data2 |=
934 			QDF_MON_STATUS_LTF_SYMBOLS_KNOWN |
935 			QDF_MON_STATUS_PRE_FEC_PADDING_KNOWN |
936 			QDF_MON_STATUS_PE_DISAMBIGUITY_KNOWN |
937 			QDF_MON_STATUS_TXOP_KNOWN |
938 			QDF_MON_STATUS_MIDABLE_PERIODICITY_KNOWN;
939 
940 		/*data3*/
941 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
942 				HE_SIG_A_MU_DL_INFO_0, BSS_COLOR_ID);
943 		ppdu_info->rx_status.he_data3 = value;
944 
945 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
946 				HE_SIG_A_MU_DL_INFO_0, DL_UL_FLAG);
947 		value = value << QDF_MON_STATUS_DL_UL_SHIFT;
948 		ppdu_info->rx_status.he_data3 |= value;
949 
950 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
951 				HE_SIG_A_MU_DL_INFO_1,
952 				LDPC_EXTRA_SYMBOL);
953 		value = value << QDF_MON_STATUS_LDPC_EXTRA_SYMBOL_SHIFT;
954 		ppdu_info->rx_status.he_data3 |= value;
955 
956 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
957 				HE_SIG_A_MU_DL_INFO_1, STBC);
958 		he_stbc = value;
959 		value = value << QDF_MON_STATUS_STBC_SHIFT;
960 		ppdu_info->rx_status.he_data3 |= value;
961 
962 		/*data4*/
963 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_0,
964 							SPATIAL_REUSE);
965 		ppdu_info->rx_status.he_data4 = value;
966 
967 		/*data5*/
968 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
969 				HE_SIG_A_MU_DL_INFO_0, TRANSMIT_BW);
970 		ppdu_info->rx_status.he_data5 = value;
971 		ppdu_info->rx_status.bw = value;
972 
973 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
974 				HE_SIG_A_MU_DL_INFO_0, CP_LTF_SIZE);
975 		switch (value) {
976 		case 0:
977 			he_gi = HE_GI_0_8;
978 			he_ltf = HE_LTF_4_X;
979 			break;
980 		case 1:
981 			he_gi = HE_GI_0_8;
982 			he_ltf = HE_LTF_2_X;
983 			break;
984 		case 2:
985 			he_gi = HE_GI_1_6;
986 			he_ltf = HE_LTF_2_X;
987 			break;
988 		case 3:
989 			he_gi = HE_GI_3_2;
990 			he_ltf = HE_LTF_4_X;
991 			break;
992 		}
993 		ppdu_info->rx_status.sgi = he_gi;
994 		value = he_gi << QDF_MON_STATUS_GI_SHIFT;
995 		ppdu_info->rx_status.he_data5 |= value;
996 
997 		value = he_ltf << QDF_MON_STATUS_HE_LTF_SHIFT;
998 		ppdu_info->rx_status.he_data5 |= value;
999 
1000 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_1,
1001 				   PACKET_EXTENSION_A_FACTOR);
1002 		value = value << QDF_MON_STATUS_PRE_FEC_PAD_SHIFT;
1003 		ppdu_info->rx_status.he_data5 |= value;
1004 
1005 
1006 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_1,
1007 				   PACKET_EXTENSION_PE_DISAMBIGUITY);
1008 		value = value << QDF_MON_STATUS_PE_DISAMBIGUITY_SHIFT;
1009 		ppdu_info->rx_status.he_data5 |= value;
1010 
1011 		/*data6*/
1012 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_0,
1013 							DOPPLER_INDICATION);
1014 		value = value << QDF_MON_STATUS_DOPPLER_SHIFT;
1015 		ppdu_info->rx_status.he_data6 |= value;
1016 
1017 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_1,
1018 							TXOP_DURATION);
1019 		value = value << QDF_MON_STATUS_TXOP_SHIFT;
1020 		ppdu_info->rx_status.he_data6 |= value;
1021 
1022 		/* HE-MU Flags */
1023 		/* HE-MU-flags1 */
1024 		ppdu_info->rx_status.he_flags1 =
1025 			QDF_MON_STATUS_SIG_B_MCS_KNOWN |
1026 			QDF_MON_STATUS_SIG_B_DCM_KNOWN |
1027 			QDF_MON_STATUS_SIG_B_COMPRESSION_FLAG_1_KNOWN |
1028 			QDF_MON_STATUS_SIG_B_SYM_NUM_KNOWN |
1029 			QDF_MON_STATUS_RU_0_KNOWN;
1030 
1031 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1032 				HE_SIG_A_MU_DL_INFO_0, MCS_OF_SIG_B);
1033 		ppdu_info->rx_status.he_flags1 |= value;
1034 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1035 				HE_SIG_A_MU_DL_INFO_0, DCM_OF_SIG_B);
1036 		value = value << QDF_MON_STATUS_DCM_FLAG_1_SHIFT;
1037 		ppdu_info->rx_status.he_flags1 |= value;
1038 
1039 		/* HE-MU-flags2 */
1040 		ppdu_info->rx_status.he_flags2 =
1041 			QDF_MON_STATUS_BW_KNOWN;
1042 
1043 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1044 				HE_SIG_A_MU_DL_INFO_0, TRANSMIT_BW);
1045 		ppdu_info->rx_status.he_flags2 |= value;
1046 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1047 				HE_SIG_A_MU_DL_INFO_0, COMP_MODE_SIG_B);
1048 		value = value << QDF_MON_STATUS_SIG_B_COMPRESSION_FLAG_2_SHIFT;
1049 		ppdu_info->rx_status.he_flags2 |= value;
1050 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1051 				HE_SIG_A_MU_DL_INFO_0, NUM_SIG_B_SYMBOLS);
1052 		value = value - 1;
1053 		value = value << QDF_MON_STATUS_NUM_SIG_B_SYMBOLS_SHIFT;
1054 		ppdu_info->rx_status.he_flags2 |= value;
1055 		break;
1056 	}
1057 	case WIFIPHYRX_HE_SIG_B1_MU_E:
1058 	{
1059 
1060 		uint8_t *he_sig_b1_mu_info = (uint8_t *)rx_tlv +
1061 			HAL_RX_OFFSET(PHYRX_HE_SIG_B1_MU_0,
1062 			HE_SIG_B1_MU_INFO_PHYRX_HE_SIG_B1_MU_INFO_DETAILS);
1063 
1064 		ppdu_info->rx_status.he_sig_b_common_known |=
1065 			QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0;
1066 		/* TODO: Check on the availability of other fields in
1067 		 * sig_b_common
1068 		 */
1069 
1070 		value = HAL_RX_GET(he_sig_b1_mu_info,
1071 				HE_SIG_B1_MU_INFO_0, RU_ALLOCATION);
1072 		ppdu_info->rx_status.he_RU[0] = value;
1073 		break;
1074 	}
1075 	case WIFIPHYRX_HE_SIG_B2_MU_E:
1076 	{
1077 		uint8_t *he_sig_b2_mu_info = (uint8_t *)rx_tlv +
1078 			HAL_RX_OFFSET(PHYRX_HE_SIG_B2_MU_0,
1079 			HE_SIG_B2_MU_INFO_PHYRX_HE_SIG_B2_MU_INFO_DETAILS);
1080 		/*
1081 		 * Not all "HE" fields can be updated from
1082 		 * WIFIPHYRX_HE_SIG_A_MU_DL_E TLV. Use WIFIPHYRX_HE_SIG_B2_MU_E
1083 		 * to populate rest of the "HE" fields for MU scenarios.
1084 		 */
1085 
1086 		/* HE-data1 */
1087 		ppdu_info->rx_status.he_data1 |=
1088 			QDF_MON_STATUS_HE_MCS_KNOWN |
1089 			QDF_MON_STATUS_HE_CODING_KNOWN;
1090 
1091 		/* HE-data2 */
1092 
1093 		/* HE-data3 */
1094 		value = HAL_RX_GET(he_sig_b2_mu_info,
1095 				HE_SIG_B2_MU_INFO_0, STA_MCS);
1096 		ppdu_info->rx_status.mcs = value;
1097 		value = value << QDF_MON_STATUS_TRANSMIT_MCS_SHIFT;
1098 		ppdu_info->rx_status.he_data3 |= value;
1099 
1100 
1101 		value = HAL_RX_GET(he_sig_b2_mu_info,
1102 				HE_SIG_B2_MU_INFO_0, STA_CODING);
1103 		value = value << QDF_MON_STATUS_CODING_SHIFT;
1104 		ppdu_info->rx_status.he_data3 |= value;
1105 
1106 		/* HE-data4 */
1107 		value = HAL_RX_GET(he_sig_b2_mu_info,
1108 				HE_SIG_B2_MU_INFO_0, STA_ID);
1109 		value = value << QDF_MON_STATUS_STA_ID_SHIFT;
1110 		ppdu_info->rx_status.he_data4 |= value;
1111 
1112 		/* HE-data5 */
1113 
1114 		/* HE-data6 */
1115 		value = HAL_RX_GET(he_sig_b2_mu_info,
1116 				   HE_SIG_B2_MU_INFO_0, NSTS);
1117 		/* value n indicates n+1 spatial streams */
1118 		value++;
1119 		ppdu_info->rx_status.nss = value;
1120 		ppdu_info->rx_status.he_data6 |= value;
1121 
1122 		break;
1123 
1124 	}
1125 	case WIFIPHYRX_HE_SIG_B2_OFDMA_E:
1126 	{
1127 		uint8_t *he_sig_b2_ofdma_info =
1128 		(uint8_t *)rx_tlv +
1129 		HAL_RX_OFFSET(PHYRX_HE_SIG_B2_OFDMA_0,
1130 		HE_SIG_B2_OFDMA_INFO_PHYRX_HE_SIG_B2_OFDMA_INFO_DETAILS);
1131 
1132 		/*
1133 		 * Not all "HE" fields can be updated from
1134 		 * WIFIPHYRX_HE_SIG_A_MU_DL_E TLV. Use WIFIPHYRX_HE_SIG_B2_MU_E
1135 		 * to populate rest of "HE" fields for MU OFDMA scenarios.
1136 		 */
1137 
1138 		/* HE-data1 */
1139 		ppdu_info->rx_status.he_data1 |=
1140 			QDF_MON_STATUS_HE_MCS_KNOWN |
1141 			QDF_MON_STATUS_HE_DCM_KNOWN |
1142 			QDF_MON_STATUS_HE_CODING_KNOWN;
1143 
1144 		/* HE-data2 */
1145 		ppdu_info->rx_status.he_data2 |=
1146 					QDF_MON_STATUS_TXBF_KNOWN;
1147 
1148 		/* HE-data3 */
1149 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
1150 				HE_SIG_B2_OFDMA_INFO_0, STA_MCS);
1151 		ppdu_info->rx_status.mcs = value;
1152 		value = value << QDF_MON_STATUS_TRANSMIT_MCS_SHIFT;
1153 		ppdu_info->rx_status.he_data3 |= value;
1154 
1155 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
1156 				HE_SIG_B2_OFDMA_INFO_0, STA_DCM);
1157 		he_dcm = value;
1158 		value = value << QDF_MON_STATUS_DCM_SHIFT;
1159 		ppdu_info->rx_status.he_data3 |= value;
1160 
1161 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
1162 				HE_SIG_B2_OFDMA_INFO_0, STA_CODING);
1163 		value = value << QDF_MON_STATUS_CODING_SHIFT;
1164 		ppdu_info->rx_status.he_data3 |= value;
1165 
1166 		/* HE-data4 */
1167 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
1168 				HE_SIG_B2_OFDMA_INFO_0, STA_ID);
1169 		value = value << QDF_MON_STATUS_STA_ID_SHIFT;
1170 		ppdu_info->rx_status.he_data4 |= value;
1171 
1172 		/* HE-data5 */
1173 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
1174 				   HE_SIG_B2_OFDMA_INFO_0, TXBF);
1175 		value = value << QDF_MON_STATUS_TXBF_SHIFT;
1176 		ppdu_info->rx_status.he_data5 |= value;
1177 
1178 		/* HE-data6 */
1179 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
1180 				   HE_SIG_B2_OFDMA_INFO_0, NSTS);
1181 		/* value n indicates n+1 spatial streams */
1182 		value++;
1183 		ppdu_info->rx_status.nss = value;
1184 		ppdu_info->rx_status.he_data6 |= value;
1185 
1186 		break;
1187 	}
1188 	case WIFIPHYRX_RSSI_LEGACY_E:
1189 	{
1190 		uint8_t *rssi_info_tlv = (uint8_t *)rx_tlv +
1191 			HAL_RX_OFFSET(PHYRX_RSSI_LEGACY_3,
1192 			RECEIVE_RSSI_INFO_PRE_RSSI_INFO_DETAILS);
1193 
1194 		ppdu_info->rx_status.rssi_comb = HAL_RX_GET(rx_tlv,
1195 			PHYRX_RSSI_LEGACY_35, RSSI_COMB);
1196 		ppdu_info->rx_status.bw = HAL_RX_GET(rx_tlv,
1197 #if !defined(QCA_WIFI_QCA6290_11AX)
1198 			PHYRX_RSSI_LEGACY_35, RECEIVE_BANDWIDTH);
1199 #else
1200 			PHYRX_RSSI_LEGACY_0, RECEIVE_BANDWIDTH);
1201 #endif
1202 		ppdu_info->rx_status.he_re = 0;
1203 
1204 		ppdu_info->rx_status.reception_type = HAL_RX_GET(rx_tlv,
1205 				PHYRX_RSSI_LEGACY_0, RECEPTION_TYPE);
1206 
1207 		value = HAL_RX_GET(rssi_info_tlv,
1208 			RECEIVE_RSSI_INFO_0, RSSI_PRI20_CHAIN0);
1209 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1210 			"RSSI_PRI20_CHAIN0: %d\n", value);
1211 
1212 		value = HAL_RX_GET(rssi_info_tlv,
1213 			RECEIVE_RSSI_INFO_0, RSSI_EXT20_CHAIN0);
1214 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1215 			"RSSI_EXT20_CHAIN0: %d\n", value);
1216 
1217 		value = HAL_RX_GET(rssi_info_tlv,
1218 			RECEIVE_RSSI_INFO_0, RSSI_EXT40_LOW20_CHAIN0);
1219 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1220 			"RSSI_EXT40_LOW20_CHAIN0: %d\n", value);
1221 
1222 		value = HAL_RX_GET(rssi_info_tlv,
1223 			RECEIVE_RSSI_INFO_0, RSSI_EXT40_HIGH20_CHAIN0);
1224 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1225 			"RSSI_EXT40_HIGH20_CHAIN0: %d\n", value);
1226 
1227 		value = HAL_RX_GET(rssi_info_tlv,
1228 			RECEIVE_RSSI_INFO_1, RSSI_EXT80_LOW20_CHAIN0);
1229 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1230 			"RSSI_EXT80_LOW20_CHAIN0: %d\n", value);
1231 
1232 		value = HAL_RX_GET(rssi_info_tlv,
1233 			RECEIVE_RSSI_INFO_1, RSSI_EXT80_LOW_HIGH20_CHAIN0);
1234 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1235 			"RSSI_EXT80_LOW_HIGH20_CHAIN0: %d\n", value);
1236 
1237 		value = HAL_RX_GET(rssi_info_tlv,
1238 			RECEIVE_RSSI_INFO_1, RSSI_EXT80_HIGH_LOW20_CHAIN0);
1239 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1240 			"RSSI_EXT80_HIGH_LOW20_CHAIN0: %d\n", value);
1241 
1242 		value = HAL_RX_GET(rssi_info_tlv,
1243 			RECEIVE_RSSI_INFO_1, RSSI_EXT80_HIGH20_CHAIN0);
1244 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1245 			"RSSI_EXT80_HIGH20_CHAIN0: %d\n", value);
1246 		break;
1247 	}
1248 	case WIFIRX_HEADER_E:
1249 		ppdu_info->msdu_info.first_msdu_payload = rx_tlv;
1250 		ppdu_info->msdu_info.payload_len = tlv_len;
1251 		break;
1252 	case WIFIRX_MPDU_START_E:
1253 	{
1254 		uint8_t *rx_mpdu_start =
1255 			(uint8_t *)rx_tlv + HAL_RX_OFFSET(RX_MPDU_START_0,
1256 					RX_MPDU_INFO_RX_MPDU_INFO_DETAILS);
1257 		uint32_t ppdu_id = HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0,
1258 					      PHY_PPDU_ID);
1259 
1260 		if (ppdu_info->rx_status.prev_ppdu_id != ppdu_id) {
1261 			ppdu_info->rx_status.prev_ppdu_id = ppdu_id;
1262 			ppdu_info->rx_status.ppdu_len =
1263 				HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_13,
1264 					   MPDU_LENGTH);
1265 		} else {
1266 			ppdu_info->rx_status.ppdu_len +=
1267 				HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_13,
1268 				MPDU_LENGTH);
1269 		}
1270 		break;
1271 	}
1272 	case 0:
1273 		return HAL_TLV_STATUS_PPDU_DONE;
1274 
1275 	default:
1276 		break;
1277 	}
1278 
1279 	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1280 			  "%s TLV type: %d, TLV len:%d",
1281 			  __func__, tlv_tag, tlv_len);
1282 
1283 	return HAL_TLV_STATUS_PPDU_NOT_DONE;
1284 }
1285 
1286 static inline
1287 uint32_t hal_get_rx_status_done_tlv_size(void *hal_soc)
1288 {
1289 	return HAL_RX_TLV32_HDR_SIZE;
1290 }
1291 
1292 static inline QDF_STATUS
1293 hal_get_rx_status_done(uint8_t *rx_tlv)
1294 {
1295 	uint32_t tlv_tag;
1296 
1297 	tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv);
1298 
1299 	if (tlv_tag == WIFIRX_STATUS_BUFFER_DONE_E)
1300 		return QDF_STATUS_SUCCESS;
1301 	else
1302 		return QDF_STATUS_E_EMPTY;
1303 }
1304 
1305 static inline QDF_STATUS
1306 hal_clear_rx_status_done(uint8_t *rx_tlv)
1307 {
1308 	*(uint32_t *)rx_tlv = 0;
1309 	return QDF_STATUS_SUCCESS;
1310 }
1311 
1312 #endif
1313