xref: /wlan-dirver/qca-wifi-host-cmn/hal/wifi3.0/qca6290/hal_6290_rx.h (revision 1b9674e21e24478fba4530f5ae7396b9555e9c6a)
1 /*
2  * Copyright (c) 2018 The Linux Foundation. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above
10  *       copyright notice, this list of conditions and the following
11  *       disclaimer in the documentation and/or other materials provided
12  *       with the distribution.
13  *     * Neither the name of The Linux Foundation nor the names of its
14  *       contributors may be used to endorse or promote products derived
15  *       from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 #include "qdf_util.h"
30 #include "qdf_types.h"
31 #include "qdf_lock.h"
32 #include "qdf_mem.h"
33 #include "qdf_nbuf.h"
34 #include "tcl_data_cmd.h"
35 #include "mac_tcl_reg_seq_hwioreg.h"
36 #include "phyrx_rssi_legacy.h"
37 #include "rx_msdu_start.h"
38 #include "tlv_tag_def.h"
39 #include "hal_hw_headers.h"
40 #include "hal_internal.h"
41 #include "cdp_txrx_mon_struct.h"
42 #include "qdf_trace.h"
43 #include "hal_rx.h"
44 #include "hal_tx.h"
45 #include "dp_types.h"
46 #include "hal_api_mon.h"
47 #include "phyrx_other_receive_info_ru_details.h"
48 
49 #if defined(QCA_WIFI_QCA6290_11AX)
50 #define HAL_RX_MSDU_START_MIMO_SS_BITMAP(_rx_msdu_start)\
51 	(_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start),\
52 	RX_MSDU_START_5_MIMO_SS_BITMAP_OFFSET)),	\
53 	RX_MSDU_START_5_MIMO_SS_BITMAP_MASK,		\
54 	RX_MSDU_START_5_MIMO_SS_BITMAP_LSB))
55 
56 /*
57  * hal_rx_msdu_start_nss_get_6290(): API to get the NSS
58  * Interval from rx_msdu_start
59  *
60  * @buf: pointer to the start of RX PKT TLV header
61  * Return: uint32_t(nss)
62  */
63 static uint32_t
64 hal_rx_msdu_start_nss_get_6290(uint8_t *buf)
65 {
66 	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
67 	struct rx_msdu_start *msdu_start =
68 				&pkt_tlvs->msdu_start_tlv.rx_msdu_start;
69 	uint8_t mimo_ss_bitmap;
70 
71 	mimo_ss_bitmap = HAL_RX_MSDU_START_MIMO_SS_BITMAP(msdu_start);
72 
73 	return qdf_get_hweight8(mimo_ss_bitmap);
74 }
75 #else
76 static uint32_t
77 hal_rx_msdu_start_nss_get_6290(uint8_t *buf)
78 {
79 	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
80 	struct rx_msdu_start *msdu_start =
81 				&pkt_tlvs->msdu_start_tlv.rx_msdu_start;
82 	uint32_t nss;
83 
84 	nss = HAL_RX_MSDU_START_NSS_GET(msdu_start);
85 	return nss;
86 }
87 #endif
88 
89 /**
90  * hal_rx_mon_hw_desc_get_mpdu_status_6290(): Retrieve MPDU status
91  *
92  * @ hw_desc_addr: Start address of Rx HW TLVs
93  * @ rs: Status for monitor mode
94  *
95  * Return: void
96  */
97 static void hal_rx_mon_hw_desc_get_mpdu_status_6290(void *hw_desc_addr,
98 						    struct mon_rx_status *rs)
99 {
100 	struct rx_msdu_start *rx_msdu_start;
101 	struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr;
102 	uint32_t reg_value;
103 	const uint32_t sgi_hw_to_cdp[] = {
104 		CDP_SGI_0_8_US,
105 		CDP_SGI_0_4_US,
106 		CDP_SGI_1_6_US,
107 		CDP_SGI_3_2_US,
108 	};
109 
110 	rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start;
111 
112 	HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs);
113 
114 	rs->ant_signal_db = HAL_RX_GET(rx_msdu_start,
115 				RX_MSDU_START_5, USER_RSSI);
116 	rs->is_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC);
117 
118 	reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI);
119 	rs->sgi = sgi_hw_to_cdp[reg_value];
120 #if !defined(QCA_WIFI_QCA6290_11AX)
121 	rs->nr_ant = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, NSS);
122 #endif
123 	reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, PKT_TYPE);
124 	switch (reg_value) {
125 	case HAL_RX_PKT_TYPE_11N:
126 		rs->ht_flags = 1;
127 		break;
128 	case HAL_RX_PKT_TYPE_11AC:
129 		rs->vht_flags = 1;
130 		reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5,
131 				       RECEIVE_BANDWIDTH);
132 		rs->vht_flag_values2 = reg_value;
133 		break;
134 	case HAL_RX_PKT_TYPE_11AX:
135 		rs->he_flags = 1;
136 		break;
137 	default:
138 		break;
139 	}
140 	reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE);
141 	rs->beamformed = (reg_value == HAL_RX_RECEPTION_TYPE_MU_MIMO) ? 1 : 0;
142 	/* TODO: rs->beamformed should be set for SU beamforming also */
143 }
144 
145 #define LINK_DESC_SIZE (NUM_OF_DWORDS_RX_MSDU_LINK << 2)
146 
147 static uint32_t hal_get_link_desc_size_6290(void)
148 {
149 	return LINK_DESC_SIZE;
150 }
151 
152 
153 #ifdef QCA_WIFI_QCA6290_11AX
154 /*
155  * hal_rx_get_tlv_6290(): API to get the tlv
156  *
157  * @rx_tlv: TLV data extracted from the rx packet
158  * Return: uint8_t
159  */
160 static uint8_t hal_rx_get_tlv_6290(void *rx_tlv)
161 {
162 	return HAL_RX_GET(rx_tlv, PHYRX_RSSI_LEGACY_0, RECEIVE_BANDWIDTH);
163 }
164 #else
165 static uint8_t hal_rx_get_tlv_6290(void *rx_tlv)
166 {
167 	return HAL_RX_GET(rx_tlv, PHYRX_RSSI_LEGACY_35, RECEIVE_BANDWIDTH);
168 }
169 #endif
170 
171 #ifdef QCA_WIFI_QCA6290_11AX
172 /**
173  * hal_rx_proc_phyrx_other_receive_info_tlv_6290()
174  *				    - process other receive info TLV
175  * @rx_tlv_hdr: pointer to TLV header
176  * @ppdu_info: pointer to ppdu_info
177  *
178  * Return: None
179  */
180 static
181 void hal_rx_proc_phyrx_other_receive_info_tlv_6290(void *rx_tlv_hdr,
182 						   void *ppdu_info_handle)
183 {
184 	uint32_t tlv_tag, tlv_len;
185 	uint32_t temp_len, other_tlv_len, other_tlv_tag;
186 	void *rx_tlv = (uint8_t *)rx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE;
187 	void *other_tlv_hdr = NULL;
188 	void *other_tlv = NULL;
189 	uint32_t ru_details_channel_0;
190 	struct hal_rx_ppdu_info *ppdu_info =
191 		(struct hal_rx_ppdu_info *)ppdu_info_handle;
192 
193 	tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv_hdr);
194 	tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv_hdr);
195 	temp_len = 0;
196 
197 	other_tlv_hdr = rx_tlv + HAL_RX_TLV32_HDR_SIZE;
198 
199 	other_tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(other_tlv_hdr);
200 	other_tlv_len = HAL_RX_GET_USER_TLV32_LEN(other_tlv_hdr);
201 	temp_len += other_tlv_len;
202 	other_tlv = other_tlv_hdr + HAL_RX_TLV32_HDR_SIZE;
203 
204 	switch (other_tlv_tag) {
205 	case WIFIPHYRX_OTHER_RECEIVE_INFO_RU_DETAILS_E:
206 		ru_details_channel_0 =
207 			HAL_RX_GET(other_tlv,
208 				   PHYRX_OTHER_RECEIVE_INFO_RU_DETAILS_0,
209 				   RU_DETAILS_CHANNEL_0);
210 
211 		qdf_mem_copy(ppdu_info->rx_status.he_RU,
212 			     &ru_details_channel_0,
213 			     sizeof(ppdu_info->rx_status.he_RU));
214 
215 		if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_20)
216 			ppdu_info->rx_status.he_sig_b_common_known |=
217 				QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0;
218 
219 		if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_40)
220 			ppdu_info->rx_status.he_sig_b_common_known |=
221 				QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU1;
222 
223 		if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_80)
224 			ppdu_info->rx_status.he_sig_b_common_known |=
225 				QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU2;
226 
227 		if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_160)
228 			ppdu_info->rx_status.he_sig_b_common_known |=
229 				QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU3;
230 			break;
231 	default:
232 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
233 			  "%s unhandled TLV type: %d, TLV len:%d",
234 			  __func__, other_tlv_tag, other_tlv_len);
235 		break;
236 	}
237 }
238 #else
239 static
240 void hal_rx_proc_phyrx_other_receive_info_tlv_6290(void *rx_tlv_hdr,
241 						   void *ppdu_info_handle)
242 {
243 }
244 #endif /* QCA_WIFI_QCA6290_11AX */
245 
246 /**
247  * hal_rx_dump_msdu_start_tlv_6290() : dump RX msdu_start TLV in structured
248  *			     human readable format.
249  * @ msdu_start: pointer the msdu_start TLV in pkt.
250  * @ dbg_level: log level.
251  *
252  * Return: void
253  */
254 static void hal_rx_dump_msdu_start_tlv_6290(void *msdustart,
255 					    uint8_t dbg_level)
256 {
257 	struct rx_msdu_start *msdu_start = (struct rx_msdu_start *)msdustart;
258 
259 	QDF_TRACE(QDF_MODULE_ID_DP, dbg_level,
260 			"rx_msdu_start tlv - "
261 			"rxpcu_mpdu_filter_in_category: %d "
262 			"sw_frame_group_id: %d "
263 			"phy_ppdu_id: %d "
264 			"msdu_length: %d "
265 			"ipsec_esp: %d "
266 			"l3_offset: %d "
267 			"ipsec_ah: %d "
268 			"l4_offset: %d "
269 			"msdu_number: %d "
270 			"decap_format: %d "
271 			"ipv4_proto: %d "
272 			"ipv6_proto: %d "
273 			"tcp_proto: %d "
274 			"udp_proto: %d "
275 			"ip_frag: %d "
276 			"tcp_only_ack: %d "
277 			"da_is_bcast_mcast: %d "
278 			"ip4_protocol_ip6_next_header: %d "
279 			"toeplitz_hash_2_or_4: %d "
280 			"flow_id_toeplitz: %d "
281 			"user_rssi: %d "
282 			"pkt_type: %d "
283 			"stbc: %d "
284 			"sgi: %d "
285 			"rate_mcs: %d "
286 			"receive_bandwidth: %d "
287 			"reception_type: %d "
288 #if !defined(QCA_WIFI_QCA6290_11AX)
289 			"toeplitz_hash: %d "
290 			"nss: %d "
291 #endif
292 			"ppdu_start_timestamp: %d "
293 			"sw_phy_meta_data: %d ",
294 			msdu_start->rxpcu_mpdu_filter_in_category,
295 			msdu_start->sw_frame_group_id,
296 			msdu_start->phy_ppdu_id,
297 			msdu_start->msdu_length,
298 			msdu_start->ipsec_esp,
299 			msdu_start->l3_offset,
300 			msdu_start->ipsec_ah,
301 			msdu_start->l4_offset,
302 			msdu_start->msdu_number,
303 			msdu_start->decap_format,
304 			msdu_start->ipv4_proto,
305 			msdu_start->ipv6_proto,
306 			msdu_start->tcp_proto,
307 			msdu_start->udp_proto,
308 			msdu_start->ip_frag,
309 			msdu_start->tcp_only_ack,
310 			msdu_start->da_is_bcast_mcast,
311 			msdu_start->ip4_protocol_ip6_next_header,
312 			msdu_start->toeplitz_hash_2_or_4,
313 			msdu_start->flow_id_toeplitz,
314 			msdu_start->user_rssi,
315 			msdu_start->pkt_type,
316 			msdu_start->stbc,
317 			msdu_start->sgi,
318 			msdu_start->rate_mcs,
319 			msdu_start->receive_bandwidth,
320 			msdu_start->reception_type,
321 #if !defined(QCA_WIFI_QCA6290_11AX)
322 			msdu_start->toeplitz_hash,
323 			msdu_start->nss,
324 #endif
325 			msdu_start->ppdu_start_timestamp,
326 			msdu_start->sw_phy_meta_data);
327 }
328 
329 /**
330  * hal_rx_dump_msdu_end_tlv_6290: dump RX msdu_end TLV in structured
331  *			     human readable format.
332  * @ msdu_end: pointer the msdu_end TLV in pkt.
333  * @ dbg_level: log level.
334  *
335  * Return: void
336  */
337 static void hal_rx_dump_msdu_end_tlv_6290(void *msduend,
338 					  uint8_t dbg_level)
339 {
340 	struct rx_msdu_end *msdu_end = (struct rx_msdu_end *)msduend;
341 
342 	QDF_TRACE(QDF_MODULE_ID_DP, dbg_level,
343 			"rx_msdu_end tlv - "
344 			"rxpcu_mpdu_filter_in_category: %d "
345 			"sw_frame_group_id: %d "
346 			"phy_ppdu_id: %d "
347 			"ip_hdr_chksum: %d "
348 			"tcp_udp_chksum: %d "
349 			"key_id_octet: %d "
350 			"cce_super_rule: %d "
351 			"cce_classify_not_done_truncat: %d "
352 			"cce_classify_not_done_cce_dis: %d "
353 			"ext_wapi_pn_63_48: %d "
354 			"ext_wapi_pn_95_64: %d "
355 			"ext_wapi_pn_127_96: %d "
356 			"reported_mpdu_length: %d "
357 			"first_msdu: %d "
358 			"last_msdu: %d "
359 			"sa_idx_timeout: %d "
360 			"da_idx_timeout: %d "
361 			"msdu_limit_error: %d "
362 			"flow_idx_timeout: %d "
363 			"flow_idx_invalid: %d "
364 			"wifi_parser_error: %d "
365 			"amsdu_parser_error: %d "
366 			"sa_is_valid: %d "
367 			"da_is_valid: %d "
368 			"da_is_mcbc: %d "
369 			"l3_header_padding: %d "
370 			"ipv6_options_crc: %d "
371 			"tcp_seq_number: %d "
372 			"tcp_ack_number: %d "
373 			"tcp_flag: %d "
374 			"lro_eligible: %d "
375 			"window_size: %d "
376 			"da_offset: %d "
377 			"sa_offset: %d "
378 			"da_offset_valid: %d "
379 			"sa_offset_valid: %d "
380 			"rule_indication_31_0: %d "
381 			"rule_indication_63_32: %d "
382 			"sa_idx: %d "
383 			"da_idx: %d "
384 			"msdu_drop: %d "
385 			"reo_destination_indication: %d "
386 			"flow_idx: %d "
387 			"fse_metadata: %d "
388 			"cce_metadata: %d "
389 			"sa_sw_peer_id: %d ",
390 			msdu_end->rxpcu_mpdu_filter_in_category,
391 			msdu_end->sw_frame_group_id,
392 			msdu_end->phy_ppdu_id,
393 			msdu_end->ip_hdr_chksum,
394 			msdu_end->tcp_udp_chksum,
395 			msdu_end->key_id_octet,
396 			msdu_end->cce_super_rule,
397 			msdu_end->cce_classify_not_done_truncate,
398 			msdu_end->cce_classify_not_done_cce_dis,
399 			msdu_end->ext_wapi_pn_63_48,
400 			msdu_end->ext_wapi_pn_95_64,
401 			msdu_end->ext_wapi_pn_127_96,
402 			msdu_end->reported_mpdu_length,
403 			msdu_end->first_msdu,
404 			msdu_end->last_msdu,
405 			msdu_end->sa_idx_timeout,
406 			msdu_end->da_idx_timeout,
407 			msdu_end->msdu_limit_error,
408 			msdu_end->flow_idx_timeout,
409 			msdu_end->flow_idx_invalid,
410 			msdu_end->wifi_parser_error,
411 			msdu_end->amsdu_parser_error,
412 			msdu_end->sa_is_valid,
413 			msdu_end->da_is_valid,
414 			msdu_end->da_is_mcbc,
415 			msdu_end->l3_header_padding,
416 			msdu_end->ipv6_options_crc,
417 			msdu_end->tcp_seq_number,
418 			msdu_end->tcp_ack_number,
419 			msdu_end->tcp_flag,
420 			msdu_end->lro_eligible,
421 			msdu_end->window_size,
422 			msdu_end->da_offset,
423 			msdu_end->sa_offset,
424 			msdu_end->da_offset_valid,
425 			msdu_end->sa_offset_valid,
426 			msdu_end->rule_indication_31_0,
427 			msdu_end->rule_indication_63_32,
428 			msdu_end->sa_idx,
429 			msdu_end->da_idx,
430 			msdu_end->msdu_drop,
431 			msdu_end->reo_destination_indication,
432 			msdu_end->flow_idx,
433 			msdu_end->fse_metadata,
434 			msdu_end->cce_metadata,
435 			msdu_end->sa_sw_peer_id);
436 }
437 
438 
439 /*
440  * Get tid from RX_MPDU_START
441  */
442 #define HAL_RX_MPDU_INFO_TID_GET(_rx_mpdu_info) \
443 	(_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info),	\
444 		RX_MPDU_INFO_3_TID_OFFSET)),		\
445 		RX_MPDU_INFO_3_TID_MASK,		\
446 		RX_MPDU_INFO_3_TID_LSB))
447 
448 static uint32_t hal_rx_mpdu_start_tid_get_6290(uint8_t *buf)
449 {
450 	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
451 	struct rx_mpdu_start *mpdu_start =
452 			&pkt_tlvs->mpdu_start_tlv.rx_mpdu_start;
453 	uint32_t tid;
454 
455 	tid = HAL_RX_MPDU_INFO_TID_GET(&mpdu_start->rx_mpdu_info_details);
456 
457 	return tid;
458 }
459 
460 #define HAL_RX_MSDU_START_RECEPTION_TYPE_GET(_rx_msdu_start) \
461 	(_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start),	\
462 	RX_MSDU_START_5_RECEPTION_TYPE_OFFSET)),	\
463 	RX_MSDU_START_5_RECEPTION_TYPE_MASK,		\
464 	RX_MSDU_START_5_RECEPTION_TYPE_LSB))
465 
466 /*
467  * hal_rx_msdu_start_reception_type_get(): API to get the reception type
468  * Interval from rx_msdu_start
469  *
470  * @buf: pointer to the start of RX PKT TLV header
471  * Return: uint32_t(reception_type)
472  */
473 static uint32_t hal_rx_msdu_start_reception_type_get_6290(uint8_t *buf)
474 {
475 	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
476 	struct rx_msdu_start *msdu_start =
477 		&pkt_tlvs->msdu_start_tlv.rx_msdu_start;
478 	uint32_t reception_type;
479 
480 	reception_type = HAL_RX_MSDU_START_RECEPTION_TYPE_GET(msdu_start);
481 
482 	return reception_type;
483 }
484 
485 #define HAL_RX_MSDU_END_DA_IDX_GET(_rx_msdu_end)	\
486 	(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end,	\
487 		RX_MSDU_END_13_DA_IDX_OFFSET)),		\
488 		RX_MSDU_END_13_DA_IDX_MASK,		\
489 		RX_MSDU_END_13_DA_IDX_LSB))
490 
491 /**
492  * hal_rx_msdu_end_da_idx_get_6290: API to get da_idx
493  * from rx_msdu_end TLV
494  *
495  * @ buf: pointer to the start of RX PKT TLV headers
496  * Return: da index
497  */
498 static uint16_t hal_rx_msdu_end_da_idx_get_6290(uint8_t *buf)
499 {
500 	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
501 	struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end;
502 	uint16_t da_idx;
503 
504 	da_idx = HAL_RX_MSDU_END_DA_IDX_GET(msdu_end);
505 
506 	return da_idx;
507 }
508 
509