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