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