xref: /wlan-dirver/qca-wifi-host-cmn/hal/wifi3.0/qca6390/hal_6390_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 #define HAL_RX_MSDU_START_MIMO_SS_BITMAP(_rx_msdu_start)\
50 	(_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start),\
51 	RX_MSDU_START_5_MIMO_SS_BITMAP_OFFSET)),	\
52 	RX_MSDU_START_5_MIMO_SS_BITMAP_MASK,		\
53 	RX_MSDU_START_5_MIMO_SS_BITMAP_LSB))
54 
55 /*
56  * hal_rx_msdu_start_nss_get_6390(): API to get the NSS
57  * Interval from rx_msdu_start
58  *
59  * @buf: pointer to the start of RX PKT TLV header
60  * Return: uint32_t(nss)
61  */
62 static uint32_t
63 hal_rx_msdu_start_nss_get_6390(uint8_t *buf)
64 {
65 	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
66 	struct rx_msdu_start *msdu_start =
67 				&pkt_tlvs->msdu_start_tlv.rx_msdu_start;
68 	uint8_t mimo_ss_bitmap;
69 
70 	mimo_ss_bitmap = HAL_RX_MSDU_START_MIMO_SS_BITMAP(msdu_start);
71 
72 	return qdf_get_hweight8(mimo_ss_bitmap);
73 }
74 
75 /**
76  * hal_rx_mon_hw_desc_get_mpdu_status_6390(): Retrieve MPDU status
77  *
78  * @ hw_desc_addr: Start address of Rx HW TLVs
79  * @ rs: Status for monitor mode
80  *
81  * Return: void
82  */
83 static void hal_rx_mon_hw_desc_get_mpdu_status_6390(void *hw_desc_addr,
84 						    struct mon_rx_status *rs)
85 {
86 	struct rx_msdu_start *rx_msdu_start;
87 	struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr;
88 	uint32_t reg_value;
89 	const uint32_t sgi_hw_to_cdp[] = {
90 		CDP_SGI_0_8_US,
91 		CDP_SGI_0_4_US,
92 		CDP_SGI_1_6_US,
93 		CDP_SGI_3_2_US,
94 	};
95 
96 	rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start;
97 
98 	HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs);
99 
100 	rs->ant_signal_db = HAL_RX_GET(rx_msdu_start,
101 				RX_MSDU_START_5, USER_RSSI);
102 	rs->is_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC);
103 
104 	reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI);
105 	rs->sgi = sgi_hw_to_cdp[reg_value];
106 
107 	reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, PKT_TYPE);
108 	switch (reg_value) {
109 	case HAL_RX_PKT_TYPE_11N:
110 		rs->ht_flags = 1;
111 		break;
112 	case HAL_RX_PKT_TYPE_11AC:
113 		rs->vht_flags = 1;
114 		reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5,
115 				       RECEIVE_BANDWIDTH);
116 		rs->vht_flag_values2 = reg_value;
117 		break;
118 	case HAL_RX_PKT_TYPE_11AX:
119 		rs->he_flags = 1;
120 		break;
121 	default:
122 		break;
123 	}
124 	reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE);
125 	rs->beamformed = (reg_value == HAL_RX_RECEPTION_TYPE_MU_MIMO) ? 1 : 0;
126 	/* TODO: rs->beamformed should be set for SU beamforming also */
127 }
128 
129 #define LINK_DESC_SIZE (NUM_OF_DWORDS_RX_MSDU_LINK << 2)
130 
131 static uint32_t hal_get_link_desc_size_6390(void)
132 {
133 	return LINK_DESC_SIZE;
134 }
135 
136 /*
137  * hal_rx_get_tlv_6390(): API to get the tlv
138  *
139  * @rx_tlv: TLV data extracted from the rx packet
140  * Return: uint8_t
141  */
142 static uint8_t hal_rx_get_tlv_6390(void *rx_tlv)
143 {
144 	return HAL_RX_GET(rx_tlv, PHYRX_RSSI_LEGACY_0, RECEIVE_BANDWIDTH);
145 }
146 
147 /**
148  * hal_rx_proc_phyrx_other_receive_info_tlv_6390()
149  *				    - process other receive info TLV
150  * @rx_tlv_hdr: pointer to TLV header
151  * @ppdu_info: pointer to ppdu_info
152  *
153  * Return: None
154  */
155 static
156 void hal_rx_proc_phyrx_other_receive_info_tlv_6390(void *rx_tlv_hdr,
157 						   void *ppdu_info_handle)
158 {
159 	uint32_t tlv_tag, tlv_len;
160 	uint32_t temp_len, other_tlv_len, other_tlv_tag;
161 	void *rx_tlv = (uint8_t *)rx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE;
162 	void *other_tlv_hdr = NULL;
163 	void *other_tlv = NULL;
164 
165 	tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv_hdr);
166 	tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv_hdr);
167 	temp_len = 0;
168 
169 	other_tlv_hdr = rx_tlv + HAL_RX_TLV32_HDR_SIZE;
170 
171 	other_tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(other_tlv_hdr);
172 	other_tlv_len = HAL_RX_GET_USER_TLV32_LEN(other_tlv_hdr);
173 	temp_len += other_tlv_len;
174 	other_tlv = other_tlv_hdr + HAL_RX_TLV32_HDR_SIZE;
175 
176 	switch (other_tlv_tag) {
177 	default:
178 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
179 			  "%s unhandled TLV type: %d, TLV len:%d",
180 			  __func__, other_tlv_tag, other_tlv_len);
181 		break;
182 	}
183 }
184 
185 /**
186  * hal_rx_dump_msdu_start_tlv_6390() : dump RX msdu_start TLV in structured
187  *			     human readable format.
188  * @ msdu_start: pointer the msdu_start TLV in pkt.
189  * @ dbg_level: log level.
190  *
191  * Return: void
192  */
193 static void hal_rx_dump_msdu_start_tlv_6390(void *msdustart, uint8_t dbg_level)
194 {
195 	struct rx_msdu_start *msdu_start = (struct rx_msdu_start *)msdustart;
196 
197 	QDF_TRACE(QDF_MODULE_ID_DP, dbg_level,
198 			"rx_msdu_start tlv - "
199 			"rxpcu_mpdu_filter_in_category: %d "
200 			"sw_frame_group_id: %d "
201 			"phy_ppdu_id: %d "
202 			"msdu_length: %d "
203 			"ipsec_esp: %d "
204 			"l3_offset: %d "
205 			"ipsec_ah: %d "
206 			"l4_offset: %d "
207 			"msdu_number: %d "
208 			"decap_format: %d "
209 			"ipv4_proto: %d "
210 			"ipv6_proto: %d "
211 			"tcp_proto: %d "
212 			"udp_proto: %d "
213 			"ip_frag: %d "
214 			"tcp_only_ack: %d "
215 			"da_is_bcast_mcast: %d "
216 			"ip4_protocol_ip6_next_header: %d "
217 			"toeplitz_hash_2_or_4: %d "
218 			"flow_id_toeplitz: %d "
219 			"user_rssi: %d "
220 			"pkt_type: %d "
221 			"stbc: %d "
222 			"sgi: %d "
223 			"rate_mcs: %d "
224 			"receive_bandwidth: %d "
225 			"reception_type: %d "
226 			"ppdu_start_timestamp: %d "
227 			"sw_phy_meta_data: %d ",
228 			msdu_start->rxpcu_mpdu_filter_in_category,
229 			msdu_start->sw_frame_group_id,
230 			msdu_start->phy_ppdu_id,
231 			msdu_start->msdu_length,
232 			msdu_start->ipsec_esp,
233 			msdu_start->l3_offset,
234 			msdu_start->ipsec_ah,
235 			msdu_start->l4_offset,
236 			msdu_start->msdu_number,
237 			msdu_start->decap_format,
238 			msdu_start->ipv4_proto,
239 			msdu_start->ipv6_proto,
240 			msdu_start->tcp_proto,
241 			msdu_start->udp_proto,
242 			msdu_start->ip_frag,
243 			msdu_start->tcp_only_ack,
244 			msdu_start->da_is_bcast_mcast,
245 			msdu_start->ip4_protocol_ip6_next_header,
246 			msdu_start->toeplitz_hash_2_or_4,
247 			msdu_start->flow_id_toeplitz,
248 			msdu_start->user_rssi,
249 			msdu_start->pkt_type,
250 			msdu_start->stbc,
251 			msdu_start->sgi,
252 			msdu_start->rate_mcs,
253 			msdu_start->receive_bandwidth,
254 			msdu_start->reception_type,
255 			msdu_start->ppdu_start_timestamp,
256 			msdu_start->sw_phy_meta_data);
257 }
258 
259 /**
260  * hal_rx_dump_msdu_end_tlv_6390: dump RX msdu_end TLV in structured
261  *			     human readable format.
262  * @ msdu_end: pointer the msdu_end TLV in pkt.
263  * @ dbg_level: log level.
264  *
265  * Return: void
266  */
267 static void hal_rx_dump_msdu_end_tlv_6390(void *msduend,
268 					  uint8_t dbg_level)
269 {
270 	struct rx_msdu_end *msdu_end = (struct rx_msdu_end *)msduend;
271 
272 	QDF_TRACE(QDF_MODULE_ID_DP, dbg_level,
273 			"rx_msdu_end tlv - "
274 			"rxpcu_mpdu_filter_in_category: %d "
275 			"sw_frame_group_id: %d "
276 			"phy_ppdu_id: %d "
277 			"ip_hdr_chksum: %d "
278 			"tcp_udp_chksum: %d "
279 			"key_id_octet: %d "
280 			"cce_super_rule: %d "
281 			"cce_classify_not_done_truncat: %d "
282 			"cce_classify_not_done_cce_dis: %d "
283 			"ext_wapi_pn_63_48: %d "
284 			"ext_wapi_pn_95_64: %d "
285 			"ext_wapi_pn_127_96: %d "
286 			"reported_mpdu_length: %d "
287 			"first_msdu: %d "
288 			"last_msdu: %d "
289 			"sa_idx_timeout: %d "
290 			"da_idx_timeout: %d "
291 			"msdu_limit_error: %d "
292 			"flow_idx_timeout: %d "
293 			"flow_idx_invalid: %d "
294 			"wifi_parser_error: %d "
295 			"amsdu_parser_error: %d "
296 			"sa_is_valid: %d "
297 			"da_is_valid: %d "
298 			"da_is_mcbc: %d "
299 			"l3_header_padding: %d "
300 			"ipv6_options_crc: %d "
301 			"tcp_seq_number: %d "
302 			"tcp_ack_number: %d "
303 			"tcp_flag: %d "
304 			"lro_eligible: %d "
305 			"window_size: %d "
306 			"da_offset: %d "
307 			"sa_offset: %d "
308 			"da_offset_valid: %d "
309 			"sa_offset_valid: %d "
310 			"rule_indication_31_0: %d "
311 			"rule_indication_63_32: %d "
312 			"sa_idx: %d "
313 			"da_idx: %d "
314 			"msdu_drop: %d "
315 			"reo_destination_indication: %d "
316 			"flow_idx: %d "
317 			"fse_metadata: %d "
318 			"cce_metadata: %d "
319 			"sa_sw_peer_id: %d ",
320 			msdu_end->rxpcu_mpdu_filter_in_category,
321 			msdu_end->sw_frame_group_id,
322 			msdu_end->phy_ppdu_id,
323 			msdu_end->ip_hdr_chksum,
324 			msdu_end->tcp_udp_chksum,
325 			msdu_end->key_id_octet,
326 			msdu_end->cce_super_rule,
327 			msdu_end->cce_classify_not_done_truncate,
328 			msdu_end->cce_classify_not_done_cce_dis,
329 			msdu_end->ext_wapi_pn_63_48,
330 			msdu_end->ext_wapi_pn_95_64,
331 			msdu_end->ext_wapi_pn_127_96,
332 			msdu_end->reported_mpdu_length,
333 			msdu_end->first_msdu,
334 			msdu_end->last_msdu,
335 			msdu_end->sa_idx_timeout,
336 			msdu_end->da_idx_timeout,
337 			msdu_end->msdu_limit_error,
338 			msdu_end->flow_idx_timeout,
339 			msdu_end->flow_idx_invalid,
340 			msdu_end->wifi_parser_error,
341 			msdu_end->amsdu_parser_error,
342 			msdu_end->sa_is_valid,
343 			msdu_end->da_is_valid,
344 			msdu_end->da_is_mcbc,
345 			msdu_end->l3_header_padding,
346 			msdu_end->ipv6_options_crc,
347 			msdu_end->tcp_seq_number,
348 			msdu_end->tcp_ack_number,
349 			msdu_end->tcp_flag,
350 			msdu_end->lro_eligible,
351 			msdu_end->window_size,
352 			msdu_end->da_offset,
353 			msdu_end->sa_offset,
354 			msdu_end->da_offset_valid,
355 			msdu_end->sa_offset_valid,
356 			msdu_end->rule_indication_31_0,
357 			msdu_end->rule_indication_63_32,
358 			msdu_end->sa_idx,
359 			msdu_end->da_idx_or_sw_peer_id,
360 			msdu_end->msdu_drop,
361 			msdu_end->reo_destination_indication,
362 			msdu_end->flow_idx,
363 			msdu_end->fse_metadata,
364 			msdu_end->cce_metadata,
365 			msdu_end->sa_sw_peer_id);
366 }
367 
368 
369 /*
370  * Get tid from RX_MPDU_START
371  */
372 #define HAL_RX_MPDU_INFO_TID_GET(_rx_mpdu_info) \
373 	(_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info),	\
374 		RX_MPDU_INFO_3_TID_OFFSET)),		\
375 		RX_MPDU_INFO_3_TID_MASK,		\
376 		RX_MPDU_INFO_3_TID_LSB))
377 
378 static uint32_t hal_rx_mpdu_start_tid_get_6390(uint8_t *buf)
379 {
380 	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
381 	struct rx_mpdu_start *mpdu_start =
382 			&pkt_tlvs->mpdu_start_tlv.rx_mpdu_start;
383 	uint32_t tid;
384 
385 	tid = HAL_RX_MPDU_INFO_TID_GET(&mpdu_start->rx_mpdu_info_details);
386 
387 	return tid;
388 }
389 
390 #define HAL_RX_MSDU_START_RECEPTION_TYPE_GET(_rx_msdu_start) \
391 	(_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start),	\
392 	RX_MSDU_START_5_RECEPTION_TYPE_OFFSET)),	\
393 	RX_MSDU_START_5_RECEPTION_TYPE_MASK,		\
394 	RX_MSDU_START_5_RECEPTION_TYPE_LSB))
395 
396 /*
397  * hal_rx_msdu_start_reception_type_get(): API to get the reception type
398  * Interval from rx_msdu_start
399  *
400  * @buf: pointer to the start of RX PKT TLV header
401  * Return: uint32_t(reception_type)
402  */
403 static
404 uint32_t hal_rx_msdu_start_reception_type_get_6390(uint8_t *buf)
405 {
406 	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
407 	struct rx_msdu_start *msdu_start =
408 		&pkt_tlvs->msdu_start_tlv.rx_msdu_start;
409 	uint32_t reception_type;
410 
411 	reception_type = HAL_RX_MSDU_START_RECEPTION_TYPE_GET(msdu_start);
412 
413 	return reception_type;
414 }
415 
416 #define HAL_RX_MSDU_END_DA_IDX_GET(_rx_msdu_end)	\
417 	(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_end,	\
418 		RX_MSDU_END_13_DA_IDX_OR_SW_PEER_ID_OFFSET)),	\
419 		RX_MSDU_END_13_DA_IDX_OR_SW_PEER_ID_MASK,	\
420 		RX_MSDU_END_13_DA_IDX_OR_SW_PEER_ID_LSB))
421 
422  /**
423  * hal_rx_msdu_end_da_idx_get_6390: API to get da_idx
424  * from rx_msdu_end TLV
425  *
426  * @ buf: pointer to the start of RX PKT TLV headers
427  * Return: da index
428  */
429 static uint16_t hal_rx_msdu_end_da_idx_get_6390(uint8_t *buf)
430 {
431 	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
432 	struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end;
433 	uint16_t da_idx;
434 
435 	da_idx = HAL_RX_MSDU_END_DA_IDX_GET(msdu_end);
436 
437 	return da_idx;
438 }
439 
440