xref: /wlan-dirver/qca-wifi-host-cmn/hal/wifi3.0/hal_generic_api.h (revision 0626a4da6c07f30da06dd6747e8cc290a60371d8)
1 /*
2  * Copyright (c) 2016-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 #ifndef _HAL_GENERIC_API_H_
19 #define _HAL_GENERIC_API_H_
20 
21 #define HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr) \
22 	((struct rx_msdu_desc_info *) \
23 	_OFFSET_TO_BYTE_PTR(msdu_details_ptr, \
24 UNIFIED_RX_MSDU_DETAILS_2_RX_MSDU_DESC_INFO_RX_MSDU_DESC_INFO_DETAILS_OFFSET))
25 /**
26  * hal_rx_msdu_desc_info_get_ptr_generic() - Get msdu desc info ptr
27  * @msdu_details_ptr - Pointer to msdu_details_ptr
28  * Return - Pointer to rx_msdu_desc_info structure.
29  *
30  */
31 static void *hal_rx_msdu_desc_info_get_ptr_generic(void *msdu_details_ptr)
32 {
33 	return HAL_RX_MSDU_DESC_INFO_GET(msdu_details_ptr);
34 }
35 
36 
37 #define HAL_RX_LINK_DESC_MSDU0_PTR(link_desc)   \
38 	((struct rx_msdu_details *) \
39 	 _OFFSET_TO_BYTE_PTR((link_desc),\
40 	UNIFIED_RX_MSDU_LINK_8_RX_MSDU_DETAILS_MSDU_0_OFFSET))
41 /**
42  * hal_rx_link_desc_msdu0_ptr_generic - Get pointer to rx_msdu details
43  * @link_desc - Pointer to link desc
44  * Return - Pointer to rx_msdu_details structure
45  *
46  */
47 
48 static void *hal_rx_link_desc_msdu0_ptr_generic(void *link_desc)
49 {
50 	return HAL_RX_LINK_DESC_MSDU0_PTR(link_desc);
51 }
52 
53 /**
54  * hal_tx_comp_get_status() - TQM Release reason
55  * @hal_desc: completion ring Tx status
56  *
57  * This function will parse the WBM completion descriptor and populate in
58  * HAL structure
59  *
60  * Return: none
61  */
62 #if defined(WCSS_VERSION) && \
63 	((defined(CONFIG_WIN) && (WCSS_VERSION > 81)) || \
64 	 (defined(CONFIG_MCL) && (WCSS_VERSION >= 72)))
65 static inline void hal_tx_comp_get_status_generic(void *desc,
66 		void *ts1)
67 {
68 	uint8_t rate_stats_valid = 0;
69 	uint32_t rate_stats = 0;
70 	struct hal_tx_completion_status *ts =
71 		(struct hal_tx_completion_status *)ts1;
72 
73 	ts->ppdu_id = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_3,
74 			TQM_STATUS_NUMBER);
75 	ts->ack_frame_rssi = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4,
76 			ACK_FRAME_RSSI);
77 	ts->first_msdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4, FIRST_MSDU);
78 	ts->last_msdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4, LAST_MSDU);
79 	ts->msdu_part_of_amsdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4,
80 			MSDU_PART_OF_AMSDU);
81 
82 	ts->peer_id = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_7, SW_PEER_ID);
83 	ts->tid = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_7, TID);
84 	ts->transmit_cnt = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_3,
85 			TRANSMIT_COUNT);
86 
87 	rate_stats = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_5,
88 			TX_RATE_STATS);
89 
90 	rate_stats_valid = HAL_TX_MS(TX_RATE_STATS_INFO_0,
91 			TX_RATE_STATS_INFO_VALID, rate_stats);
92 
93 	ts->valid = rate_stats_valid;
94 
95 	if (rate_stats_valid) {
96 		ts->bw = HAL_TX_MS(TX_RATE_STATS_INFO_0, TRANSMIT_BW,
97 				rate_stats);
98 		ts->pkt_type = HAL_TX_MS(TX_RATE_STATS_INFO_0,
99 				TRANSMIT_PKT_TYPE, rate_stats);
100 		ts->stbc = HAL_TX_MS(TX_RATE_STATS_INFO_0,
101 				TRANSMIT_STBC, rate_stats);
102 		ts->ldpc = HAL_TX_MS(TX_RATE_STATS_INFO_0, TRANSMIT_LDPC,
103 				rate_stats);
104 		ts->sgi = HAL_TX_MS(TX_RATE_STATS_INFO_0, TRANSMIT_SGI,
105 				rate_stats);
106 		ts->mcs = HAL_TX_MS(TX_RATE_STATS_INFO_0, TRANSMIT_MCS,
107 				rate_stats);
108 		ts->ofdma = HAL_TX_MS(TX_RATE_STATS_INFO_0, OFDMA_TRANSMISSION,
109 				rate_stats);
110 		ts->tones_in_ru = HAL_TX_MS(TX_RATE_STATS_INFO_0, TONES_IN_RU,
111 				rate_stats);
112 	}
113 
114 	ts->release_src = hal_tx_comp_get_buffer_source(desc);
115 	ts->status = hal_tx_comp_get_release_reason(desc);
116 
117 	ts->tsf = HAL_TX_DESC_GET(desc, UNIFIED_WBM_RELEASE_RING_6,
118 			TX_RATE_STATS_INFO_TX_RATE_STATS);
119 }
120 #else
121 static inline void hal_tx_comp_get_status_generic(void *desc,
122 		struct hal_tx_completion_status *ts)
123 {
124 
125 	ts->ppdu_id = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_3,
126 			TQM_STATUS_NUMBER);
127 	ts->ack_frame_rssi = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4,
128 			ACK_FRAME_RSSI);
129 	ts->first_msdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4, FIRST_MSDU);
130 	ts->last_msdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4, LAST_MSDU);
131 	ts->msdu_part_of_amsdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4,
132 			MSDU_PART_OF_AMSDU);
133 
134 	ts->release_src = hal_tx_comp_get_buffer_source(desc);
135 	ts->status = hal_tx_comp_get_release_reason(desc);
136 }
137 #endif
138 
139 
140 /**
141  * hal_tx_desc_set_buf_addr - Fill Buffer Address information in Tx Descriptor
142  * @desc: Handle to Tx Descriptor
143  * @paddr: Physical Address
144  * @pool_id: Return Buffer Manager ID
145  * @desc_id: Descriptor ID
146  * @type: 0 - Address points to a MSDU buffer
147  *		1 - Address points to MSDU extension descriptor
148  *
149  * Return: void
150  */
151 static inline void hal_tx_desc_set_buf_addr_generic(void *desc,
152 		dma_addr_t paddr, uint8_t pool_id,
153 		uint32_t desc_id, uint8_t type)
154 {
155 	/* Set buffer_addr_info.buffer_addr_31_0 */
156 	HAL_SET_FLD(desc, UNIFIED_TCL_DATA_CMD_0, BUFFER_ADDR_INFO_BUF_ADDR_INFO) =
157 		HAL_TX_SM(UNIFIED_BUFFER_ADDR_INFO_0, BUFFER_ADDR_31_0, paddr);
158 
159 	/* Set buffer_addr_info.buffer_addr_39_32 */
160 	HAL_SET_FLD(desc, UNIFIED_TCL_DATA_CMD_1,
161 			 BUFFER_ADDR_INFO_BUF_ADDR_INFO) |=
162 		HAL_TX_SM(UNIFIED_BUFFER_ADDR_INFO_1, BUFFER_ADDR_39_32,
163 		       (((uint64_t) paddr) >> 32));
164 
165 	/* Set buffer_addr_info.return_buffer_manager = pool id */
166 	HAL_SET_FLD(desc, UNIFIED_TCL_DATA_CMD_1,
167 			 BUFFER_ADDR_INFO_BUF_ADDR_INFO) |=
168 		HAL_TX_SM(UNIFIED_BUFFER_ADDR_INFO_1,
169 		       RETURN_BUFFER_MANAGER, (pool_id + HAL_WBM_SW0_BM_ID));
170 
171 	/* Set buffer_addr_info.sw_buffer_cookie = desc_id */
172 	HAL_SET_FLD(desc, UNIFIED_TCL_DATA_CMD_1,
173 			BUFFER_ADDR_INFO_BUF_ADDR_INFO) |=
174 		HAL_TX_SM(UNIFIED_BUFFER_ADDR_INFO_1, SW_BUFFER_COOKIE, desc_id);
175 
176 	/* Set  Buffer or Ext Descriptor Type */
177 	HAL_SET_FLD(desc, UNIFIED_TCL_DATA_CMD_2,
178 			BUF_OR_EXT_DESC_TYPE) |=
179 		HAL_TX_SM(UNIFIED_TCL_DATA_CMD_2, BUF_OR_EXT_DESC_TYPE, type);
180 }
181 
182 #if defined(CONFIG_MCL) && defined(QCA_WIFI_QCA6290_11AX)
183 /**
184  * hal_rx_handle_other_tlvs() - handle special TLVs like MU_UL
185  * tlv_tag: Taf of the TLVs
186  * rx_tlv: the pointer to the TLVs
187  * @ppdu_info: pointer to ppdu_info
188  *
189  * Return: true if the tlv is handled, false if not
190  */
191 static inline bool
192 hal_rx_handle_other_tlvs(uint32_t tlv_tag, void *rx_tlv,
193 			 struct hal_rx_ppdu_info *ppdu_info)
194 {
195 	uint32_t value;
196 
197 	switch (tlv_tag) {
198 	case WIFIPHYRX_HE_SIG_A_MU_UL_E:
199 	{
200 		uint8_t *he_sig_a_mu_ul_info =
201 			(uint8_t *)rx_tlv +
202 			HAL_RX_OFFSET(PHYRX_HE_SIG_A_MU_UL_0,
203 					  HE_SIG_A_MU_UL_INFO_PHYRX_HE_SIG_A_MU_UL_INFO_DETAILS);
204 		ppdu_info->rx_status.he_flags = 1;
205 
206 		value = HAL_RX_GET(he_sig_a_mu_ul_info, HE_SIG_A_MU_UL_INFO_0,
207 				   FORMAT_INDICATION);
208 		if (value == 0) {
209 			ppdu_info->rx_status.he_data1 =
210 				QDF_MON_STATUS_HE_TRIG_FORMAT_TYPE;
211 		} else {
212 			 ppdu_info->rx_status.he_data1 =
213 				QDF_MON_STATUS_HE_SU_FORMAT_TYPE;
214 		}
215 		return true;
216 	}
217 	default:
218 		return false;
219 	}
220 }
221 #else
222 static inline bool
223 hal_rx_handle_other_tlvs(uint32_t tlv_tag, void *rx_tlv,
224 			 struct hal_rx_ppdu_info *ppdu_info)
225 {
226 	return false;
227 }
228 #endif /* CONFIG_MCL && QCA_WIFI_QCA6290_11AX */
229 
230 /**
231  * hal_rx_status_get_tlv_info() - process receive info TLV
232  * @rx_tlv_hdr: pointer to TLV header
233  * @ppdu_info: pointer to ppdu_info
234  *
235  * Return: HAL_TLV_STATUS_PPDU_NOT_DONE or HAL_TLV_STATUS_PPDU_DONE from tlv
236  */
237 static inline uint32_t
238 hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo,
239 			   void *halsoc)
240 {
241 	struct hal_soc *hal = (struct hal_soc *)halsoc;
242 	uint32_t tlv_tag, user_id, tlv_len, value;
243 	uint8_t group_id = 0;
244 	uint8_t he_dcm = 0;
245 	uint8_t he_stbc = 0;
246 	uint16_t he_gi = 0;
247 	uint16_t he_ltf = 0;
248 	void *rx_tlv;
249 	bool unhandled = false;
250 	struct hal_rx_ppdu_info *ppdu_info =
251 			(struct hal_rx_ppdu_info *)ppduinfo;
252 
253 	tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv_hdr);
254 	user_id = HAL_RX_GET_USER_TLV32_USERID(rx_tlv_hdr);
255 	tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv_hdr);
256 
257 	rx_tlv = (uint8_t *)rx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE;
258 	switch (tlv_tag) {
259 
260 	case WIFIRX_PPDU_START_E:
261 		ppdu_info->com_info.ppdu_id =
262 			HAL_RX_GET(rx_tlv, RX_PPDU_START_0,
263 				PHY_PPDU_ID);
264 		/* channel number is set in PHY meta data */
265 		ppdu_info->rx_status.chan_num =
266 			HAL_RX_GET(rx_tlv, RX_PPDU_START_1,
267 				SW_PHY_META_DATA);
268 		ppdu_info->com_info.ppdu_timestamp =
269 			HAL_RX_GET(rx_tlv, RX_PPDU_START_2,
270 				PPDU_START_TIMESTAMP);
271 		ppdu_info->rx_state = HAL_RX_MON_PPDU_START;
272 		break;
273 
274 	case WIFIRX_PPDU_START_USER_INFO_E:
275 		break;
276 
277 	case WIFIRX_PPDU_END_E:
278 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
279 			"[%s][%d] ppdu_end_e len=%d",
280 				__func__, __LINE__, tlv_len);
281 		/* This is followed by sub-TLVs of PPDU_END */
282 		ppdu_info->rx_state = HAL_RX_MON_PPDU_END;
283 		break;
284 
285 	case WIFIRXPCU_PPDU_END_INFO_E:
286 		ppdu_info->rx_status.tsft =
287 			HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_1,
288 				WB_TIMESTAMP_UPPER_32);
289 		ppdu_info->rx_status.tsft = (ppdu_info->rx_status.tsft << 32) |
290 			HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_0,
291 				WB_TIMESTAMP_LOWER_32);
292 		ppdu_info->rx_status.duration =
293 			HAL_RX_GET(rx_tlv, UNIFIED_RXPCU_PPDU_END_INFO_8,
294 				RX_PPDU_DURATION);
295 		break;
296 
297 	case WIFIRX_PPDU_END_USER_STATS_E:
298 	{
299 		unsigned long tid = 0;
300 		uint16_t seq = 0;
301 
302 		ppdu_info->rx_status.ast_index =
303 				HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_4,
304 						AST_INDEX);
305 
306 		tid = HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_12,
307 				RECEIVED_QOS_DATA_TID_BITMAP);
308 		ppdu_info->rx_status.tid = qdf_find_first_bit(&tid, sizeof(tid)*8);
309 
310 		if (ppdu_info->rx_status.tid == (sizeof(tid) * 8))
311 			ppdu_info->rx_status.tid = HAL_TID_INVALID;
312 
313 		ppdu_info->rx_status.tcp_msdu_count =
314 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_9,
315 					TCP_MSDU_COUNT) +
316 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_10,
317 					TCP_ACK_MSDU_COUNT);
318 		ppdu_info->rx_status.udp_msdu_count =
319 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_9,
320 						UDP_MSDU_COUNT);
321 		ppdu_info->rx_status.other_msdu_count =
322 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_10,
323 					OTHER_MSDU_COUNT);
324 
325 		ppdu_info->rx_status.frame_control_info_valid =
326 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3,
327 					DATA_SEQUENCE_CONTROL_INFO_VALID);
328 
329 		seq = HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_5,
330 					FIRST_DATA_SEQ_CTRL);
331 		if (ppdu_info->rx_status.frame_control_info_valid)
332 			ppdu_info->rx_status.first_data_seq_ctrl = seq;
333 
334 		ppdu_info->rx_status.preamble_type =
335 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3,
336 						HT_CONTROL_FIELD_PKT_TYPE);
337 		switch (ppdu_info->rx_status.preamble_type) {
338 		case HAL_RX_PKT_TYPE_11N:
339 			ppdu_info->rx_status.ht_flags = 1;
340 			ppdu_info->rx_status.rtap_flags |= HT_SGI_PRESENT;
341 			break;
342 		case HAL_RX_PKT_TYPE_11AC:
343 			ppdu_info->rx_status.vht_flags = 1;
344 			break;
345 		case HAL_RX_PKT_TYPE_11AX:
346 			ppdu_info->rx_status.he_flags = 1;
347 			break;
348 		default:
349 			break;
350 		}
351 
352 		ppdu_info->com_info.mpdu_cnt_fcs_ok =
353 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_3,
354 					MPDU_CNT_FCS_OK);
355 		ppdu_info->com_info.mpdu_cnt_fcs_err =
356 			HAL_RX_GET(rx_tlv, RX_PPDU_END_USER_STATS_2,
357 					MPDU_CNT_FCS_ERR);
358 		if ((ppdu_info->com_info.mpdu_cnt_fcs_ok |
359 			ppdu_info->com_info.mpdu_cnt_fcs_err) > 1)
360 			ppdu_info->rx_status.rs_flags |= IEEE80211_AMPDU_FLAG;
361 		else
362 			ppdu_info->rx_status.rs_flags &=
363 				(~IEEE80211_AMPDU_FLAG);
364 		break;
365 	}
366 
367 	case WIFIRX_PPDU_END_USER_STATS_EXT_E:
368 		break;
369 
370 	case WIFIRX_PPDU_END_STATUS_DONE_E:
371 		return HAL_TLV_STATUS_PPDU_DONE;
372 
373 	case WIFIDUMMY_E:
374 		return HAL_TLV_STATUS_BUF_DONE;
375 
376 	case WIFIPHYRX_HT_SIG_E:
377 	{
378 		uint8_t *ht_sig_info = (uint8_t *)rx_tlv +
379 				HAL_RX_OFFSET(UNIFIED_PHYRX_HT_SIG_0,
380 				HT_SIG_INFO_PHYRX_HT_SIG_INFO_DETAILS);
381 		value = HAL_RX_GET(ht_sig_info, HT_SIG_INFO_1,
382 				FEC_CODING);
383 		ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ?
384 			1 : 0;
385 		ppdu_info->rx_status.mcs = HAL_RX_GET(ht_sig_info,
386 				HT_SIG_INFO_0, MCS);
387 		ppdu_info->rx_status.bw = HAL_RX_GET(ht_sig_info,
388 				HT_SIG_INFO_0, CBW);
389 		ppdu_info->rx_status.sgi = HAL_RX_GET(ht_sig_info,
390 				HT_SIG_INFO_1, SHORT_GI);
391 		ppdu_info->rx_status.reception_type = HAL_RX_TYPE_SU;
392 		break;
393 	}
394 
395 	case WIFIPHYRX_L_SIG_B_E:
396 	{
397 		uint8_t *l_sig_b_info = (uint8_t *)rx_tlv +
398 				HAL_RX_OFFSET(UNIFIED_PHYRX_L_SIG_B_0,
399 				L_SIG_B_INFO_PHYRX_L_SIG_B_INFO_DETAILS);
400 
401 		value = HAL_RX_GET(l_sig_b_info, L_SIG_B_INFO_0, RATE);
402 		switch (value) {
403 		case 1:
404 			ppdu_info->rx_status.rate = HAL_11B_RATE_3MCS;
405 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS3;
406 			break;
407 		case 2:
408 			ppdu_info->rx_status.rate = HAL_11B_RATE_2MCS;
409 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS2;
410 			break;
411 		case 3:
412 			ppdu_info->rx_status.rate = HAL_11B_RATE_1MCS;
413 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS1;
414 			break;
415 		case 4:
416 			ppdu_info->rx_status.rate = HAL_11B_RATE_0MCS;
417 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS0;
418 			break;
419 		case 5:
420 			ppdu_info->rx_status.rate = HAL_11B_RATE_6MCS;
421 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS6;
422 			break;
423 		case 6:
424 			ppdu_info->rx_status.rate = HAL_11B_RATE_5MCS;
425 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS5;
426 			break;
427 		case 7:
428 			ppdu_info->rx_status.rate = HAL_11B_RATE_4MCS;
429 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS4;
430 			break;
431 		default:
432 			break;
433 		}
434 		ppdu_info->rx_status.cck_flag = 1;
435 		ppdu_info->rx_status.reception_type = HAL_RX_TYPE_SU;
436 	break;
437 	}
438 
439 	case WIFIPHYRX_L_SIG_A_E:
440 	{
441 		uint8_t *l_sig_a_info = (uint8_t *)rx_tlv +
442 				HAL_RX_OFFSET(UNIFIED_PHYRX_L_SIG_A_0,
443 				L_SIG_A_INFO_PHYRX_L_SIG_A_INFO_DETAILS);
444 
445 		value = HAL_RX_GET(l_sig_a_info, L_SIG_A_INFO_0, RATE);
446 		switch (value) {
447 		case 8:
448 			ppdu_info->rx_status.rate = HAL_11A_RATE_0MCS;
449 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS0;
450 			break;
451 		case 9:
452 			ppdu_info->rx_status.rate = HAL_11A_RATE_1MCS;
453 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS1;
454 			break;
455 		case 10:
456 			ppdu_info->rx_status.rate = HAL_11A_RATE_2MCS;
457 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS2;
458 			break;
459 		case 11:
460 			ppdu_info->rx_status.rate = HAL_11A_RATE_3MCS;
461 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS3;
462 			break;
463 		case 12:
464 			ppdu_info->rx_status.rate = HAL_11A_RATE_4MCS;
465 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS4;
466 			break;
467 		case 13:
468 			ppdu_info->rx_status.rate = HAL_11A_RATE_5MCS;
469 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS5;
470 			break;
471 		case 14:
472 			ppdu_info->rx_status.rate = HAL_11A_RATE_6MCS;
473 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS6;
474 			break;
475 		case 15:
476 			ppdu_info->rx_status.rate = HAL_11A_RATE_7MCS;
477 			ppdu_info->rx_status.mcs = HAL_LEGACY_MCS7;
478 			break;
479 		default:
480 			break;
481 		}
482 		ppdu_info->rx_status.ofdm_flag = 1;
483 		ppdu_info->rx_status.reception_type = HAL_RX_TYPE_SU;
484 	break;
485 	}
486 
487 	case WIFIPHYRX_VHT_SIG_A_E:
488 	{
489 		uint8_t *vht_sig_a_info = (uint8_t *)rx_tlv +
490 				HAL_RX_OFFSET(UNIFIED_PHYRX_VHT_SIG_A_0,
491 				VHT_SIG_A_INFO_PHYRX_VHT_SIG_A_INFO_DETAILS);
492 
493 		value = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_1,
494 				SU_MU_CODING);
495 		ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ?
496 			1 : 0;
497 		group_id = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_0, GROUP_ID);
498 		ppdu_info->rx_status.vht_flag_values5 = group_id;
499 		ppdu_info->rx_status.mcs = HAL_RX_GET(vht_sig_a_info,
500 				VHT_SIG_A_INFO_1, MCS);
501 		ppdu_info->rx_status.sgi = HAL_RX_GET(vht_sig_a_info,
502 				VHT_SIG_A_INFO_1, GI_SETTING);
503 
504 		switch (hal->target_type) {
505 		case TARGET_TYPE_QCA8074:
506 		case TARGET_TYPE_QCA8074V2:
507 			ppdu_info->rx_status.is_stbc =
508 				HAL_RX_GET(vht_sig_a_info,
509 					   VHT_SIG_A_INFO_0, STBC);
510 			value =  HAL_RX_GET(vht_sig_a_info,
511 					    VHT_SIG_A_INFO_0, N_STS);
512 			if (ppdu_info->rx_status.is_stbc && (value > 0))
513 				value = ((value + 1) >> 1) - 1;
514 			ppdu_info->rx_status.nss =
515 				((value & VHT_SIG_SU_NSS_MASK) + 1);
516 
517 			break;
518 		case TARGET_TYPE_QCA6290:
519 #if !defined(QCA_WIFI_QCA6290_11AX)
520 			ppdu_info->rx_status.is_stbc =
521 				HAL_RX_GET(vht_sig_a_info,
522 					   VHT_SIG_A_INFO_0, STBC);
523 			value =  HAL_RX_GET(vht_sig_a_info,
524 					    VHT_SIG_A_INFO_0, N_STS);
525 			if (ppdu_info->rx_status.is_stbc && (value > 0))
526 				value = ((value + 1) >> 1) - 1;
527 			ppdu_info->rx_status.nss =
528 				((value & VHT_SIG_SU_NSS_MASK) + 1);
529 #else
530 			ppdu_info->rx_status.nss = 0;
531 #endif
532 			break;
533 #ifdef QCA_WIFI_QCA6390
534 		case TARGET_TYPE_QCA6390:
535 			ppdu_info->rx_status.nss = 0;
536 			break;
537 #endif
538 		default:
539 			break;
540 		}
541 		ppdu_info->rx_status.vht_flag_values3[0] =
542 				(((ppdu_info->rx_status.mcs) << 4)
543 				| ppdu_info->rx_status.nss);
544 		ppdu_info->rx_status.bw = HAL_RX_GET(vht_sig_a_info,
545 				VHT_SIG_A_INFO_0, BANDWIDTH);
546 		ppdu_info->rx_status.vht_flag_values2 =
547 			ppdu_info->rx_status.bw;
548 		ppdu_info->rx_status.vht_flag_values4 =
549 			HAL_RX_GET(vht_sig_a_info,
550 				  VHT_SIG_A_INFO_1, SU_MU_CODING);
551 
552 		ppdu_info->rx_status.beamformed = HAL_RX_GET(vht_sig_a_info,
553 				VHT_SIG_A_INFO_1, BEAMFORMED);
554 		if (group_id == 0 || group_id == 63)
555 			ppdu_info->rx_status.reception_type = HAL_RX_TYPE_SU;
556 		else
557 			ppdu_info->rx_status.reception_type =
558 				HAL_RX_TYPE_MU_MIMO;
559 
560 		break;
561 	}
562 	case WIFIPHYRX_HE_SIG_A_SU_E:
563 	{
564 		uint8_t *he_sig_a_su_info = (uint8_t *)rx_tlv +
565 			HAL_RX_OFFSET(UNIFIED_PHYRX_HE_SIG_A_SU_0,
566 			HE_SIG_A_SU_INFO_PHYRX_HE_SIG_A_SU_INFO_DETAILS);
567 		ppdu_info->rx_status.he_flags = 1;
568 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0,
569 			FORMAT_INDICATION);
570 		if (value == 0) {
571 			ppdu_info->rx_status.he_data1 =
572 				QDF_MON_STATUS_HE_TRIG_FORMAT_TYPE;
573 		} else {
574 			 ppdu_info->rx_status.he_data1 =
575 				 QDF_MON_STATUS_HE_SU_FORMAT_TYPE;
576 		}
577 
578 		/* data1 */
579 		ppdu_info->rx_status.he_data1 |=
580 			QDF_MON_STATUS_HE_BSS_COLOR_KNOWN |
581 			QDF_MON_STATUS_HE_BEAM_CHANGE_KNOWN |
582 			QDF_MON_STATUS_HE_DL_UL_KNOWN |
583 			QDF_MON_STATUS_HE_MCS_KNOWN |
584 			QDF_MON_STATUS_HE_DCM_KNOWN |
585 			QDF_MON_STATUS_HE_CODING_KNOWN |
586 			QDF_MON_STATUS_HE_LDPC_EXTRA_SYMBOL_KNOWN |
587 			QDF_MON_STATUS_HE_STBC_KNOWN |
588 			QDF_MON_STATUS_HE_DATA_BW_RU_KNOWN |
589 			QDF_MON_STATUS_HE_DOPPLER_KNOWN;
590 
591 		/* data2 */
592 		ppdu_info->rx_status.he_data2 =
593 			QDF_MON_STATUS_HE_GI_KNOWN;
594 		ppdu_info->rx_status.he_data2 |=
595 			QDF_MON_STATUS_TXBF_KNOWN |
596 			QDF_MON_STATUS_PE_DISAMBIGUITY_KNOWN |
597 			QDF_MON_STATUS_TXOP_KNOWN |
598 			QDF_MON_STATUS_LTF_SYMBOLS_KNOWN |
599 			QDF_MON_STATUS_PRE_FEC_PADDING_KNOWN |
600 			QDF_MON_STATUS_MIDABLE_PERIODICITY_KNOWN;
601 
602 		/* data3 */
603 		value = HAL_RX_GET(he_sig_a_su_info,
604 				HE_SIG_A_SU_INFO_0, BSS_COLOR_ID);
605 		ppdu_info->rx_status.he_data3 = value;
606 		value = HAL_RX_GET(he_sig_a_su_info,
607 				HE_SIG_A_SU_INFO_0, BEAM_CHANGE);
608 		value = value << QDF_MON_STATUS_BEAM_CHANGE_SHIFT;
609 		ppdu_info->rx_status.he_data3 |= value;
610 		value = HAL_RX_GET(he_sig_a_su_info,
611 				HE_SIG_A_SU_INFO_0, DL_UL_FLAG);
612 		value = value << QDF_MON_STATUS_DL_UL_SHIFT;
613 		ppdu_info->rx_status.he_data3 |= value;
614 
615 		value = HAL_RX_GET(he_sig_a_su_info,
616 				HE_SIG_A_SU_INFO_0, TRANSMIT_MCS);
617 		ppdu_info->rx_status.mcs = value;
618 		value = value << QDF_MON_STATUS_TRANSMIT_MCS_SHIFT;
619 		ppdu_info->rx_status.he_data3 |= value;
620 
621 		value = HAL_RX_GET(he_sig_a_su_info,
622 				HE_SIG_A_SU_INFO_0, DCM);
623 		he_dcm = value;
624 		value = value << QDF_MON_STATUS_DCM_SHIFT;
625 		ppdu_info->rx_status.he_data3 |= value;
626 		value = HAL_RX_GET(he_sig_a_su_info,
627 				HE_SIG_A_SU_INFO_1, CODING);
628 		value = value << QDF_MON_STATUS_CODING_SHIFT;
629 		ppdu_info->rx_status.he_data3 |= value;
630 		value = HAL_RX_GET(he_sig_a_su_info,
631 				HE_SIG_A_SU_INFO_1,
632 				LDPC_EXTRA_SYMBOL);
633 		value = value << QDF_MON_STATUS_LDPC_EXTRA_SYMBOL_SHIFT;
634 		ppdu_info->rx_status.he_data3 |= value;
635 		value = HAL_RX_GET(he_sig_a_su_info,
636 				HE_SIG_A_SU_INFO_1, STBC);
637 		he_stbc = value;
638 		value = value << QDF_MON_STATUS_STBC_SHIFT;
639 		ppdu_info->rx_status.he_data3 |= value;
640 
641 		/* data4 */
642 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0,
643 							SPATIAL_REUSE);
644 		ppdu_info->rx_status.he_data4 = value;
645 
646 		/* data5 */
647 		value = HAL_RX_GET(he_sig_a_su_info,
648 				HE_SIG_A_SU_INFO_0, TRANSMIT_BW);
649 		ppdu_info->rx_status.he_data5 = value;
650 		ppdu_info->rx_status.bw = value;
651 		value = HAL_RX_GET(he_sig_a_su_info,
652 				HE_SIG_A_SU_INFO_0, CP_LTF_SIZE);
653 		switch (value) {
654 		case 0:
655 				he_gi = HE_GI_0_8;
656 				he_ltf = HE_LTF_1_X;
657 				break;
658 		case 1:
659 				he_gi = HE_GI_0_8;
660 				he_ltf = HE_LTF_2_X;
661 				break;
662 		case 2:
663 				he_gi = HE_GI_1_6;
664 				he_ltf = HE_LTF_2_X;
665 				break;
666 		case 3:
667 				if (he_dcm && he_stbc) {
668 					he_gi = HE_GI_0_8;
669 					he_ltf = HE_LTF_4_X;
670 				} else {
671 					he_gi = HE_GI_3_2;
672 					he_ltf = HE_LTF_4_X;
673 				}
674 				break;
675 		}
676 		ppdu_info->rx_status.sgi = he_gi;
677 		value = he_gi << QDF_MON_STATUS_GI_SHIFT;
678 		ppdu_info->rx_status.he_data5 |= value;
679 		value = he_ltf << QDF_MON_STATUS_HE_LTF_SIZE_SHIFT;
680 		ppdu_info->rx_status.he_data5 |= value;
681 
682 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0, NSTS);
683 		value = (value << QDF_MON_STATUS_HE_LTF_SYM_SHIFT);
684 		ppdu_info->rx_status.he_data5 |= value;
685 
686 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1,
687 						PACKET_EXTENSION_A_FACTOR);
688 		value = value << QDF_MON_STATUS_PRE_FEC_PAD_SHIFT;
689 		ppdu_info->rx_status.he_data5 |= value;
690 
691 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1, TXBF);
692 		value = value << QDF_MON_STATUS_TXBF_SHIFT;
693 		ppdu_info->rx_status.he_data5 |= value;
694 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1,
695 					PACKET_EXTENSION_PE_DISAMBIGUITY);
696 		value = value << QDF_MON_STATUS_PE_DISAMBIGUITY_SHIFT;
697 		ppdu_info->rx_status.he_data5 |= value;
698 
699 		/* data6 */
700 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_0, NSTS);
701 		value++;
702 		ppdu_info->rx_status.nss = value;
703 		ppdu_info->rx_status.he_data6 = value;
704 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1,
705 							DOPPLER_INDICATION);
706 		value = value << QDF_MON_STATUS_DOPPLER_SHIFT;
707 		ppdu_info->rx_status.he_data6 |= value;
708 		value = HAL_RX_GET(he_sig_a_su_info, HE_SIG_A_SU_INFO_1,
709 							TXOP_DURATION);
710 		value = value << QDF_MON_STATUS_TXOP_SHIFT;
711 		ppdu_info->rx_status.he_data6 |= value;
712 
713 		ppdu_info->rx_status.beamformed = HAL_RX_GET(he_sig_a_su_info,
714 					HE_SIG_A_SU_INFO_1, TXBF);
715 		ppdu_info->rx_status.reception_type = HAL_RX_TYPE_SU;
716 		break;
717 	}
718 	case WIFIPHYRX_HE_SIG_A_MU_DL_E:
719 	{
720 		uint8_t *he_sig_a_mu_dl_info = (uint8_t *)rx_tlv +
721 			HAL_RX_OFFSET(UNIFIED_PHYRX_HE_SIG_A_MU_DL_0,
722 			HE_SIG_A_MU_DL_INFO_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS);
723 
724 		ppdu_info->rx_status.he_mu_flags = 1;
725 
726 		/* HE Flags */
727 		/*data1*/
728 		ppdu_info->rx_status.he_data1 =
729 					QDF_MON_STATUS_HE_MU_FORMAT_TYPE;
730 		ppdu_info->rx_status.he_data1 |=
731 			QDF_MON_STATUS_HE_BSS_COLOR_KNOWN |
732 			QDF_MON_STATUS_HE_DL_UL_KNOWN |
733 			QDF_MON_STATUS_HE_LDPC_EXTRA_SYMBOL_KNOWN |
734 			QDF_MON_STATUS_HE_STBC_KNOWN |
735 			QDF_MON_STATUS_HE_DATA_BW_RU_KNOWN |
736 			QDF_MON_STATUS_HE_DOPPLER_KNOWN;
737 
738 		/* data2 */
739 		ppdu_info->rx_status.he_data2 =
740 			QDF_MON_STATUS_HE_GI_KNOWN;
741 		ppdu_info->rx_status.he_data2 |=
742 			QDF_MON_STATUS_LTF_SYMBOLS_KNOWN |
743 			QDF_MON_STATUS_PRE_FEC_PADDING_KNOWN |
744 			QDF_MON_STATUS_PE_DISAMBIGUITY_KNOWN |
745 			QDF_MON_STATUS_TXOP_KNOWN |
746 			QDF_MON_STATUS_MIDABLE_PERIODICITY_KNOWN;
747 
748 		/*data3*/
749 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
750 				HE_SIG_A_MU_DL_INFO_0, BSS_COLOR_ID);
751 		ppdu_info->rx_status.he_data3 = value;
752 
753 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
754 				HE_SIG_A_MU_DL_INFO_0, DL_UL_FLAG);
755 		value = value << QDF_MON_STATUS_DL_UL_SHIFT;
756 		ppdu_info->rx_status.he_data3 |= value;
757 
758 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
759 				HE_SIG_A_MU_DL_INFO_1,
760 				LDPC_EXTRA_SYMBOL);
761 		value = value << QDF_MON_STATUS_LDPC_EXTRA_SYMBOL_SHIFT;
762 		ppdu_info->rx_status.he_data3 |= value;
763 
764 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
765 				HE_SIG_A_MU_DL_INFO_1, STBC);
766 		he_stbc = value;
767 		value = value << QDF_MON_STATUS_STBC_SHIFT;
768 		ppdu_info->rx_status.he_data3 |= value;
769 
770 		/*data4*/
771 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_0,
772 							SPATIAL_REUSE);
773 		ppdu_info->rx_status.he_data4 = value;
774 
775 		/*data5*/
776 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
777 				HE_SIG_A_MU_DL_INFO_0, TRANSMIT_BW);
778 		ppdu_info->rx_status.he_data5 = value;
779 		ppdu_info->rx_status.bw = value;
780 
781 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
782 				HE_SIG_A_MU_DL_INFO_0, CP_LTF_SIZE);
783 		switch (value) {
784 		case 0:
785 			he_gi = HE_GI_0_8;
786 			he_ltf = HE_LTF_4_X;
787 			break;
788 		case 1:
789 			he_gi = HE_GI_0_8;
790 			he_ltf = HE_LTF_2_X;
791 			break;
792 		case 2:
793 			he_gi = HE_GI_1_6;
794 			he_ltf = HE_LTF_2_X;
795 			break;
796 		case 3:
797 			he_gi = HE_GI_3_2;
798 			he_ltf = HE_LTF_4_X;
799 			break;
800 		}
801 		ppdu_info->rx_status.sgi = he_gi;
802 		value = he_gi << QDF_MON_STATUS_GI_SHIFT;
803 		ppdu_info->rx_status.he_data5 |= value;
804 
805 		value = he_ltf << QDF_MON_STATUS_HE_LTF_SIZE_SHIFT;
806 		ppdu_info->rx_status.he_data5 |= value;
807 
808 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
809 				   HE_SIG_A_MU_DL_INFO_1, NUM_LTF_SYMBOLS);
810 		value = (value << QDF_MON_STATUS_HE_LTF_SYM_SHIFT);
811 		ppdu_info->rx_status.he_data5 |= value;
812 
813 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_1,
814 				   PACKET_EXTENSION_A_FACTOR);
815 		value = value << QDF_MON_STATUS_PRE_FEC_PAD_SHIFT;
816 		ppdu_info->rx_status.he_data5 |= value;
817 
818 
819 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_1,
820 				   PACKET_EXTENSION_PE_DISAMBIGUITY);
821 		value = value << QDF_MON_STATUS_PE_DISAMBIGUITY_SHIFT;
822 		ppdu_info->rx_status.he_data5 |= value;
823 
824 		/*data6*/
825 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_0,
826 							DOPPLER_INDICATION);
827 		value = value << QDF_MON_STATUS_DOPPLER_SHIFT;
828 		ppdu_info->rx_status.he_data6 |= value;
829 
830 		value = HAL_RX_GET(he_sig_a_mu_dl_info, HE_SIG_A_MU_DL_INFO_1,
831 							TXOP_DURATION);
832 		value = value << QDF_MON_STATUS_TXOP_SHIFT;
833 		ppdu_info->rx_status.he_data6 |= value;
834 
835 		/* HE-MU Flags */
836 		/* HE-MU-flags1 */
837 		ppdu_info->rx_status.he_flags1 =
838 			QDF_MON_STATUS_SIG_B_MCS_KNOWN |
839 			QDF_MON_STATUS_SIG_B_DCM_KNOWN |
840 			QDF_MON_STATUS_SIG_B_COMPRESSION_FLAG_1_KNOWN |
841 			QDF_MON_STATUS_SIG_B_SYM_NUM_KNOWN |
842 			QDF_MON_STATUS_RU_0_KNOWN;
843 
844 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
845 				HE_SIG_A_MU_DL_INFO_0, MCS_OF_SIG_B);
846 		ppdu_info->rx_status.he_flags1 |= value;
847 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
848 				HE_SIG_A_MU_DL_INFO_0, DCM_OF_SIG_B);
849 		value = value << QDF_MON_STATUS_DCM_FLAG_1_SHIFT;
850 		ppdu_info->rx_status.he_flags1 |= value;
851 
852 		/* HE-MU-flags2 */
853 		ppdu_info->rx_status.he_flags2 =
854 			QDF_MON_STATUS_BW_KNOWN;
855 
856 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
857 				HE_SIG_A_MU_DL_INFO_0, TRANSMIT_BW);
858 		ppdu_info->rx_status.he_flags2 |= value;
859 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
860 				HE_SIG_A_MU_DL_INFO_0, COMP_MODE_SIG_B);
861 		value = value << QDF_MON_STATUS_SIG_B_COMPRESSION_FLAG_2_SHIFT;
862 		ppdu_info->rx_status.he_flags2 |= value;
863 		value = HAL_RX_GET(he_sig_a_mu_dl_info,
864 				HE_SIG_A_MU_DL_INFO_0, NUM_SIG_B_SYMBOLS);
865 		value = value - 1;
866 		value = value << QDF_MON_STATUS_NUM_SIG_B_SYMBOLS_SHIFT;
867 		ppdu_info->rx_status.he_flags2 |= value;
868 		ppdu_info->rx_status.reception_type = HAL_RX_TYPE_MU_MIMO;
869 		break;
870 	}
871 	case WIFIPHYRX_HE_SIG_B1_MU_E:
872 	{
873 
874 		uint8_t *he_sig_b1_mu_info = (uint8_t *)rx_tlv +
875 			HAL_RX_OFFSET(UNIFIED_PHYRX_HE_SIG_B1_MU_0,
876 			HE_SIG_B1_MU_INFO_PHYRX_HE_SIG_B1_MU_INFO_DETAILS);
877 
878 		ppdu_info->rx_status.he_sig_b_common_known |=
879 			QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0;
880 		/* TODO: Check on the availability of other fields in
881 		 * sig_b_common
882 		 */
883 
884 		value = HAL_RX_GET(he_sig_b1_mu_info,
885 				HE_SIG_B1_MU_INFO_0, RU_ALLOCATION);
886 		ppdu_info->rx_status.he_RU[0] = value;
887 		ppdu_info->rx_status.reception_type = HAL_RX_TYPE_MU_MIMO;
888 		break;
889 	}
890 	case WIFIPHYRX_HE_SIG_B2_MU_E:
891 	{
892 		uint8_t *he_sig_b2_mu_info = (uint8_t *)rx_tlv +
893 			HAL_RX_OFFSET(UNIFIED_PHYRX_HE_SIG_B2_MU_0,
894 			HE_SIG_B2_MU_INFO_PHYRX_HE_SIG_B2_MU_INFO_DETAILS);
895 		/*
896 		 * Not all "HE" fields can be updated from
897 		 * WIFIPHYRX_HE_SIG_A_MU_DL_E TLV. Use WIFIPHYRX_HE_SIG_B2_MU_E
898 		 * to populate rest of the "HE" fields for MU scenarios.
899 		 */
900 
901 		/* HE-data1 */
902 		ppdu_info->rx_status.he_data1 |=
903 			QDF_MON_STATUS_HE_MCS_KNOWN |
904 			QDF_MON_STATUS_HE_CODING_KNOWN;
905 
906 		/* HE-data2 */
907 
908 		/* HE-data3 */
909 		value = HAL_RX_GET(he_sig_b2_mu_info,
910 				HE_SIG_B2_MU_INFO_0, STA_MCS);
911 		ppdu_info->rx_status.mcs = value;
912 		value = value << QDF_MON_STATUS_TRANSMIT_MCS_SHIFT;
913 		ppdu_info->rx_status.he_data3 |= value;
914 
915 
916 		value = HAL_RX_GET(he_sig_b2_mu_info,
917 				HE_SIG_B2_MU_INFO_0, STA_CODING);
918 		value = value << QDF_MON_STATUS_CODING_SHIFT;
919 		ppdu_info->rx_status.he_data3 |= value;
920 
921 		/* HE-data4 */
922 		value = HAL_RX_GET(he_sig_b2_mu_info,
923 				HE_SIG_B2_MU_INFO_0, STA_ID);
924 		value = value << QDF_MON_STATUS_STA_ID_SHIFT;
925 		ppdu_info->rx_status.he_data4 |= value;
926 
927 		/* HE-data5 */
928 
929 		/* HE-data6 */
930 		value = HAL_RX_GET(he_sig_b2_mu_info,
931 				   HE_SIG_B2_MU_INFO_0, NSTS);
932 		/* value n indicates n+1 spatial streams */
933 		value++;
934 		ppdu_info->rx_status.nss = value;
935 		ppdu_info->rx_status.he_data6 |= value;
936 
937 		break;
938 
939 	}
940 	case WIFIPHYRX_HE_SIG_B2_OFDMA_E:
941 	{
942 		uint8_t *he_sig_b2_ofdma_info =
943 		(uint8_t *)rx_tlv +
944 		HAL_RX_OFFSET(UNIFIED_PHYRX_HE_SIG_B2_OFDMA_0,
945 		HE_SIG_B2_OFDMA_INFO_PHYRX_HE_SIG_B2_OFDMA_INFO_DETAILS);
946 
947 		/*
948 		 * Not all "HE" fields can be updated from
949 		 * WIFIPHYRX_HE_SIG_A_MU_DL_E TLV. Use WIFIPHYRX_HE_SIG_B2_MU_E
950 		 * to populate rest of "HE" fields for MU OFDMA scenarios.
951 		 */
952 
953 		/* HE-data1 */
954 		ppdu_info->rx_status.he_data1 |=
955 			QDF_MON_STATUS_HE_MCS_KNOWN |
956 			QDF_MON_STATUS_HE_DCM_KNOWN |
957 			QDF_MON_STATUS_HE_CODING_KNOWN;
958 
959 		/* HE-data2 */
960 		ppdu_info->rx_status.he_data2 |=
961 					QDF_MON_STATUS_TXBF_KNOWN;
962 
963 		/* HE-data3 */
964 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
965 				HE_SIG_B2_OFDMA_INFO_0, STA_MCS);
966 		ppdu_info->rx_status.mcs = value;
967 		value = value << QDF_MON_STATUS_TRANSMIT_MCS_SHIFT;
968 		ppdu_info->rx_status.he_data3 |= value;
969 
970 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
971 				HE_SIG_B2_OFDMA_INFO_0, STA_DCM);
972 		he_dcm = value;
973 		value = value << QDF_MON_STATUS_DCM_SHIFT;
974 		ppdu_info->rx_status.he_data3 |= value;
975 
976 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
977 				HE_SIG_B2_OFDMA_INFO_0, STA_CODING);
978 		value = value << QDF_MON_STATUS_CODING_SHIFT;
979 		ppdu_info->rx_status.he_data3 |= value;
980 
981 		/* HE-data4 */
982 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
983 				HE_SIG_B2_OFDMA_INFO_0, STA_ID);
984 		value = value << QDF_MON_STATUS_STA_ID_SHIFT;
985 		ppdu_info->rx_status.he_data4 |= value;
986 
987 		/* HE-data5 */
988 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
989 				   HE_SIG_B2_OFDMA_INFO_0, TXBF);
990 		value = value << QDF_MON_STATUS_TXBF_SHIFT;
991 		ppdu_info->rx_status.he_data5 |= value;
992 
993 		/* HE-data6 */
994 		value = HAL_RX_GET(he_sig_b2_ofdma_info,
995 				   HE_SIG_B2_OFDMA_INFO_0, NSTS);
996 		/* value n indicates n+1 spatial streams */
997 		value++;
998 		ppdu_info->rx_status.nss = value;
999 		ppdu_info->rx_status.he_data6 |= value;
1000 		ppdu_info->rx_status.reception_type = HAL_RX_TYPE_MU_OFDMA;
1001 		break;
1002 	}
1003 	case WIFIPHYRX_RSSI_LEGACY_E:
1004 	{
1005 		uint8_t *rssi_info_tlv = (uint8_t *)rx_tlv +
1006 			HAL_RX_OFFSET(UNIFIED_PHYRX_RSSI_LEGACY_3,
1007 			RECEIVE_RSSI_INFO_PRE_RSSI_INFO_DETAILS);
1008 
1009 		ppdu_info->rx_status.rssi_comb = HAL_RX_GET(rx_tlv,
1010 			PHYRX_RSSI_LEGACY_35, RSSI_COMB);
1011 		ppdu_info->rx_status.bw = hal->ops->hal_rx_get_tlv(rx_tlv);
1012 		ppdu_info->rx_status.he_re = 0;
1013 
1014 		value = HAL_RX_GET(rssi_info_tlv,
1015 			RECEIVE_RSSI_INFO_0, RSSI_PRI20_CHAIN0);
1016 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1017 			"RSSI_PRI20_CHAIN0: %d\n", value);
1018 
1019 		value = HAL_RX_GET(rssi_info_tlv,
1020 			RECEIVE_RSSI_INFO_0, RSSI_EXT20_CHAIN0);
1021 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1022 			"RSSI_EXT20_CHAIN0: %d\n", value);
1023 
1024 		value = HAL_RX_GET(rssi_info_tlv,
1025 			RECEIVE_RSSI_INFO_0, RSSI_EXT40_LOW20_CHAIN0);
1026 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1027 			"RSSI_EXT40_LOW20_CHAIN0: %d\n", value);
1028 
1029 		value = HAL_RX_GET(rssi_info_tlv,
1030 			RECEIVE_RSSI_INFO_0, RSSI_EXT40_HIGH20_CHAIN0);
1031 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1032 			"RSSI_EXT40_HIGH20_CHAIN0: %d\n", value);
1033 
1034 		value = HAL_RX_GET(rssi_info_tlv,
1035 			RECEIVE_RSSI_INFO_1, RSSI_EXT80_LOW20_CHAIN0);
1036 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1037 			"RSSI_EXT80_LOW20_CHAIN0: %d\n", value);
1038 
1039 		value = HAL_RX_GET(rssi_info_tlv,
1040 			RECEIVE_RSSI_INFO_1, RSSI_EXT80_LOW_HIGH20_CHAIN0);
1041 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1042 			"RSSI_EXT80_LOW_HIGH20_CHAIN0: %d\n", value);
1043 
1044 		value = HAL_RX_GET(rssi_info_tlv,
1045 			RECEIVE_RSSI_INFO_1, RSSI_EXT80_HIGH_LOW20_CHAIN0);
1046 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1047 			"RSSI_EXT80_HIGH_LOW20_CHAIN0: %d\n", value);
1048 
1049 		value = HAL_RX_GET(rssi_info_tlv,
1050 				   RECEIVE_RSSI_INFO_1,
1051 				   RSSI_EXT80_HIGH20_CHAIN0);
1052 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1053 			"RSSI_EXT80_HIGH20_CHAIN0: %d\n", value);
1054 		break;
1055 	}
1056 	case WIFIPHYRX_OTHER_RECEIVE_INFO_E:
1057 		hal_rx_proc_phyrx_other_receive_info_tlv(hal, rx_tlv_hdr,
1058 								ppdu_info);
1059 		break;
1060 	case WIFIRX_HEADER_E:
1061 		ppdu_info->msdu_info.first_msdu_payload = rx_tlv;
1062 		ppdu_info->msdu_info.payload_len = tlv_len;
1063 		break;
1064 	case WIFIRX_MPDU_START_E:
1065 	{
1066 		uint8_t *rx_mpdu_start =
1067 			(uint8_t *)rx_tlv + HAL_RX_OFFSET(UNIFIED_RX_MPDU_START_0,
1068 					RX_MPDU_INFO_RX_MPDU_INFO_DETAILS);
1069 		uint32_t ppdu_id = HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0,
1070 					      PHY_PPDU_ID);
1071 		uint8_t filter_category = 0;
1072 
1073 		ppdu_info->nac_info.fc_valid =
1074 			HAL_RX_GET(rx_mpdu_start,
1075 				   RX_MPDU_INFO_2,
1076 				   MPDU_FRAME_CONTROL_VALID);
1077 
1078 		ppdu_info->nac_info.to_ds_flag =
1079 			HAL_RX_GET(rx_mpdu_start,
1080 				   RX_MPDU_INFO_2,
1081 				   TO_DS);
1082 
1083 		ppdu_info->nac_info.mac_addr2_valid =
1084 			HAL_RX_GET(rx_mpdu_start,
1085 				   RX_MPDU_INFO_2,
1086 				   MAC_ADDR_AD2_VALID);
1087 
1088 		*(uint16_t *)&ppdu_info->nac_info.mac_addr2[0] =
1089 			HAL_RX_GET(rx_mpdu_start,
1090 				   RX_MPDU_INFO_16,
1091 				   MAC_ADDR_AD2_15_0);
1092 
1093 		*(uint32_t *)&ppdu_info->nac_info.mac_addr2[2] =
1094 			HAL_RX_GET(rx_mpdu_start,
1095 				   RX_MPDU_INFO_17,
1096 				   MAC_ADDR_AD2_47_16);
1097 
1098 		if (ppdu_info->rx_status.prev_ppdu_id != ppdu_id) {
1099 			ppdu_info->rx_status.prev_ppdu_id = ppdu_id;
1100 			ppdu_info->rx_status.ppdu_len =
1101 				HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_13,
1102 					   MPDU_LENGTH);
1103 		} else {
1104 			ppdu_info->rx_status.ppdu_len +=
1105 				HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_13,
1106 				MPDU_LENGTH);
1107 		}
1108 
1109 		filter_category = HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0,
1110 							RXPCU_MPDU_FILTER_IN_CATEGORY);
1111 		if (filter_category == 1)
1112 			ppdu_info->rx_status.monitor_direct_used = 1;
1113 		break;
1114 	}
1115 	case 0:
1116 		return HAL_TLV_STATUS_PPDU_DONE;
1117 
1118 	default:
1119 		if (hal_rx_handle_other_tlvs(tlv_tag, rx_tlv, ppdu_info))
1120 			unhandled = false;
1121 		else
1122 			unhandled = true;
1123 		break;
1124 	}
1125 
1126 	if (!unhandled)
1127 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1128 			  "%s TLV type: %d, TLV len:%d %s",
1129 			  __func__, tlv_tag, tlv_len,
1130 			  unhandled == true ? "unhandled" : "");
1131 
1132 	qdf_trace_hex_dump(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
1133 				rx_tlv, tlv_len);
1134 
1135 	return HAL_TLV_STATUS_PPDU_NOT_DONE;
1136 }
1137 /**
1138  * hal_reo_status_get_header_generic - Process reo desc info
1139  * @d - Pointer to reo descriptior
1140  * @b - tlv type info
1141  * @h1 - Pointer to hal_reo_status_header where info to be stored
1142  *
1143  * Return - none.
1144  *
1145  */
1146 static void hal_reo_status_get_header_generic(uint32_t *d, int b, void *h1)
1147 {
1148 
1149 	uint32_t val1 = 0;
1150 	struct hal_reo_status_header *h =
1151 			(struct hal_reo_status_header *)h1;
1152 
1153 	switch (b) {
1154 	case HAL_REO_QUEUE_STATS_STATUS_TLV:
1155 		val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_0,
1156 			UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)];
1157 		break;
1158 	case HAL_REO_FLUSH_QUEUE_STATUS_TLV:
1159 		val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_0,
1160 			UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)];
1161 		break;
1162 	case HAL_REO_FLUSH_CACHE_STATUS_TLV:
1163 		val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_0,
1164 			UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)];
1165 		break;
1166 	case HAL_REO_UNBLK_CACHE_STATUS_TLV:
1167 		val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_0,
1168 			UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)];
1169 		break;
1170 	case HAL_REO_TIMOUT_LIST_STATUS_TLV:
1171 		val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_0,
1172 			UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)];
1173 		break;
1174 	case HAL_REO_DESC_THRES_STATUS_TLV:
1175 		val1 = d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_0,
1176 			UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)];
1177 		break;
1178 	case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV:
1179 		val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_0,
1180 			UNIFORM_REO_STATUS_HEADER_STATUS_HEADER)];
1181 		break;
1182 	default:
1183 		pr_err("ERROR: Unknown tlv\n");
1184 		break;
1185 	}
1186 	h->cmd_num =
1187 		HAL_GET_FIELD(
1188 			      UNIFORM_REO_STATUS_HEADER_0, REO_STATUS_NUMBER,
1189 			      val1);
1190 	h->exec_time =
1191 		HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0,
1192 			      CMD_EXECUTION_TIME, val1);
1193 	h->status =
1194 		HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_0,
1195 			      REO_CMD_EXECUTION_STATUS, val1);
1196 	switch (b) {
1197 	case HAL_REO_QUEUE_STATS_STATUS_TLV:
1198 		val1 = d[HAL_OFFSET_DW(REO_GET_QUEUE_STATS_STATUS_1,
1199 			UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)];
1200 		break;
1201 	case HAL_REO_FLUSH_QUEUE_STATUS_TLV:
1202 		val1 = d[HAL_OFFSET_DW(REO_FLUSH_QUEUE_STATUS_1,
1203 			UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)];
1204 		break;
1205 	case HAL_REO_FLUSH_CACHE_STATUS_TLV:
1206 		val1 = d[HAL_OFFSET_DW(REO_FLUSH_CACHE_STATUS_1,
1207 			UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)];
1208 		break;
1209 	case HAL_REO_UNBLK_CACHE_STATUS_TLV:
1210 		val1 = d[HAL_OFFSET_DW(REO_UNBLOCK_CACHE_STATUS_1,
1211 			UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)];
1212 		break;
1213 	case HAL_REO_TIMOUT_LIST_STATUS_TLV:
1214 		val1 = d[HAL_OFFSET_DW(REO_FLUSH_TIMEOUT_LIST_STATUS_1,
1215 			UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)];
1216 		break;
1217 	case HAL_REO_DESC_THRES_STATUS_TLV:
1218 		val1 = d[HAL_OFFSET_DW(REO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_1,
1219 			UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)];
1220 		break;
1221 	case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV:
1222 		val1 = d[HAL_OFFSET_DW(REO_UPDATE_RX_REO_QUEUE_STATUS_1,
1223 			UNIFORM_REO_STATUS_HEADER_STATUS_HEADER_GENERIC)];
1224 		break;
1225 	default:
1226 		pr_err("ERROR: Unknown tlv\n");
1227 		break;
1228 	}
1229 	h->tstamp =
1230 		HAL_GET_FIELD(UNIFORM_REO_STATUS_HEADER_1, TIMESTAMP, val1);
1231 }
1232 
1233 /**
1234  * hal_reo_setup - Initialize HW REO block
1235  *
1236  * @hal_soc: Opaque HAL SOC handle
1237  * @reo_params: parameters needed by HAL for REO config
1238  */
1239 static void hal_reo_setup_generic(void *hal_soc,
1240 	 void *reoparams)
1241 {
1242 	struct hal_soc *soc = (struct hal_soc *)hal_soc;
1243 	uint32_t reg_val;
1244 	struct hal_reo_params *reo_params = (struct hal_reo_params *)reoparams;
1245 
1246 	reg_val = HAL_REG_READ(soc, HWIO_REO_R0_GENERAL_ENABLE_ADDR(
1247 		SEQ_WCSS_UMAC_REO_REG_OFFSET));
1248 
1249 	reg_val &= ~(HWIO_REO_R0_GENERAL_ENABLE_FRAGMENT_DEST_RING_BMSK |
1250 		HWIO_REO_R0_GENERAL_ENABLE_AGING_LIST_ENABLE_BMSK |
1251 		HWIO_REO_R0_GENERAL_ENABLE_AGING_FLUSH_ENABLE_BMSK);
1252 
1253 	reg_val |= HAL_SM(HWIO_REO_R0_GENERAL_ENABLE,
1254 		FRAGMENT_DEST_RING, reo_params->frag_dst_ring) |
1255 		HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, AGING_LIST_ENABLE, 1) |
1256 		HAL_SM(HWIO_REO_R0_GENERAL_ENABLE, AGING_FLUSH_ENABLE, 1);
1257 
1258 	HAL_REG_WRITE(soc, HWIO_REO_R0_GENERAL_ENABLE_ADDR(
1259 		SEQ_WCSS_UMAC_REO_REG_OFFSET), reg_val);
1260 
1261 	/* Other ring enable bits and REO_ENABLE will be set by FW */
1262 
1263 	/* TODO: Setup destination ring mapping if enabled */
1264 
1265 	/* TODO: Error destination ring setting is left to default.
1266 	 * Default setting is to send all errors to release ring.
1267 	 */
1268 
1269 	HAL_REG_WRITE(soc,
1270 		HWIO_REO_R0_AGING_THRESHOLD_IX_0_ADDR(
1271 		SEQ_WCSS_UMAC_REO_REG_OFFSET),
1272 		HAL_DEFAULT_REO_TIMEOUT_MS * 1000);
1273 
1274 	HAL_REG_WRITE(soc,
1275 		HWIO_REO_R0_AGING_THRESHOLD_IX_1_ADDR(
1276 		SEQ_WCSS_UMAC_REO_REG_OFFSET),
1277 		(HAL_DEFAULT_REO_TIMEOUT_MS * 1000));
1278 
1279 	HAL_REG_WRITE(soc,
1280 		HWIO_REO_R0_AGING_THRESHOLD_IX_2_ADDR(
1281 		SEQ_WCSS_UMAC_REO_REG_OFFSET),
1282 		(HAL_DEFAULT_REO_TIMEOUT_MS * 1000));
1283 
1284 	HAL_REG_WRITE(soc,
1285 		HWIO_REO_R0_AGING_THRESHOLD_IX_3_ADDR(
1286 		SEQ_WCSS_UMAC_REO_REG_OFFSET),
1287 		(HAL_DEFAULT_REO_TIMEOUT_MS * 1000));
1288 
1289 	/*
1290 	 * When hash based routing is enabled, routing of the rx packet
1291 	 * is done based on the following value: 1 _ _ _ _ The last 4
1292 	 * bits are based on hash[3:0]. This means the possible values
1293 	 * are 0x10 to 0x1f. This value is used to look-up the
1294 	 * ring ID configured in Destination_Ring_Ctrl_IX_* register.
1295 	 * The Destination_Ring_Ctrl_IX_2 and Destination_Ring_Ctrl_IX_3
1296 	 * registers need to be configured to set-up the 16 entries to
1297 	 * map the hash values to a ring number. There are 3 bits per
1298 	 * hash entry – which are mapped as follows:
1299 	 * 0: TCL, 1:SW1, 2:SW2, * 3:SW3, 4:SW4, 5:Release, 6:FW(WIFI),
1300 	 * 7: NOT_USED.
1301 	*/
1302 	if (reo_params->rx_hash_enabled) {
1303 		HAL_REG_WRITE(soc,
1304 			HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR(
1305 			SEQ_WCSS_UMAC_REO_REG_OFFSET),
1306 			reo_params->remap1);
1307 
1308 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
1309 			FL("HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR 0x%x"),
1310 			HAL_REG_READ(soc,
1311 			HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR(
1312 			SEQ_WCSS_UMAC_REO_REG_OFFSET)));
1313 
1314 		HAL_REG_WRITE(soc,
1315 			HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR(
1316 			SEQ_WCSS_UMAC_REO_REG_OFFSET),
1317 			reo_params->remap2);
1318 
1319 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
1320 			FL("HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR 0x%x"),
1321 			HAL_REG_READ(soc,
1322 			HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR(
1323 			SEQ_WCSS_UMAC_REO_REG_OFFSET)));
1324 	}
1325 
1326 
1327 	/* TODO: Check if the following registers shoould be setup by host:
1328 	 * AGING_CONTROL
1329 	 * HIGH_MEMORY_THRESHOLD
1330 	 * GLOBAL_LINK_DESC_COUNT_THRESH_IX_0[1,2]
1331 	 * GLOBAL_LINK_DESC_COUNT_CTRL
1332 	 */
1333 }
1334 
1335 /**
1336  * hal_srng_src_hw_init - Private function to initialize SRNG
1337  * source ring HW
1338  * @hal_soc: HAL SOC handle
1339  * @srng: SRNG ring pointer
1340  */
1341 static inline void hal_srng_src_hw_init_generic(void *halsoc,
1342 	struct hal_srng *srng)
1343 {
1344 	struct hal_soc *hal = (struct hal_soc *)halsoc;
1345 	uint32_t reg_val = 0;
1346 	uint64_t tp_addr = 0;
1347 
1348 	HIF_DBG("%s: hw_init srng %d", __func__, srng->ring_id);
1349 
1350 	if (srng->flags & HAL_SRNG_MSI_INTR) {
1351 		SRNG_SRC_REG_WRITE(srng, MSI1_BASE_LSB,
1352 			srng->msi_addr & 0xffffffff);
1353 		reg_val = SRNG_SM(SRNG_SRC_FLD(MSI1_BASE_MSB, ADDR),
1354 			(uint64_t)(srng->msi_addr) >> 32) |
1355 			SRNG_SM(SRNG_SRC_FLD(MSI1_BASE_MSB,
1356 			MSI1_ENABLE), 1);
1357 		SRNG_SRC_REG_WRITE(srng, MSI1_BASE_MSB, reg_val);
1358 		SRNG_SRC_REG_WRITE(srng, MSI1_DATA, srng->msi_data);
1359 	}
1360 
1361 	SRNG_SRC_REG_WRITE(srng, BASE_LSB, srng->ring_base_paddr & 0xffffffff);
1362 	reg_val = SRNG_SM(SRNG_SRC_FLD(BASE_MSB, RING_BASE_ADDR_MSB),
1363 		((uint64_t)(srng->ring_base_paddr) >> 32)) |
1364 		SRNG_SM(SRNG_SRC_FLD(BASE_MSB, RING_SIZE),
1365 		srng->entry_size * srng->num_entries);
1366 	SRNG_SRC_REG_WRITE(srng, BASE_MSB, reg_val);
1367 
1368 #if defined(WCSS_VERSION) && \
1369 	((defined(CONFIG_WIN) && (WCSS_VERSION > 81)) || \
1370 	 (defined(CONFIG_MCL) && (WCSS_VERSION >= 72)))
1371 	reg_val = SRNG_SM(SRNG_SRC_FLD(ID, ENTRY_SIZE), srng->entry_size);
1372 #else
1373 	reg_val = SRNG_SM(SRNG_SRC_FLD(ID, RING_ID), srng->ring_id) |
1374 		SRNG_SM(SRNG_SRC_FLD(ID, ENTRY_SIZE), srng->entry_size);
1375 #endif
1376 	SRNG_SRC_REG_WRITE(srng, ID, reg_val);
1377 
1378 	/**
1379 	 * Interrupt setup:
1380 	 * Default interrupt mode is 'pulse'. Need to setup SW_INTERRUPT_MODE
1381 	 * if level mode is required
1382 	 */
1383 	reg_val = 0;
1384 
1385 	/*
1386 	 * WAR - Hawkeye v1 has a hardware bug which requires timer value to be
1387 	 * programmed in terms of 1us resolution instead of 8us resolution as
1388 	 * given in MLD.
1389 	 */
1390 	if (srng->intr_timer_thres_us) {
1391 		reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX0,
1392 			INTERRUPT_TIMER_THRESHOLD),
1393 			srng->intr_timer_thres_us);
1394 		/* For HK v2 this should be (srng->intr_timer_thres_us >> 3) */
1395 	}
1396 
1397 	if (srng->intr_batch_cntr_thres_entries) {
1398 		reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX0,
1399 			BATCH_COUNTER_THRESHOLD),
1400 			srng->intr_batch_cntr_thres_entries *
1401 			srng->entry_size);
1402 	}
1403 	SRNG_SRC_REG_WRITE(srng, CONSUMER_INT_SETUP_IX0, reg_val);
1404 
1405 	reg_val = 0;
1406 	if (srng->flags & HAL_SRNG_LOW_THRES_INTR_ENABLE) {
1407 		reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX1,
1408 			LOW_THRESHOLD), srng->u.src_ring.low_threshold);
1409 	}
1410 
1411 	SRNG_SRC_REG_WRITE(srng, CONSUMER_INT_SETUP_IX1, reg_val);
1412 
1413 	/* As per HW team, TP_ADDR and HP_ADDR for Idle link ring should
1414 	 * remain 0 to avoid some WBM stability issues. Remote head/tail
1415 	 * pointers are not required since this ring is completely managed
1416 	 * by WBM HW
1417 	 */
1418 	if (srng->ring_id != HAL_SRNG_WBM_IDLE_LINK) {
1419 		tp_addr = (uint64_t)(hal->shadow_rdptr_mem_paddr +
1420 			((unsigned long)(srng->u.src_ring.tp_addr) -
1421 			(unsigned long)(hal->shadow_rdptr_mem_vaddr)));
1422 		SRNG_SRC_REG_WRITE(srng, TP_ADDR_LSB, tp_addr & 0xffffffff);
1423 		SRNG_SRC_REG_WRITE(srng, TP_ADDR_MSB, tp_addr >> 32);
1424 	}
1425 
1426 	/* Initilaize head and tail pointers to indicate ring is empty */
1427 	SRNG_SRC_REG_WRITE(srng, HP, 0);
1428 	SRNG_SRC_REG_WRITE(srng, TP, 0);
1429 	*(srng->u.src_ring.tp_addr) = 0;
1430 
1431 	reg_val = ((srng->flags & HAL_SRNG_DATA_TLV_SWAP) ?
1432 			SRNG_SM(SRNG_SRC_FLD(MISC, DATA_TLV_SWAP_BIT), 1) : 0) |
1433 			((srng->flags & HAL_SRNG_RING_PTR_SWAP) ?
1434 			SRNG_SM(SRNG_SRC_FLD(MISC, HOST_FW_SWAP_BIT), 1) : 0) |
1435 			((srng->flags & HAL_SRNG_MSI_SWAP) ?
1436 			SRNG_SM(SRNG_SRC_FLD(MISC, MSI_SWAP_BIT), 1) : 0);
1437 
1438 	/* Loop count is not used for SRC rings */
1439 	reg_val |= SRNG_SM(SRNG_SRC_FLD(MISC, LOOPCNT_DISABLE), 1);
1440 
1441 	/*
1442 	 * reg_val |= SRNG_SM(SRNG_SRC_FLD(MISC, SRNG_ENABLE), 1);
1443 	 * todo: update fw_api and replace with above line
1444 	 * (when SRNG_ENABLE field for the MISC register is available in fw_api)
1445 	 * (WCSS_UMAC_CE_0_SRC_WFSS_CE_CHANNEL_SRC_R0_SRC_RING_MISC)
1446 	 */
1447 	reg_val |= 0x40;
1448 
1449 	SRNG_SRC_REG_WRITE(srng, MISC, reg_val);
1450 
1451 }
1452 
1453 /**
1454  * hal_srng_dst_hw_init - Private function to initialize SRNG
1455  * destination ring HW
1456  * @hal_soc: HAL SOC handle
1457  * @srng: SRNG ring pointer
1458  */
1459 static inline void hal_srng_dst_hw_init_generic(void *halsoc,
1460 	struct hal_srng *srng)
1461 {
1462 	struct hal_soc *hal = (struct hal_soc *)halsoc;
1463 	uint32_t reg_val = 0;
1464 	uint64_t hp_addr = 0;
1465 
1466 	HIF_DBG("%s: hw_init srng %d", __func__, srng->ring_id);
1467 
1468 	if (srng->flags & HAL_SRNG_MSI_INTR) {
1469 		SRNG_DST_REG_WRITE(srng, MSI1_BASE_LSB,
1470 			srng->msi_addr & 0xffffffff);
1471 		reg_val = SRNG_SM(SRNG_DST_FLD(MSI1_BASE_MSB, ADDR),
1472 			(uint64_t)(srng->msi_addr) >> 32) |
1473 			SRNG_SM(SRNG_DST_FLD(MSI1_BASE_MSB,
1474 			MSI1_ENABLE), 1);
1475 		SRNG_DST_REG_WRITE(srng, MSI1_BASE_MSB, reg_val);
1476 		SRNG_DST_REG_WRITE(srng, MSI1_DATA, srng->msi_data);
1477 	}
1478 
1479 	SRNG_DST_REG_WRITE(srng, BASE_LSB, srng->ring_base_paddr & 0xffffffff);
1480 	reg_val = SRNG_SM(SRNG_DST_FLD(BASE_MSB, RING_BASE_ADDR_MSB),
1481 		((uint64_t)(srng->ring_base_paddr) >> 32)) |
1482 		SRNG_SM(SRNG_DST_FLD(BASE_MSB, RING_SIZE),
1483 		srng->entry_size * srng->num_entries);
1484 	SRNG_DST_REG_WRITE(srng, BASE_MSB, reg_val);
1485 
1486 	reg_val = SRNG_SM(SRNG_DST_FLD(ID, RING_ID), srng->ring_id) |
1487 		SRNG_SM(SRNG_DST_FLD(ID, ENTRY_SIZE), srng->entry_size);
1488 	SRNG_DST_REG_WRITE(srng, ID, reg_val);
1489 
1490 
1491 	/**
1492 	 * Interrupt setup:
1493 	 * Default interrupt mode is 'pulse'. Need to setup SW_INTERRUPT_MODE
1494 	 * if level mode is required
1495 	 */
1496 	reg_val = 0;
1497 	if (srng->intr_timer_thres_us) {
1498 		reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT_SETUP,
1499 			INTERRUPT_TIMER_THRESHOLD),
1500 			srng->intr_timer_thres_us >> 3);
1501 	}
1502 
1503 	if (srng->intr_batch_cntr_thres_entries) {
1504 		reg_val |= SRNG_SM(SRNG_DST_FLD(PRODUCER_INT_SETUP,
1505 			BATCH_COUNTER_THRESHOLD),
1506 			srng->intr_batch_cntr_thres_entries *
1507 			srng->entry_size);
1508 	}
1509 
1510 	SRNG_DST_REG_WRITE(srng, PRODUCER_INT_SETUP, reg_val);
1511 	hp_addr = (uint64_t)(hal->shadow_rdptr_mem_paddr +
1512 		((unsigned long)(srng->u.dst_ring.hp_addr) -
1513 		(unsigned long)(hal->shadow_rdptr_mem_vaddr)));
1514 	SRNG_DST_REG_WRITE(srng, HP_ADDR_LSB, hp_addr & 0xffffffff);
1515 	SRNG_DST_REG_WRITE(srng, HP_ADDR_MSB, hp_addr >> 32);
1516 
1517 	/* Initilaize head and tail pointers to indicate ring is empty */
1518 	SRNG_DST_REG_WRITE(srng, HP, 0);
1519 	SRNG_DST_REG_WRITE(srng, TP, 0);
1520 	*(srng->u.dst_ring.hp_addr) = 0;
1521 
1522 	reg_val = ((srng->flags & HAL_SRNG_DATA_TLV_SWAP) ?
1523 			SRNG_SM(SRNG_DST_FLD(MISC, DATA_TLV_SWAP_BIT), 1) : 0) |
1524 			((srng->flags & HAL_SRNG_RING_PTR_SWAP) ?
1525 			SRNG_SM(SRNG_DST_FLD(MISC, HOST_FW_SWAP_BIT), 1) : 0) |
1526 			((srng->flags & HAL_SRNG_MSI_SWAP) ?
1527 			SRNG_SM(SRNG_DST_FLD(MISC, MSI_SWAP_BIT), 1) : 0);
1528 
1529 	/*
1530 	 * reg_val |= SRNG_SM(SRNG_SRC_FLD(MISC, SRNG_ENABLE), 1);
1531 	 * todo: update fw_api and replace with above line
1532 	 * (when SRNG_ENABLE field for the MISC register is available in fw_api)
1533 	 * (WCSS_UMAC_CE_0_SRC_WFSS_CE_CHANNEL_SRC_R0_SRC_RING_MISC)
1534 	 */
1535 	reg_val |= 0x40;
1536 
1537 	SRNG_DST_REG_WRITE(srng, MISC, reg_val);
1538 
1539 }
1540 #endif
1541 
1542 /**
1543  * hal_tx_desc_set_search_type - Set the search type value
1544  * @desc: Handle to Tx Descriptor
1545  * @search_type: search type
1546  *		     0 – Normal search
1547  *		     1 – Index based address search
1548  *		     2 – Index based flow search
1549  *
1550  * Return: void
1551  */
1552 #ifdef TCL_DATA_CMD_2_SEARCH_TYPE_OFFSET
1553 static void hal_tx_desc_set_search_type_generic(void *desc,
1554 						uint8_t search_type)
1555 {
1556 	HAL_SET_FLD(desc, TCL_DATA_CMD_2, SEARCH_TYPE) |=
1557 		HAL_TX_SM(TCL_DATA_CMD_2, SEARCH_TYPE, search_type);
1558 }
1559 #else
1560 static void hal_tx_desc_set_search_type_generic(void *desc,
1561 						uint8_t search_type)
1562 {
1563 }
1564 
1565 #endif
1566 
1567 /**
1568  * hal_tx_desc_set_search_index - Set the search index value
1569  * @desc: Handle to Tx Descriptor
1570  * @search_index: The index that will be used for index based address or
1571  *                flow search. The field is valid when 'search_type' is
1572  *                1 0r 2
1573  *
1574  * Return: void
1575  */
1576 #ifdef TCL_DATA_CMD_5_SEARCH_INDEX_OFFSET
1577 static void hal_tx_desc_set_search_index_generic(void *desc,
1578 						 uint32_t search_index)
1579 {
1580 	HAL_SET_FLD(desc, TCL_DATA_CMD_5, SEARCH_INDEX) |=
1581 		HAL_TX_SM(TCL_DATA_CMD_5, SEARCH_INDEX, search_index);
1582 }
1583 #else
1584 static void hal_tx_desc_set_search_index_generic(void *desc,
1585 						 uint32_t search_index)
1586 {
1587 }
1588 #endif
1589