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