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