xref: /wlan-dirver/qca-wifi-host-cmn/hal/wifi3.0/hal_generic_api.h (revision 503663c6daafffe652fa360bde17243568cd6d2a)
1 /*
2  * Copyright (c) 2016-2019 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 #ifndef _HAL_GENERIC_API_H_
19 #define _HAL_GENERIC_API_H_
20 
21 #include <hal_rx.h>
22 
23 /**
24  * hal_tx_comp_get_status() - TQM Release reason
25  * @hal_desc: completion ring Tx status
26  *
27  * This function will parse the WBM completion descriptor and populate in
28  * HAL structure
29  *
30  * Return: none
31  */
32 static inline
33 void hal_tx_comp_get_status_generic(void *desc,
34 				    void *ts1,
35 				    struct hal_soc *hal)
36 {
37 	uint8_t rate_stats_valid = 0;
38 	uint32_t rate_stats = 0;
39 	struct hal_tx_completion_status *ts =
40 		(struct hal_tx_completion_status *)ts1;
41 
42 	ts->ppdu_id = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_3,
43 			TQM_STATUS_NUMBER);
44 	ts->ack_frame_rssi = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4,
45 			ACK_FRAME_RSSI);
46 	ts->first_msdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4, FIRST_MSDU);
47 	ts->last_msdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4, LAST_MSDU);
48 	ts->msdu_part_of_amsdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4,
49 			MSDU_PART_OF_AMSDU);
50 
51 	ts->peer_id = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_7, SW_PEER_ID);
52 	ts->tid = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_7, TID);
53 	ts->transmit_cnt = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_3,
54 			TRANSMIT_COUNT);
55 
56 	rate_stats = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_5,
57 			TX_RATE_STATS);
58 
59 	rate_stats_valid = HAL_TX_MS(TX_RATE_STATS_INFO_0,
60 			TX_RATE_STATS_INFO_VALID, rate_stats);
61 
62 	ts->valid = rate_stats_valid;
63 
64 	if (rate_stats_valid) {
65 		ts->bw = HAL_TX_MS(TX_RATE_STATS_INFO_0, TRANSMIT_BW,
66 				rate_stats);
67 		ts->pkt_type = HAL_TX_MS(TX_RATE_STATS_INFO_0,
68 				TRANSMIT_PKT_TYPE, rate_stats);
69 		ts->stbc = HAL_TX_MS(TX_RATE_STATS_INFO_0,
70 				TRANSMIT_STBC, rate_stats);
71 		ts->ldpc = HAL_TX_MS(TX_RATE_STATS_INFO_0, TRANSMIT_LDPC,
72 				rate_stats);
73 		ts->sgi = HAL_TX_MS(TX_RATE_STATS_INFO_0, TRANSMIT_SGI,
74 				rate_stats);
75 		ts->mcs = HAL_TX_MS(TX_RATE_STATS_INFO_0, TRANSMIT_MCS,
76 				rate_stats);
77 		ts->ofdma = HAL_TX_MS(TX_RATE_STATS_INFO_0, OFDMA_TRANSMISSION,
78 				rate_stats);
79 		ts->tones_in_ru = HAL_TX_MS(TX_RATE_STATS_INFO_0, TONES_IN_RU,
80 				rate_stats);
81 	}
82 
83 	ts->release_src = hal_tx_comp_get_buffer_source(desc);
84 	ts->status = hal_tx_comp_get_release_reason(
85 					desc,
86 					hal_soc_to_hal_soc_handle(hal));
87 
88 	ts->tsf = HAL_TX_DESC_GET(desc, UNIFIED_WBM_RELEASE_RING_6,
89 			TX_RATE_STATS_INFO_TX_RATE_STATS);
90 }
91 
92 /**
93  * hal_tx_desc_set_buf_addr - Fill Buffer Address information in Tx Descriptor
94  * @desc: Handle to Tx Descriptor
95  * @paddr: Physical Address
96  * @pool_id: Return Buffer Manager ID
97  * @desc_id: Descriptor ID
98  * @type: 0 - Address points to a MSDU buffer
99  *		1 - Address points to MSDU extension descriptor
100  *
101  * Return: void
102  */
103 static inline void hal_tx_desc_set_buf_addr_generic(void *desc,
104 		dma_addr_t paddr, uint8_t pool_id,
105 		uint32_t desc_id, uint8_t type)
106 {
107 	/* Set buffer_addr_info.buffer_addr_31_0 */
108 	HAL_SET_FLD(desc, UNIFIED_TCL_DATA_CMD_0, BUFFER_ADDR_INFO_BUF_ADDR_INFO) =
109 		HAL_TX_SM(UNIFIED_BUFFER_ADDR_INFO_0, BUFFER_ADDR_31_0, paddr);
110 
111 	/* Set buffer_addr_info.buffer_addr_39_32 */
112 	HAL_SET_FLD(desc, UNIFIED_TCL_DATA_CMD_1,
113 			 BUFFER_ADDR_INFO_BUF_ADDR_INFO) |=
114 		HAL_TX_SM(UNIFIED_BUFFER_ADDR_INFO_1, BUFFER_ADDR_39_32,
115 		       (((uint64_t) paddr) >> 32));
116 
117 	/* Set buffer_addr_info.return_buffer_manager = pool id */
118 	HAL_SET_FLD(desc, UNIFIED_TCL_DATA_CMD_1,
119 			 BUFFER_ADDR_INFO_BUF_ADDR_INFO) |=
120 		HAL_TX_SM(UNIFIED_BUFFER_ADDR_INFO_1,
121 		       RETURN_BUFFER_MANAGER, (pool_id + HAL_WBM_SW0_BM_ID));
122 
123 	/* Set buffer_addr_info.sw_buffer_cookie = desc_id */
124 	HAL_SET_FLD(desc, UNIFIED_TCL_DATA_CMD_1,
125 			BUFFER_ADDR_INFO_BUF_ADDR_INFO) |=
126 		HAL_TX_SM(UNIFIED_BUFFER_ADDR_INFO_1, SW_BUFFER_COOKIE, desc_id);
127 
128 	/* Set  Buffer or Ext Descriptor Type */
129 	HAL_SET_FLD(desc, UNIFIED_TCL_DATA_CMD_2,
130 			BUF_OR_EXT_DESC_TYPE) |=
131 		HAL_TX_SM(UNIFIED_TCL_DATA_CMD_2, BUF_OR_EXT_DESC_TYPE, type);
132 }
133 
134 #if defined(QCA_WIFI_QCA6290_11AX_MU_UL) && defined(QCA_WIFI_QCA6290_11AX)
135 /**
136  * hal_rx_handle_other_tlvs() - handle special TLVs like MU_UL
137  * tlv_tag: Taf of the TLVs
138  * rx_tlv: the pointer to the TLVs
139  * @ppdu_info: pointer to ppdu_info
140  *
141  * Return: true if the tlv is handled, false if not
142  */
143 static inline bool
144 hal_rx_handle_other_tlvs(uint32_t tlv_tag, void *rx_tlv,
145 			 struct hal_rx_ppdu_info *ppdu_info)
146 {
147 	uint32_t value;
148 
149 	switch (tlv_tag) {
150 	case WIFIPHYRX_HE_SIG_A_MU_UL_E:
151 	{
152 		uint8_t *he_sig_a_mu_ul_info =
153 			(uint8_t *)rx_tlv +
154 			HAL_RX_OFFSET(PHYRX_HE_SIG_A_MU_UL_0,
155 					  HE_SIG_A_MU_UL_INFO_PHYRX_HE_SIG_A_MU_UL_INFO_DETAILS);
156 		ppdu_info->rx_status.he_flags = 1;
157 
158 		value = HAL_RX_GET(he_sig_a_mu_ul_info, HE_SIG_A_MU_UL_INFO_0,
159 				   FORMAT_INDICATION);
160 		if (value == 0) {
161 			ppdu_info->rx_status.he_data1 =
162 				QDF_MON_STATUS_HE_TRIG_FORMAT_TYPE;
163 		} else {
164 			 ppdu_info->rx_status.he_data1 =
165 				QDF_MON_STATUS_HE_SU_FORMAT_TYPE;
166 		}
167 
168 		/* data1 */
169 		ppdu_info->rx_status.he_data1 |=
170 			QDF_MON_STATUS_HE_BSS_COLOR_KNOWN |
171 			QDF_MON_STATUS_HE_DL_UL_KNOWN |
172 			QDF_MON_STATUS_HE_DATA_BW_RU_KNOWN;
173 
174 		/* data2 */
175 		ppdu_info->rx_status.he_data2 |=
176 			QDF_MON_STATUS_TXOP_KNOWN;
177 
178 		/*data3*/
179 		value = HAL_RX_GET(he_sig_a_mu_ul_info,
180 				   HE_SIG_A_MU_UL_INFO_0, BSS_COLOR_ID);
181 		ppdu_info->rx_status.he_data3 = value;
182 		/* 1 for UL and 0 for DL */
183 		value = 1;
184 		value = value << QDF_MON_STATUS_DL_UL_SHIFT;
185 		ppdu_info->rx_status.he_data3 |= value;
186 
187 		/*data4*/
188 		value = HAL_RX_GET(he_sig_a_mu_ul_info, HE_SIG_A_MU_UL_INFO_0,
189 				   SPATIAL_REUSE);
190 		ppdu_info->rx_status.he_data4 = value;
191 
192 		/*data5*/
193 		value = HAL_RX_GET(he_sig_a_mu_ul_info,
194 				   HE_SIG_A_MU_UL_INFO_0, TRANSMIT_BW);
195 		ppdu_info->rx_status.he_data5 = value;
196 		ppdu_info->rx_status.bw = value;
197 
198 		/*data6*/
199 		value = HAL_RX_GET(he_sig_a_mu_ul_info, HE_SIG_A_MU_UL_INFO_1,
200 				   TXOP_DURATION);
201 		value = value << QDF_MON_STATUS_TXOP_SHIFT;
202 		ppdu_info->rx_status.he_data6 |= value;
203 		return true;
204 	}
205 	default:
206 		return false;
207 	}
208 }
209 #else
210 static inline bool
211 hal_rx_handle_other_tlvs(uint32_t tlv_tag, void *rx_tlv,
212 			 struct hal_rx_ppdu_info *ppdu_info)
213 {
214 	return false;
215 }
216 #endif /* QCA_WIFI_QCA6290_11AX_MU_UL && QCA_WIFI_QCA6290_11AX */
217 
218 #if defined(RX_PPDU_END_USER_STATS_1_OFDMA_INFO_VALID_OFFSET) && \
219 defined(RX_PPDU_END_USER_STATS_22_SW_RESPONSE_REFERENCE_PTR_EXT_OFFSET)
220 
221 static inline void
222 hal_rx_handle_mu_ul_info(
223 	void *rx_tlv,
224 	struct mon_rx_user_status *mon_rx_user_status)
225 {
226 	mon_rx_user_status->mu_ul_user_v0_word0 =
227 		HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_11,
228 			   SW_RESPONSE_REFERENCE_PTR);
229 
230 	mon_rx_user_status->mu_ul_user_v0_word1 =
231 		HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_22,
232 			   SW_RESPONSE_REFERENCE_PTR_EXT);
233 }
234 
235 static inline void
236 hal_rx_populate_byte_count(void *rx_tlv, void *ppduinfo,
237 			   struct mon_rx_user_status *mon_rx_user_status)
238 {
239 	uint32_t mpdu_ok_byte_count;
240 	uint32_t mpdu_err_byte_count;
241 
242 	mpdu_ok_byte_count = HAL_RX_GET(rx_tlv,
243 					RX_PPDU_END_USER_STATS_17,
244 					MPDU_OK_BYTE_COUNT);
245 	mpdu_err_byte_count = HAL_RX_GET(rx_tlv,
246 					 RX_PPDU_END_USER_STATS_19,
247 					 MPDU_ERR_BYTE_COUNT);
248 
249 	mon_rx_user_status->mpdu_ok_byte_count = mpdu_ok_byte_count;
250 	mon_rx_user_status->mpdu_err_byte_count = mpdu_err_byte_count;
251 }
252 #else
253 static inline void
254 hal_rx_handle_mu_ul_info(void *rx_tlv,
255 			 struct mon_rx_user_status *mon_rx_user_status)
256 {
257 }
258 
259 static inline void
260 hal_rx_populate_byte_count(void *rx_tlv, void *ppduinfo,
261 			   struct mon_rx_user_status *mon_rx_user_status)
262 {
263 	struct hal_rx_ppdu_info *ppdu_info =
264 			(struct hal_rx_ppdu_info *)ppduinfo;
265 
266 	/* HKV1: doesn't support mpdu byte count */
267 	mon_rx_user_status->mpdu_ok_byte_count = ppdu_info->rx_status.ppdu_len;
268 	mon_rx_user_status->mpdu_err_byte_count = 0;
269 }
270 #endif
271 
272 static inline void
273 hal_rx_populate_mu_user_info(void *rx_tlv, void *ppduinfo,
274 			     struct mon_rx_user_status *mon_rx_user_status)
275 {
276 	struct hal_rx_ppdu_info *ppdu_info =
277 			(struct hal_rx_ppdu_info *)ppduinfo;
278 
279 	mon_rx_user_status->ast_index = ppdu_info->rx_status.ast_index;
280 	mon_rx_user_status->tid = ppdu_info->rx_status.tid;
281 	mon_rx_user_status->tcp_msdu_count =
282 		ppdu_info->rx_status.tcp_msdu_count;
283 	mon_rx_user_status->udp_msdu_count =
284 		ppdu_info->rx_status.udp_msdu_count;
285 	mon_rx_user_status->other_msdu_count =
286 		ppdu_info->rx_status.other_msdu_count;
287 	mon_rx_user_status->frame_control = ppdu_info->rx_status.frame_control;
288 	mon_rx_user_status->frame_control_info_valid =
289 		ppdu_info->rx_status.frame_control_info_valid;
290 	mon_rx_user_status->data_sequence_control_info_valid =
291 		ppdu_info->rx_status.data_sequence_control_info_valid;
292 	mon_rx_user_status->first_data_seq_ctrl =
293 		ppdu_info->rx_status.first_data_seq_ctrl;
294 	mon_rx_user_status->preamble_type = ppdu_info->rx_status.preamble_type;
295 	mon_rx_user_status->ht_flags = ppdu_info->rx_status.ht_flags;
296 	mon_rx_user_status->rtap_flags = ppdu_info->rx_status.rtap_flags;
297 	mon_rx_user_status->vht_flags = ppdu_info->rx_status.vht_flags;
298 	mon_rx_user_status->he_flags = ppdu_info->rx_status.he_flags;
299 	mon_rx_user_status->rs_flags = ppdu_info->rx_status.rs_flags;
300 
301 	mon_rx_user_status->mpdu_cnt_fcs_ok =
302 		ppdu_info->com_info.mpdu_cnt_fcs_ok;
303 	mon_rx_user_status->mpdu_cnt_fcs_err =
304 		ppdu_info->com_info.mpdu_cnt_fcs_err;
305 	qdf_mem_copy(&mon_rx_user_status->mpdu_fcs_ok_bitmap,
306 		     &ppdu_info->com_info.mpdu_fcs_ok_bitmap,
307 		     HAL_RX_NUM_WORDS_PER_PPDU_BITMAP *
308 		     sizeof(ppdu_info->com_info.mpdu_fcs_ok_bitmap[0]));
309 
310 	hal_rx_populate_byte_count(rx_tlv, ppdu_info, mon_rx_user_status);
311 }
312 
313 #define HAL_RX_UPDATE_RSSI_PER_CHAIN_BW(chain, word_1, word_2, \
314 					ppdu_info, rssi_info_tlv) \
315 	{						\
316 	ppdu_info->rx_status.rssi_chain[chain][0] = \
317 			HAL_RX_GET(rssi_info_tlv, RECEIVE_RSSI_INFO_##word_1,\
318 				   RSSI_PRI20_CHAIN##chain); \
319 	ppdu_info->rx_status.rssi_chain[chain][1] = \
320 			HAL_RX_GET(rssi_info_tlv, RECEIVE_RSSI_INFO_##word_1,\
321 				   RSSI_EXT20_CHAIN##chain); \
322 	ppdu_info->rx_status.rssi_chain[chain][2] = \
323 			HAL_RX_GET(rssi_info_tlv, RECEIVE_RSSI_INFO_##word_1,\
324 				   RSSI_EXT40_LOW20_CHAIN##chain); \
325 	ppdu_info->rx_status.rssi_chain[chain][3] = \
326 			HAL_RX_GET(rssi_info_tlv, RECEIVE_RSSI_INFO_##word_1,\
327 				   RSSI_EXT40_HIGH20_CHAIN##chain); \
328 	ppdu_info->rx_status.rssi_chain[chain][4] = \
329 			HAL_RX_GET(rssi_info_tlv, RECEIVE_RSSI_INFO_##word_2,\
330 				   RSSI_EXT80_LOW20_CHAIN##chain); \
331 	ppdu_info->rx_status.rssi_chain[chain][5] = \
332 			HAL_RX_GET(rssi_info_tlv, RECEIVE_RSSI_INFO_##word_2,\
333 				   RSSI_EXT80_LOW_HIGH20_CHAIN##chain); \
334 	ppdu_info->rx_status.rssi_chain[chain][6] = \
335 			HAL_RX_GET(rssi_info_tlv, RECEIVE_RSSI_INFO_##word_2,\
336 				   RSSI_EXT80_HIGH_LOW20_CHAIN##chain); \
337 	ppdu_info->rx_status.rssi_chain[chain][7] = \
338 			HAL_RX_GET(rssi_info_tlv, RECEIVE_RSSI_INFO_##word_2,\
339 				   RSSI_EXT80_HIGH20_CHAIN##chain); \
340 	}						\
341 
342 #define HAL_RX_PPDU_UPDATE_RSSI(ppdu_info, rssi_info_tlv) \
343 	{HAL_RX_UPDATE_RSSI_PER_CHAIN_BW(0, 0, 1, ppdu_info, rssi_info_tlv) \
344 	HAL_RX_UPDATE_RSSI_PER_CHAIN_BW(1, 2, 3, ppdu_info, rssi_info_tlv) \
345 	HAL_RX_UPDATE_RSSI_PER_CHAIN_BW(2, 4, 5, ppdu_info, rssi_info_tlv) \
346 	HAL_RX_UPDATE_RSSI_PER_CHAIN_BW(3, 6, 7, ppdu_info, rssi_info_tlv) \
347 	HAL_RX_UPDATE_RSSI_PER_CHAIN_BW(4, 8, 9, ppdu_info, rssi_info_tlv) \
348 	HAL_RX_UPDATE_RSSI_PER_CHAIN_BW(5, 10, 11, ppdu_info, rssi_info_tlv) \
349 	HAL_RX_UPDATE_RSSI_PER_CHAIN_BW(6, 12, 13, ppdu_info, rssi_info_tlv) \
350 	HAL_RX_UPDATE_RSSI_PER_CHAIN_BW(7, 14, 15, ppdu_info, rssi_info_tlv)} \
351 
352 static inline uint32_t
353 hal_rx_update_rssi_chain(struct hal_rx_ppdu_info *ppdu_info,
354 			 uint8_t *rssi_info_tlv)
355 {
356 	HAL_RX_PPDU_UPDATE_RSSI(ppdu_info, rssi_info_tlv)
357 	return 0;
358 }
359 
360 /**
361  * hal_rx_status_get_tlv_info() - process receive info TLV
362  * @rx_tlv_hdr: pointer to TLV header
363  * @ppdu_info: pointer to ppdu_info
364  *
365  * Return: HAL_TLV_STATUS_PPDU_NOT_DONE or HAL_TLV_STATUS_PPDU_DONE from tlv
366  */
367 static inline uint32_t
368 hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo,
369 				   hal_soc_handle_t hal_soc_hdl,
370 				   qdf_nbuf_t nbuf)
371 {
372 	struct hal_soc *hal = (struct hal_soc *)hal_soc_hdl;
373 	uint32_t tlv_tag, user_id, tlv_len, value;
374 	uint8_t group_id = 0;
375 	uint8_t he_dcm = 0;
376 	uint8_t he_stbc = 0;
377 	uint16_t he_gi = 0;
378 	uint16_t he_ltf = 0;
379 	void *rx_tlv;
380 	bool unhandled = false;
381 	struct mon_rx_user_status *mon_rx_user_status;
382 	struct hal_rx_ppdu_info *ppdu_info =
383 			(struct hal_rx_ppdu_info *)ppduinfo;
384 
385 	tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv_hdr);
386 	user_id = HAL_RX_GET_USER_TLV32_USERID(rx_tlv_hdr);
387 	tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv_hdr);
388 
389 	rx_tlv = (uint8_t *)rx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE;
390 
391 	qdf_trace_hex_dump(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
392 			   rx_tlv, tlv_len);
393 
394 	switch (tlv_tag) {
395 
396 	case WIFIRX_PPDU_START_E:
397 	{
398 		struct hal_rx_ppdu_common_info *com_info = &ppdu_info->com_info;
399 
400 		ppdu_info->com_info.ppdu_id =
401 			HAL_RX_GET(rx_tlv, RX_PPDU_START_0,
402 				PHY_PPDU_ID);
403 		/* channel number is set in PHY meta data */
404 		ppdu_info->rx_status.chan_num =
405 			HAL_RX_GET(rx_tlv, RX_PPDU_START_1,
406 				SW_PHY_META_DATA);
407 		ppdu_info->com_info.ppdu_timestamp =
408 			HAL_RX_GET(rx_tlv, RX_PPDU_START_2,
409 				PPDU_START_TIMESTAMP);
410 		ppdu_info->rx_status.ppdu_timestamp =
411 			ppdu_info->com_info.ppdu_timestamp;
412 		ppdu_info->rx_state = HAL_RX_MON_PPDU_START;
413 
414 		/* If last ppdu_id doesn't match new ppdu_id,
415 		 * 1. reset mpdu_cnt
416 		 * 2. update last_ppdu_id with new
417 		 * 3. reset mpdu fcs bitmap
418 		 */
419 		if (com_info->ppdu_id != com_info->last_ppdu_id) {
420 			com_info->mpdu_cnt = 0;
421 			com_info->last_ppdu_id =
422 				com_info->ppdu_id;
423 			com_info->num_users = 0;
424 			qdf_mem_zero(&com_info->mpdu_fcs_ok_bitmap,
425 				     HAL_RX_NUM_WORDS_PER_PPDU_BITMAP *
426 				     sizeof(com_info->mpdu_fcs_ok_bitmap[0]));
427 		}
428 		break;
429 	}
430 
431 	case WIFIRX_PPDU_START_USER_INFO_E:
432 		break;
433 
434 	case WIFIRX_PPDU_END_E:
435 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
436 			"[%s][%d] ppdu_end_e len=%d",
437 				__func__, __LINE__, tlv_len);
438 		/* This is followed by sub-TLVs of PPDU_END */
439 		ppdu_info->rx_state = HAL_RX_MON_PPDU_END;
440 		break;
441 
442 	case WIFIRXPCU_PPDU_END_INFO_E:
443 		ppdu_info->rx_status.rx_antenna =
444 			HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_2, RX_ANTENNA);
445 		ppdu_info->rx_status.tsft =
446 			HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_1,
447 				WB_TIMESTAMP_UPPER_32);
448 		ppdu_info->rx_status.tsft = (ppdu_info->rx_status.tsft << 32) |
449 			HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_0,
450 				WB_TIMESTAMP_LOWER_32);
451 		ppdu_info->rx_status.duration =
452 			HAL_RX_GET(rx_tlv, UNIFIED_RXPCU_PPDU_END_INFO_8,
453 				RX_PPDU_DURATION);
454 		break;
455 
456 	/*
457 	 * WIFIRX_PPDU_END_USER_STATS_E comes for each user received.
458 	 * for MU, based on num users we see this tlv that many times.
459 	 */
460 	case WIFIRX_PPDU_END_USER_STATS_E:
461 	{
462 		unsigned long tid = 0;
463 		uint16_t seq = 0;
464 
465 		ppdu_info->rx_status.ast_index =
466 				HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_4,
467 						AST_INDEX);
468 
469 		tid = HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_12,
470 				RECEIVED_QOS_DATA_TID_BITMAP);
471 		ppdu_info->rx_status.tid = qdf_find_first_bit(&tid, sizeof(tid)*8);
472 
473 		if (ppdu_info->rx_status.tid == (sizeof(tid) * 8))
474 			ppdu_info->rx_status.tid = HAL_TID_INVALID;
475 
476 		ppdu_info->rx_status.tcp_msdu_count =
477 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_9,
478 					TCP_MSDU_COUNT) +
479 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_10,
480 					TCP_ACK_MSDU_COUNT);
481 		ppdu_info->rx_status.udp_msdu_count =
482 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_9,
483 						UDP_MSDU_COUNT);
484 		ppdu_info->rx_status.other_msdu_count =
485 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_10,
486 					OTHER_MSDU_COUNT);
487 
488 		if (ppdu_info->sw_frame_group_id
489 		    != HAL_MPDU_SW_FRAME_GROUP_NULL_DATA) {
490 			ppdu_info->rx_status.frame_control_info_valid =
491 				HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3,
492 					   FRAME_CONTROL_INFO_VALID);
493 
494 			if (ppdu_info->rx_status.frame_control_info_valid)
495 				ppdu_info->rx_status.frame_control =
496 					HAL_RX_GET(rx_tlv,
497 						   RX_PPDU_END_USER_STATS_4,
498 						   FRAME_CONTROL_FIELD);
499 		}
500 
501 		ppdu_info->rx_status.data_sequence_control_info_valid =
502 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3,
503 				   DATA_SEQUENCE_CONTROL_INFO_VALID);
504 
505 		seq = HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_5,
506 				 FIRST_DATA_SEQ_CTRL);
507 		if (ppdu_info->rx_status.data_sequence_control_info_valid)
508 			ppdu_info->rx_status.first_data_seq_ctrl = seq;
509 
510 		ppdu_info->rx_status.preamble_type =
511 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3,
512 						HT_CONTROL_FIELD_PKT_TYPE);
513 		switch (ppdu_info->rx_status.preamble_type) {
514 		case HAL_RX_PKT_TYPE_11N:
515 			ppdu_info->rx_status.ht_flags = 1;
516 			ppdu_info->rx_status.rtap_flags |= HT_SGI_PRESENT;
517 			break;
518 		case HAL_RX_PKT_TYPE_11AC:
519 			ppdu_info->rx_status.vht_flags = 1;
520 			break;
521 		case HAL_RX_PKT_TYPE_11AX:
522 			ppdu_info->rx_status.he_flags = 1;
523 			break;
524 		default:
525 			break;
526 		}
527 
528 		ppdu_info->com_info.mpdu_cnt_fcs_ok =
529 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3,
530 					MPDU_CNT_FCS_OK);
531 		ppdu_info->com_info.mpdu_cnt_fcs_err =
532 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_2,
533 					MPDU_CNT_FCS_ERR);
534 		if ((ppdu_info->com_info.mpdu_cnt_fcs_ok |
535 			ppdu_info->com_info.mpdu_cnt_fcs_err) > 1)
536 			ppdu_info->rx_status.rs_flags |= IEEE80211_AMPDU_FLAG;
537 		else
538 			ppdu_info->rx_status.rs_flags &=
539 				(~IEEE80211_AMPDU_FLAG);
540 
541 		ppdu_info->com_info.mpdu_fcs_ok_bitmap[0] =
542 				HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_7,
543 					   FCS_OK_BITMAP_31_0);
544 
545 		ppdu_info->com_info.mpdu_fcs_ok_bitmap[1] =
546 				HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_8,
547 					   FCS_OK_BITMAP_63_32);
548 
549 		if (user_id < HAL_MAX_UL_MU_USERS) {
550 			mon_rx_user_status =
551 				&ppdu_info->rx_user_status[user_id];
552 
553 			hal_rx_handle_mu_ul_info(rx_tlv, mon_rx_user_status);
554 
555 			ppdu_info->com_info.num_users++;
556 
557 			hal_rx_populate_mu_user_info(rx_tlv, ppdu_info,
558 						     mon_rx_user_status);
559 		}
560 		break;
561 	}
562 
563 	case WIFIRX_PPDU_END_USER_STATS_EXT_E:
564 		ppdu_info->com_info.mpdu_fcs_ok_bitmap[2] =
565 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_EXT_1,
566 				   FCS_OK_BITMAP_95_64);
567 
568 		ppdu_info->com_info.mpdu_fcs_ok_bitmap[3] =
569 			 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_EXT_2,
570 				    FCS_OK_BITMAP_127_96);
571 
572 		ppdu_info->com_info.mpdu_fcs_ok_bitmap[4] =
573 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_EXT_3,
574 				   FCS_OK_BITMAP_159_128);
575 
576 		ppdu_info->com_info.mpdu_fcs_ok_bitmap[5] =
577 			 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_EXT_4,
578 				    FCS_OK_BITMAP_191_160);
579 
580 		ppdu_info->com_info.mpdu_fcs_ok_bitmap[6] =
581 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_EXT_5,
582 				   FCS_OK_BITMAP_223_192);
583 
584 		ppdu_info->com_info.mpdu_fcs_ok_bitmap[7] =
585 			 HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_EXT_6,
586 				    FCS_OK_BITMAP_255_224);
587 		break;
588 
589 	case WIFIRX_PPDU_END_STATUS_DONE_E:
590 		return HAL_TLV_STATUS_PPDU_DONE;
591 
592 	case WIFIDUMMY_E:
593 		return HAL_TLV_STATUS_BUF_DONE;
594 
595 	case WIFIPHYRX_HT_SIG_E:
596 	{
597 		uint8_t *ht_sig_info = (uint8_t *)rx_tlv +
598 				HAL_RX_OFFSET(UNIFIED_PHYRX_HT_SIG_0,
599 				HT_SIG_INFO_PHYRX_HT_SIG_INFO_DETAILS);
600 		value = HAL_RX_GET(ht_sig_info, HT_SIG_INFO_1,
601 				FEC_CODING);
602 		ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ?
603 			1 : 0;
604 		ppdu_info->rx_status.mcs = HAL_RX_GET(ht_sig_info,
605 				HT_SIG_INFO_0, MCS);
606 		ppdu_info->rx_status.ht_mcs = ppdu_info->rx_status.mcs;
607 		ppdu_info->rx_status.bw = HAL_RX_GET(ht_sig_info,
608 				HT_SIG_INFO_0, CBW);
609 		ppdu_info->rx_status.sgi = HAL_RX_GET(ht_sig_info,
610 				HT_SIG_INFO_1, SHORT_GI);
611 		ppdu_info->rx_status.reception_type = HAL_RX_TYPE_SU;
612 		ppdu_info->rx_status.nss = ((ppdu_info->rx_status.mcs) >>
613 				HT_SIG_SU_NSS_SHIFT) + 1;
614 		ppdu_info->rx_status.mcs &= ((1 << HT_SIG_SU_NSS_SHIFT) - 1);
615 		break;
616 	}
617 
618 	case WIFIPHYRX_L_SIG_B_E:
619 	{
620 		uint8_t *l_sig_b_info = (uint8_t *)rx_tlv +
621 				HAL_RX_OFFSET(UNIFIED_PHYRX_L_SIG_B_0,
622 				L_SIG_B_INFO_PHYRX_L_SIG_B_INFO_DETAILS);
623 
624 		value = HAL_RX_GET(l_sig_b_info, L_SIG_B_INFO_0, RATE);
625 		ppdu_info->rx_status.l_sig_b_info = *((uint32_t *)l_sig_b_info);
626 		switch (value) {
627 		case 1:
628 			ppdu_info->rx_status.rate = HAL_11B_RATE_3MCS;
629 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS3;
630 			break;
631 		case 2:
632 			ppdu_info->rx_status.rate = HAL_11B_RATE_2MCS;
633 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS2;
634 			break;
635 		case 3:
636 			ppdu_info->rx_status.rate = HAL_11B_RATE_1MCS;
637 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS1;
638 			break;
639 		case 4:
640 			ppdu_info->rx_status.rate = HAL_11B_RATE_0MCS;
641 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS0;
642 			break;
643 		case 5:
644 			ppdu_info->rx_status.rate = HAL_11B_RATE_6MCS;
645 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS6;
646 			break;
647 		case 6:
648 			ppdu_info->rx_status.rate = HAL_11B_RATE_5MCS;
649 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS5;
650 			break;
651 		case 7:
652 			ppdu_info->rx_status.rate = HAL_11B_RATE_4MCS;
653 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS4;
654 			break;
655 		default:
656 			break;
657 		}
658 		ppdu_info->rx_status.cck_flag = 1;
659 		ppdu_info->rx_status.reception_type = HAL_RX_TYPE_SU;
660 	break;
661 	}
662 
663 	case WIFIPHYRX_L_SIG_A_E:
664 	{
665 		uint8_t *l_sig_a_info = (uint8_t *)rx_tlv +
666 				HAL_RX_OFFSET(UNIFIED_PHYRX_L_SIG_A_0,
667 				L_SIG_A_INFO_PHYRX_L_SIG_A_INFO_DETAILS);
668 
669 		value = HAL_RX_GET(l_sig_a_info, L_SIG_A_INFO_0, RATE);
670 		ppdu_info->rx_status.l_sig_a_info = *((uint32_t *)l_sig_a_info);
671 		switch (value) {
672 		case 8:
673 			ppdu_info->rx_status.rate = HAL_11A_RATE_0MCS;
674 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS0;
675 			break;
676 		case 9:
677 			ppdu_info->rx_status.rate = HAL_11A_RATE_1MCS;
678 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS1;
679 			break;
680 		case 10:
681 			ppdu_info->rx_status.rate = HAL_11A_RATE_2MCS;
682 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS2;
683 			break;
684 		case 11:
685 			ppdu_info->rx_status.rate = HAL_11A_RATE_3MCS;
686 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS3;
687 			break;
688 		case 12:
689 			ppdu_info->rx_status.rate = HAL_11A_RATE_4MCS;
690 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS4;
691 			break;
692 		case 13:
693 			ppdu_info->rx_status.rate = HAL_11A_RATE_5MCS;
694 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS5;
695 			break;
696 		case 14:
697 			ppdu_info->rx_status.rate = HAL_11A_RATE_6MCS;
698 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS6;
699 			break;
700 		case 15:
701 			ppdu_info->rx_status.rate = HAL_11A_RATE_7MCS;
702 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS7;
703 			break;
704 		default:
705 			break;
706 		}
707 		ppdu_info->rx_status.ofdm_flag = 1;
708 		ppdu_info->rx_status.reception_type = HAL_RX_TYPE_SU;
709 	break;
710 	}
711 
712 	case WIFIPHYRX_VHT_SIG_A_E:
713 	{
714 		uint8_t *vht_sig_a_info = (uint8_t *)rx_tlv +
715 				HAL_RX_OFFSET(UNIFIED_PHYRX_VHT_SIG_A_0,
716 				VHT_SIG_A_INFO_PHYRX_VHT_SIG_A_INFO_DETAILS);
717 
718 		value = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_1,
719 				SU_MU_CODING);
720 		ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ?
721 			1 : 0;
722 		group_id = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_0, GROUP_ID);
723 		ppdu_info->rx_status.vht_flag_values5 = group_id;
724 		ppdu_info->rx_status.mcs = HAL_RX_GET(vht_sig_a_info,
725 				VHT_SIG_A_INFO_1, MCS);
726 		ppdu_info->rx_status.sgi = HAL_RX_GET(vht_sig_a_info,
727 				VHT_SIG_A_INFO_1, GI_SETTING);
728 
729 		switch (hal->target_type) {
730 		case TARGET_TYPE_QCA8074:
731 		case TARGET_TYPE_QCA8074V2:
732 		case TARGET_TYPE_QCA6018:
733 		case TARGET_TYPE_QCN9000:
734 #ifdef QCA_WIFI_QCA6390
735 		case TARGET_TYPE_QCA6390:
736 #endif
737 			ppdu_info->rx_status.is_stbc =
738 				HAL_RX_GET(vht_sig_a_info,
739 					   VHT_SIG_A_INFO_0, STBC);
740 			value =  HAL_RX_GET(vht_sig_a_info,
741 					    VHT_SIG_A_INFO_0, N_STS);
742 			value = value & VHT_SIG_SU_NSS_MASK;
743 			if (ppdu_info->rx_status.is_stbc && (value > 0))
744 				value = ((value + 1) >> 1) - 1;
745 			ppdu_info->rx_status.nss =
746 				((value & VHT_SIG_SU_NSS_MASK) + 1);
747 
748 			break;
749 		case TARGET_TYPE_QCA6290:
750 #if !defined(QCA_WIFI_QCA6290_11AX)
751 			ppdu_info->rx_status.is_stbc =
752 				HAL_RX_GET(vht_sig_a_info,
753 					   VHT_SIG_A_INFO_0, STBC);
754 			value =  HAL_RX_GET(vht_sig_a_info,
755 					    VHT_SIG_A_INFO_0, N_STS);
756 			value = value & VHT_SIG_SU_NSS_MASK;
757 			if (ppdu_info->rx_status.is_stbc && (value > 0))
758 				value = ((value + 1) >> 1) - 1;
759 			ppdu_info->rx_status.nss =
760 				((value & VHT_SIG_SU_NSS_MASK) + 1);
761 #else
762 			ppdu_info->rx_status.nss = 0;
763 #endif
764 			break;
765 		case TARGET_TYPE_QCA6490:
766 			ppdu_info->rx_status.nss = 0;
767 			break;
768 		default:
769 			break;
770 		}
771 		ppdu_info->rx_status.vht_flag_values3[0] =
772 				(((ppdu_info->rx_status.mcs) << 4)
773 				| ppdu_info->rx_status.nss);
774 		ppdu_info->rx_status.bw = HAL_RX_GET(vht_sig_a_info,
775 				VHT_SIG_A_INFO_0, BANDWIDTH);
776 		ppdu_info->rx_status.vht_flag_values2 =
777 			ppdu_info->rx_status.bw;
778 		ppdu_info->rx_status.vht_flag_values4 =
779 			HAL_RX_GET(vht_sig_a_info,
780 				  VHT_SIG_A_INFO_1, SU_MU_CODING);
781 
782 		ppdu_info->rx_status.beamformed = HAL_RX_GET(vht_sig_a_info,
783 				VHT_SIG_A_INFO_1, BEAMFORMED);
784 		if (group_id == 0 || group_id == 63)
785 			ppdu_info->rx_status.reception_type = HAL_RX_TYPE_SU;
786 		else
787 			ppdu_info->rx_status.reception_type =
788 				HAL_RX_TYPE_MU_MIMO;
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(UNIFIED_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 		ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ?
859 			1 : 0;
860 		value = value << QDF_MON_STATUS_CODING_SHIFT;
861 		ppdu_info->rx_status.he_data3 |= value;
862 		value = HAL_RX_GET(he_sig_a_su_info,
863 				HE_SIG_A_SU_INFO_1,
864 				LDPC_EXTRA_SYMBOL);
865 		value = value << QDF_MON_STATUS_LDPC_EXTRA_SYMBOL_SHIFT;
866 		ppdu_info->rx_status.he_data3 |= value;
867 		value = HAL_RX_GET(he_sig_a_su_info,
868 				HE_SIG_A_SU_INFO_1, STBC);
869 		he_stbc = value;
870 		value = value << QDF_MON_STATUS_STBC_SHIFT;
871 		ppdu_info->rx_status.he_data3 |= value;
872 
873 		/* data4 */
874 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0,
875 							SPATIAL_REUSE);
876 		ppdu_info->rx_status.he_data4 = value;
877 
878 		/* data5 */
879 		value = HAL_RX_GET(he_sig_a_su_info,
880 				HE_SIG_A_SU_INFO_0, TRANSMIT_BW);
881 		ppdu_info->rx_status.he_data5 = value;
882 		ppdu_info->rx_status.bw = value;
883 		value = HAL_RX_GET(he_sig_a_su_info,
884 				HE_SIG_A_SU_INFO_0, CP_LTF_SIZE);
885 		switch (value) {
886 		case 0:
887 				he_gi = HE_GI_0_8;
888 				he_ltf = HE_LTF_1_X;
889 				break;
890 		case 1:
891 				he_gi = HE_GI_0_8;
892 				he_ltf = HE_LTF_2_X;
893 				break;
894 		case 2:
895 				he_gi = HE_GI_1_6;
896 				he_ltf = HE_LTF_2_X;
897 				break;
898 		case 3:
899 				if (he_dcm && he_stbc) {
900 					he_gi = HE_GI_0_8;
901 					he_ltf = HE_LTF_4_X;
902 				} else {
903 					he_gi = HE_GI_3_2;
904 					he_ltf = HE_LTF_4_X;
905 				}
906 				break;
907 		}
908 		ppdu_info->rx_status.sgi = he_gi;
909 		value = he_gi << QDF_MON_STATUS_GI_SHIFT;
910 		ppdu_info->rx_status.he_data5 |= value;
911 		value = he_ltf << QDF_MON_STATUS_HE_LTF_SIZE_SHIFT;
912 		ppdu_info->rx_status.ltf_size = he_ltf;
913 		ppdu_info->rx_status.he_data5 |= value;
914 
915 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0, NSTS);
916 		value = (value << QDF_MON_STATUS_HE_LTF_SYM_SHIFT);
917 		ppdu_info->rx_status.he_data5 |= value;
918 
919 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1,
920 						PACKET_EXTENSION_A_FACTOR);
921 		value = value << QDF_MON_STATUS_PRE_FEC_PAD_SHIFT;
922 		ppdu_info->rx_status.he_data5 |= value;
923 
924 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1, TXBF);
925 		value = value << QDF_MON_STATUS_TXBF_SHIFT;
926 		ppdu_info->rx_status.he_data5 |= value;
927 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1,
928 					PACKET_EXTENSION_PE_DISAMBIGUITY);
929 		value = value << QDF_MON_STATUS_PE_DISAMBIGUITY_SHIFT;
930 		ppdu_info->rx_status.he_data5 |= value;
931 
932 		/* data6 */
933 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0, NSTS);
934 		value++;
935 		ppdu_info->rx_status.nss = value;
936 		ppdu_info->rx_status.he_data6 = value;
937 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1,
938 							DOPPLER_INDICATION);
939 		value = value << QDF_MON_STATUS_DOPPLER_SHIFT;
940 		ppdu_info->rx_status.he_data6 |= value;
941 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1,
942 							TXOP_DURATION);
943 		value = value << QDF_MON_STATUS_TXOP_SHIFT;
944 		ppdu_info->rx_status.he_data6 |= value;
945 
946 		ppdu_info->rx_status.beamformed = HAL_RX_GET(he_sig_a_su_info,
947 					HE_SIG_A_SU_INFO_1, TXBF);
948 		ppdu_info->rx_status.reception_type = HAL_RX_TYPE_SU;
949 		break;
950 	}
951 	case WIFIPHYRX_HE_SIG_A_MU_DL_E:
952 	{
953 		uint8_t *he_sig_a_mu_dl_info = (uint8_t *)rx_tlv +
954 			HAL_RX_OFFSET(UNIFIED_PHYRX_HE_SIG_A_MU_DL_0,
955 			HE_SIG_A_MU_DL_INFO_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS);
956 
957 		ppdu_info->rx_status.he_mu_flags = 1;
958 
959 		/* HE Flags */
960 		/*data1*/
961 		ppdu_info->rx_status.he_data1 =
962 					QDF_MON_STATUS_HE_MU_FORMAT_TYPE;
963 		ppdu_info->rx_status.he_data1 |=
964 			QDF_MON_STATUS_HE_BSS_COLOR_KNOWN |
965 			QDF_MON_STATUS_HE_DL_UL_KNOWN |
966 			QDF_MON_STATUS_HE_LDPC_EXTRA_SYMBOL_KNOWN |
967 			QDF_MON_STATUS_HE_STBC_KNOWN |
968 			QDF_MON_STATUS_HE_DATA_BW_RU_KNOWN |
969 			QDF_MON_STATUS_HE_DOPPLER_KNOWN;
970 
971 		/* data2 */
972 		ppdu_info->rx_status.he_data2 =
973 			QDF_MON_STATUS_HE_GI_KNOWN;
974 		ppdu_info->rx_status.he_data2 |=
975 			QDF_MON_STATUS_LTF_SYMBOLS_KNOWN |
976 			QDF_MON_STATUS_PRE_FEC_PADDING_KNOWN |
977 			QDF_MON_STATUS_PE_DISAMBIGUITY_KNOWN |
978 			QDF_MON_STATUS_TXOP_KNOWN |
979 			QDF_MON_STATUS_MIDABLE_PERIODICITY_KNOWN;
980 
981 		/*data3*/
982 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
983 				HE_SIG_A_MU_DL_INFO_0, BSS_COLOR_ID);
984 		ppdu_info->rx_status.he_data3 = value;
985 
986 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
987 				HE_SIG_A_MU_DL_INFO_0, DL_UL_FLAG);
988 		value = value << QDF_MON_STATUS_DL_UL_SHIFT;
989 		ppdu_info->rx_status.he_data3 |= value;
990 
991 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
992 				HE_SIG_A_MU_DL_INFO_1,
993 				LDPC_EXTRA_SYMBOL);
994 		value = value << QDF_MON_STATUS_LDPC_EXTRA_SYMBOL_SHIFT;
995 		ppdu_info->rx_status.he_data3 |= value;
996 
997 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
998 				HE_SIG_A_MU_DL_INFO_1, STBC);
999 		he_stbc = value;
1000 		value = value << QDF_MON_STATUS_STBC_SHIFT;
1001 		ppdu_info->rx_status.he_data3 |= value;
1002 
1003 		/*data4*/
1004 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_0,
1005 							SPATIAL_REUSE);
1006 		ppdu_info->rx_status.he_data4 = value;
1007 
1008 		/*data5*/
1009 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1010 				HE_SIG_A_MU_DL_INFO_0, TRANSMIT_BW);
1011 		ppdu_info->rx_status.he_data5 = value;
1012 		ppdu_info->rx_status.bw = value;
1013 
1014 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1015 				HE_SIG_A_MU_DL_INFO_0, CP_LTF_SIZE);
1016 		switch (value) {
1017 		case 0:
1018 			he_gi = HE_GI_0_8;
1019 			he_ltf = HE_LTF_4_X;
1020 			break;
1021 		case 1:
1022 			he_gi = HE_GI_0_8;
1023 			he_ltf = HE_LTF_2_X;
1024 			break;
1025 		case 2:
1026 			he_gi = HE_GI_1_6;
1027 			he_ltf = HE_LTF_2_X;
1028 			break;
1029 		case 3:
1030 			he_gi = HE_GI_3_2;
1031 			he_ltf = HE_LTF_4_X;
1032 			break;
1033 		}
1034 		ppdu_info->rx_status.sgi = he_gi;
1035 		value = he_gi << QDF_MON_STATUS_GI_SHIFT;
1036 		ppdu_info->rx_status.he_data5 |= value;
1037 
1038 		value = he_ltf << QDF_MON_STATUS_HE_LTF_SIZE_SHIFT;
1039 		ppdu_info->rx_status.he_data5 |= value;
1040 
1041 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1042 				   HE_SIG_A_MU_DL_INFO_1, NUM_LTF_SYMBOLS);
1043 		value = (value << QDF_MON_STATUS_HE_LTF_SYM_SHIFT);
1044 		ppdu_info->rx_status.he_data5 |= value;
1045 
1046 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_1,
1047 				   PACKET_EXTENSION_A_FACTOR);
1048 		value = value << QDF_MON_STATUS_PRE_FEC_PAD_SHIFT;
1049 		ppdu_info->rx_status.he_data5 |= value;
1050 
1051 
1052 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_1,
1053 				   PACKET_EXTENSION_PE_DISAMBIGUITY);
1054 		value = value << QDF_MON_STATUS_PE_DISAMBIGUITY_SHIFT;
1055 		ppdu_info->rx_status.he_data5 |= value;
1056 
1057 		/*data6*/
1058 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_0,
1059 							DOPPLER_INDICATION);
1060 		value = value << QDF_MON_STATUS_DOPPLER_SHIFT;
1061 		ppdu_info->rx_status.he_data6 |= value;
1062 
1063 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_1,
1064 							TXOP_DURATION);
1065 		value = value << QDF_MON_STATUS_TXOP_SHIFT;
1066 		ppdu_info->rx_status.he_data6 |= value;
1067 
1068 		/* HE-MU Flags */
1069 		/* HE-MU-flags1 */
1070 		ppdu_info->rx_status.he_flags1 =
1071 			QDF_MON_STATUS_SIG_B_MCS_KNOWN |
1072 			QDF_MON_STATUS_SIG_B_DCM_KNOWN |
1073 			QDF_MON_STATUS_SIG_B_COMPRESSION_FLAG_1_KNOWN |
1074 			QDF_MON_STATUS_SIG_B_SYM_NUM_KNOWN |
1075 			QDF_MON_STATUS_RU_0_KNOWN;
1076 
1077 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1078 				HE_SIG_A_MU_DL_INFO_0, MCS_OF_SIG_B);
1079 		ppdu_info->rx_status.he_flags1 |= value;
1080 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1081 				HE_SIG_A_MU_DL_INFO_0, DCM_OF_SIG_B);
1082 		value = value << QDF_MON_STATUS_DCM_FLAG_1_SHIFT;
1083 		ppdu_info->rx_status.he_flags1 |= value;
1084 
1085 		/* HE-MU-flags2 */
1086 		ppdu_info->rx_status.he_flags2 =
1087 			QDF_MON_STATUS_BW_KNOWN;
1088 
1089 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1090 				HE_SIG_A_MU_DL_INFO_0, TRANSMIT_BW);
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, COMP_MODE_SIG_B);
1094 		value = value << QDF_MON_STATUS_SIG_B_COMPRESSION_FLAG_2_SHIFT;
1095 		ppdu_info->rx_status.he_flags2 |= value;
1096 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
1097 				HE_SIG_A_MU_DL_INFO_0, NUM_SIG_B_SYMBOLS);
1098 		value = value - 1;
1099 		value = value << QDF_MON_STATUS_NUM_SIG_B_SYMBOLS_SHIFT;
1100 		ppdu_info->rx_status.he_flags2 |= value;
1101 		ppdu_info->rx_status.reception_type = HAL_RX_TYPE_MU_MIMO;
1102 		break;
1103 	}
1104 	case WIFIPHYRX_HE_SIG_B1_MU_E:
1105 	{
1106 
1107 		uint8_t *he_sig_b1_mu_info = (uint8_t *)rx_tlv +
1108 			HAL_RX_OFFSET(UNIFIED_PHYRX_HE_SIG_B1_MU_0,
1109 			HE_SIG_B1_MU_INFO_PHYRX_HE_SIG_B1_MU_INFO_DETAILS);
1110 
1111 		ppdu_info->rx_status.he_sig_b_common_known |=
1112 			QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0;
1113 		/* TODO: Check on the availability of other fields in
1114 		 * sig_b_common
1115 		 */
1116 
1117 		value = HAL_RX_GET(he_sig_b1_mu_info,
1118 				HE_SIG_B1_MU_INFO_0, RU_ALLOCATION);
1119 		ppdu_info->rx_status.he_RU[0] = value;
1120 		ppdu_info->rx_status.reception_type = HAL_RX_TYPE_MU_MIMO;
1121 		break;
1122 	}
1123 	case WIFIPHYRX_HE_SIG_B2_MU_E:
1124 	{
1125 		uint8_t *he_sig_b2_mu_info = (uint8_t *)rx_tlv +
1126 			HAL_RX_OFFSET(UNIFIED_PHYRX_HE_SIG_B2_MU_0,
1127 			HE_SIG_B2_MU_INFO_PHYRX_HE_SIG_B2_MU_INFO_DETAILS);
1128 		/*
1129 		 * Not all "HE" fields can be updated from
1130 		 * WIFIPHYRX_HE_SIG_A_MU_DL_E TLV. Use WIFIPHYRX_HE_SIG_B2_MU_E
1131 		 * to populate rest of the "HE" fields for MU scenarios.
1132 		 */
1133 
1134 		/* HE-data1 */
1135 		ppdu_info->rx_status.he_data1 |=
1136 			QDF_MON_STATUS_HE_MCS_KNOWN |
1137 			QDF_MON_STATUS_HE_CODING_KNOWN;
1138 
1139 		/* HE-data2 */
1140 
1141 		/* HE-data3 */
1142 		value = HAL_RX_GET(he_sig_b2_mu_info,
1143 				HE_SIG_B2_MU_INFO_0, STA_MCS);
1144 		ppdu_info->rx_status.mcs = value;
1145 		value = value << QDF_MON_STATUS_TRANSMIT_MCS_SHIFT;
1146 		ppdu_info->rx_status.he_data3 |= value;
1147 
1148 
1149 		value = HAL_RX_GET(he_sig_b2_mu_info,
1150 				HE_SIG_B2_MU_INFO_0, STA_CODING);
1151 		value = value << QDF_MON_STATUS_CODING_SHIFT;
1152 		ppdu_info->rx_status.he_data3 |= value;
1153 
1154 		/* HE-data4 */
1155 		value = HAL_RX_GET(he_sig_b2_mu_info,
1156 				HE_SIG_B2_MU_INFO_0, STA_ID);
1157 		value = value << QDF_MON_STATUS_STA_ID_SHIFT;
1158 		ppdu_info->rx_status.he_data4 |= value;
1159 
1160 		/* HE-data5 */
1161 
1162 		/* HE-data6 */
1163 		value = HAL_RX_GET(he_sig_b2_mu_info,
1164 				   HE_SIG_B2_MU_INFO_0, NSTS);
1165 		/* value n indicates n+1 spatial streams */
1166 		value++;
1167 		ppdu_info->rx_status.nss = value;
1168 		ppdu_info->rx_status.he_data6 |= value;
1169 
1170 		break;
1171 
1172 	}
1173 	case WIFIPHYRX_HE_SIG_B2_OFDMA_E:
1174 	{
1175 		uint8_t *he_sig_b2_ofdma_info =
1176 		(uint8_t *)rx_tlv +
1177 		HAL_RX_OFFSET(UNIFIED_PHYRX_HE_SIG_B2_OFDMA_0,
1178 		HE_SIG_B2_OFDMA_INFO_PHYRX_HE_SIG_B2_OFDMA_INFO_DETAILS);
1179 
1180 		/*
1181 		 * Not all "HE" fields can be updated from
1182 		 * WIFIPHYRX_HE_SIG_A_MU_DL_E TLV. Use WIFIPHYRX_HE_SIG_B2_MU_E
1183 		 * to populate rest of "HE" fields for MU OFDMA scenarios.
1184 		 */
1185 
1186 		/* HE-data1 */
1187 		ppdu_info->rx_status.he_data1 |=
1188 			QDF_MON_STATUS_HE_MCS_KNOWN |
1189 			QDF_MON_STATUS_HE_DCM_KNOWN |
1190 			QDF_MON_STATUS_HE_CODING_KNOWN;
1191 
1192 		/* HE-data2 */
1193 		ppdu_info->rx_status.he_data2 |=
1194 					QDF_MON_STATUS_TXBF_KNOWN;
1195 
1196 		/* HE-data3 */
1197 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
1198 				HE_SIG_B2_OFDMA_INFO_0, STA_MCS);
1199 		ppdu_info->rx_status.mcs = value;
1200 		value = value << QDF_MON_STATUS_TRANSMIT_MCS_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_DCM);
1205 		he_dcm = value;
1206 		value = value << QDF_MON_STATUS_DCM_SHIFT;
1207 		ppdu_info->rx_status.he_data3 |= value;
1208 
1209 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
1210 				HE_SIG_B2_OFDMA_INFO_0, STA_CODING);
1211 		value = value << QDF_MON_STATUS_CODING_SHIFT;
1212 		ppdu_info->rx_status.he_data3 |= value;
1213 
1214 		/* HE-data4 */
1215 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
1216 				HE_SIG_B2_OFDMA_INFO_0, STA_ID);
1217 		value = value << QDF_MON_STATUS_STA_ID_SHIFT;
1218 		ppdu_info->rx_status.he_data4 |= value;
1219 
1220 		/* HE-data5 */
1221 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
1222 				   HE_SIG_B2_OFDMA_INFO_0, TXBF);
1223 		value = value << QDF_MON_STATUS_TXBF_SHIFT;
1224 		ppdu_info->rx_status.he_data5 |= value;
1225 
1226 		/* HE-data6 */
1227 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
1228 				   HE_SIG_B2_OFDMA_INFO_0, NSTS);
1229 		/* value n indicates n+1 spatial streams */
1230 		value++;
1231 		ppdu_info->rx_status.nss = value;
1232 		ppdu_info->rx_status.he_data6 |= value;
1233 		ppdu_info->rx_status.reception_type = HAL_RX_TYPE_MU_OFDMA;
1234 		break;
1235 	}
1236 	case WIFIPHYRX_RSSI_LEGACY_E:
1237 	{
1238 		uint8_t reception_type;
1239 		int8_t rssi_value;
1240 		uint8_t *rssi_info_tlv = (uint8_t *)rx_tlv +
1241 			HAL_RX_OFFSET(UNIFIED_PHYRX_RSSI_LEGACY_19,
1242 				RECEIVE_RSSI_INFO_PREAMBLE_RSSI_INFO_DETAILS);
1243 
1244 		ppdu_info->rx_status.rssi_comb = HAL_RX_GET(rx_tlv,
1245 			PHYRX_RSSI_LEGACY_35, RSSI_COMB);
1246 		ppdu_info->rx_status.bw = hal->ops->hal_rx_get_tlv(rx_tlv);
1247 		ppdu_info->rx_status.he_re = 0;
1248 
1249 		reception_type = HAL_RX_GET(rx_tlv,
1250 					    PHYRX_RSSI_LEGACY_0,
1251 					    RECEPTION_TYPE);
1252 		switch (reception_type) {
1253 		case QDF_RECEPTION_TYPE_ULOFMDA:
1254 			ppdu_info->rx_status.reception_type =
1255 				HAL_RX_TYPE_MU_OFDMA;
1256 			ppdu_info->rx_status.ulofdma_flag = 1;
1257 			ppdu_info->rx_status.he_data1 =
1258 				QDF_MON_STATUS_HE_TRIG_FORMAT_TYPE;
1259 			break;
1260 		case QDF_RECEPTION_TYPE_ULMIMO:
1261 			ppdu_info->rx_status.reception_type =
1262 				HAL_RX_TYPE_MU_MIMO;
1263 			ppdu_info->rx_status.he_data1 =
1264 				QDF_MON_STATUS_HE_MU_FORMAT_TYPE;
1265 			break;
1266 		default:
1267 			ppdu_info->rx_status.reception_type =
1268 				HAL_RX_TYPE_SU;
1269 			break;
1270 		}
1271 		hal_rx_update_rssi_chain(ppdu_info, rssi_info_tlv);
1272 		rssi_value = HAL_RX_GET(rssi_info_tlv,
1273 					RECEIVE_RSSI_INFO_0, RSSI_PRI20_CHAIN0);
1274 		ppdu_info->rx_status.rssi[0] = rssi_value;
1275 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1276 			  "RSSI_PRI20_CHAIN0: %d\n", rssi_value);
1277 
1278 		rssi_value = HAL_RX_GET(rssi_info_tlv,
1279 					RECEIVE_RSSI_INFO_2, RSSI_PRI20_CHAIN1);
1280 		ppdu_info->rx_status.rssi[1] = rssi_value;
1281 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1282 			  "RSSI_PRI20_CHAIN1: %d\n", rssi_value);
1283 
1284 		rssi_value = HAL_RX_GET(rssi_info_tlv,
1285 					RECEIVE_RSSI_INFO_4, RSSI_PRI20_CHAIN2);
1286 		ppdu_info->rx_status.rssi[2] = rssi_value;
1287 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1288 			  "RSSI_PRI20_CHAIN2: %d\n", rssi_value);
1289 
1290 		rssi_value = HAL_RX_GET(rssi_info_tlv,
1291 					RECEIVE_RSSI_INFO_6, RSSI_PRI20_CHAIN3);
1292 		ppdu_info->rx_status.rssi[3] = rssi_value;
1293 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1294 			  "RSSI_PRI20_CHAIN3: %d\n", rssi_value);
1295 
1296 		rssi_value = HAL_RX_GET(rssi_info_tlv,
1297 					RECEIVE_RSSI_INFO_8, RSSI_PRI20_CHAIN4);
1298 		ppdu_info->rx_status.rssi[4] = rssi_value;
1299 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1300 			  "RSSI_PRI20_CHAIN4: %d\n", rssi_value);
1301 
1302 		rssi_value = HAL_RX_GET(rssi_info_tlv,
1303 					RECEIVE_RSSI_INFO_10,
1304 					RSSI_PRI20_CHAIN5);
1305 		ppdu_info->rx_status.rssi[5] = rssi_value;
1306 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1307 			  "RSSI_PRI20_CHAIN5: %d\n", rssi_value);
1308 
1309 		rssi_value = HAL_RX_GET(rssi_info_tlv,
1310 					RECEIVE_RSSI_INFO_12,
1311 					RSSI_PRI20_CHAIN6);
1312 		ppdu_info->rx_status.rssi[6] = rssi_value;
1313 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1314 			  "RSSI_PRI20_CHAIN6: %d\n", rssi_value);
1315 
1316 		rssi_value = HAL_RX_GET(rssi_info_tlv,
1317 					RECEIVE_RSSI_INFO_14,
1318 					RSSI_PRI20_CHAIN7);
1319 		ppdu_info->rx_status.rssi[7] = rssi_value;
1320 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1321 			  "RSSI_PRI20_CHAIN7: %d\n", rssi_value);
1322 		break;
1323 	}
1324 	case WIFIPHYRX_OTHER_RECEIVE_INFO_E:
1325 		hal_rx_proc_phyrx_other_receive_info_tlv(hal, rx_tlv_hdr,
1326 								ppdu_info);
1327 		break;
1328 	case WIFIRX_HEADER_E:
1329 	{
1330 		struct hal_rx_ppdu_common_info *com_info = &ppdu_info->com_info;
1331 		uint16_t mpdu_cnt = com_info->mpdu_cnt;
1332 
1333 		if (mpdu_cnt >= HAL_RX_MAX_MPDU) {
1334 			hal_alert("Number of MPDUs per PPDU exceeded");
1335 			break;
1336 		}
1337 		/* Update first_msdu_payload for every mpdu and increment
1338 		 * com_info->mpdu_cnt for every WIFIRX_HEADER_E TLV
1339 		 */
1340 		ppdu_info->ppdu_msdu_info[mpdu_cnt].first_msdu_payload =
1341 			rx_tlv;
1342 		ppdu_info->ppdu_msdu_info[mpdu_cnt].payload_len = tlv_len;
1343 		ppdu_info->ppdu_msdu_info[mpdu_cnt].nbuf = nbuf;
1344 		ppdu_info->msdu_info.first_msdu_payload = rx_tlv;
1345 		ppdu_info->msdu_info.payload_len = tlv_len;
1346 		ppdu_info->user_id = user_id;
1347 		ppdu_info->hdr_len = tlv_len;
1348 		ppdu_info->data = rx_tlv;
1349 		ppdu_info->data += 4;
1350 
1351 		/* for every RX_HEADER TLV increment mpdu_cnt */
1352 		com_info->mpdu_cnt++;
1353 		return HAL_TLV_STATUS_HEADER;
1354 	}
1355 	case WIFIRX_MPDU_START_E:
1356 	{
1357 		uint8_t *rx_mpdu_start =
1358 			(uint8_t *)rx_tlv + HAL_RX_OFFSET(UNIFIED_RX_MPDU_START_0,
1359 					RX_MPDU_INFO_RX_MPDU_INFO_DETAILS);
1360 		uint32_t ppdu_id =
1361 				HAL_RX_GET_PPDU_ID(rx_mpdu_start);
1362 		uint8_t filter_category = 0;
1363 
1364 		ppdu_info->nac_info.fc_valid =
1365 				HAL_RX_GET_FC_VALID(rx_mpdu_start);
1366 
1367 		ppdu_info->nac_info.to_ds_flag =
1368 				HAL_RX_GET_TO_DS_FLAG(rx_mpdu_start);
1369 
1370 		ppdu_info->nac_info.frame_control =
1371 			HAL_RX_GET(rx_mpdu_start,
1372 				   RX_MPDU_INFO_14,
1373 				   MPDU_FRAME_CONTROL_FIELD);
1374 
1375 		ppdu_info->sw_frame_group_id =
1376 			HAL_RX_GET_SW_FRAME_GROUP_ID(rx_mpdu_start);
1377 
1378 		if (ppdu_info->sw_frame_group_id ==
1379 		    HAL_MPDU_SW_FRAME_GROUP_NULL_DATA) {
1380 			ppdu_info->rx_status.frame_control_info_valid =
1381 				ppdu_info->nac_info.fc_valid;
1382 			ppdu_info->rx_status.frame_control =
1383 				ppdu_info->nac_info.frame_control;
1384 		}
1385 
1386 		ppdu_info->nac_info.mac_addr2_valid =
1387 				HAL_RX_GET_MAC_ADDR2_VALID(rx_mpdu_start);
1388 
1389 		*(uint16_t *)&ppdu_info->nac_info.mac_addr2[0] =
1390 			HAL_RX_GET(rx_mpdu_start,
1391 				   RX_MPDU_INFO_16,
1392 				   MAC_ADDR_AD2_15_0);
1393 
1394 		*(uint32_t *)&ppdu_info->nac_info.mac_addr2[2] =
1395 			HAL_RX_GET(rx_mpdu_start,
1396 				   RX_MPDU_INFO_17,
1397 				   MAC_ADDR_AD2_47_16);
1398 
1399 		if (ppdu_info->rx_status.prev_ppdu_id != ppdu_id) {
1400 			ppdu_info->rx_status.prev_ppdu_id = ppdu_id;
1401 			ppdu_info->rx_status.ppdu_len =
1402 				HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_13,
1403 					   MPDU_LENGTH);
1404 		} else {
1405 			ppdu_info->rx_status.ppdu_len +=
1406 				HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_13,
1407 				MPDU_LENGTH);
1408 		}
1409 
1410 		filter_category =
1411 				HAL_RX_GET_FILTER_CATEGORY(rx_mpdu_start);
1412 
1413 		if (filter_category == 0)
1414 			ppdu_info->rx_status.rxpcu_filter_pass = 1;
1415 		else if (filter_category == 1)
1416 			ppdu_info->rx_status.monitor_direct_used = 1;
1417 
1418 		ppdu_info->nac_info.mcast_bcast =
1419 			HAL_RX_GET(rx_mpdu_start,
1420 				   RX_MPDU_INFO_13,
1421 				   MCAST_BCAST);
1422 		break;
1423 	}
1424 	case WIFIRX_MPDU_END_E:
1425 		ppdu_info->user_id = user_id;
1426 		ppdu_info->fcs_err =
1427 			HAL_RX_GET(rx_tlv, RX_MPDU_END_1,
1428 				   FCS_ERR);
1429 		return HAL_TLV_STATUS_MPDU_END;
1430 	case WIFIRX_MSDU_END_E:
1431 		if (user_id < HAL_MAX_UL_MU_USERS) {
1432 			ppdu_info->rx_msdu_info[user_id].cce_metadata =
1433 				HAL_RX_MSDU_END_CCE_METADATA_GET(rx_tlv);
1434 			ppdu_info->rx_msdu_info[user_id].fse_metadata =
1435 				HAL_RX_MSDU_END_FSE_METADATA_GET(rx_tlv);
1436 			ppdu_info->rx_msdu_info[user_id].is_flow_idx_timeout =
1437 				HAL_RX_MSDU_END_FLOW_IDX_TIMEOUT_GET(rx_tlv);
1438 			ppdu_info->rx_msdu_info[user_id].is_flow_idx_invalid =
1439 				HAL_RX_MSDU_END_FLOW_IDX_INVALID_GET(rx_tlv);
1440 			ppdu_info->rx_msdu_info[user_id].flow_idx =
1441 				HAL_RX_MSDU_END_FLOW_IDX_GET(rx_tlv);
1442 		}
1443 		return HAL_TLV_STATUS_MSDU_END;
1444 	case 0:
1445 		return HAL_TLV_STATUS_PPDU_DONE;
1446 
1447 	default:
1448 		if (hal_rx_handle_other_tlvs(tlv_tag, rx_tlv, ppdu_info))
1449 			unhandled = false;
1450 		else
1451 			unhandled = true;
1452 		break;
1453 	}
1454 
1455 	if (!unhandled)
1456 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1457 			  "%s TLV type: %d, TLV len:%d %s",
1458 			  __func__, tlv_tag, tlv_len,
1459 			  unhandled == true ? "unhandled" : "");
1460 
1461 	qdf_trace_hex_dump(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1462 				rx_tlv, tlv_len);
1463 
1464 	return HAL_TLV_STATUS_PPDU_NOT_DONE;
1465 }
1466 
1467 /**
1468  * hal_reo_setup - Initialize HW REO block
1469  *
1470  * @hal_soc: Opaque HAL SOC handle
1471  * @reo_params: parameters needed by HAL for REO config
1472  */
1473 static void hal_reo_setup_generic(struct hal_soc *soc,
1474 				  void *reoparams)
1475 {
1476 	uint32_t reg_val;
1477 	struct hal_reo_params *reo_params = (struct hal_reo_params *)reoparams;
1478 
1479 	reg_val = HAL_REG_READ(soc, HWIO_REO_R0_GENERAL_ENABLE_ADDR(
1480 		SEQ_WCSS_UMAC_REO_REG_OFFSET));
1481 
1482 	hal_reo_config(soc, reg_val, reo_params);
1483 	/* Other ring enable bits and REO_ENABLE will be set by FW */
1484 
1485 	/* TODO: Setup destination ring mapping if enabled */
1486 
1487 	/* TODO: Error destination ring setting is left to default.
1488 	 * Default setting is to send all errors to release ring.
1489 	 */
1490 
1491 	HAL_REG_WRITE(soc,
1492 		HWIO_REO_R0_AGING_THRESHOLD_IX_0_ADDR(
1493 		SEQ_WCSS_UMAC_REO_REG_OFFSET),
1494 		HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_MS * 1000);
1495 
1496 	HAL_REG_WRITE(soc,
1497 		HWIO_REO_R0_AGING_THRESHOLD_IX_1_ADDR(
1498 		SEQ_WCSS_UMAC_REO_REG_OFFSET),
1499 		(HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_MS * 1000));
1500 
1501 	HAL_REG_WRITE(soc,
1502 		HWIO_REO_R0_AGING_THRESHOLD_IX_2_ADDR(
1503 		SEQ_WCSS_UMAC_REO_REG_OFFSET),
1504 		(HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_MS * 1000));
1505 
1506 	HAL_REG_WRITE(soc,
1507 		HWIO_REO_R0_AGING_THRESHOLD_IX_3_ADDR(
1508 		SEQ_WCSS_UMAC_REO_REG_OFFSET),
1509 		(HAL_DEFAULT_VO_REO_TIMEOUT_MS * 1000));
1510 
1511 	/*
1512 	 * When hash based routing is enabled, routing of the rx packet
1513 	 * is done based on the following value: 1 _ _ _ _ The last 4
1514 	 * bits are based on hash[3:0]. This means the possible values
1515 	 * are 0x10 to 0x1f. This value is used to look-up the
1516 	 * ring ID configured in Destination_Ring_Ctrl_IX_* register.
1517 	 * The Destination_Ring_Ctrl_IX_2 and Destination_Ring_Ctrl_IX_3
1518 	 * registers need to be configured to set-up the 16 entries to
1519 	 * map the hash values to a ring number. There are 3 bits per
1520 	 * hash entry – which are mapped as follows:
1521 	 * 0: TCL, 1:SW1, 2:SW2, * 3:SW3, 4:SW4, 5:Release, 6:FW(WIFI),
1522 	 * 7: NOT_USED.
1523 	*/
1524 	if (reo_params->rx_hash_enabled) {
1525 		HAL_REG_WRITE(soc,
1526 			HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR(
1527 			SEQ_WCSS_UMAC_REO_REG_OFFSET),
1528 			reo_params->remap1);
1529 
1530 		hal_debug("HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR 0x%x",
1531 			  HAL_REG_READ(soc,
1532 				       HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR(
1533 				       SEQ_WCSS_UMAC_REO_REG_OFFSET)));
1534 
1535 		HAL_REG_WRITE(soc,
1536 			HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR(
1537 			SEQ_WCSS_UMAC_REO_REG_OFFSET),
1538 			reo_params->remap2);
1539 
1540 		hal_debug("HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR 0x%x",
1541 			  HAL_REG_READ(soc,
1542 				       HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR(
1543 				       SEQ_WCSS_UMAC_REO_REG_OFFSET)));
1544 	}
1545 
1546 
1547 	/* TODO: Check if the following registers shoould be setup by host:
1548 	 * AGING_CONTROL
1549 	 * HIGH_MEMORY_THRESHOLD
1550 	 * GLOBAL_LINK_DESC_COUNT_THRESH_IX_0[1,2]
1551 	 * GLOBAL_LINK_DESC_COUNT_CTRL
1552 	 */
1553 }
1554 
1555 /**
1556  * hal_get_hw_hptp_generic()  - Get HW head and tail pointer value for any ring
1557  * @hal_soc: Opaque HAL SOC handle
1558  * @hal_ring: Source ring pointer
1559  * @headp: Head Pointer
1560  * @tailp: Tail Pointer
1561  * @ring: Ring type
1562  *
1563  * Return: Update tail pointer and head pointer in arguments.
1564  */
1565 static inline
1566 void hal_get_hw_hptp_generic(struct hal_soc *hal_soc,
1567 			     hal_ring_handle_t hal_ring_hdl,
1568 			     uint32_t *headp, uint32_t *tailp,
1569 			     uint8_t ring)
1570 {
1571 	struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
1572 	struct hal_hw_srng_config *ring_config;
1573 	enum hal_ring_type ring_type = (enum hal_ring_type)ring;
1574 
1575 	if (!hal_soc  || !srng) {
1576 		QDF_TRACE(QDF_MODULE_ID_HAL, QDF_TRACE_LEVEL_ERROR,
1577 			  "%s: Context is Null", __func__);
1578 		return;
1579 	}
1580 
1581 	ring_config = HAL_SRNG_CONFIG(hal_soc, ring_type);
1582 	if (!ring_config->lmac_ring) {
1583 		if (srng->ring_dir == HAL_SRNG_SRC_RING) {
1584 			*headp = SRNG_SRC_REG_READ(srng, HP);
1585 			*tailp = SRNG_SRC_REG_READ(srng, TP);
1586 		} else {
1587 			*headp = SRNG_DST_REG_READ(srng, HP);
1588 			*tailp = SRNG_DST_REG_READ(srng, TP);
1589 		}
1590 	}
1591 }
1592 
1593 /**
1594  * hal_srng_src_hw_init - Private function to initialize SRNG
1595  * source ring HW
1596  * @hal_soc: HAL SOC handle
1597  * @srng: SRNG ring pointer
1598  */
1599 static inline
1600 void hal_srng_src_hw_init_generic(struct hal_soc *hal,
1601 				  struct hal_srng *srng)
1602 {
1603 	uint32_t reg_val = 0;
1604 	uint64_t tp_addr = 0;
1605 
1606 	hal_debug("hw_init srng %d", srng->ring_id);
1607 
1608 	if (srng->flags & HAL_SRNG_MSI_INTR) {
1609 		SRNG_SRC_REG_WRITE(srng, MSI1_BASE_LSB,
1610 			srng->msi_addr & 0xffffffff);
1611 		reg_val = SRNG_SM(SRNG_SRC_FLD(MSI1_BASE_MSB, ADDR),
1612 			(uint64_t)(srng->msi_addr) >> 32) |
1613 			SRNG_SM(SRNG_SRC_FLD(MSI1_BASE_MSB,
1614 			MSI1_ENABLE), 1);
1615 		SRNG_SRC_REG_WRITE(srng, MSI1_BASE_MSB, reg_val);
1616 		SRNG_SRC_REG_WRITE(srng, MSI1_DATA, srng->msi_data);
1617 	}
1618 
1619 	SRNG_SRC_REG_WRITE(srng, BASE_LSB, srng->ring_base_paddr & 0xffffffff);
1620 	reg_val = SRNG_SM(SRNG_SRC_FLD(BASE_MSB, RING_BASE_ADDR_MSB),
1621 		((uint64_t)(srng->ring_base_paddr) >> 32)) |
1622 		SRNG_SM(SRNG_SRC_FLD(BASE_MSB, RING_SIZE),
1623 		srng->entry_size * srng->num_entries);
1624 	SRNG_SRC_REG_WRITE(srng, BASE_MSB, reg_val);
1625 
1626 	reg_val = SRNG_SM(SRNG_SRC_FLD(ID, ENTRY_SIZE), srng->entry_size);
1627 	SRNG_SRC_REG_WRITE(srng, ID, reg_val);
1628 
1629 	/**
1630 	 * Interrupt setup:
1631 	 * Default interrupt mode is 'pulse'. Need to setup SW_INTERRUPT_MODE
1632 	 * if level mode is required
1633 	 */
1634 	reg_val = 0;
1635 
1636 	/*
1637 	 * WAR - Hawkeye v1 has a hardware bug which requires timer value to be
1638 	 * programmed in terms of 1us resolution instead of 8us resolution as
1639 	 * given in MLD.
1640 	 */
1641 	if (srng->intr_timer_thres_us) {
1642 		reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX0,
1643 			INTERRUPT_TIMER_THRESHOLD),
1644 			srng->intr_timer_thres_us);
1645 		/* For HK v2 this should be (srng->intr_timer_thres_us >> 3) */
1646 	}
1647 
1648 	if (srng->intr_batch_cntr_thres_entries) {
1649 		reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX0,
1650 			BATCH_COUNTER_THRESHOLD),
1651 			srng->intr_batch_cntr_thres_entries *
1652 			srng->entry_size);
1653 	}
1654 	SRNG_SRC_REG_WRITE(srng, CONSUMER_INT_SETUP_IX0, reg_val);
1655 
1656 	reg_val = 0;
1657 	if (srng->flags & HAL_SRNG_LOW_THRES_INTR_ENABLE) {
1658 		reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX1,
1659 			LOW_THRESHOLD), srng->u.src_ring.low_threshold);
1660 	}
1661 
1662 	SRNG_SRC_REG_WRITE(srng, CONSUMER_INT_SETUP_IX1, reg_val);
1663 
1664 	/* As per HW team, TP_ADDR and HP_ADDR for Idle link ring should
1665 	 * remain 0 to avoid some WBM stability issues. Remote head/tail
1666 	 * pointers are not required since this ring is completely managed
1667 	 * by WBM HW
1668 	 */
1669 	reg_val = 0;
1670 	if (srng->ring_id != HAL_SRNG_WBM_IDLE_LINK) {
1671 		tp_addr = (uint64_t)(hal->shadow_rdptr_mem_paddr +
1672 			((unsigned long)(srng->u.src_ring.tp_addr) -
1673 			(unsigned long)(hal->shadow_rdptr_mem_vaddr)));
1674 		SRNG_SRC_REG_WRITE(srng, TP_ADDR_LSB, tp_addr & 0xffffffff);
1675 		SRNG_SRC_REG_WRITE(srng, TP_ADDR_MSB, tp_addr >> 32);
1676 	} else {
1677 		reg_val |= SRNG_SM(SRNG_SRC_FLD(MISC, RING_ID_DISABLE), 1);
1678 	}
1679 
1680 	/* Initilaize head and tail pointers to indicate ring is empty */
1681 	SRNG_SRC_REG_WRITE(srng, HP, 0);
1682 	SRNG_SRC_REG_WRITE(srng, TP, 0);
1683 	*(srng->u.src_ring.tp_addr) = 0;
1684 
1685 	reg_val |= ((srng->flags & HAL_SRNG_DATA_TLV_SWAP) ?
1686 			SRNG_SM(SRNG_SRC_FLD(MISC, DATA_TLV_SWAP_BIT), 1) : 0) |
1687 			((srng->flags & HAL_SRNG_RING_PTR_SWAP) ?
1688 			SRNG_SM(SRNG_SRC_FLD(MISC, HOST_FW_SWAP_BIT), 1) : 0) |
1689 			((srng->flags & HAL_SRNG_MSI_SWAP) ?
1690 			SRNG_SM(SRNG_SRC_FLD(MISC, MSI_SWAP_BIT), 1) : 0);
1691 
1692 	/* Loop count is not used for SRC rings */
1693 	reg_val |= SRNG_SM(SRNG_SRC_FLD(MISC, LOOPCNT_DISABLE), 1);
1694 
1695 	/*
1696 	 * reg_val |= SRNG_SM(SRNG_SRC_FLD(MISC, SRNG_ENABLE), 1);
1697 	 * todo: update fw_api and replace with above line
1698 	 * (when SRNG_ENABLE field for the MISC register is available in fw_api)
1699 	 * (WCSS_UMAC_CE_0_SRC_WFSS_CE_CHANNEL_SRC_R0_SRC_RING_MISC)
1700 	 */
1701 	reg_val |= 0x40;
1702 
1703 	SRNG_SRC_REG_WRITE(srng, MISC, reg_val);
1704 }
1705 
1706 /**
1707  * hal_srng_dst_hw_init - Private function to initialize SRNG
1708  * destination ring HW
1709  * @hal_soc: HAL SOC handle
1710  * @srng: SRNG ring pointer
1711  */
1712 static inline
1713 void hal_srng_dst_hw_init_generic(struct hal_soc *hal,
1714 				  struct hal_srng *srng)
1715 {
1716 	uint32_t reg_val = 0;
1717 	uint64_t hp_addr = 0;
1718 
1719 	hal_debug("hw_init srng %d", srng->ring_id);
1720 
1721 	if (srng->flags & HAL_SRNG_MSI_INTR) {
1722 		SRNG_DST_REG_WRITE(srng, MSI1_BASE_LSB,
1723 			srng->msi_addr & 0xffffffff);
1724 		reg_val = SRNG_SM(SRNG_DST_FLD(MSI1_BASE_MSB, ADDR),
1725 			(uint64_t)(srng->msi_addr) >> 32) |
1726 			SRNG_SM(SRNG_DST_FLD(MSI1_BASE_MSB,
1727 			MSI1_ENABLE), 1);
1728 		SRNG_DST_REG_WRITE(srng, MSI1_BASE_MSB, reg_val);
1729 		SRNG_DST_REG_WRITE(srng, MSI1_DATA, srng->msi_data);
1730 	}
1731 
1732 	SRNG_DST_REG_WRITE(srng, BASE_LSB, srng->ring_base_paddr & 0xffffffff);
1733 	reg_val = SRNG_SM(SRNG_DST_FLD(BASE_MSB, RING_BASE_ADDR_MSB),
1734 		((uint64_t)(srng->ring_base_paddr) >> 32)) |
1735 		SRNG_SM(SRNG_DST_FLD(BASE_MSB, RING_SIZE),
1736 		srng->entry_size * srng->num_entries);
1737 	SRNG_DST_REG_WRITE(srng, BASE_MSB, reg_val);
1738 
1739 	reg_val = SRNG_SM(SRNG_DST_FLD(ID, RING_ID), srng->ring_id) |
1740 		SRNG_SM(SRNG_DST_FLD(ID, ENTRY_SIZE), srng->entry_size);
1741 	SRNG_DST_REG_WRITE(srng, ID, reg_val);
1742 
1743 
1744 	/**
1745 	 * Interrupt setup:
1746 	 * Default interrupt mode is 'pulse'. Need to setup SW_INTERRUPT_MODE
1747 	 * if level mode is required
1748 	 */
1749 	reg_val = 0;
1750 	if (srng->intr_timer_thres_us) {
1751 		reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT_SETUP,
1752 			INTERRUPT_TIMER_THRESHOLD),
1753 			srng->intr_timer_thres_us >> 3);
1754 	}
1755 
1756 	if (srng->intr_batch_cntr_thres_entries) {
1757 		reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT_SETUP,
1758 			BATCH_COUNTER_THRESHOLD),
1759 			srng->intr_batch_cntr_thres_entries *
1760 			srng->entry_size);
1761 	}
1762 
1763 	SRNG_DST_REG_WRITE(srng, PRODUCER_INT_SETUP, reg_val);
1764 	hp_addr = (uint64_t)(hal->shadow_rdptr_mem_paddr +
1765 		((unsigned long)(srng->u.dst_ring.hp_addr) -
1766 		(unsigned long)(hal->shadow_rdptr_mem_vaddr)));
1767 	SRNG_DST_REG_WRITE(srng, HP_ADDR_LSB, hp_addr & 0xffffffff);
1768 	SRNG_DST_REG_WRITE(srng, HP_ADDR_MSB, hp_addr >> 32);
1769 
1770 	/* Initilaize head and tail pointers to indicate ring is empty */
1771 	SRNG_DST_REG_WRITE(srng, HP, 0);
1772 	SRNG_DST_REG_WRITE(srng, TP, 0);
1773 	*(srng->u.dst_ring.hp_addr) = 0;
1774 
1775 	reg_val = ((srng->flags & HAL_SRNG_DATA_TLV_SWAP) ?
1776 			SRNG_SM(SRNG_DST_FLD(MISC, DATA_TLV_SWAP_BIT), 1) : 0) |
1777 			((srng->flags & HAL_SRNG_RING_PTR_SWAP) ?
1778 			SRNG_SM(SRNG_DST_FLD(MISC, HOST_FW_SWAP_BIT), 1) : 0) |
1779 			((srng->flags & HAL_SRNG_MSI_SWAP) ?
1780 			SRNG_SM(SRNG_DST_FLD(MISC, MSI_SWAP_BIT), 1) : 0);
1781 
1782 	/*
1783 	 * reg_val |= SRNG_SM(SRNG_SRC_FLD(MISC, SRNG_ENABLE), 1);
1784 	 * todo: update fw_api and replace with above line
1785 	 * (when SRNG_ENABLE field for the MISC register is available in fw_api)
1786 	 * (WCSS_UMAC_CE_0_SRC_WFSS_CE_CHANNEL_SRC_R0_SRC_RING_MISC)
1787 	 */
1788 	reg_val |= 0x40;
1789 
1790 	SRNG_DST_REG_WRITE(srng, MISC, reg_val);
1791 
1792 }
1793 
1794 #define HAL_RX_WBM_ERR_SRC_GET(wbm_desc) (((*(((uint32_t *) wbm_desc)+ \
1795 		(WBM_RELEASE_RING_2_RELEASE_SOURCE_MODULE_OFFSET >> 2))) & \
1796 		WBM_RELEASE_RING_2_RELEASE_SOURCE_MODULE_MASK) >> \
1797 		WBM_RELEASE_RING_2_RELEASE_SOURCE_MODULE_LSB)
1798 
1799 #define HAL_RX_WBM_REO_PUSH_REASON_GET(wbm_desc) (((*(((uint32_t *) wbm_desc)+ \
1800 		(WBM_RELEASE_RING_2_REO_PUSH_REASON_OFFSET >> 2))) & \
1801 		WBM_RELEASE_RING_2_REO_PUSH_REASON_MASK) >> \
1802 		WBM_RELEASE_RING_2_REO_PUSH_REASON_LSB)
1803 
1804 #define HAL_RX_WBM_REO_ERROR_CODE_GET(wbm_desc) (((*(((uint32_t *) wbm_desc)+ \
1805 		(WBM_RELEASE_RING_2_REO_ERROR_CODE_OFFSET >> 2))) & \
1806 		WBM_RELEASE_RING_2_REO_ERROR_CODE_MASK) >> \
1807 		WBM_RELEASE_RING_2_REO_ERROR_CODE_LSB)
1808 
1809 #define HAL_RX_WBM_RXDMA_PUSH_REASON_GET(wbm_desc)	\
1810 	(((*(((uint32_t *) wbm_desc) +			\
1811 	(WBM_RELEASE_RING_2_RXDMA_PUSH_REASON_OFFSET >> 2))) & \
1812 	WBM_RELEASE_RING_2_RXDMA_PUSH_REASON_MASK) >>	\
1813 	WBM_RELEASE_RING_2_RXDMA_PUSH_REASON_LSB)
1814 
1815 #define HAL_RX_WBM_RXDMA_ERROR_CODE_GET(wbm_desc)	\
1816 	(((*(((uint32_t *) wbm_desc) +			\
1817 	(WBM_RELEASE_RING_2_RXDMA_ERROR_CODE_OFFSET >> 2))) & \
1818 	WBM_RELEASE_RING_2_RXDMA_ERROR_CODE_MASK) >>	\
1819 	WBM_RELEASE_RING_2_RXDMA_ERROR_CODE_LSB)
1820 
1821 /**
1822  * hal_rx_wbm_err_info_get_generic(): Retrieves WBM error code and reason and
1823  *	save it to hal_wbm_err_desc_info structure passed by caller
1824  * @wbm_desc: wbm ring descriptor
1825  * @wbm_er_info1: hal_wbm_err_desc_info structure, output parameter.
1826  * Return: void
1827  */
1828 static inline void hal_rx_wbm_err_info_get_generic(void *wbm_desc,
1829 				void *wbm_er_info1)
1830 {
1831 	struct hal_wbm_err_desc_info *wbm_er_info =
1832 		(struct hal_wbm_err_desc_info *)wbm_er_info1;
1833 
1834 	wbm_er_info->wbm_err_src = HAL_RX_WBM_ERR_SRC_GET(wbm_desc);
1835 	wbm_er_info->reo_psh_rsn = HAL_RX_WBM_REO_PUSH_REASON_GET(wbm_desc);
1836 	wbm_er_info->reo_err_code = HAL_RX_WBM_REO_ERROR_CODE_GET(wbm_desc);
1837 	wbm_er_info->rxdma_psh_rsn = HAL_RX_WBM_RXDMA_PUSH_REASON_GET(wbm_desc);
1838 	wbm_er_info->rxdma_err_code = HAL_RX_WBM_RXDMA_ERROR_CODE_GET(wbm_desc);
1839 }
1840 
1841 /**
1842  * hal_tx_comp_get_release_reason_generic() - TQM Release reason
1843  * @hal_desc: completion ring descriptor pointer
1844  *
1845  * This function will return the type of pointer - buffer or descriptor
1846  *
1847  * Return: buffer type
1848  */
1849 static inline uint8_t hal_tx_comp_get_release_reason_generic(void *hal_desc)
1850 {
1851 	uint32_t comp_desc =
1852 		*(uint32_t *) (((uint8_t *) hal_desc) +
1853 			       WBM_RELEASE_RING_2_TQM_RELEASE_REASON_OFFSET);
1854 
1855 	return (comp_desc & WBM_RELEASE_RING_2_TQM_RELEASE_REASON_MASK) >>
1856 		WBM_RELEASE_RING_2_TQM_RELEASE_REASON_LSB;
1857 }
1858 
1859 /**
1860  * hal_rx_dump_mpdu_start_tlv_generic: dump RX mpdu_start TLV in structured
1861  *			       human readable format.
1862  * @mpdu_start: pointer the rx_attention TLV in pkt.
1863  * @dbg_level: log level.
1864  *
1865  * Return: void
1866  */
1867 static inline void hal_rx_dump_mpdu_start_tlv_generic(void *mpdustart,
1868 						      uint8_t dbg_level)
1869 {
1870 	struct rx_mpdu_start *mpdu_start = (struct rx_mpdu_start *)mpdustart;
1871 	struct rx_mpdu_info *mpdu_info =
1872 		(struct rx_mpdu_info *)&mpdu_start->rx_mpdu_info_details;
1873 
1874 	hal_verbose_debug(
1875 			  "rx_mpdu_start tlv (1/5) - "
1876 			  "rxpcu_mpdu_filter_in_category: %x "
1877 			  "sw_frame_group_id: %x "
1878 			  "ndp_frame: %x "
1879 			  "phy_err: %x "
1880 			  "phy_err_during_mpdu_header: %x "
1881 			  "protocol_version_err: %x "
1882 			  "ast_based_lookup_valid: %x "
1883 			  "phy_ppdu_id: %x "
1884 			  "ast_index: %x "
1885 			  "sw_peer_id: %x "
1886 			  "mpdu_frame_control_valid: %x "
1887 			  "mpdu_duration_valid: %x "
1888 			  "mac_addr_ad1_valid: %x "
1889 			  "mac_addr_ad2_valid: %x "
1890 			  "mac_addr_ad3_valid: %x "
1891 			  "mac_addr_ad4_valid: %x "
1892 			  "mpdu_sequence_control_valid: %x "
1893 			  "mpdu_qos_control_valid: %x "
1894 			  "mpdu_ht_control_valid: %x "
1895 			  "frame_encryption_info_valid: %x ",
1896 			  mpdu_info->rxpcu_mpdu_filter_in_category,
1897 			  mpdu_info->sw_frame_group_id,
1898 			  mpdu_info->ndp_frame,
1899 			  mpdu_info->phy_err,
1900 			  mpdu_info->phy_err_during_mpdu_header,
1901 			  mpdu_info->protocol_version_err,
1902 			  mpdu_info->ast_based_lookup_valid,
1903 			  mpdu_info->phy_ppdu_id,
1904 			  mpdu_info->ast_index,
1905 			  mpdu_info->sw_peer_id,
1906 			  mpdu_info->mpdu_frame_control_valid,
1907 			  mpdu_info->mpdu_duration_valid,
1908 			  mpdu_info->mac_addr_ad1_valid,
1909 			  mpdu_info->mac_addr_ad2_valid,
1910 			  mpdu_info->mac_addr_ad3_valid,
1911 			  mpdu_info->mac_addr_ad4_valid,
1912 			  mpdu_info->mpdu_sequence_control_valid,
1913 			  mpdu_info->mpdu_qos_control_valid,
1914 			  mpdu_info->mpdu_ht_control_valid,
1915 			  mpdu_info->frame_encryption_info_valid);
1916 
1917 	hal_verbose_debug(
1918 			  "rx_mpdu_start tlv (2/5) - "
1919 			  "fr_ds: %x "
1920 			  "to_ds: %x "
1921 			  "encrypted: %x "
1922 			  "mpdu_retry: %x "
1923 			  "mpdu_sequence_number: %x "
1924 			  "epd_en: %x "
1925 			  "all_frames_shall_be_encrypted: %x "
1926 			  "encrypt_type: %x "
1927 			  "mesh_sta: %x "
1928 			  "bssid_hit: %x "
1929 			  "bssid_number: %x "
1930 			  "tid: %x "
1931 			  "pn_31_0: %x "
1932 			  "pn_63_32: %x "
1933 			  "pn_95_64: %x "
1934 			  "pn_127_96: %x "
1935 			  "peer_meta_data: %x "
1936 			  "rxpt_classify_info.reo_destination_indication: %x "
1937 			  "rxpt_classify_info.use_flow_id_toeplitz_clfy: %x "
1938 			  "rx_reo_queue_desc_addr_31_0: %x ",
1939 			  mpdu_info->fr_ds,
1940 			  mpdu_info->to_ds,
1941 			  mpdu_info->encrypted,
1942 			  mpdu_info->mpdu_retry,
1943 			  mpdu_info->mpdu_sequence_number,
1944 			  mpdu_info->epd_en,
1945 			  mpdu_info->all_frames_shall_be_encrypted,
1946 			  mpdu_info->encrypt_type,
1947 			  mpdu_info->mesh_sta,
1948 			  mpdu_info->bssid_hit,
1949 			  mpdu_info->bssid_number,
1950 			  mpdu_info->tid,
1951 			  mpdu_info->pn_31_0,
1952 			  mpdu_info->pn_63_32,
1953 			  mpdu_info->pn_95_64,
1954 			  mpdu_info->pn_127_96,
1955 			  mpdu_info->peer_meta_data,
1956 			  mpdu_info->rxpt_classify_info_details.reo_destination_indication,
1957 			  mpdu_info->rxpt_classify_info_details.use_flow_id_toeplitz_clfy,
1958 			  mpdu_info->rx_reo_queue_desc_addr_31_0);
1959 
1960 	hal_verbose_debug(
1961 			  "rx_mpdu_start tlv (3/5) - "
1962 			  "rx_reo_queue_desc_addr_39_32: %x "
1963 			  "receive_queue_number: %x "
1964 			  "pre_delim_err_warning: %x "
1965 			  "first_delim_err: %x "
1966 			  "key_id_octet: %x "
1967 			  "new_peer_entry: %x "
1968 			  "decrypt_needed: %x "
1969 			  "decap_type: %x "
1970 			  "rx_insert_vlan_c_tag_padding: %x "
1971 			  "rx_insert_vlan_s_tag_padding: %x "
1972 			  "strip_vlan_c_tag_decap: %x "
1973 			  "strip_vlan_s_tag_decap: %x "
1974 			  "pre_delim_count: %x "
1975 			  "ampdu_flag: %x "
1976 			  "bar_frame: %x "
1977 			  "mpdu_length: %x "
1978 			  "first_mpdu: %x "
1979 			  "mcast_bcast: %x "
1980 			  "ast_index_not_found: %x "
1981 			  "ast_index_timeout: %x ",
1982 			  mpdu_info->rx_reo_queue_desc_addr_39_32,
1983 			  mpdu_info->receive_queue_number,
1984 			  mpdu_info->pre_delim_err_warning,
1985 			  mpdu_info->first_delim_err,
1986 			  mpdu_info->key_id_octet,
1987 			  mpdu_info->new_peer_entry,
1988 			  mpdu_info->decrypt_needed,
1989 			  mpdu_info->decap_type,
1990 			  mpdu_info->rx_insert_vlan_c_tag_padding,
1991 			  mpdu_info->rx_insert_vlan_s_tag_padding,
1992 			  mpdu_info->strip_vlan_c_tag_decap,
1993 			  mpdu_info->strip_vlan_s_tag_decap,
1994 			  mpdu_info->pre_delim_count,
1995 			  mpdu_info->ampdu_flag,
1996 			  mpdu_info->bar_frame,
1997 			  mpdu_info->mpdu_length,
1998 			  mpdu_info->first_mpdu,
1999 			  mpdu_info->mcast_bcast,
2000 			  mpdu_info->ast_index_not_found,
2001 			  mpdu_info->ast_index_timeout);
2002 
2003 	hal_verbose_debug(
2004 			  "rx_mpdu_start tlv (4/5) - "
2005 			  "power_mgmt: %x "
2006 			  "non_qos: %x "
2007 			  "null_data: %x "
2008 			  "mgmt_type: %x "
2009 			  "ctrl_type: %x "
2010 			  "more_data: %x "
2011 			  "eosp: %x "
2012 			  "fragment_flag: %x "
2013 			  "order: %x "
2014 			  "u_apsd_trigger: %x "
2015 			  "encrypt_required: %x "
2016 			  "directed: %x "
2017 			  "mpdu_frame_control_field: %x "
2018 			  "mpdu_duration_field: %x "
2019 			  "mac_addr_ad1_31_0: %x "
2020 			  "mac_addr_ad1_47_32: %x "
2021 			  "mac_addr_ad2_15_0: %x "
2022 			  "mac_addr_ad2_47_16: %x "
2023 			  "mac_addr_ad3_31_0: %x "
2024 			  "mac_addr_ad3_47_32: %x ",
2025 			  mpdu_info->power_mgmt,
2026 			  mpdu_info->non_qos,
2027 			  mpdu_info->null_data,
2028 			  mpdu_info->mgmt_type,
2029 			  mpdu_info->ctrl_type,
2030 			  mpdu_info->more_data,
2031 			  mpdu_info->eosp,
2032 			  mpdu_info->fragment_flag,
2033 			  mpdu_info->order,
2034 			  mpdu_info->u_apsd_trigger,
2035 			  mpdu_info->encrypt_required,
2036 			  mpdu_info->directed,
2037 			  mpdu_info->mpdu_frame_control_field,
2038 			  mpdu_info->mpdu_duration_field,
2039 			  mpdu_info->mac_addr_ad1_31_0,
2040 			  mpdu_info->mac_addr_ad1_47_32,
2041 			  mpdu_info->mac_addr_ad2_15_0,
2042 			  mpdu_info->mac_addr_ad2_47_16,
2043 			  mpdu_info->mac_addr_ad3_31_0,
2044 			  mpdu_info->mac_addr_ad3_47_32);
2045 
2046 	hal_verbose_debug(
2047 			  "rx_mpdu_start tlv (5/5) - "
2048 			  "mpdu_sequence_control_field: %x "
2049 			  "mac_addr_ad4_31_0: %x "
2050 			  "mac_addr_ad4_47_32: %x "
2051 			  "mpdu_qos_control_field: %x "
2052 			  "mpdu_ht_control_field: %x ",
2053 			  mpdu_info->mpdu_sequence_control_field,
2054 			  mpdu_info->mac_addr_ad4_31_0,
2055 			  mpdu_info->mac_addr_ad4_47_32,
2056 			  mpdu_info->mpdu_qos_control_field,
2057 			  mpdu_info->mpdu_ht_control_field);
2058 }
2059 
2060 /**
2061  * hal_tx_desc_set_search_type - Set the search type value
2062  * @desc: Handle to Tx Descriptor
2063  * @search_type: search type
2064  *		     0 – Normal search
2065  *		     1 – Index based address search
2066  *		     2 – Index based flow search
2067  *
2068  * Return: void
2069  */
2070 #ifdef TCL_DATA_CMD_2_SEARCH_TYPE_OFFSET
2071 static void hal_tx_desc_set_search_type_generic(void *desc,
2072 						uint8_t search_type)
2073 {
2074 	HAL_SET_FLD(desc, TCL_DATA_CMD_2, SEARCH_TYPE) |=
2075 		HAL_TX_SM(TCL_DATA_CMD_2, SEARCH_TYPE, search_type);
2076 }
2077 #else
2078 static void hal_tx_desc_set_search_type_generic(void *desc,
2079 						uint8_t search_type)
2080 {
2081 }
2082 
2083 #endif
2084 
2085 /**
2086  * hal_tx_desc_set_search_index - Set the search index value
2087  * @desc: Handle to Tx Descriptor
2088  * @search_index: The index that will be used for index based address or
2089  *                flow search. The field is valid when 'search_type' is
2090  *                1 0r 2
2091  *
2092  * Return: void
2093  */
2094 #ifdef TCL_DATA_CMD_5_SEARCH_INDEX_OFFSET
2095 static void hal_tx_desc_set_search_index_generic(void *desc,
2096 						 uint32_t search_index)
2097 {
2098 	HAL_SET_FLD(desc, TCL_DATA_CMD_5, SEARCH_INDEX) |=
2099 		HAL_TX_SM(TCL_DATA_CMD_5, SEARCH_INDEX, search_index);
2100 }
2101 #else
2102 static void hal_tx_desc_set_search_index_generic(void *desc,
2103 						 uint32_t search_index)
2104 {
2105 }
2106 #endif
2107 
2108 /**
2109  * hal_tx_desc_set_cache_set_num_generic - Set the cache-set-num value
2110  * @desc: Handle to Tx Descriptor
2111  * @cache_num: Cache set number that should be used to cache the index
2112  *                based search results, for address and flow search.
2113  *                This value should be equal to LSB four bits of the hash value
2114  *                of match data, in case of search index points to an entry
2115  *                which may be used in content based search also. The value can
2116  *                be anything when the entry pointed by search index will not be
2117  *                used for content based search.
2118  *
2119  * Return: void
2120  */
2121 #ifdef TCL_DATA_CMD_5_CACHE_SET_NUM_OFFSET
2122 static void hal_tx_desc_set_cache_set_num_generic(void *desc,
2123 						  uint8_t cache_num)
2124 {
2125 	HAL_SET_FLD(desc, TCL_DATA_CMD_5, CACHE_SET_NUM) |=
2126 		HAL_TX_SM(TCL_DATA_CMD_5, CACHE_SET_NUM, cache_num);
2127 }
2128 #else
2129 static void hal_tx_desc_set_cache_set_num_generic(void *desc,
2130 						  uint8_t cache_num)
2131 {
2132 }
2133 #endif
2134 
2135 /**
2136  * hal_tx_set_pcp_tid_map_generic() - Configure default PCP to TID map table
2137  * @soc: HAL SoC context
2138  * @map: PCP-TID mapping table
2139  *
2140  * PCP are mapped to 8 TID values using TID values programmed
2141  * in one set of mapping registers PCP_TID_MAP_<0 to 6>
2142  * The mapping register has TID mapping for 8 PCP values
2143  *
2144  * Return: none
2145  */
2146 static void hal_tx_set_pcp_tid_map_generic(struct hal_soc *soc, uint8_t *map)
2147 {
2148 	uint32_t addr, value;
2149 
2150 	addr = HWIO_TCL_R0_PCP_TID_MAP_ADDR(
2151 				SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET);
2152 
2153 	value = (map[0] |
2154 		(map[1] << HWIO_TCL_R0_PCP_TID_MAP_PCP_1_SHFT) |
2155 		(map[2] << HWIO_TCL_R0_PCP_TID_MAP_PCP_2_SHFT) |
2156 		(map[3] << HWIO_TCL_R0_PCP_TID_MAP_PCP_3_SHFT) |
2157 		(map[4] << HWIO_TCL_R0_PCP_TID_MAP_PCP_4_SHFT) |
2158 		(map[5] << HWIO_TCL_R0_PCP_TID_MAP_PCP_5_SHFT) |
2159 		(map[6] << HWIO_TCL_R0_PCP_TID_MAP_PCP_6_SHFT) |
2160 		(map[7] << HWIO_TCL_R0_PCP_TID_MAP_PCP_7_SHFT));
2161 
2162 	HAL_REG_WRITE(soc, addr, (value & HWIO_TCL_R0_PCP_TID_MAP_RMSK));
2163 }
2164 
2165 /**
2166  * hal_tx_update_pcp_tid_generic() - Update the pcp tid map table with
2167  *					value received from user-space
2168  * @soc: HAL SoC context
2169  * @pcp: pcp value
2170  * @tid : tid value
2171  *
2172  * Return: void
2173  */
2174 static
2175 void hal_tx_update_pcp_tid_generic(struct hal_soc *soc,
2176 				   uint8_t pcp, uint8_t tid)
2177 {
2178 	uint32_t addr, value, regval;
2179 
2180 	addr = HWIO_TCL_R0_PCP_TID_MAP_ADDR(
2181 				SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET);
2182 
2183 	value = (uint32_t)tid << (HAL_TX_BITS_PER_TID * pcp);
2184 
2185 	/* Read back previous PCP TID config and update
2186 	 * with new config.
2187 	 */
2188 	regval = HAL_REG_READ(soc, addr);
2189 	regval &= ~(HAL_TX_TID_BITS_MASK << (HAL_TX_BITS_PER_TID * pcp));
2190 	regval |= value;
2191 
2192 	HAL_REG_WRITE(soc, addr,
2193 		      (regval & HWIO_TCL_R0_PCP_TID_MAP_RMSK));
2194 }
2195 
2196 /**
2197  * hal_tx_update_tidmap_prty_generic() - Update the tid map priority
2198  * @soc: HAL SoC context
2199  * @val: priority value
2200  *
2201  * Return: void
2202  */
2203 static
2204 void hal_tx_update_tidmap_prty_generic(struct hal_soc *soc, uint8_t value)
2205 {
2206 	uint32_t addr;
2207 
2208 	addr = HWIO_TCL_R0_TID_MAP_PRTY_ADDR(
2209 				SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET);
2210 
2211 	HAL_REG_WRITE(soc, addr,
2212 		      (value & HWIO_TCL_R0_TID_MAP_PRTY_RMSK));
2213 }
2214 
2215 #endif /* _HAL_GENERIC_API_H_ */
2216