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