1 /*
2  * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <target_if_cfr.h>
21 #include <wlan_tgt_def_config.h>
22 #include <target_type.h>
23 #include <hif_hw_version.h>
24 #include <target_if.h>
25 #include <wlan_lmac_if_def.h>
26 #include <wlan_osif_priv.h>
27 #include <init_deinit_lmac.h>
28 #include <wlan_cfr_utils_api.h>
29 #include <target_if_direct_buf_rx_api.h>
30 #include <target_if_cfr_enh.h>
31 #include "cdp_txrx_ctrl.h"
32 #include <wlan_reg_services_api.h>
33 
34 #define CMN_NOISE_FLOOR       (-96)
35 #define NUM_CHAINS_FW_TO_HOST(n) ((1 << ((n) + 1)) - 1)
36 
37 #define CFR_INVALID_SNR 0x80
38 #define CHAIN_SHIFT_INDEX_PINE_SCAN 2
39 
40 static u_int32_t end_magic = 0xBEAFDEAD;
41 
42 /**
43  * snr_to_signal_strength() - Convert SNR(dB) to signal strength(dBm)
44  * @snr: SNR in dB
45  *
46  * Return: signal strength in dBm
47  */
48 #if defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_KIWI)
49 static inline
snr_to_signal_strength(uint8_t snr)50 u_int32_t snr_to_signal_strength(uint8_t snr)
51 {
52 	/* target onverts snr to dBm */
53 	return snr;
54 }
55 #else
56 static inline
snr_to_signal_strength(uint8_t snr)57 u_int32_t snr_to_signal_strength(uint8_t snr)
58 {
59 	/* SNR value 0x80 indicates -128dB which is not a valid value */
60 	return (snr != CFR_INVALID_SNR) ?
61 		(((int8_t)snr) + CMN_NOISE_FLOOR) :
62 		((int8_t)snr);
63 }
64 #endif
65 
66 /**
67  * target_if_snr_to_signal_strength() - wrapper API to snr_to_signal_strength to
68  *                                      consider target_type.
69  * @target_type: target type of the pdev
70  * @meta: pointer to CFR metadata
71  * @ppdu: rx ppdu having per chain rssi to be converted to dBm
72  *
73  * Return: none
74  */
75 static inline
target_if_snr_to_signal_strength(uint32_t target_type,struct enh_cfr_metadata * meta,struct cdp_rx_indication_ppdu * ppdu)76 void target_if_snr_to_signal_strength(uint32_t target_type,
77 				      struct enh_cfr_metadata *meta,
78 				      struct cdp_rx_indication_ppdu *ppdu)
79 {
80 	uint8_t i;
81 
82 	/* No need to add CMN_NOISE_FLOOR for york */
83 	if (target_type == TARGET_TYPE_QCN9160) {
84 		for (i = 0; i < MAX_CHAIN; i++) {
85 			meta->chain_rssi[i] = (int8_t)ppdu->per_chain_rssi[i];
86 		}
87 	} else {
88 		for (i = 0; i < MAX_CHAIN; i++) {
89 			meta->chain_rssi[i] =
90 				snr_to_signal_strength(ppdu->per_chain_rssi[i]);
91 		}
92 	}
93 }
94 
95 /**
96  * get_lut_entry() - Retrieve LUT entry using cookie number
97  * @pcfr: PDEV CFR object
98  * @offset: cookie number
99  *
100  * Return: look up table entry
101  */
get_lut_entry(struct pdev_cfr * pcfr,int offset)102 static struct look_up_table *get_lut_entry(struct pdev_cfr *pcfr,
103 					   int offset)
104 {
105 	if (offset >= pcfr->lut_num) {
106 		cfr_err("Invalid offset %d, lut_num %d",
107 			offset, pcfr->lut_num);
108 		return NULL;
109 	}
110 
111 	return pcfr->lut[offset];
112 }
113 
114 /**
115  * release_lut_entry_enh() - Clear all params in an LUT entry
116  * @pdev: objmgr PDEV
117  * @lut: pointer to LUT
118  *
119  * Return: status
120  */
release_lut_entry_enh(struct wlan_objmgr_pdev * pdev,struct look_up_table * lut)121 static int release_lut_entry_enh(struct wlan_objmgr_pdev *pdev,
122 				 struct look_up_table *lut)
123 {
124 	lut->dbr_recv = false;
125 	lut->tx_recv = false;
126 	lut->data = NULL;
127 	lut->data_len = 0;
128 	lut->dbr_ppdu_id = 0;
129 	lut->tx_ppdu_id = 0;
130 	lut->dbr_tstamp = 0;
131 	lut->txrx_tstamp = 0;
132 	lut->tx_address1 = 0;
133 	lut->tx_address2 = 0;
134 	lut->dbr_address = 0;
135 	qdf_mem_zero(&lut->header, sizeof(struct csi_cfr_header));
136 
137 	return 0;
138 }
139 
140 /**
141  * target_if_cfr_dump_lut_enh() - dump all valid lut entries
142  * @pdev: objmgr pdev
143  *
144  * return: none
145  */
target_if_cfr_dump_lut_enh(struct wlan_objmgr_pdev * pdev)146 void target_if_cfr_dump_lut_enh(struct wlan_objmgr_pdev *pdev)
147 {
148 	struct pdev_cfr *pcfr;
149 	struct look_up_table *lut = NULL;
150 	int i = 0;
151 	uint64_t diff;
152 	QDF_STATUS retval = 0;
153 
154 	retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID);
155 	if (retval != QDF_STATUS_SUCCESS) {
156 		cfr_err("failed to get pdev reference");
157 		return;
158 	}
159 
160 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
161 						     WLAN_UMAC_COMP_CFR);
162 	if (!pcfr) {
163 		cfr_err("pdev object for CFR is null");
164 		wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
165 		return;
166 	}
167 
168 	qdf_spin_lock_bh(&pcfr->lut_lock);
169 
170 	for (i = 0; i < pcfr->lut_num; i++) {
171 		lut = get_lut_entry(pcfr, i);
172 		if (!lut)
173 			continue;
174 		if (lut->dbr_recv ^ lut->tx_recv) {
175 			diff = (lut->dbr_tstamp > lut->txrx_tstamp) ?
176 				(lut->dbr_tstamp - lut->txrx_tstamp) :
177 				(lut->txrx_tstamp - lut->dbr_tstamp);
178 		}
179 	}
180 
181 	qdf_spin_unlock_bh(&pcfr->lut_lock);
182 
183 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
184 }
185 
186 /**
187  * cfr_free_pending_dbr_events() - Flush all pending DBR events. This is useful
188  * in cases where for RXTLV drops in host monitor status ring is huge.
189  * @pdev: objmgr pdev
190  *
191  * return: none
192  */
cfr_free_pending_dbr_events(struct wlan_objmgr_pdev * pdev)193 static void cfr_free_pending_dbr_events(struct wlan_objmgr_pdev *pdev)
194 {
195 	struct pdev_cfr *pcfr;
196 	struct look_up_table *lut = NULL;
197 	int i = 0;
198 	QDF_STATUS retval = 0;
199 
200 	retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID);
201 	if (retval != QDF_STATUS_SUCCESS) {
202 		cfr_err("failed to get pdev reference");
203 		return;
204 	}
205 
206 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
207 						     WLAN_UMAC_COMP_CFR);
208 	if (!pcfr) {
209 		cfr_err("pdev object for CFR is null");
210 		wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
211 		return;
212 	}
213 
214 	for (i = 0; i < pcfr->lut_num; i++) {
215 		lut = get_lut_entry(pcfr, i);
216 		if (!lut)
217 			continue;
218 
219 		if (lut->dbr_recv && !lut->tx_recv &&
220 		    (lut->dbr_tstamp < pcfr->last_success_tstamp)) {
221 			target_if_dbr_buf_release(pdev, DBR_MODULE_CFR,
222 						  lut->dbr_address,
223 						  i, 0);
224 			pcfr->flush_dbr_cnt++;
225 			release_lut_entry_enh(pdev, lut);
226 		}
227 	}
228 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
229 }
230 
231 /**
232  * dump_freeze_tlv() - Dump freeze TLV sent in enhanced DMA header
233  * @freeze_tlv: Freeze TLV sent from MAC to PHY
234  * @cookie: Index into lookup table
235  *
236  * Return: none
237  */
dump_freeze_tlv(void * freeze_tlv,uint32_t cookie)238 static void dump_freeze_tlv(void *freeze_tlv, uint32_t cookie)
239 {
240 	struct macrx_freeze_capture_channel *freeze =
241 		(struct macrx_freeze_capture_channel *)freeze_tlv;
242 
243 	cfr_debug("<DBRCOMP><FREEZE><%u>\n"
244 		  "freeze: %d capture_reason: %d packet_type: 0x%x\n"
245 		  "packet_subtype: 0x%x sw_peer_id_valid: %d sw_peer_id: %d\n"
246 		  "phy_ppdu_id: 0x%04x packet_ta_upper_16: 0x%04x\n"
247 		  "packet_ta_mid_16: 0x%04x packet_ta_lower_16: 0x%04x\n"
248 		  "packet_ra_upper_16: 0x%04x packet_ra_mid_16: 0x%04x\n"
249 		  "packet_ra_lower_16: 0x%04x tsf_timestamp_63_48: 0x%04x\n"
250 		  "tsf_timestamp_47_32: 0x%04x tsf_timestamp_31_16: 0x%04x\n"
251 		  "tsf_timestamp_15_0: 0x%04x user_index_or_user_mask_5_0: %d\n"
252 		  "directed: %d\n",
253 		  cookie,
254 		  freeze->freeze,
255 		  freeze->capture_reason,
256 		  freeze->packet_type,
257 		  freeze->packet_sub_type,
258 		  freeze->sw_peer_id_valid,
259 		  freeze->sw_peer_id,
260 		  freeze->phy_ppdu_id,
261 		  freeze->packet_ta_upper_16,
262 		  freeze->packet_ta_mid_16,
263 		  freeze->packet_ta_lower_16,
264 		  freeze->packet_ra_upper_16,
265 		  freeze->packet_ra_mid_16,
266 		  freeze->packet_ra_lower_16,
267 		  freeze->tsf_timestamp_63_48,
268 		  freeze->tsf_timestamp_47_32,
269 		  freeze->tsf_timestamp_31_16,
270 		  freeze->tsf_timestamp_15_0,
271 		  freeze->user_index_or_user_mask_5_0,
272 		  freeze->directed);
273 }
274 
275 /**
276  * dump_freeze_tlv_v3() - Dump freeze TLV v2 sent in enhanced DMA header
277  * @freeze_tlv: Freeze TLV sent from MAC to PHY
278  * @cookie: Index into lookup table
279  *
280  * Return: none
281  */
dump_freeze_tlv_v3(void * freeze_tlv,uint32_t cookie)282 static void dump_freeze_tlv_v3(void *freeze_tlv, uint32_t cookie)
283 {
284 	struct macrx_freeze_capture_channel_v3 *freeze =
285 		(struct macrx_freeze_capture_channel_v3 *)freeze_tlv;
286 
287 	cfr_debug("<DBRCOMP><FREEZE><%u>\n"
288 		  "freeze: %d capture_reason: %d packet_type: 0x%x\n"
289 		  "packet_subtype: 0x%x sw_peer_id_valid: %d sw_peer_id: %d\n"
290 		  "phy_ppdu_id: 0x%04x packet_ta_upper_16: 0x%04x\n"
291 		  "packet_ta_mid_16: 0x%04x packet_ta_lower_16: 0x%04x\n"
292 		  "packet_ra_upper_16: 0x%04x packet_ra_mid_16: 0x%04x\n"
293 		  "packet_ra_lower_16: 0x%04x\n"
294 		  "tsf_63_48_or_user_mask_36_32: 0x%04x\n"
295 		  "tsf_timestamp_47_32: 0x%04x\n"
296 		  "tsf_timestamp_31_16: 0x%04x\n"
297 		  "tsf_timestamp_15_0: 0x%04x\n"
298 		  "user_index_or_user_mask_15_0: 0x%04x\n"
299 		  "user_mask_31_16: 0x%04x\n"
300 		  "directed: %d\n",
301 		  cookie,
302 		  freeze->freeze,
303 		  freeze->capture_reason,
304 		  freeze->packet_type,
305 		  freeze->packet_sub_type,
306 		  freeze->sw_peer_id_valid,
307 		  freeze->sw_peer_id,
308 		  freeze->phy_ppdu_id,
309 		  freeze->packet_ta_upper_16,
310 		  freeze->packet_ta_mid_16,
311 		  freeze->packet_ta_lower_16,
312 		  freeze->packet_ra_upper_16,
313 		  freeze->packet_ra_mid_16,
314 		  freeze->packet_ra_lower_16,
315 		  freeze->tsf_63_48_or_user_mask_36_32,
316 		  freeze->tsf_timestamp_47_32,
317 		  freeze->tsf_timestamp_31_16,
318 		  freeze->tsf_timestamp_15_0,
319 		  freeze->user_index_or_user_mask_15_0,
320 		  freeze->user_mask_31_16,
321 		  freeze->directed);
322 }
323 
324 /**
325  * dump_freeze_tlv_v5() - Dump freeze TLV sent in enhanced DMA header
326  * @freeze_tlv: Freeze TLV sent from MAC to PHY
327  * @cookie: Index into lookup table
328  *
329  * Return: none
330  */
dump_freeze_tlv_v5(void * freeze_tlv,uint32_t cookie)331 static void dump_freeze_tlv_v5(void *freeze_tlv, uint32_t cookie)
332 {
333 	struct macrx_freeze_capture_channel_v5 *freeze =
334 		(struct macrx_freeze_capture_channel_v5 *)freeze_tlv;
335 
336 	cfr_debug("<DBRCOMP><FREEZE><%u>\n"
337 		  "freeze: %d capture_reason: %d packet_type: 0x%x\n"
338 		  "packet_subtype: 0x%x sw_peer_id_valid: %d sw_peer_id: %d\n"
339 		  "phy_ppdu_id: 0x%04x packet_ta_lower_16: 0x%04x\n"
340 		  "packet_ta_mid_16: 0x%04x packet_ta_upper_16: 0x%04x\n"
341 		  "packet_ra_lower_16: 0x%04x packet_ra_mid_16: 0x%04x\n"
342 		  "packet_ra_upper_16: 0x%04x\n"
343 		  "tsf_timestamp_15_0: 0x%04x\n"
344 		  "tsf_timestamp_31_16: 0x%04x\n"
345 		  "tsf_timestamp_47_32: 0x%04x\n"
346 		  "tsf_timestamp_63_48: 0x%04x\n"
347 		  "user_index_or_user_mask_5_0: 0x%04x\n"
348 		  "directed: %d\n"
349 		  "user_mask_21_6: 0x%04x\n"
350 		  "user_mask_36_22: 0x%04x\n",
351 		  cookie,
352 		  freeze->freeze,
353 		  freeze->capture_reason,
354 		  freeze->packet_type,
355 		  freeze->packet_sub_type,
356 		  freeze->sw_peer_id_valid,
357 		  freeze->sw_peer_id,
358 		  freeze->phy_ppdu_id,
359 		  freeze->packet_ta_lower_16,
360 		  freeze->packet_ta_mid_16,
361 		  freeze->packet_ta_upper_16,
362 		  freeze->packet_ra_lower_16,
363 		  freeze->packet_ra_mid_16,
364 		  freeze->packet_ra_upper_16,
365 		  freeze->tsf_timestamp_15_0,
366 		  freeze->tsf_timestamp_31_16,
367 		  freeze->tsf_timestamp_47_32,
368 		  freeze->tsf_timestamp_63_48,
369 		  freeze->user_index_or_user_mask_5_0,
370 		  freeze->directed,
371 		  freeze->user_mask_21_6,
372 		  freeze->user_mask_36_22);
373 }
374 
375 /**
376  * dump_mu_rx_info() - Dump MU info in enhanced DMA header
377  * @mu_rx_user_info: MU info sent by ucode
378  * @mu_rx_num_users: Number of MU users in UL-MU-PPDU
379  * @cookie: Index into lookup table
380  *
381  * Return: none
382  */
dump_mu_rx_info(void * mu_rx_user_info,uint8_t mu_rx_num_users,uint32_t cookie)383 static void dump_mu_rx_info(void *mu_rx_user_info,
384 			    uint8_t mu_rx_num_users,
385 			    uint32_t cookie)
386 {
387 	uint8_t i;
388 	struct uplink_user_setup_info *ul_mu_user_info =
389 		(struct uplink_user_setup_info *)mu_rx_user_info;
390 
391 	for (i = 0 ; i < mu_rx_num_users; i++) {
392 		cfr_debug("<DBRCOMP><MU><%u>\n"
393 			  "<user_id:%d>\n"
394 			  "bw_info_valid = %d\n"
395 			  "uplink_receive_type = %d\n"
396 			  "uplink_11ax_mcs = %d\n"
397 			  "ru_width = %d\n"
398 			  "nss = %d\n"
399 			  "stream_offset = %d\n"
400 			  "sta_dcm = %d\n"
401 			  "sta_coding = %d\n"
402 			  "ru_start_index = %d\n",
403 			  cookie,
404 			  i,
405 			  ul_mu_user_info->bw_info_valid,
406 			  ul_mu_user_info->uplink_receive_type,
407 			  ul_mu_user_info->uplink_11ax_mcs,
408 			  ul_mu_user_info->ru_width,
409 			  ul_mu_user_info->nss,
410 			  ul_mu_user_info->stream_offset,
411 			  ul_mu_user_info->sta_dcm,
412 			  ul_mu_user_info->sta_coding,
413 			  ul_mu_user_info->ru_start_index);
414 		ul_mu_user_info += sizeof(struct uplink_user_setup_info);
415 	}
416 }
417 
418 /**
419  * dump_mu_rx_info_v2() - Dump MU info in enhanced DMA header
420  * @mu_rx_user_info: MU info sent by ucode
421  * @mu_rx_num_users: Number of MU users in UL-MU-PPDU
422  * @cookie: Index into lookup table
423  *
424  * Return: none
425  */
dump_mu_rx_info_v2(void * mu_rx_user_info,uint8_t mu_rx_num_users,uint32_t cookie)426 static void dump_mu_rx_info_v2(void *mu_rx_user_info,
427 			       uint8_t mu_rx_num_users,
428 			       uint32_t cookie)
429 {
430 	uint8_t i;
431 	struct uplink_user_setup_info_v2 *ul_mu_user_info =
432 		(struct uplink_user_setup_info_v2 *)mu_rx_user_info;
433 
434 	for (i = 0 ; i < mu_rx_num_users; i++) {
435 		cfr_debug("<DBRCOMP><MU><%u>\n"
436 			  "<user_id:%d>\n"
437 			  "bw_info_valid = %d\n"
438 			  "uplink_receive_type = %d\n"
439 			  "uplink_11ax_mcs = %d\n"
440 			  "nss = %d\n"
441 			  "stream_offset = %d\n"
442 			  "sta_dcm = %d\n"
443 			  "sta_coding = %d\n"
444 			  "ru_type_80_0 = %d\n"
445 			  "ru_type_80_1 = %d\n"
446 			  "ru_type_80_2 = %d\n"
447 			  "ru_type_80_3 = %d\n"
448 			  "ru_start_index_80_0 = %d\n"
449 			  "ru_start_index_80_1 = %d\n"
450 			  "ru_start_index_80_2 = %d\n"
451 			  "ru_start_index_80_3 = %d\n",
452 			  cookie,
453 			  i,
454 			  ul_mu_user_info->bw_info_valid,
455 			  ul_mu_user_info->uplink_receive_type,
456 			  ul_mu_user_info->uplink_11ax_mcs,
457 			  ul_mu_user_info->nss,
458 			  ul_mu_user_info->stream_offset,
459 			  ul_mu_user_info->sta_dcm,
460 			  ul_mu_user_info->sta_coding,
461 			  ul_mu_user_info->ru_type_80_0,
462 			  ul_mu_user_info->ru_type_80_1,
463 			  ul_mu_user_info->ru_type_80_2,
464 			  ul_mu_user_info->ru_type_80_3,
465 			  ul_mu_user_info->ru_start_index_80_0,
466 			  ul_mu_user_info->ru_start_index_80_1,
467 			  ul_mu_user_info->ru_start_index_80_2,
468 			  ul_mu_user_info->ru_start_index_80_3);
469 		ul_mu_user_info += sizeof(struct uplink_user_setup_info_v2);
470 	}
471 }
472 
dump_metadata(struct csi_cfr_header * header,uint32_t cookie)473 static void dump_metadata(struct csi_cfr_header *header, uint32_t cookie)
474 {
475 	uint8_t user_id, chain_id;
476 	struct enh_cfr_metadata *meta = &header->u.meta_enh;
477 	uint8_t *usermac = NULL;
478 
479 	cfr_debug("<METADATA><%u>\n"
480 		  "start_magic_num = 0x%x\n"
481 		  "vendorid = 0x%x\n"
482 		  "cfr_metadata_version = %d\n"
483 		  "cfr_data_version = %d\n"
484 		  "cfr_metadata_len = %d\n"
485 		  "chip_type = %d\n"
486 		  "platform_type = %d\n"
487 		  "status = %d\n"
488 		  "capture_bw = %d\n"
489 		  "channel_bw = %d\n"
490 		  "phy_mode = %d\n"
491 		  "prim20_chan = %d\n"
492 		  "center_freq1 = %d\n"
493 		  "center_freq2 = %d\n"
494 		  "ack_capture_mode = %d\n"
495 		  "cfr_capture_type = %d\n"
496 		  "sts_count = %d\n"
497 		  "num_rx_chain = %d\n"
498 		  "timestamp = %llu\n"
499 		  "length = %d\n"
500 		  "is_mu_ppdu = %d\n"
501 		  "num_users = %d\n",
502 		cookie,
503 		header->cmn.start_magic_num,
504 		header->cmn.vendorid,
505 		header->cmn.cfr_metadata_version,
506 		header->cmn.cfr_data_version,
507 		header->cmn.cfr_metadata_len,
508 		header->cmn.chip_type,
509 		header->cmn.pltform_type,
510 		meta->status,
511 		meta->capture_bw,
512 		meta->channel_bw,
513 		meta->phy_mode,
514 		meta->prim20_chan,
515 		meta->center_freq1,
516 		meta->center_freq2,
517 		meta->capture_mode,
518 		meta->capture_type,
519 		meta->sts_count,
520 		meta->num_rx_chain,
521 		meta->timestamp,
522 		meta->length,
523 		meta->is_mu_ppdu,
524 		meta->num_mu_users);
525 
526 	if (meta->is_mu_ppdu) {
527 		for (user_id = 0; user_id < meta->num_mu_users; user_id++) {
528 			usermac = meta->peer_addr.mu_peer_addr[user_id];
529 			cfr_debug("peermac[%d]: " QDF_MAC_ADDR_FMT,
530 				  user_id, QDF_MAC_ADDR_REF(usermac));
531 		}
532 	} else {
533 		cfr_debug("peermac: " QDF_MAC_ADDR_FMT,
534 			  QDF_MAC_ADDR_REF(meta->peer_addr.su_peer_addr));
535 	}
536 
537 	for (chain_id = 0; chain_id < HOST_MAX_CHAINS; chain_id++) {
538 		cfr_debug("chain_rssi[%d] = %d\n",
539 			  chain_id,
540 			  meta->chain_rssi[chain_id]);
541 	}
542 
543 	for (chain_id = 0; chain_id < HOST_MAX_CHAINS; chain_id++) {
544 		cfr_debug("chain_phase[%d] = %d\n",
545 			  chain_id,
546 			  meta->chain_phase[chain_id]);
547 	}
548 
549 	if (header->cmn.cfr_metadata_version >= CFR_META_VERSION_5) {
550 		cfr_debug("rtt_cfo_measurement = %d\n",
551 			  meta->rtt_cfo_measurement);
552 		cfr_debug("rx_start_ts = %u\n", meta->rx_start_ts);
553 
554 		for (chain_id = 0; chain_id < HOST_MAX_CHAINS; chain_id++) {
555 			cfr_debug("agc_gain[%d] = %d\n",
556 				  chain_id,
557 				  meta->agc_gain[chain_id]);
558 			cfr_debug("agc_gain_tbl_idx[%d] = %d\n",
559 				  chain_id,
560 				  meta->agc_gain_tbl_index[chain_id]);
561 		}
562 
563 		cfr_debug("mcs_rate = %u\n", meta->mcs_rate);
564 		cfr_debug("gi_type = %u\n", meta->gi_type);
565 	}
566 }
567 
568 /**
569  * dump_enh_dma_hdr() - Dump enhanced DMA header populated by ucode
570  * @dma_hdr: pointer to enhanced DMA header
571  * @freeze_tlv: pointer to MACRX_FREEZE_CAPTURE_CHANNEL TLV
572  * @mu_rx_user_info: UPLINK_USER_SETUP_INFO TLV
573  * @header: pointer to metadata passed to userspace
574  * @error: Indicates whether it is an error
575  * @cookie: Index into lookup table
576  *
577  * Return: none
578  */
dump_enh_dma_hdr(struct whal_cfir_enhanced_hdr * dma_hdr,void * freeze_tlv,void * mu_rx_user_info,struct csi_cfr_header * header,int error,uint32_t cookie)579 static void dump_enh_dma_hdr(struct whal_cfir_enhanced_hdr *dma_hdr,
580 			     void *freeze_tlv, void *mu_rx_user_info,
581 			     struct csi_cfr_header *header, int error,
582 			     uint32_t cookie)
583 {
584 	if (!error) {
585 		if (dma_hdr->header_version == UPLOAD_HEADER_VERSION_9) {
586 			cfr_debug("<DBRCOMP><%u>\n"
587 				  "Tag: 0x%02x Length: %d udone: %d\n"
588 				  "ctype: %d preamble: %d Nss: %d\n"
589 				  "num_chains: %d bw: %d peervalid: %d\n"
590 				  "peer_id: %d ppdu_id: 0x%04x\n"
591 				  "total_bytes: %d header_version: %d\n"
592 				  "target_id: %d cfr_fmt: %d\n"
593 				  "mu_rx_data_incl: %d freeze_data_incl: %d\n"
594 				  "mu_rx_num_users: %d decimation_factor: %d\n"
595 				  "freeze_tlv_version: %d\n"
596 				  "he_ltf_type: %u ext_preamble_type = %u\n",
597 				  cookie,
598 				  dma_hdr->tag,
599 				  dma_hdr->length,
600 				  dma_hdr->upload_done,
601 				  dma_hdr->capture_type,
602 				  dma_hdr->preamble_type,
603 				  dma_hdr->nss,
604 				  dma_hdr->num_chains,
605 				  dma_hdr->upload_pkt_bw,
606 				  dma_hdr->sw_peer_id_valid,
607 				  dma_hdr->sw_peer_id,
608 				  dma_hdr->phy_ppdu_id,
609 				  dma_hdr->total_bytes,
610 				  dma_hdr->header_version,
611 				  dma_hdr->target_id,
612 				  dma_hdr->cfr_fmt,
613 				  dma_hdr->mu_rx_data_incl,
614 				  dma_hdr->freeze_data_incl,
615 				  dma_hdr->mu_rx_num_users,
616 				  dma_hdr->decimation_factor,
617 				  dma_hdr->freeze_tlv_version,
618 				  dma_hdr->rsvd3,
619 				  dma_hdr->rsvd4);
620 
621 		} else {
622 			cfr_debug("<DBRCOMP><%u>\n"
623 				  "Tag: 0x%02x Length: %d udone: %d\n"
624 				  "ctype: %d preamble: %d Nss: %d\n"
625 				  "num_chains: %d bw: %d peervalid: %d\n"
626 				  "peer_id: %d ppdu_id: 0x%04x\n"
627 				  "total_bytes: %d header_version: %d\n"
628 				  "target_id: %d cfr_fmt: %d\n"
629 				  "mu_rx_data_incl: %d freeze_data_incl: %d\n"
630 				  "mu_rx_num_users: %d decimation_factor: %d\n"
631 				  "freeze_tlv_version: %d\n",
632 				  cookie,
633 				  dma_hdr->tag,
634 				  dma_hdr->length,
635 				  dma_hdr->upload_done,
636 				  dma_hdr->capture_type,
637 				  dma_hdr->preamble_type,
638 				  dma_hdr->nss,
639 				  dma_hdr->num_chains,
640 				  dma_hdr->upload_pkt_bw,
641 				  dma_hdr->sw_peer_id_valid,
642 				  dma_hdr->sw_peer_id,
643 				  dma_hdr->phy_ppdu_id,
644 				  dma_hdr->total_bytes,
645 				  dma_hdr->header_version,
646 				  dma_hdr->target_id,
647 				  dma_hdr->cfr_fmt,
648 				  dma_hdr->mu_rx_data_incl,
649 				  dma_hdr->freeze_data_incl,
650 				  dma_hdr->mu_rx_num_users,
651 				  dma_hdr->decimation_factor,
652 				  dma_hdr->freeze_tlv_version);
653 		}
654 
655 		if (dma_hdr->freeze_data_incl) {
656 			if (dma_hdr->freeze_tlv_version ==
657 					MACRX_FREEZE_TLV_VERSION_3)
658 				dump_freeze_tlv_v3(freeze_tlv, cookie);
659 			else if (dma_hdr->freeze_tlv_version ==
660 					MACRX_FREEZE_TLV_VERSION_5)
661 				dump_freeze_tlv_v5(freeze_tlv, cookie);
662 			else
663 				dump_freeze_tlv(freeze_tlv, cookie);
664 		}
665 
666 		if ((dma_hdr->mu_rx_data_incl) &&
667 		    (dma_hdr->freeze_tlv_version ==
668 		     MACRX_FREEZE_TLV_VERSION_5)) {
669 			dump_mu_rx_info_v2(mu_rx_user_info,
670 					   dma_hdr->mu_rx_num_users,
671 					   cookie);
672 		} else if (dma_hdr->mu_rx_data_incl) {
673 			dump_mu_rx_info(mu_rx_user_info,
674 					dma_hdr->mu_rx_num_users,
675 					cookie);
676 		}
677 	} else {
678 		cfr_err("<DBRCOMP><%u>\n"
679 			"Tag: 0x%02x Length: %d udone: %d\n"
680 			"ctype: %d preamble: %d Nss: %d\n"
681 			"num_chains: %d bw: %d peervalid: %d\n"
682 			"peer_id: %d ppdu_id: 0x%04x total_bytes: %d\n"
683 			"header_version: %d target_id: %d cfr_fmt: %d\n"
684 			"mu_rx_data_incl: %d freeze_data_incl: %d\n"
685 			"mu_rx_num_users: %d decimation_factor: %d\n"
686 			"freeze_tlv_version: %d\n",
687 			cookie,
688 			dma_hdr->tag,
689 			dma_hdr->length,
690 			dma_hdr->upload_done,
691 			dma_hdr->capture_type,
692 			dma_hdr->preamble_type,
693 			dma_hdr->nss,
694 			dma_hdr->num_chains,
695 			dma_hdr->upload_pkt_bw,
696 			dma_hdr->sw_peer_id_valid,
697 			dma_hdr->sw_peer_id,
698 			dma_hdr->phy_ppdu_id,
699 			dma_hdr->total_bytes,
700 			dma_hdr->header_version,
701 			dma_hdr->target_id,
702 			dma_hdr->cfr_fmt,
703 			dma_hdr->mu_rx_data_incl,
704 			dma_hdr->freeze_data_incl,
705 			dma_hdr->mu_rx_num_users,
706 			dma_hdr->decimation_factor,
707 			dma_hdr->freeze_tlv_version);
708 	}
709 }
710 
711 /**
712  * extract_peer_mac_from_freeze_tlv() - extract macaddr from freeze tlv
713  * @freeze_tlv: Freeze TLV sent from MAC to PHY
714  * @peermac: macaddr of the peer
715  *
716  * Return: none
717  */
718 static void
extract_peer_mac_from_freeze_tlv(void * freeze_tlv,uint8_t * peermac)719 extract_peer_mac_from_freeze_tlv(void *freeze_tlv, uint8_t *peermac)
720 {
721 	/*
722 	 * Packet_ta fields position is common between freeze tlv v1
723 	 * and v2, hence typecasting to v1 is also fine
724 	 */
725 	struct macrx_freeze_capture_channel *freeze =
726 		(struct macrx_freeze_capture_channel *)freeze_tlv;
727 
728 	peermac[0] = freeze->packet_ta_lower_16 & 0x00FF;
729 	peermac[1] = (freeze->packet_ta_lower_16 & 0xFF00) >> 8;
730 	peermac[2] = freeze->packet_ta_mid_16 & 0x00FF;
731 	peermac[3] = (freeze->packet_ta_mid_16 & 0xFF00) >> 8;
732 	peermac[4] = freeze->packet_ta_upper_16 & 0x00FF;
733 	peermac[5] = (freeze->packet_ta_upper_16 & 0xFF00) >> 8;
734 }
735 
736 /**
737  * check_dma_length() - Sanity check DMA header and payload length
738  * @lut: lookup table entry to check
739  * @target_type: target type
740  *
741  * Return: QDF_STATUS
742  */
check_dma_length(struct look_up_table * lut,uint32_t target_type)743 static QDF_STATUS check_dma_length(struct look_up_table *lut,
744 				   uint32_t target_type)
745 {
746 	if (target_type == TARGET_TYPE_QCN9000) {
747 		if (lut->header_length <= PINE_MAX_HEADER_LENGTH_WORDS &&
748 		    lut->payload_length <= PINE_MAX_DATA_LENGTH_BYTES) {
749 			return QDF_STATUS_SUCCESS;
750 		}
751 	} else if (target_type == TARGET_TYPE_QCN6122 ||
752 		   target_type == TARGET_TYPE_QCN9160) {
753 		if (lut->header_length <= SPRUCE_MAX_HEADER_LENGTH_WORDS &&
754 		    lut->payload_length <= SPRUCE_MAX_DATA_LENGTH_BYTES) {
755 			return QDF_STATUS_SUCCESS;
756 		}
757 	} else if (target_type == TARGET_TYPE_QCA5018) {
758 		if (lut->header_length <= MAPLE_MAX_HEADER_LENGTH_WORDS &&
759 		    lut->payload_length <= MAPLE_MAX_DATA_LENGTH_BYTES) {
760 			return QDF_STATUS_SUCCESS;
761 		}
762 	} else if (target_type == TARGET_TYPE_QCN9224) {
763 		if (lut->header_length <= WAIKIKI_MAX_HEADER_LENGTH_WORDS &&
764 		    lut->payload_length <= WAIKIKI_MAX_DATA_LENGTH_BYTES) {
765 			return QDF_STATUS_SUCCESS;
766 		}
767 	} else if (target_type == TARGET_TYPE_QCN6432) {
768 		if (lut->header_length <= QCN6432_MAX_HEADER_LENGTH_WORDS &&
769 		    lut->payload_length <= QCN6432_MAX_DATA_LENGTH_BYTES) {
770 			return QDF_STATUS_SUCCESS;
771 		}
772 	} else if (target_type == TARGET_TYPE_QCA5332) {
773 		if (lut->header_length <= QCA5332_MAX_HEADER_LENGTH_WORDS &&
774 		    lut->payload_length <= QCA5332_MAX_DATA_LENGTH_BYTES) {
775 			return QDF_STATUS_SUCCESS;
776 		}
777 	} else {
778 		if (lut->header_length <= CYP_MAX_HEADER_LENGTH_WORDS &&
779 		    lut->payload_length <= CYP_MAX_DATA_LENGTH_BYTES) {
780 			return QDF_STATUS_SUCCESS;
781 		}
782 	}
783 	return QDF_STATUS_E_FAILURE;
784 }
785 
786 /**
787  * correlate_and_relay_enh() - Correlate TXRX and DBR events and stream CFR
788  * data to userspace
789  * @pdev: objmgr PDEV
790  * @cookie: Index into lookup table
791  * @lut: pointer to lookup table
792  * @module_id: ID of the event received
793  *  0 - DBR event
794  *  1 - TXRX event
795  *
796  * Return:
797  *	- STATUS_ERROR
798  *	- STATUS_HOLD
799  *	- STATUS_STREAM_AND_RELEASE
800  */
correlate_and_relay_enh(struct wlan_objmgr_pdev * pdev,uint32_t cookie,struct look_up_table * lut,uint8_t module_id)801 static int correlate_and_relay_enh(struct wlan_objmgr_pdev *pdev,
802 				   uint32_t cookie,
803 				   struct look_up_table *lut,
804 				   uint8_t module_id)
805 {
806 	struct pdev_cfr *pcfr;
807 	uint64_t diff;
808 	int status = STATUS_ERROR;
809 	struct wlan_objmgr_psoc *psoc;
810 	uint32_t target_type;
811 
812 	if (module_id > 1) {
813 		cfr_err("Received request with invalid mod id. Investigate!!");
814 		QDF_ASSERT(0);
815 		status = STATUS_ERROR;
816 		goto done;
817 	}
818 
819 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
820 						     WLAN_UMAC_COMP_CFR);
821 
822 	psoc = wlan_pdev_get_psoc(pdev);
823 	if (qdf_unlikely(!psoc)) {
824 		cfr_err("psoc is null\n");
825 		status = STATUS_ERROR;
826 		goto done;
827 	}
828 
829 	target_type = target_if_cfr_get_target_type(psoc);
830 
831 	if (module_id == CORRELATE_TX_EV_MODULE_ID) {
832 		if (lut->tx_recv)
833 			pcfr->cfr_dma_aborts++;
834 		lut->tx_recv = true;
835 	} else if (module_id == CORRELATE_DBR_MODULE_ID) {
836 		pcfr->dbr_evt_cnt++;
837 		lut->dbr_recv = true;
838 	}
839 
840 	if ((lut->dbr_recv) && (lut->tx_recv)) {
841 		if (lut->dbr_ppdu_id == lut->tx_ppdu_id) {
842 			pcfr->last_success_tstamp = lut->dbr_tstamp;
843 			if (lut->dbr_tstamp > lut->txrx_tstamp) {
844 				diff = lut->dbr_tstamp - lut->txrx_tstamp;
845 				cfr_debug("<CORRELATE><%u>: "
846 					  "TXRX evt -> DBR evt"
847 					  "(delay = %llu ms)\n", cookie, diff);
848 			} else if (lut->txrx_tstamp > lut->dbr_tstamp) {
849 				diff = lut->txrx_tstamp - lut->dbr_tstamp;
850 				cfr_debug("<CORRELATE><%u>: "
851 					  "DBR evt -> TXRX evt"
852 					  "(delay = %llu ms)\n", cookie, diff);
853 			}
854 
855 			/*
856 			 * Flush pending dbr events, if newer PPDU TLV is
857 			 * received
858 			 */
859 			cfr_free_pending_dbr_events(pdev);
860 
861 			if (check_dma_length(lut, target_type) ==
862 					QDF_STATUS_SUCCESS) {
863 				pcfr->release_cnt++;
864 				cfr_debug("<CORRELATE><%u>:Stream and release "
865 					  "CFR data for "
866 					  "ppdu_id:0x%04x\n", cookie,
867 					  lut->tx_ppdu_id);
868 				status = STATUS_STREAM_AND_RELEASE;
869 				goto done;
870 			} else {
871 				pcfr->invalid_dma_length_cnt++;
872 				cfr_err("<CORRELATE><%u>:CFR buffers "
873 					"received with invalid length "
874 					"header_length_words = %d "
875 					"cfr_payload_length_bytes = %d "
876 					"ppdu_id:0x%04x\n",
877 					cookie,
878 					lut->header_length,
879 					lut->payload_length,
880 					lut->tx_ppdu_id);
881 				/*
882 				 * Assert here as length exceeding the allowed
883 				 * limit would anyway manifest as random crash
884 				 */
885 				QDF_ASSERT(0);
886 				status = STATUS_ERROR;
887 				goto done;
888 			}
889 		} else {
890 			/*
891 			 * When there is a ppdu id mismatch, discard the TXRX
892 			 * event since multiple PPDUs are likely to have same
893 			 * dma addr, due to ucode aborts
894 			 */
895 			cfr_debug("Received new dbr event for same "
896 				  "cookie %u",
897 				  cookie);
898 			lut->tx_recv = false;
899 			lut->tx_ppdu_id = 0;
900 			pcfr->clear_txrx_event++;
901 			pcfr->cfr_dma_aborts++;
902 			status = STATUS_HOLD;
903 		}
904 	} else {
905 		status = STATUS_HOLD;
906 	}
907 done:
908 	return status;
909 }
910 
911 /**
912  * target_if_cfr_get_11be_support_flag(): check if target supports 11be
913  * @pdev_id: pdev id of the pdev
914  * @tgt_hdl: psoc info of pdev associated with pdev_id. Caller of this API to
915  *           ensure that tgt_hdl is not NULL
916  *
917  * Return: true if 11be supported, false otherwise
918  */
919 #ifdef WLAN_FEATURE_11BE
920 static inline
target_if_cfr_get_11be_support_flag(uint8_t pdev_id,struct target_psoc_info * tgt_hdl)921 bool target_if_cfr_get_11be_support_flag(uint8_t pdev_id,
922 					 struct target_psoc_info *tgt_hdl)
923 {
924 	struct wlan_psoc_host_mac_phy_caps *mac_phy_cap_arr, *mac_phy_cap;
925 
926 	mac_phy_cap_arr = target_psoc_get_mac_phy_cap(tgt_hdl);
927 
928 	if (!mac_phy_cap_arr)
929 		return false;
930 
931 	mac_phy_cap = &mac_phy_cap_arr[pdev_id];
932 	if (mac_phy_cap && mac_phy_cap->supports_11be)
933 		return true;
934 
935 	return false;
936 }
937 #else
938 static inline
target_if_cfr_get_11be_support_flag(uint8_t pdev_id,struct target_psoc_info * tgt_hdl)939 bool target_if_cfr_get_11be_support_flag(uint8_t pdev_id,
940 					 struct target_psoc_info *tgt_hdl)
941 {
942 	return false;
943 }
944 #endif
945 
946 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT
947 static inline
is_valid_gain_table_idx(uint16_t tbl_idx,struct pdev_cfr * pcfr)948 bool is_valid_gain_table_idx(uint16_t tbl_idx, struct pdev_cfr *pcfr)
949 {
950 	/* if default gain table return true */
951 	if (!tbl_idx)
952 		return true;
953 
954 	/* non zero gain table is invalid when is_enh_aoa_data is not set */
955 	if (!pcfr->is_enh_aoa_data)
956 		return false;
957 
958 	if ((tbl_idx > 0) && (tbl_idx < pcfr->max_agc_gain_tbls))
959 		return true;
960 
961 	return false;
962 }
963 
964 static inline
get_max_agc_gain(struct wlan_objmgr_vdev * vdev,uint16_t tbl_idx,struct pdev_cfr * pcfr,bool supports_11be)965 uint16_t get_max_agc_gain(struct wlan_objmgr_vdev *vdev,
966 			  uint16_t tbl_idx, struct pdev_cfr *pcfr,
967 			  bool supports_11be)
968 {
969 	uint16_t *max_agc_gain_per_tbl = NULL;
970 	struct wlan_channel *bss_chan;
971 
972 	if (!supports_11be)
973 		return MAX_AGC_GAIN;
974 
975 	if (!pcfr->is_enh_aoa_data)
976 		return INVALID_AGC_GAIN;
977 
978 	bss_chan = wlan_vdev_mlme_get_bss_chan(vdev);
979 	if (wlan_reg_is_24ghz_ch_freq(bss_chan->ch_freq))
980 		max_agc_gain_per_tbl = pcfr->max_agc_gain_per_tbl_2g;
981 	else if (wlan_reg_is_5ghz_ch_freq(bss_chan->ch_freq))
982 		max_agc_gain_per_tbl = pcfr->max_agc_gain_per_tbl_5g;
983 	else if (wlan_reg_is_6ghz_chan_freq(bss_chan->ch_freq))
984 		max_agc_gain_per_tbl = pcfr->max_agc_gain_per_tbl_6g;
985 
986 	if (is_valid_gain_table_idx(tbl_idx, pcfr) && max_agc_gain_per_tbl)
987 		return max_agc_gain_per_tbl[tbl_idx];
988 	else
989 		return INVALID_AGC_GAIN;
990 }
991 
992 static
populate_enh_chain_phase(struct wlan_objmgr_vdev * vdev,struct pdev_cfr * pcfr,struct enh_cfr_metadata * meta,bool invalid_gain_table_idx)993 void populate_enh_chain_phase(struct wlan_objmgr_vdev *vdev,
994 			      struct pdev_cfr *pcfr,
995 			      struct enh_cfr_metadata *meta,
996 			      bool invalid_gain_table_idx)
997 {
998 	uint16_t *phase_array, *gain_array;
999 	uint16_t phase_delta;
1000 	uint32_t start_ent, stop_ent, chain, tbl_idx, grp_stp_idx, found;
1001 	uint32_t data_idx, rf_chain;
1002 
1003 	if (invalid_gain_table_idx || !pcfr->is_enh_aoa_data) {
1004 		/**
1005 		 * When AoA is enabled but invalid gain table index is reported
1006 		 * by HW, it indicates the AoA result is not reliable. Hence,
1007 		 * set the chain_phase to 0xFFFF indicating an error.
1008 		 * Set invalid phase when enhanced aoa capability is not set.
1009 		 */
1010 		for (chain = 0; chain < pcfr->max_aoa_chains; chain++)
1011 			meta->chain_phase[chain] = INVALID_PHASE_DELTA;
1012 
1013 		return;
1014 	}
1015 
1016 	for (chain = 0; chain < pcfr->max_aoa_chains; chain++) {
1017 		rf_chain = (pcfr->xbar_config) ?
1018 			    ((pcfr->xbar_config >> (3 * chain)) & 0x07) :
1019 			    chain;
1020 		data_idx = (rf_chain * pcfr->max_entries_all_table);
1021 
1022 		phase_array = &pcfr->enh_phase_delta_array[data_idx];
1023 		gain_array = &pcfr->gain_stop_index_array[data_idx];
1024 		tbl_idx = meta->agc_gain_tbl_index[chain];
1025 		start_ent = pcfr->start_ent[tbl_idx];
1026 		stop_ent = start_ent + pcfr->max_bdf_entries_per_tbl[tbl_idx];
1027 
1028 		/**
1029 		 * if default gain table exceeds max_agc_gain, chain_phase needs
1030 		 * to be considered as 0. Remaining gain tables would have a
1031 		 * phase delta assigned with max agc gain as well
1032 		 */
1033 		if (!tbl_idx && (meta->agc_gain[chain] ==
1034 				get_max_agc_gain(vdev, tbl_idx, pcfr, true))) {
1035 			phase_delta = 0;
1036 			meta->chain_phase[chain] =
1037 				(pcfr->ibf_cal_val[rf_chain] +
1038 				 phase_delta) & 0x3FF;
1039 			continue;
1040 		}
1041 
1042 		for (grp_stp_idx = start_ent, found = 0;
1043 		     grp_stp_idx < stop_ent; grp_stp_idx++) {
1044 			if (meta->agc_gain[chain] <= gain_array[grp_stp_idx]) {
1045 				phase_delta = phase_array[grp_stp_idx];
1046 				found = 1;
1047 				break;
1048 			}
1049 		}
1050 
1051 		if ((!found) && (grp_stp_idx >= stop_ent))
1052 			phase_delta = 0;
1053 
1054 		/**
1055 		 * FW sets 0xFFFF as invalid phase delta in invalid cases.
1056 		 * Retain same in HOST as well. In case of valid phase, add the
1057 		 * ibf cal value to the delta & ensure the derived phase value
1058 		 * is in the range of 0 - 1024 indicating 0 - 360 degrees.
1059 		 */
1060 		if (phase_delta == INVALID_PHASE_DELTA)
1061 			meta->chain_phase[chain] = INVALID_PHASE_DELTA;
1062 		else
1063 			meta->chain_phase[chain] =
1064 				((pcfr->ibf_cal_val[rf_chain] + phase_delta) &
1065 				 0x3FF);
1066 	}
1067 }
1068 #else
1069 static inline
is_valid_gain_table_idx(uint16_t tbl_idx,struct pdev_cfr * pcfr)1070 bool is_valid_gain_table_idx(uint16_t tbl_idx, struct pdev_cfr *pcfr)
1071 {
1072 	/* if default gain table return true */
1073 	if (!tbl_idx)
1074 		return true;
1075 
1076 	return false;
1077 }
1078 
1079 static inline
get_max_agc_gain(struct wlan_objmgr_vdev * vdev,uint16_t tbl_idx,struct pdev_cfr * pcfr,bool supports_11be)1080 uint16_t get_max_agc_gain(struct wlan_objmgr_vdev *vdev,
1081 			  uint16_t tbl_idx, struct pdev_cfr *pcfr,
1082 			  bool supports_11be)
1083 {
1084 	if (!supports_11be)
1085 		return MAX_AGC_GAIN;
1086 
1087 	return INVALID_AGC_GAIN;
1088 }
1089 
1090 static
populate_enh_chain_phase(struct wlan_objmgr_vdev * vdev,struct pdev_cfr * pcfr,struct enh_cfr_metadata * meta,bool invalid_gain_table_idx)1091 void populate_enh_chain_phase(struct wlan_objmgr_vdev *vdev,
1092 			      struct pdev_cfr *pcfr,
1093 			      struct enh_cfr_metadata *meta,
1094 			      bool invalid_gain_table_idx)
1095 {
1096 	uint8_t chain;
1097 
1098 	cfr_debug("Enahced AoA not supported.. Invsetigate");
1099 	for (chain = 0; chain < pcfr->max_aoa_chains; chain++)
1100 		meta->chain_phase[chain] = INVALID_PHASE_DELTA;
1101 }
1102 #endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */
1103 
1104 static
populate_chain_phase(struct wlan_objmgr_vdev * vdev,struct pdev_cfr * pcfr,struct enh_cfr_metadata * meta,bool invalid_gain_table_idx)1105 void populate_chain_phase(struct wlan_objmgr_vdev *vdev,
1106 			  struct pdev_cfr *pcfr,
1107 			  struct enh_cfr_metadata *meta,
1108 			  bool invalid_gain_table_idx)
1109 {
1110 	uint8_t i;
1111 	uint16_t gain, pdelta;
1112 
1113 	if (invalid_gain_table_idx) {
1114 		/**
1115 		 * When AoA is enabled but invalid gain table index is reported
1116 		 * by HW, it indicates the AoA result is not reliable. Hence,
1117 		 * set the chain_phase to 0xFFFF indicating an error.
1118 		 */
1119 		for (i = 0; i < pcfr->max_aoa_chains; i++) {
1120 			if (wlan_vdev_mlme_is_special_vdev(vdev) &&
1121 			    i == CHAIN_SHIFT_INDEX_PINE_SCAN) {
1122 				meta->chain_phase[i - 1] = INVALID_PHASE_DELTA;
1123 				break;
1124 			}
1125 			meta->chain_phase[i] = INVALID_PHASE_DELTA;
1126 		}
1127 		return;
1128 	}
1129 
1130 	for (i = 0; i < pcfr->max_aoa_chains; i++) {
1131 		/**
1132 		 * phase delta stored in reverse order by FW.
1133 		 * Hence, index accordingly
1134 		 */
1135 		gain = meta->agc_gain[i];
1136 		if (gain < MAX_AGC_GAIN) {
1137 			pdelta = pcfr->phase_delta[i][MAX_AGC_GAIN -
1138 				1 -
1139 				gain];
1140 		} else {
1141 			/* populate 0 for last gain index */
1142 			pdelta = 0;
1143 		}
1144 		/**
1145 		 * FW sets 0xFFFF as invalid phase delta in
1146 		 * invalid cases. Retain same in HOST as well.
1147 		 * In case of valid phase, add the ibf cal value
1148 		 * to the delta & ensure the derived phase value
1149 		 * is in the range of 0 - 1024 indicating 0 - 360
1150 		 * degrees
1151 		 */
1152 		if (pdelta == INVALID_PHASE_DELTA) {
1153 			if (wlan_vdev_mlme_is_special_vdev(vdev) &&
1154 			    i == CHAIN_SHIFT_INDEX_PINE_SCAN) {
1155 				meta->chain_phase[i - 1] =
1156 					INVALID_PHASE_DELTA;
1157 				break;
1158 			}
1159 			meta->chain_phase[i] = INVALID_PHASE_DELTA;
1160 		} else {
1161 			if (wlan_vdev_mlme_is_special_vdev(vdev) &&
1162 			    i == CHAIN_SHIFT_INDEX_PINE_SCAN) {
1163 				meta->chain_phase[i - 1] =
1164 					((pcfr->ibf_cal_val[i] +
1165 					  pdelta) & 0x3FF);
1166 				break;
1167 			}
1168 			meta->chain_phase[i] = ((pcfr->ibf_cal_val[i] +
1169 						pdelta) & 0x3FF);
1170 		}
1171 	}
1172 }
1173 
1174 /**
1175  * target_if_cfr_rx_tlv_process() - Process PPDU status TLVs and store info in
1176  * lookup table
1177  * @pdev: PDEV object
1178  * @nbuf: ppdu info
1179  *
1180  * Return: none
1181  */
target_if_cfr_rx_tlv_process(struct wlan_objmgr_pdev * pdev,void * nbuf)1182 void target_if_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf)
1183 {
1184 	struct cdp_rx_indication_ppdu *cdp_rx_ppdu;
1185 	struct cdp_rx_stats_ppdu_user *rx_stats_peruser;
1186 	struct cdp_rx_ppdu_cfr_info *cfr_info;
1187 	qdf_dma_addr_t buf_addr = 0, buf_addr_extn = 0;
1188 	struct pdev_cfr *pcfr;
1189 	struct look_up_table *lut = NULL;
1190 	struct csi_cfr_header *header = NULL;
1191 	uint32_t cookie;
1192 	struct wlan_objmgr_psoc *psoc;
1193 	struct wlan_channel *bss_chan;
1194 	enum wlan_phymode ch_phymode;
1195 	uint16_t ch_freq;
1196 	uint32_t ch_cfreq1;
1197 	uint32_t ch_cfreq2;
1198 	struct wlan_objmgr_vdev *vdev = NULL;
1199 	int i, status = 0;
1200 	QDF_STATUS retval = 0;
1201 	struct wlan_lmac_if_cfr_rx_ops *cfr_rx_ops = NULL;
1202 	struct enh_cfr_metadata *meta = NULL;
1203 	uint8_t srng_id = 0;
1204 	struct wlan_lmac_if_rx_ops *rx_ops;
1205 	uint32_t target_type;
1206 	uint16_t gain_info[HOST_MAX_CHAINS];
1207 	bool invalid_gain_table_idx = false;
1208 	uint32_t max_agc_gain = 0;
1209 	bool supports_11be;
1210 	uint8_t pdev_id;
1211 	struct target_psoc_info *tgt_hdl;
1212 
1213 	if (qdf_unlikely(!pdev)) {
1214 		cfr_err("pdev is null\n");
1215 		qdf_nbuf_free(nbuf);
1216 		return;
1217 	}
1218 
1219 	retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID);
1220 	if (qdf_unlikely(retval != QDF_STATUS_SUCCESS)) {
1221 		cfr_err("failed to get pdev reference");
1222 		qdf_nbuf_free(nbuf);
1223 		return;
1224 	}
1225 
1226 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
1227 						     WLAN_UMAC_COMP_CFR);
1228 	if (qdf_unlikely(!pcfr)) {
1229 		cfr_err("pdev object for CFR is NULL");
1230 		goto relref;
1231 	}
1232 
1233 	cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)qdf_nbuf_data(nbuf);
1234 	cfr_info = &cdp_rx_ppdu->cfr_info;
1235 
1236 	if (!cfr_info->bb_captured_channel)
1237 		goto relref;
1238 
1239 	psoc = wlan_pdev_get_psoc(pdev);
1240 	if (qdf_unlikely(!psoc)) {
1241 		cfr_err("psoc is null\n");
1242 		goto relref;
1243 	}
1244 
1245 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
1246 	if (!rx_ops) {
1247 		cfr_err("rx_ops is NULL");
1248 		goto relref;
1249 	}
1250 
1251 	tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc);
1252 	if (qdf_unlikely(!tgt_hdl)) {
1253 		cfr_err("tgt_hdl is NULL");
1254 		goto relref;
1255 	}
1256 
1257 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
1258 
1259 	supports_11be = target_if_cfr_get_11be_support_flag(pdev_id, tgt_hdl);
1260 
1261 	target_type = target_if_cfr_get_target_type(psoc);
1262 	cfr_rx_ops = &rx_ops->cfr_rx_ops;
1263 	buf_addr_extn = cfr_info->rtt_che_buffer_pointer_high8 & 0xF;
1264 	buf_addr = (cfr_info->rtt_che_buffer_pointer_low32 |
1265 		    ((uint64_t)buf_addr_extn << 32));
1266 
1267 	srng_id = pcfr->rcc_param.srng_id;
1268 	if (target_if_dbr_cookie_lookup(pdev, DBR_MODULE_CFR, buf_addr,
1269 					&cookie, srng_id)) {
1270 		cfr_debug("Cookie lookup failure for addr: 0x%pK",
1271 			  (void *)((uintptr_t)buf_addr));
1272 		goto relref;
1273 	}
1274 
1275 	cfr_debug("<RXTLV><%u>:buffer address: 0x%pK\n"
1276 		  "<WIFIRX_PPDU_START_E> ppdu_id: 0x%04x\n"
1277 		  "<WIFIRXPCU_PPDU_END_INFO_E> BB_CAPTURED_CHANNEL = %d\n"
1278 		  "<WIFIPHYRX_PKT_END_E> RX_LOCATION_INFO_VALID = %d\n"
1279 		  "<WIFIPHYRX_PKT_END_E> RTT_CHE_BUFFER_POINTER_LOW32 = %x\n"
1280 		  "<WIFIPHYRX_PKT_END_E> RTT_CHE_BUFFER_POINTER_HIGH8 = %x\n"
1281 		  "<WIFIPHYRX_PKT_END_E> CHAN_CAPTURE_STATUS = %d\n",
1282 		  cookie,
1283 		  (void *)((uintptr_t)buf_addr),
1284 		  cdp_rx_ppdu->ppdu_id,
1285 		  cfr_info->bb_captured_channel,
1286 		  cfr_info->rx_location_info_valid,
1287 		  cfr_info->rtt_che_buffer_pointer_low32,
1288 		  cfr_info->rtt_che_buffer_pointer_high8,
1289 		  cfr_info->chan_capture_status);
1290 
1291 	qdf_spin_lock_bh(&pcfr->lut_lock);
1292 
1293 	lut = get_lut_entry(pcfr, cookie);
1294 	if (qdf_unlikely(!lut)) {
1295 		cfr_err("lut is NULL");
1296 		goto unlock;
1297 	}
1298 
1299 	if (pcfr->rcc_param.vdev_id == CFR_INVALID_VDEV_ID)
1300 		vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_CFR_ID);
1301 	else
1302 		vdev = wlan_objmgr_get_vdev_by_id_from_pdev(
1303 				pdev, pcfr->rcc_param.vdev_id, WLAN_CFR_ID);
1304 	if (qdf_unlikely(!vdev)) {
1305 		cfr_debug("vdev is null\n");
1306 		goto unlock;
1307 	}
1308 
1309 	bss_chan = wlan_vdev_mlme_get_bss_chan(vdev);
1310 	ch_freq = bss_chan->ch_freq;
1311 	ch_cfreq1 = bss_chan->ch_cfreq1;
1312 	ch_cfreq2 = bss_chan->ch_cfreq2;
1313 	ch_phymode = bss_chan->ch_phymode;
1314 	wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
1315 
1316 	pcfr->rx_tlv_evt_cnt++;
1317 	lut->tx_ppdu_id = cdp_rx_ppdu->ppdu_id;
1318 	lut->tx_address1 = cfr_info->rtt_che_buffer_pointer_low32;
1319 	lut->tx_address2 = cfr_info->rtt_che_buffer_pointer_high8;
1320 	lut->txrx_tstamp = qdf_ktime_to_ms(qdf_ktime_get());
1321 	header = &lut->header;
1322 	meta = &header->u.meta_enh;
1323 
1324 	target_if_cfr_fill_header(header, false, target_type, true);
1325 
1326 	meta->status       = 1;
1327 	meta->phy_mode = ch_phymode;
1328 	meta->prim20_chan  = ch_freq;
1329 	meta->center_freq1 = ch_cfreq1;
1330 	meta->center_freq2 = ch_cfreq2;
1331 	meta->capture_mode = 0;
1332 
1333 	meta->timestamp = cdp_rx_ppdu->timestamp;
1334 	meta->is_mu_ppdu = (cdp_rx_ppdu->u.ppdu_type == CDP_RX_TYPE_SU) ? 0 : 1;
1335 	meta->num_mu_users = (meta->is_mu_ppdu) ? (cdp_rx_ppdu->num_users) : 0;
1336 
1337 	meta->rtt_cfo_measurement = cfr_info->rtt_cfo_measurement;
1338 	meta->rx_start_ts = cfr_info->rx_start_ts;
1339 
1340 	gain_info[0] = get_u16_lsb(cfr_info->agc_gain_info0);
1341 	gain_info[1] = get_u16_msb(cfr_info->agc_gain_info0);
1342 	gain_info[2] = get_u16_lsb(cfr_info->agc_gain_info1);
1343 	gain_info[3] = get_u16_msb(cfr_info->agc_gain_info1);
1344 	gain_info[4] = get_u16_lsb(cfr_info->agc_gain_info2);
1345 	gain_info[5] = get_u16_msb(cfr_info->agc_gain_info2);
1346 	gain_info[6] = get_u16_lsb(cfr_info->agc_gain_info3);
1347 	gain_info[7] = get_u16_msb(cfr_info->agc_gain_info3);
1348 
1349 	for (i = 0; i < HOST_MAX_CHAINS; i++) {
1350 		meta->agc_gain[i] = get_gain_db(gain_info[i]);
1351 		meta->agc_gain_tbl_index[i] = get_gain_table_idx(gain_info[i]);
1352 		max_agc_gain = get_max_agc_gain(vdev,
1353 						meta->agc_gain_tbl_index[i],
1354 						pcfr,
1355 						supports_11be);
1356 		if (!is_valid_gain_table_idx(meta->agc_gain_tbl_index[i],
1357 					     pcfr)) {
1358 			cfr_debug("Invalid gain table index reported");
1359 			invalid_gain_table_idx = true;
1360 		}
1361 
1362 		if (meta->agc_gain[i] > max_agc_gain)
1363 			meta->agc_gain[i] = max_agc_gain;
1364 	}
1365 
1366 	if (wlan_vdev_mlme_is_special_vdev(vdev)) {
1367 		for (i = 0; i < pcfr->max_aoa_chains; i++)
1368 			meta->chain_phase[i] = INVALID_PHASE_DELTA;
1369 	}
1370 
1371 	/**
1372 	 * Do not derive the chain phase when capability is not set Or
1373 	 * when an invalid gain table index is reported by Hardware.
1374 	 */
1375 	if (pcfr->is_aoa_for_rcc_support) {
1376 		if (supports_11be) {
1377 			populate_enh_chain_phase(vdev, pcfr,
1378 						 meta, invalid_gain_table_idx);
1379 		} else {
1380 			populate_chain_phase(vdev, pcfr,
1381 					     meta, invalid_gain_table_idx);
1382 		}
1383 	}
1384 
1385 	meta->mcs_rate = cfr_info->mcs_rate;
1386 	meta->gi_type = cfr_info->gi_type;
1387 	meta->sig_info.ltf_size = cdp_rx_ppdu->u.ltf_size;
1388 	meta->sig_info.stbc = cdp_rx_ppdu->u.stbc;
1389 	meta->sig_info.sgi = (cdp_rx_ppdu->u.gi == CDP_SGI_0_4_US) ? 1 : 0;
1390 	meta->sig_info.dcm = cdp_rx_ppdu->u.dcm;
1391 	meta->sig_info.coding = cdp_rx_ppdu->u.ldpc;
1392 	meta->sig_info.beamformed = cdp_rx_ppdu->beamformed;
1393 
1394 	if (meta->num_mu_users > pcfr->max_mu_users)
1395 		meta->num_mu_users = pcfr->max_mu_users;
1396 
1397 	target_if_snr_to_signal_strength(target_type, meta, cdp_rx_ppdu);
1398 
1399 	if (cdp_rx_ppdu->u.ppdu_type != CDP_RX_TYPE_SU) {
1400 		for (i = 0 ; i < meta->num_mu_users; i++) {
1401 			rx_stats_peruser = &cdp_rx_ppdu->user[i];
1402 			qdf_mem_copy(meta->peer_addr.mu_peer_addr[i],
1403 				     rx_stats_peruser->mac_addr,
1404 				     QDF_MAC_ADDR_SIZE);
1405 		}
1406 	}
1407 	status = correlate_and_relay_enh(pdev, cookie, lut,
1408 					 CORRELATE_TX_EV_MODULE_ID);
1409 	if (status == STATUS_STREAM_AND_RELEASE) {
1410 		if (cfr_rx_ops->cfr_info_send)
1411 			status = cfr_rx_ops->cfr_info_send(pdev,
1412 							   &lut->header,
1413 							   sizeof(struct
1414 							   csi_cfr_header),
1415 							   lut->data,
1416 							   lut->data_len,
1417 							   &end_magic, 4);
1418 		dump_metadata(header, cookie);
1419 		release_lut_entry_enh(pdev, lut);
1420 		target_if_dbr_buf_release(pdev, DBR_MODULE_CFR, buf_addr,
1421 					  cookie, srng_id);
1422 	}
1423 
1424 unlock:
1425 	qdf_spin_unlock_bh(&pcfr->lut_lock);
1426 relref:
1427 	qdf_nbuf_free(nbuf);
1428 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1429 }
1430 
1431 /**
1432  * freeze_reason_to_capture_type() - Convert capture type enum in freeze tlv
1433  * to the cfr type enum shared with userspace
1434  * @freeze_tlv: pointer to MACRX_FREEZE_CAPTURE_CHANNEL TLV
1435  *
1436  * Return: cfr type enum
1437  */
freeze_reason_to_capture_type(void * freeze_tlv)1438 static uint8_t freeze_reason_to_capture_type(void *freeze_tlv)
1439 {
1440 	/*
1441 	 * Capture_reason field position is common between freeze_tlv v1
1442 	 * and v2, hence typecasting to any one is fine
1443 	 */
1444 	struct macrx_freeze_capture_channel *freeze =
1445 		(struct macrx_freeze_capture_channel *)freeze_tlv;
1446 
1447 	switch (freeze->capture_reason) {
1448 	case FREEZE_REASON_TM:
1449 		return CFR_TYPE_METHOD_TM;
1450 	case FREEZE_REASON_FTM:
1451 		return CFR_TYPE_METHOD_FTM;
1452 	case FREEZE_REASON_TA_RA_TYPE_FILTER:
1453 		return CFR_TYPE_METHOD_TA_RA_TYPE_FILTER;
1454 	case FREEZE_REASON_NDPA_NDP:
1455 		return CFR_TYPE_METHOD_NDPA_NDP;
1456 	case FREEZE_REASON_ALL_PACKET:
1457 		return CFR_TYPE_METHOD_ALL_PACKET;
1458 	case FREEZE_REASON_ACK_RESP_TO_TM_FTM:
1459 		return CFR_TYPE_METHOD_ACK_RESP_TO_TM_FTM;
1460 	default:
1461 		return CFR_TYPE_METHOD_AUTO;
1462 	}
1463 	return CFR_TYPE_METHOD_AUTO;
1464 }
1465 
1466 #ifdef DIRECT_BUF_RX_ENABLE
1467 /**
1468  * enh_cfr_dbr_event_handler() - Process DBR event for CFR data DMA completion
1469  * @pdev: PDEV object
1470  * @payload: pointer to CFR data
1471  *
1472  * Return: status
1473  */
enh_cfr_dbr_event_handler(struct wlan_objmgr_pdev * pdev,struct direct_buf_rx_data * payload)1474 static bool enh_cfr_dbr_event_handler(struct wlan_objmgr_pdev *pdev,
1475 				      struct direct_buf_rx_data *payload)
1476 {
1477 	uint8_t *data = NULL;
1478 	uint32_t cookie = 0;
1479 	struct whal_cfir_enhanced_hdr dma_hdr = {0};
1480 	int  length, status = 0;
1481 	struct wlan_objmgr_psoc *psoc;
1482 	struct pdev_cfr *pcfr;
1483 	struct look_up_table *lut = NULL;
1484 	struct csi_cfr_header *header = NULL;
1485 	void *mu_rx_user_info = NULL, *freeze_tlv = NULL;
1486 	uint8_t capture_type = CFR_TYPE_METHOD_AUTO;
1487 	uint8_t *peer_macaddr = NULL;
1488 	struct wlan_lmac_if_cfr_rx_ops *cfr_rx_ops = NULL;
1489 	struct enh_cfr_metadata *meta = NULL;
1490 	struct wlan_lmac_if_rx_ops *rx_ops;
1491 
1492 	if ((!pdev) || (!payload)) {
1493 		cfr_err("pdev or payload is null");
1494 		return true;
1495 	}
1496 
1497 	psoc = wlan_pdev_get_psoc(pdev);
1498 	if (!psoc) {
1499 		cfr_err("psoc is null");
1500 		return true;
1501 	}
1502 
1503 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
1504 	if (!rx_ops) {
1505 		cfr_err("rx_ops is NULL");
1506 		return true;
1507 	}
1508 	cfr_rx_ops = &rx_ops->cfr_rx_ops;
1509 
1510 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
1511 						     WLAN_UMAC_COMP_CFR);
1512 	if (!pcfr) {
1513 		cfr_err("pdev object for CFR is null");
1514 		return true;
1515 	}
1516 
1517 	data = payload->vaddr;
1518 	cookie = payload->cookie;
1519 
1520 	cfr_debug("<DBRCOMP><%u>:bufferaddr: 0x%pK cookie: %u\n", cookie,
1521 		  (void *)((uintptr_t)payload->paddr), cookie);
1522 
1523 	qdf_mem_copy(&dma_hdr, &data[0],
1524 		     sizeof(struct whal_cfir_enhanced_hdr));
1525 
1526 	if (dma_hdr.freeze_data_incl) {
1527 		freeze_tlv = data + sizeof(struct whal_cfir_enhanced_hdr);
1528 		capture_type = freeze_reason_to_capture_type(freeze_tlv);
1529 	}
1530 
1531 	if (dma_hdr.mu_rx_data_incl) {
1532 		uint8_t freeze_tlv_len;
1533 
1534 		if (dma_hdr.freeze_tlv_version == MACRX_FREEZE_TLV_VERSION_3) {
1535 			freeze_tlv_len =
1536 				sizeof(struct macrx_freeze_capture_channel_v3);
1537 		} else if (dma_hdr.freeze_tlv_version ==
1538 				MACRX_FREEZE_TLV_VERSION_5) {
1539 			freeze_tlv_len =
1540 				sizeof(struct macrx_freeze_capture_channel_v5);
1541 		} else {
1542 			freeze_tlv_len =
1543 				sizeof(struct macrx_freeze_capture_channel);
1544 		}
1545 		mu_rx_user_info = data +
1546 			sizeof(struct whal_cfir_enhanced_hdr) +
1547 			(dma_hdr.freeze_data_incl ? freeze_tlv_len : 0);
1548 	}
1549 
1550 	length  = dma_hdr.length * 4;
1551 	length += dma_hdr.total_bytes; /* size of cfr data */
1552 
1553 	qdf_spin_lock_bh(&pcfr->lut_lock);
1554 
1555 	lut = get_lut_entry(pcfr, cookie);
1556 	if (!lut) {
1557 		cfr_err("lut is NULL");
1558 		qdf_spin_unlock_bh(&pcfr->lut_lock);
1559 		return true;
1560 	}
1561 
1562 	lut->data = data;
1563 	lut->data_len = length;
1564 	lut->dbr_ppdu_id = dma_hdr.phy_ppdu_id;
1565 	lut->dbr_address = payload->paddr;
1566 	lut->dbr_tstamp = qdf_ktime_to_ms(qdf_ktime_get());
1567 	lut->header_length = dma_hdr.length;
1568 	lut->payload_length = dma_hdr.total_bytes;
1569 	qdf_mem_copy(&lut->dma_hdr, &dma_hdr,
1570 		     sizeof(struct whal_cfir_dma_hdr));
1571 
1572 	header = &lut->header;
1573 	header->cmn.chip_type = pcfr->chip_type;
1574 	meta = &header->u.meta_enh;
1575 	meta->channel_bw = dma_hdr.upload_pkt_bw;
1576 	meta->num_rx_chain = NUM_CHAINS_FW_TO_HOST(dma_hdr.num_chains);
1577 	meta->length = length;
1578 	/* For Tx based captures, capture type is sent from FW */
1579 	if (capture_type != CFR_TYPE_METHOD_ACK_RESP_TO_TM_FTM) {
1580 		meta->capture_type = capture_type;
1581 		meta->sts_count = (dma_hdr.nss + 1);
1582 		if (!dma_hdr.mu_rx_data_incl) {
1583 			/* extract peer addr from freeze tlv */
1584 			peer_macaddr = meta->peer_addr.su_peer_addr;
1585 			if (dma_hdr.freeze_data_incl) {
1586 				extract_peer_mac_from_freeze_tlv(freeze_tlv,
1587 								 peer_macaddr);
1588 			}
1589 		}
1590 	}
1591 
1592 	if (dma_hdr.freeze_data_incl) {
1593 		dump_enh_dma_hdr(&dma_hdr, freeze_tlv, mu_rx_user_info,
1594 				 header, 0, cookie);
1595 	}
1596 
1597 	status = correlate_and_relay_enh(pdev, cookie, lut,
1598 					 CORRELATE_DBR_MODULE_ID);
1599 	if (status == STATUS_STREAM_AND_RELEASE) {
1600 		/*
1601 		 * Message format
1602 		 *  Meta data Header + actual payload + trailer
1603 		 */
1604 		if (cfr_rx_ops->cfr_info_send)
1605 			status = cfr_rx_ops->cfr_info_send(pdev,
1606 							   &lut->header,
1607 							   sizeof(struct
1608 							   csi_cfr_header),
1609 							   lut->data,
1610 							   lut->data_len,
1611 							   &end_magic, 4);
1612 		dump_metadata(header, cookie);
1613 		release_lut_entry_enh(pdev, lut);
1614 		status = true;
1615 	} else if (status == STATUS_HOLD) {
1616 		status = false;
1617 	} else {
1618 		status = true;
1619 	}
1620 
1621 	qdf_spin_unlock_bh(&pcfr->lut_lock);
1622 	return status;
1623 }
1624 
1625 /**
1626  * target_if_register_to_dbr_enh() - Initialize DBR ring and register callback
1627  * for DBR events
1628  * @pdev: PDEV object
1629  *
1630  * Return: status
1631  */
1632 static QDF_STATUS
target_if_register_to_dbr_enh(struct wlan_objmgr_pdev * pdev)1633 target_if_register_to_dbr_enh(struct wlan_objmgr_pdev *pdev)
1634 {
1635 	struct wlan_objmgr_psoc *psoc;
1636 	struct wlan_lmac_if_direct_buf_rx_tx_ops *dbr_tx_ops = NULL;
1637 	struct dbr_module_config dbr_config;
1638 	struct wlan_lmac_if_tx_ops *tx_ops;
1639 
1640 	psoc = wlan_pdev_get_psoc(pdev);
1641 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
1642 	if (!tx_ops) {
1643 		cfr_err("tx_ops is NULL");
1644 		return QDF_STATUS_SUCCESS;
1645 	}
1646 	dbr_tx_ops = &tx_ops->dbr_tx_ops;
1647 	dbr_config.num_resp_per_event = DBR_NUM_RESP_PER_EVENT_CFR;
1648 	dbr_config.event_timeout_in_ms = DBR_EVENT_TIMEOUT_IN_MS_CFR;
1649 	if (dbr_tx_ops->direct_buf_rx_module_register) {
1650 		return dbr_tx_ops->direct_buf_rx_module_register
1651 			(pdev, DBR_MODULE_CFR, &dbr_config,
1652 			 enh_cfr_dbr_event_handler);
1653 	}
1654 
1655 	return QDF_STATUS_SUCCESS;
1656 }
1657 
1658 /**
1659  * target_if_unregister_to_dbr_enh() - Unregister callback for DBR events
1660  * @pdev: PDEV object
1661  *
1662  * Return: status
1663  */
1664 static QDF_STATUS
target_if_unregister_to_dbr_enh(struct wlan_objmgr_pdev * pdev)1665 target_if_unregister_to_dbr_enh(struct wlan_objmgr_pdev *pdev)
1666 {
1667 	struct wlan_objmgr_psoc *psoc;
1668 	struct wlan_lmac_if_direct_buf_rx_tx_ops *dbr_tx_ops = NULL;
1669 	struct wlan_lmac_if_tx_ops *tx_ops;
1670 
1671 	psoc = wlan_pdev_get_psoc(pdev);
1672 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
1673 	if (!tx_ops) {
1674 		cfr_err("tx_ops is NULL");
1675 		return QDF_STATUS_SUCCESS;
1676 	}
1677 	dbr_tx_ops = &tx_ops->dbr_tx_ops;
1678 	if (dbr_tx_ops->direct_buf_rx_module_unregister) {
1679 		return dbr_tx_ops->direct_buf_rx_module_unregister
1680 			(pdev, DBR_MODULE_CFR);
1681 	}
1682 
1683 	return QDF_STATUS_SUCCESS;
1684 }
1685 #endif
1686 
1687 /**
1688  * dump_cfr_peer_tx_event_enh() - Dump TX completion event
1689  * @event: ptr to WMI TX completion event for QOS frames sent during
1690  * one-shot capture
1691  * @cookie: Index into lookup table
1692  *
1693  * Return: none
1694  */
dump_cfr_peer_tx_event_enh(wmi_cfr_peer_tx_event_param * event,uint32_t cookie)1695 static void dump_cfr_peer_tx_event_enh(wmi_cfr_peer_tx_event_param *event,
1696 				       uint32_t cookie)
1697 {
1698 	cfr_debug("<TXCOMP><%u>CFR capture method: %d vdev_id: %d mac: "
1699 		  QDF_MAC_ADDR_FMT, cookie,
1700 		  event->capture_method, event->vdev_id,
1701 		  QDF_MAC_ADDR_REF(event->peer_mac_addr.bytes));
1702 
1703 	cfr_debug("<TXCOMP><%u>Chan: %d bw: %d phymode: %d cfreq1: %d cfrq2: %d "
1704 		  "nss: %d\n",
1705 		  cookie,
1706 		  event->primary_20mhz_chan, event->bandwidth,
1707 		  event->phy_mode, event->band_center_freq1,
1708 		  event->band_center_freq2, event->spatial_streams);
1709 
1710 	cfr_debug("<TXCOMP><%u>Correlation_info1: 0x%08x "
1711 		  "Correlation_info2: 0x%08x\n",
1712 		  cookie,
1713 		  event->correlation_info_1, event->correlation_info_2);
1714 
1715 	cfr_debug("<TXCOMP><%u>status: 0x%x ts: %d counter: %d rssi0: 0x%08x\n",
1716 		  cookie,
1717 		  event->status, event->timestamp_us, event->counter,
1718 		  event->chain_rssi[0]);
1719 }
1720 
1721 static void
populate_phase_delta(struct pdev_cfr * pcfr,struct wmi_cfr_phase_delta_param param)1722 populate_phase_delta(struct pdev_cfr *pcfr,
1723 		     struct wmi_cfr_phase_delta_param param)
1724 {
1725 	int c, g, pc, pg;
1726 	uint32_t c_mask = param.chain_phase_mask;
1727 
1728 	pc = 0;
1729 
1730 	/* populate phase delta for max chains indicated by target */
1731 	for (c = 0; c < pcfr->max_aoa_chains; c++) {
1732 		pg = 0;
1733 		if (((0x1 << c) & c_mask) && (pc < WMI_MAX_CHAINS_PHASE)) {
1734 			pcfr->ibf_cal_val[c] = param.ibf_cal_val[pc];
1735 			for (g = 0; g < MAX_AGC_GAIN; g = g + 2) {
1736 				if (pg < WMI_MAX_AOA_PHASE_DELTA) {
1737 					pcfr->phase_delta[c][g] = get_u16_lsb
1738 						(param.phase_delta[pc][pg]);
1739 					pcfr->phase_delta[c][g + 1] = get_u16_msb
1740 						(param.phase_delta[pc][pg]);
1741 					pg++;
1742 				}
1743 			}
1744 			pc++;
1745 		}
1746 	}
1747 }
1748 
1749 static int
target_if_pdev_aoa_phasedaelta_event_handler(ol_scn_t sc,uint8_t * data,uint32_t datalen)1750 target_if_pdev_aoa_phasedaelta_event_handler(ol_scn_t sc,
1751 					     uint8_t *data,
1752 					     uint32_t datalen)
1753 {
1754 	struct wmi_unified *wmi_handle;
1755 	struct wlan_objmgr_psoc *psoc;
1756 	struct wlan_objmgr_pdev *pdev;
1757 	struct pdev_cfr *pcfr;
1758 	QDF_STATUS retval = 0;
1759 	struct wmi_cfr_phase_delta_param param = {0};
1760 
1761 	if (!sc || !data) {
1762 		cfr_err("sc or data is null");
1763 		return -EINVAL;
1764 	}
1765 
1766 	psoc = target_if_get_psoc_from_scn_hdl(sc);
1767 	if (!psoc) {
1768 		cfr_err("psoc is null");
1769 		return -EINVAL;
1770 	}
1771 
1772 	retval = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_CFR_ID);
1773 	if (QDF_IS_STATUS_ERROR(retval)) {
1774 		cfr_err("unable to get psoc reference");
1775 		return -EINVAL;
1776 	}
1777 
1778 	wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
1779 	if (!wmi_handle) {
1780 		cfr_err("wmi_handle is null");
1781 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1782 		return -EINVAL;
1783 	}
1784 
1785 	retval = wmi_extract_cfr_pdev_phase_delta_event
1786 			(wmi_handle, data, &param);
1787 
1788 	if (QDF_IS_STATUS_ERROR(retval)) {
1789 		cfr_err("Failed to extract phase params");
1790 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1791 		return -EINVAL;
1792 	}
1793 
1794 	pdev = wlan_objmgr_get_pdev_by_id(psoc, param.pdev_id, WLAN_CFR_ID);
1795 	if (!pdev) {
1796 		cfr_err("pdev is null");
1797 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1798 		return -EINVAL;
1799 	}
1800 
1801 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
1802 	if (!pcfr) {
1803 		cfr_err("pdev object for CFR is NULL");
1804 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1805 		wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1806 		return -EINVAL;
1807 	}
1808 
1809 	if (!pcfr->is_aoa_for_rcc_support) {
1810 		cfr_err("AoA data event from unsupported target");
1811 	}
1812 
1813 	pcfr->freq = param.freq;
1814 	pcfr->max_aoa_chains = (param.max_chains <= HOST_MAX_CHAINS) ?
1815 				param.max_chains : HOST_MAX_CHAINS;
1816 
1817 	populate_phase_delta(pcfr, param);
1818 
1819 	wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1820 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1821 
1822 	return retval;
1823 }
1824 
1825 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT
1826 static int
target_if_pdev_enhanced_aoa_phasedelta_event_handler(ol_scn_t sc,uint8_t * data,uint32_t datalen)1827 target_if_pdev_enhanced_aoa_phasedelta_event_handler(ol_scn_t sc,
1828 						     uint8_t *data,
1829 						     uint32_t datalen)
1830 {
1831 	struct wmi_unified *wmi_handle;
1832 	struct wlan_objmgr_psoc *psoc;
1833 	struct wlan_objmgr_pdev *pdev;
1834 	struct pdev_cfr *pcfr;
1835 	QDF_STATUS retval = 0;
1836 	struct wmi_cfr_enh_phase_delta_param param = {0};
1837 	uint32_t dst_idx, src_idx, max_src_ent, max_dst_ent;
1838 	uint32_t num_data_chains;
1839 	uint32_t offset;
1840 
1841 	qdf_bitmap(data_chain_bmap, sizeof(uint32_t) * QDF_CHAR_BIT);
1842 
1843 	if (!sc || !data) {
1844 		cfr_err("sc or data is null");
1845 		return -EINVAL;
1846 	}
1847 
1848 	psoc = target_if_get_psoc_from_scn_hdl(sc);
1849 	if (!psoc) {
1850 		cfr_err("psoc is null");
1851 		return -EINVAL;
1852 	}
1853 
1854 	retval = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_CFR_ID);
1855 	if (QDF_IS_STATUS_ERROR(retval)) {
1856 		cfr_err("unable to get psoc reference");
1857 		return -EINVAL;
1858 	}
1859 
1860 	wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
1861 	if (!wmi_handle) {
1862 		cfr_err("wmi_handle is null");
1863 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1864 		return -EINVAL;
1865 	}
1866 
1867 	retval = wmi_extract_cfr_pdev_enhanced_aoa_phasedelta_event_fixed_param
1868 			(wmi_handle, data, &param);
1869 
1870 	if (QDF_IS_STATUS_ERROR(retval)) {
1871 		cfr_err("Failed to extract phase delta fixed param tlv");
1872 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1873 		return -EINVAL;
1874 	}
1875 
1876 	pdev = wlan_objmgr_get_pdev_by_id(psoc, param.pdev_id, WLAN_CFR_ID);
1877 	if (!pdev) {
1878 		cfr_err("pdev is null");
1879 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1880 		return -EINVAL;
1881 	}
1882 
1883 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
1884 
1885 	if (!pcfr) {
1886 		cfr_err("pdev object for CFR is NULL");
1887 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1888 		wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1889 		return -EINVAL;
1890 	}
1891 
1892 	pcfr->freq = param.freq;
1893 	pcfr->max_aoa_chains = (param.max_chains <= HOST_MAX_CHAINS) ?
1894 				param.max_chains : HOST_MAX_CHAINS;
1895 
1896 	num_data_chains = qdf_get_hweight32(param.data_for_chainmask);
1897 
1898 	if (num_data_chains != param.max_chains)
1899 		cfr_debug("data not received for all chains");
1900 
1901 	qdf_mem_zero(data_chain_bmap, sizeof(data_chain_bmap));
1902 	qdf_mem_copy(data_chain_bmap, &param.data_for_chainmask,
1903 		     qdf_min(sizeof(data_chain_bmap),
1904 			     sizeof(param.data_for_chainmask)));
1905 	pcfr->xbar_config = param.xbar_config;
1906 
1907 	qdf_mem_copy(pcfr->ibf_cal_val, param.ibf_cal_val,
1908 		     sizeof(uint32_t) * HOST_MAX_CHAINS);
1909 
1910 	param.array_size = (pcfr->max_aoa_chains *
1911 			    pcfr->max_entries_all_table * sizeof(uint16_t));
1912 
1913 	param.gain_stop_index_array = qdf_mem_malloc(param.array_size);
1914 	if (!param.gain_stop_index_array) {
1915 		cfr_err("Failed to allocate gain stop index array");
1916 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1917 		wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1918 		return -EINVAL;
1919 	}
1920 
1921 	param.enh_phase_delta_array = qdf_mem_malloc(param.array_size);
1922 	if (!param.enh_phase_delta_array) {
1923 		cfr_err("Failed to allocate phase delta array");
1924 		qdf_mem_free(param.gain_stop_index_array);
1925 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1926 		wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1927 		return -EINVAL;
1928 	}
1929 
1930 	qdf_mem_zero(param.gain_stop_index_array, param.array_size);
1931 	qdf_mem_zero(param.enh_phase_delta_array, param.array_size);
1932 
1933 	retval = wmi_extract_cfr_pdev_enhanced_aoa_phasedelta_event_data
1934 			(wmi_handle, data, &param);
1935 
1936 	if (QDF_IS_STATUS_ERROR(retval)) {
1937 		cfr_err("Failed to extract phase data tlv");
1938 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1939 		wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1940 		qdf_mem_free(param.gain_stop_index_array);
1941 		qdf_mem_free(param.enh_phase_delta_array);
1942 		return -EINVAL;
1943 	}
1944 
1945 	if (!pcfr->is_aoa_for_rcc_support || !pcfr->is_enh_aoa_data)
1946 		cfr_err("AoA data event from unsupported target");
1947 
1948 	max_src_ent = param.array_size / sizeof(uint32_t);
1949 	max_dst_ent = pcfr->max_entries_all_table * pcfr->max_aoa_chains;
1950 
1951 	offset = pcfr->max_entries_all_table *
1952 			qdf_find_first_bit(data_chain_bmap,
1953 					   sizeof(uint32_t) * QDF_CHAR_BIT);
1954 	for (dst_idx = (0 + offset), src_idx = 0;
1955 	     ((dst_idx < max_dst_ent) && (src_idx < max_src_ent));
1956 	     dst_idx += 2, src_idx++) {
1957 		uint32_t data;
1958 
1959 		data = param.gain_stop_index_array[src_idx];
1960 		pcfr->gain_stop_index_array[dst_idx] = get_u16_lsb(data);
1961 		pcfr->gain_stop_index_array[dst_idx + 1] = get_u16_msb(data);
1962 
1963 		data = param.enh_phase_delta_array[src_idx];
1964 		pcfr->enh_phase_delta_array[dst_idx] = get_u16_lsb(data);
1965 		pcfr->enh_phase_delta_array[dst_idx + 1] = get_u16_msb(data);
1966 	}
1967 
1968 	wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1969 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1970 	qdf_mem_free(param.gain_stop_index_array);
1971 	qdf_mem_free(param.enh_phase_delta_array);
1972 
1973 	return QDF_STATUS_SUCCESS;
1974 }
1975 #endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */
1976 
1977 #ifdef DIRECT_BUF_RX_ENABLE
1978 /**
1979  * enh_prepare_cfr_header_txstatus() - Prepare CFR metadata for TX failures
1980  * @tx_evt_param: ptr to WMI TX completion event
1981  * @header: pointer to metadata
1982  * @target_type: target type
1983  *
1984  * Return: none
1985  */
enh_prepare_cfr_header_txstatus(wmi_cfr_peer_tx_event_param * tx_evt_param,struct csi_cfr_header * header,uint32_t target_type)1986 static void enh_prepare_cfr_header_txstatus(wmi_cfr_peer_tx_event_param
1987 					    *tx_evt_param,
1988 					    struct csi_cfr_header *header,
1989 					    uint32_t target_type)
1990 {
1991 	target_if_cfr_fill_header(header, false, target_type, false);
1992 	header->u.meta_enh.status       = 0; /* failure */
1993 	header->u.meta_enh.length       = 0;
1994 	header->u.meta_enh.rtt_cfo_measurement = tx_evt_param->cfo_measurement;
1995 	header->u.meta_enh.rx_start_ts = tx_evt_param->rx_start_ts;
1996 
1997 	qdf_mem_copy(&header->u.meta_enh.peer_addr.su_peer_addr[0],
1998 		     &tx_evt_param->peer_mac_addr.bytes[0], QDF_MAC_ADDR_SIZE);
1999 }
2000 
2001 /**
2002  * target_if_peer_capture_event() - WMI TX completion event for one-shot
2003  * capture
2004  * @sc: pointer to offload soc object
2005  * @data: WMI TX completion event buffer
2006  * @datalen: WMI Tx completion event buffer length
2007  *
2008  * Return: status
2009  */
2010 static int
target_if_peer_capture_event(ol_scn_t sc,uint8_t * data,uint32_t datalen)2011 target_if_peer_capture_event(ol_scn_t sc, uint8_t *data, uint32_t datalen)
2012 {
2013 	QDF_STATUS retval = 0;
2014 	struct wmi_unified *wmi_handle;
2015 	struct wlan_objmgr_psoc *psoc;
2016 	struct wlan_objmgr_pdev *pdev;
2017 	struct wlan_objmgr_vdev *vdev;
2018 	uint32_t cookie;
2019 	struct pdev_cfr *pcfr;
2020 	struct look_up_table *lut = NULL;
2021 	struct csi_cfr_header *header = NULL;
2022 	struct csi_cfr_header header_error = {{0} };
2023 	wmi_cfr_peer_tx_event_param tx_evt_param = {0};
2024 	qdf_dma_addr_t buf_addr = 0, buf_addr_temp = 0;
2025 	int status;
2026 	struct wlan_channel *bss_chan;
2027 	struct wlan_lmac_if_cfr_rx_ops *cfr_rx_ops = NULL;
2028 	struct wlan_lmac_if_rx_ops *rx_ops;
2029 	uint32_t target_type;
2030 
2031 	if (!sc || !data) {
2032 		cfr_err("sc or data is null");
2033 		return -EINVAL;
2034 	}
2035 
2036 	psoc = target_if_get_psoc_from_scn_hdl(sc);
2037 	if (!psoc) {
2038 		cfr_err("psoc is null");
2039 		return -EINVAL;
2040 	}
2041 
2042 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
2043 	if (!rx_ops) {
2044 		cfr_err("rx_ops is NULL");
2045 		return -EINVAL;
2046 	}
2047 	cfr_rx_ops = &rx_ops->cfr_rx_ops;
2048 
2049 	retval = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_CFR_ID);
2050 	if (QDF_IS_STATUS_ERROR(retval)) {
2051 		cfr_err("unable to get psoc reference");
2052 		return -EINVAL;
2053 	}
2054 
2055 	wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
2056 	if (!wmi_handle) {
2057 		cfr_err("wmi_handle is null");
2058 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
2059 		return -EINVAL;
2060 	}
2061 
2062 	retval = wmi_extract_cfr_peer_tx_event_param(wmi_handle, data,
2063 						     &tx_evt_param);
2064 
2065 	if (retval != QDF_STATUS_SUCCESS) {
2066 		cfr_err("Failed to extract cfr tx event param");
2067 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
2068 		return -EINVAL;
2069 	}
2070 
2071 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, tx_evt_param.vdev_id,
2072 						    WLAN_CFR_ID);
2073 	if (!vdev) {
2074 		cfr_err("vdev is null");
2075 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
2076 		return -EINVAL;
2077 	}
2078 
2079 	pdev = wlan_vdev_get_pdev(vdev);
2080 	if (!pdev) {
2081 		cfr_err("pdev is null");
2082 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
2083 		wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
2084 		return -EINVAL;
2085 	}
2086 
2087 	retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID);
2088 	if (retval != QDF_STATUS_SUCCESS) {
2089 		cfr_err("failed to get pdev reference");
2090 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
2091 		wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
2092 		return -EINVAL;
2093 	}
2094 
2095 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
2096 						     WLAN_UMAC_COMP_CFR);
2097 	if (!pcfr) {
2098 		cfr_err("pdev object for CFR is NULL");
2099 		retval = -EINVAL;
2100 		goto relref;
2101 	}
2102 
2103 	target_type = target_if_cfr_get_target_type(psoc);
2104 
2105 	if (tx_evt_param.status & PEER_CFR_CAPTURE_EVT_PS_STATUS_MASK) {
2106 		cfr_err("CFR capture failed as peer is in powersave: "
2107 			QDF_MAC_ADDR_FMT,
2108 			QDF_MAC_ADDR_REF(tx_evt_param.peer_mac_addr.bytes));
2109 
2110 		enh_prepare_cfr_header_txstatus(&tx_evt_param,
2111 						&header_error,
2112 						target_type);
2113 		if (cfr_rx_ops->cfr_info_send)
2114 			cfr_rx_ops->cfr_info_send(pdev,
2115 						  &header_error,
2116 						  sizeof(struct
2117 							 csi_cfr_header),
2118 						  NULL, 0, &end_magic, 4);
2119 
2120 		retval = -EINVAL;
2121 		goto relref;
2122 	}
2123 
2124 	if ((tx_evt_param.status & PEER_CFR_CAPTURE_EVT_STATUS_MASK) == 0) {
2125 		cfr_debug("CFR capture failed for peer: " QDF_MAC_ADDR_FMT,
2126 			  QDF_MAC_ADDR_REF(tx_evt_param.peer_mac_addr.bytes));
2127 		pcfr->tx_peer_status_cfr_fail++;
2128 		retval = -EINVAL;
2129 		goto relref;
2130 	}
2131 
2132 	if (tx_evt_param.status & CFR_TX_EVT_STATUS_MASK) {
2133 		cfr_debug("TX packet returned status %d for peer: "
2134 			  QDF_MAC_ADDR_FMT,
2135 			  tx_evt_param.status & CFR_TX_EVT_STATUS_MASK,
2136 			  QDF_MAC_ADDR_REF(tx_evt_param.peer_mac_addr.bytes));
2137 		pcfr->tx_evt_status_cfr_fail++;
2138 		retval = -EINVAL;
2139 		goto relref;
2140 	}
2141 
2142 	buf_addr_temp = (tx_evt_param.correlation_info_2 & 0x0f);
2143 	buf_addr = (tx_evt_param.correlation_info_1 |
2144 		    ((uint64_t)buf_addr_temp << 32));
2145 
2146 	if (target_if_dbr_cookie_lookup(pdev, DBR_MODULE_CFR, buf_addr,
2147 					&cookie, 0)) {
2148 		cfr_debug("Cookie lookup failure for addr: 0x%pK status: 0x%x",
2149 			  (void *)((uintptr_t)buf_addr), tx_evt_param.status);
2150 		pcfr->tx_dbr_cookie_lookup_fail++;
2151 		retval = -EINVAL;
2152 		goto relref;
2153 	}
2154 
2155 	cfr_debug("buffer address: 0x%pK cookie: %u",
2156 		  (void *)((uintptr_t)buf_addr), cookie);
2157 
2158 	dump_cfr_peer_tx_event_enh(&tx_evt_param, cookie);
2159 
2160 	qdf_spin_lock_bh(&pcfr->lut_lock);
2161 
2162 	lut = get_lut_entry(pcfr, cookie);
2163 	if (!lut) {
2164 		cfr_err("lut is NULL\n");
2165 		retval = -EINVAL;
2166 		goto unlock;
2167 	}
2168 
2169 	pcfr->tx_evt_cnt++;
2170 	pcfr->total_tx_evt_cnt++;
2171 
2172 	lut->tx_ppdu_id = (tx_evt_param.correlation_info_2 >> 16);
2173 	lut->tx_address1 = tx_evt_param.correlation_info_1;
2174 	lut->tx_address2 = tx_evt_param.correlation_info_2;
2175 	lut->txrx_tstamp = qdf_ktime_to_ms(qdf_ktime_get());
2176 
2177 	header = &lut->header;
2178 	target_if_cfr_fill_header(header, false, target_type, false);
2179 	header->u.meta_enh.status       = (tx_evt_param.status &
2180 					   PEER_CFR_CAPTURE_EVT_STATUS_MASK) ?
2181 					   1 : 0;
2182 	header->u.meta_enh.capture_bw   = tx_evt_param.bandwidth;
2183 
2184 	bss_chan = wlan_vdev_mlme_get_bss_chan(vdev);
2185 	header->u.meta_enh.phy_mode     = bss_chan->ch_phymode;
2186 
2187 	header->u.meta_enh.prim20_chan  = tx_evt_param.primary_20mhz_chan;
2188 	header->u.meta_enh.center_freq1 = tx_evt_param.band_center_freq1;
2189 	header->u.meta_enh.center_freq2 = tx_evt_param.band_center_freq2;
2190 
2191 	/* Currently CFR data is captured on ACK of a Qos NULL frame.
2192 	 * For 20 MHz, ACK is Legacy and for 40/80/160, ACK is DUP Legacy.
2193 	 */
2194 	header->u.meta_enh.capture_mode = tx_evt_param.bandwidth ?
2195 		CFR_DUP_LEGACY_ACK : CFR_LEGACY_ACK;
2196 	header->u.meta_enh.capture_type = tx_evt_param.capture_method;
2197 	header->u.meta_enh.num_rx_chain = wlan_vdev_mlme_get_rxchainmask(vdev);
2198 	header->u.meta_enh.sts_count    = tx_evt_param.spatial_streams;
2199 	header->u.meta_enh.timestamp    = tx_evt_param.timestamp_us;
2200 
2201 	qdf_mem_copy(&header->u.meta_enh.peer_addr.su_peer_addr[0],
2202 		     &tx_evt_param.peer_mac_addr.bytes[0], QDF_MAC_ADDR_SIZE);
2203 	qdf_mem_copy(&header->u.meta_enh.chain_rssi[0],
2204 		     &tx_evt_param.chain_rssi[0],
2205 		     HOST_MAX_CHAINS * sizeof(tx_evt_param.chain_rssi[0]));
2206 	qdf_mem_copy(&header->u.meta_enh.chain_phase[0],
2207 		     &tx_evt_param.chain_phase[0],
2208 		     HOST_MAX_CHAINS * sizeof(tx_evt_param.chain_phase[0]));
2209 	qdf_mem_copy(&header->u.meta_enh.agc_gain[0],
2210 		     &tx_evt_param.agc_gain[0],
2211 		     HOST_MAX_CHAINS * sizeof(tx_evt_param.agc_gain[0]));
2212 	qdf_mem_copy(&header->u.meta_enh.agc_gain_tbl_index[0],
2213 		     &tx_evt_param.agc_gain_tbl_index[0],
2214 		     (HOST_MAX_CHAINS *
2215 		      sizeof(tx_evt_param.agc_gain_tbl_index[0])));
2216 
2217 	header->u.meta_enh.rtt_cfo_measurement = tx_evt_param.cfo_measurement;
2218 	header->u.meta_enh.rx_start_ts = tx_evt_param.rx_start_ts;
2219 	header->u.meta_enh.mcs_rate    = tx_evt_param.mcs_rate;
2220 	header->u.meta_enh.gi_type     = tx_evt_param.gi_type;
2221 
2222 	status = correlate_and_relay_enh(pdev, cookie, lut,
2223 					 CORRELATE_TX_EV_MODULE_ID);
2224 	if (status == STATUS_STREAM_AND_RELEASE) {
2225 		if (cfr_rx_ops->cfr_info_send)
2226 			status = cfr_rx_ops->cfr_info_send(pdev,
2227 							   &lut->header,
2228 							   sizeof(
2229 							   struct
2230 							   csi_cfr_header),
2231 							   lut->data,
2232 							   lut->data_len,
2233 							   &end_magic, 4);
2234 		dump_metadata(header, cookie);
2235 		release_lut_entry_enh(pdev, lut);
2236 		target_if_dbr_buf_release(pdev, DBR_MODULE_CFR, buf_addr,
2237 					  cookie, 0);
2238 	} else {
2239 		retval = -EINVAL;
2240 	}
2241 
2242 unlock:
2243 	qdf_spin_unlock_bh(&pcfr->lut_lock);
2244 relref:
2245 
2246 	wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
2247 	wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
2248 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
2249 
2250 	return retval;
2251 }
2252 #else
2253 static int
target_if_peer_capture_event(ol_scn_t sc,uint8_t * data,uint32_t datalen)2254 target_if_peer_capture_event(ol_scn_t sc, uint8_t *data, uint32_t datalen)
2255 {
2256 	return 0;
2257 }
2258 #endif
2259 
2260 /**
2261  * target_if_register_phase_delta_for_rcc_event_handler() - Register callback
2262  * for WMI phase delta event
2263  * @psoc: PSOC object
2264  *
2265  * Return: Success/Failure status
2266  */
2267 static QDF_STATUS
target_if_register_phase_delta_for_rcc_event_handler(struct wlan_objmgr_psoc * psoc)2268 target_if_register_phase_delta_for_rcc_event_handler(struct wlan_objmgr_psoc
2269 						     *psoc)
2270 {
2271 	wmi_unified_t wmi_hdl;
2272 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
2273 
2274 	wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc);
2275 	if (!wmi_hdl) {
2276 		cfr_err("Unable to get wmi handle");
2277 		return QDF_STATUS_E_NULL_VALUE;
2278 	}
2279 
2280 	ret = wmi_unified_register_event_handler
2281 		(wmi_hdl, wmi_pdev_aoa_phasedelta_event_id,
2282 		 target_if_pdev_aoa_phasedaelta_event_handler,
2283 		 WMI_RX_UMAC_CTX);
2284 
2285 	/*
2286 	 * Event registration is called per pdev
2287 	 * Ignore error if event is already registered.
2288 	 */
2289 	if (ret == QDF_STATUS_E_FAILURE)
2290 		ret = QDF_STATUS_SUCCESS;
2291 
2292 	return ret;
2293 }
2294 
2295 /**
2296  * target_if_unregister_phase_delta_for_rcc_event_handler() - Unregister
2297  * call back for WMI phase delta for rcc event
2298  * @psoc: PSOC object
2299  *
2300  * Return Success/Failure status
2301  */
2302 static QDF_STATUS
target_if_unregister_phase_delta_for_rcc_event_handler(struct wlan_objmgr_psoc * psoc)2303 target_if_unregister_phase_delta_for_rcc_event_handler(struct wlan_objmgr_psoc
2304 						       *psoc)
2305 {
2306 	wmi_unified_t wmi_hdl;
2307 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2308 
2309 	wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc);
2310 	if (!wmi_hdl) {
2311 		cfr_err("Unable to get wmi handle");
2312 		return QDF_STATUS_E_NULL_VALUE;
2313 	}
2314 
2315 	status = wmi_unified_unregister_event
2316 		(wmi_hdl, wmi_pdev_aoa_phasedelta_event_id);
2317 
2318 	return status;
2319 }
2320 
2321 #ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT
2322 static QDF_STATUS
target_if_register_enh_phase_for_rcc_event_handler(struct wlan_objmgr_psoc * psoc)2323 target_if_register_enh_phase_for_rcc_event_handler(struct wlan_objmgr_psoc
2324 						   *psoc)
2325 {
2326 	wmi_unified_t wmi_hdl;
2327 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
2328 
2329 	wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc);
2330 	if (!wmi_hdl) {
2331 		cfr_err("Unable to get wmi handle");
2332 		return QDF_STATUS_E_NULL_VALUE;
2333 	}
2334 
2335 	ret = wmi_unified_register_event_handler
2336 		(wmi_hdl, wmi_pdev_enhanced_aoa_phasedelta_eventid,
2337 		 target_if_pdev_enhanced_aoa_phasedelta_event_handler,
2338 		 WMI_RX_UMAC_CTX);
2339 
2340 	/*
2341 	 * Event registration is called per pdev
2342 	 * Ignore error if event is already registered.
2343 	 */
2344 	if (ret == QDF_STATUS_E_FAILURE)
2345 		ret = QDF_STATUS_SUCCESS;
2346 
2347 	return ret;
2348 }
2349 
2350 static QDF_STATUS
target_if_unregister_enh_phase_for_rcc_event_handler(struct wlan_objmgr_psoc * psoc)2351 target_if_unregister_enh_phase_for_rcc_event_handler(struct wlan_objmgr_psoc
2352 						     *psoc)
2353 {
2354 	wmi_unified_t wmi_hdl;
2355 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2356 
2357 	wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc);
2358 	if (!wmi_hdl) {
2359 		cfr_err("Unable to get wmi handle");
2360 		return QDF_STATUS_E_NULL_VALUE;
2361 	}
2362 
2363 	status = wmi_unified_unregister_event
2364 			(wmi_hdl, wmi_pdev_enhanced_aoa_phasedelta_eventid);
2365 
2366 	return status;
2367 }
2368 #else
2369 static QDF_STATUS
target_if_register_enh_phase_for_rcc_event_handler(struct wlan_objmgr_psoc * psoc)2370 target_if_register_enh_phase_for_rcc_event_handler(struct wlan_objmgr_psoc
2371 						   *psoc)
2372 {
2373 	return QDF_STATUS_SUCCESS;
2374 }
2375 
2376 static QDF_STATUS
target_if_unregister_enh_phase_for_rcc_event_handler(struct wlan_objmgr_psoc * psoc)2377 target_if_unregister_enh_phase_for_rcc_event_handler(struct wlan_objmgr_psoc
2378 						     *psoc)
2379 {
2380 	return QDF_STATUS_SUCCESS;
2381 }
2382 #endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */
2383 
2384 /**
2385  * target_if_register_tx_completion_enh_event_handler() - Register callback for
2386  * WMI TX completion event
2387  * @psoc: PSOC object
2388  *
2389  * Return: Success/Failure status
2390  */
2391 static QDF_STATUS
target_if_register_tx_completion_enh_event_handler(struct wlan_objmgr_psoc * psoc)2392 target_if_register_tx_completion_enh_event_handler(struct wlan_objmgr_psoc
2393 						   *psoc)
2394 {
2395 	/* Register completion handler here */
2396 	wmi_unified_t wmi_hdl;
2397 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
2398 
2399 	wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc);
2400 	if (!wmi_hdl) {
2401 		cfr_err("Unable to get wmi handle");
2402 		return QDF_STATUS_E_NULL_VALUE;
2403 	}
2404 
2405 	ret = wmi_unified_register_event_handler(wmi_hdl,
2406 						 wmi_peer_cfr_capture_event_id,
2407 						 target_if_peer_capture_event,
2408 						 WMI_RX_UMAC_CTX);
2409 	/*
2410 	 * Event registration is called per pdev
2411 	 * Ignore error if event is already registered.
2412 	 */
2413 	if (ret == QDF_STATUS_E_FAILURE)
2414 		ret = QDF_STATUS_SUCCESS;
2415 
2416 	return ret;
2417 }
2418 
2419 /**
2420  * target_if_unregister_tx_completion_enh_event_handler() - Unregister callback
2421  * for WMI TX completion event
2422  * @psoc: PSOC object
2423  *
2424  * Return: Success/Failure status
2425  */
2426 static QDF_STATUS
target_if_unregister_tx_completion_enh_event_handler(struct wlan_objmgr_psoc * psoc)2427 target_if_unregister_tx_completion_enh_event_handler(struct wlan_objmgr_psoc
2428 						     *psoc)
2429 {
2430 	/* Unregister completion handler here */
2431 	wmi_unified_t wmi_hdl;
2432 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2433 
2434 	wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc);
2435 	if (!wmi_hdl) {
2436 		cfr_err("Unable to get wmi handle");
2437 		return QDF_STATUS_E_NULL_VALUE;
2438 	}
2439 
2440 	status = wmi_unified_unregister_event(wmi_hdl,
2441 					      wmi_peer_cfr_capture_event_id);
2442 	return status;
2443 }
2444 
2445 /*
2446  * lut_ageout_timer_task() - Timer to flush pending TXRX/DBR events
2447  *
2448  * Return: none
2449  * NB: kernel-doc script doesn't parse os_timer_func
2450 
2451  */
os_timer_func(lut_ageout_timer_task)2452 static os_timer_func(lut_ageout_timer_task)
2453 {
2454 	int i = 0;
2455 	struct pdev_cfr *pcfr = NULL;
2456 	struct wlan_objmgr_pdev *pdev = NULL;
2457 	struct look_up_table *lut = NULL;
2458 	uint64_t diff, cur_tstamp;
2459 	uint8_t srng_id = 0;
2460 
2461 	OS_GET_TIMER_ARG(pcfr, struct pdev_cfr*);
2462 
2463 	if (!pcfr) {
2464 		cfr_err("pdev object for CFR is null");
2465 		return;
2466 	}
2467 
2468 	pdev = pcfr->pdev_obj;
2469 	if (!pdev) {
2470 		cfr_err("pdev is null");
2471 		return;
2472 	}
2473 
2474 	srng_id = pcfr->rcc_param.srng_id;
2475 	if (wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID)
2476 	    != QDF_STATUS_SUCCESS) {
2477 		cfr_err("failed to get pdev reference");
2478 		return;
2479 	}
2480 
2481 	cur_tstamp = qdf_ktime_to_ms(qdf_ktime_get());
2482 
2483 	qdf_spin_lock_bh(&pcfr->lut_lock);
2484 
2485 	for (i = 0; i < pcfr->lut_num; i++) {
2486 		lut = get_lut_entry(pcfr, i);
2487 		if (!lut)
2488 			continue;
2489 
2490 		if (lut->dbr_recv && !lut->tx_recv) {
2491 			diff = cur_tstamp - lut->dbr_tstamp;
2492 			if (diff > LUT_AGE_THRESHOLD) {
2493 				target_if_dbr_buf_release(pdev, DBR_MODULE_CFR,
2494 							  lut->dbr_address,
2495 							  i, srng_id);
2496 				pcfr->flush_timeout_dbr_cnt++;
2497 				release_lut_entry_enh(pdev, lut);
2498 			}
2499 		}
2500 	}
2501 
2502 	qdf_spin_unlock_bh(&pcfr->lut_lock);
2503 
2504 	if (pcfr->lut_timer_init)
2505 		qdf_timer_mod(&pcfr->lut_age_timer, LUT_AGE_TIMER);
2506 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
2507 }
2508 
2509 /**
2510  * target_if_cfr_start_lut_age_timer() - Start timer to flush aged-out LUT
2511  * entries
2512  * @pdev: pointer to pdev object
2513  *
2514  * Return: None
2515  */
target_if_cfr_start_lut_age_timer(struct wlan_objmgr_pdev * pdev)2516 void target_if_cfr_start_lut_age_timer(struct wlan_objmgr_pdev *pdev)
2517 {
2518 	struct pdev_cfr *pcfr;
2519 
2520 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
2521 						     WLAN_UMAC_COMP_CFR);
2522 	if (pcfr->lut_timer_init)
2523 		qdf_timer_mod(&pcfr->lut_age_timer, LUT_AGE_TIMER);
2524 }
2525 
2526 /**
2527  * target_if_cfr_stop_lut_age_timer() - Stop timer to flush aged-out LUT
2528  * entries
2529  * @pdev: pointer to pdev object
2530  *
2531  * Return: None
2532  */
target_if_cfr_stop_lut_age_timer(struct wlan_objmgr_pdev * pdev)2533 void target_if_cfr_stop_lut_age_timer(struct wlan_objmgr_pdev *pdev)
2534 {
2535 	struct pdev_cfr *pcfr;
2536 
2537 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
2538 						     WLAN_UMAC_COMP_CFR);
2539 	if (pcfr->lut_timer_init)
2540 		qdf_timer_stop(&pcfr->lut_age_timer);
2541 }
2542 
2543 /**
2544  * target_if_cfr_update_global_cfg() - Update global config after a successful
2545  * commit
2546  * @pdev: pointer to pdev object
2547  *
2548  * Return: None
2549  */
target_if_cfr_update_global_cfg(struct wlan_objmgr_pdev * pdev)2550 void target_if_cfr_update_global_cfg(struct wlan_objmgr_pdev *pdev)
2551 {
2552 	int grp_id;
2553 	struct pdev_cfr *pcfr;
2554 	struct ta_ra_cfr_cfg *curr_cfg = NULL;
2555 	struct ta_ra_cfr_cfg *glbl_cfg = NULL;
2556 
2557 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
2558 						     WLAN_UMAC_COMP_CFR);
2559 
2560 	if (!pcfr) {
2561 		target_if_err("pcfr is null");
2562 		return;
2563 	}
2564 
2565 	for (grp_id = 0; grp_id < MAX_TA_RA_ENTRIES; grp_id++) {
2566 		if (qdf_test_bit(grp_id,
2567 				 &pcfr->rcc_param.modified_in_curr_session)) {
2568 			/* Populating global config based on user's input */
2569 			glbl_cfg = &pcfr->global[grp_id];
2570 			curr_cfg = &pcfr->rcc_param.curr[grp_id];
2571 
2572 			if (curr_cfg->valid_ta)
2573 				qdf_mem_copy(glbl_cfg->tx_addr,
2574 					     curr_cfg->tx_addr,
2575 					     QDF_MAC_ADDR_SIZE);
2576 
2577 			if (curr_cfg->valid_ra)
2578 				qdf_mem_copy(glbl_cfg->rx_addr,
2579 					     curr_cfg->rx_addr,
2580 					     QDF_MAC_ADDR_SIZE);
2581 
2582 			if (curr_cfg->valid_ta_mask)
2583 				qdf_mem_copy(glbl_cfg->tx_addr_mask,
2584 					     curr_cfg->tx_addr_mask,
2585 					     QDF_MAC_ADDR_SIZE);
2586 
2587 			if (curr_cfg->valid_ra_mask)
2588 				qdf_mem_copy(glbl_cfg->rx_addr_mask,
2589 					     curr_cfg->rx_addr_mask,
2590 					     QDF_MAC_ADDR_SIZE);
2591 
2592 			if (curr_cfg->valid_bw_mask)
2593 				glbl_cfg->bw = curr_cfg->bw;
2594 
2595 			if (curr_cfg->valid_nss_mask)
2596 				glbl_cfg->nss = curr_cfg->nss;
2597 
2598 			if (curr_cfg->valid_mgmt_subtype)
2599 				glbl_cfg->mgmt_subtype_filter =
2600 					curr_cfg->mgmt_subtype_filter;
2601 
2602 			if (curr_cfg->valid_ctrl_subtype)
2603 				glbl_cfg->ctrl_subtype_filter =
2604 					curr_cfg->ctrl_subtype_filter;
2605 
2606 			if (curr_cfg->valid_data_subtype)
2607 				glbl_cfg->data_subtype_filter =
2608 					curr_cfg->data_subtype_filter;
2609 		}
2610 	}
2611 }
2612 
2613 /**
2614  * cfr_enh_init_pdev() - Inits cfr pdev and registers necessary handlers.
2615  * @psoc: pointer to psoc object
2616  * @pdev: pointer to pdev object
2617  *
2618  * Return: Registration status for necessary handlers
2619  */
cfr_enh_init_pdev(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_pdev * pdev)2620 QDF_STATUS cfr_enh_init_pdev(struct wlan_objmgr_psoc *psoc,
2621 			     struct wlan_objmgr_pdev *pdev)
2622 {
2623 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2624 	struct pdev_cfr *pcfr;
2625 	uint32_t target_type;
2626 	struct psoc_cfr *cfr_sc;
2627 
2628 	if (!pdev) {
2629 		cfr_err("PDEV is NULL!");
2630 		return QDF_STATUS_E_NULL_VALUE;
2631 	}
2632 
2633 	if (!psoc) {
2634 		cfr_err("PSOC is NULL");
2635 		return QDF_STATUS_E_NULL_VALUE;
2636 	}
2637 
2638 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
2639 						     WLAN_UMAC_COMP_CFR);
2640 	if (!pcfr) {
2641 		cfr_err("pcfr is NULL!");
2642 		return QDF_STATUS_E_NULL_VALUE;
2643 	}
2644 
2645 	cfr_sc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
2646 						       WLAN_UMAC_COMP_CFR);
2647 
2648 	if (!cfr_sc) {
2649 		cfr_err("cfr_sc is NULL");
2650 		return QDF_STATUS_E_NULL_VALUE;
2651 	}
2652 
2653 	target_type = target_if_cfr_get_target_type(psoc);
2654 
2655 #if DIRECT_BUF_RX_ENABLE
2656 	status = target_if_register_to_dbr_enh(pdev);
2657 	if (status != QDF_STATUS_SUCCESS) {
2658 		cfr_err("Failed to register with dbr");
2659 		return status;
2660 	}
2661 #endif
2662 
2663 	status = target_if_register_tx_completion_enh_event_handler(psoc);
2664 	if (status != QDF_STATUS_SUCCESS) {
2665 		cfr_err("Failed to register with tx event handler");
2666 		return status;
2667 	}
2668 
2669 	status = target_if_register_enh_phase_for_rcc_event_handler(psoc);
2670 	if (status != QDF_STATUS_SUCCESS) {
2671 		cfr_err("Failed to register with phase delta event handler");
2672 		return status;
2673 	}
2674 
2675 	status = target_if_register_phase_delta_for_rcc_event_handler(psoc);
2676 	if (status != QDF_STATUS_SUCCESS) {
2677 		cfr_err("Failed to register with phase delta event handler");
2678 		return status;
2679 	}
2680 
2681 	pcfr->is_cfr_rcc_capable = 1;
2682 	pcfr->rcc_param.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
2683 	pcfr->rcc_param.modified_in_curr_session = MAX_RESET_CFG_ENTRY;
2684 	pcfr->rcc_param.num_grp_tlvs = MAX_TA_RA_ENTRIES;
2685 	pcfr->rcc_param.vdev_id = CFR_INVALID_VDEV_ID;
2686 	pcfr->rcc_param.srng_id = DEFAULT_SRNGID_CFR;
2687 	pcfr->is_cap_interval_mode_sel_support =
2688 				cfr_sc->is_cap_interval_mode_sel_support;
2689 	pcfr->is_mo_marking_support = cfr_sc->is_mo_marking_support;
2690 	pcfr->is_aoa_for_rcc_support = cfr_sc->is_aoa_for_rcc_support;
2691 
2692 	if (pcfr->is_aoa_for_rcc_support) {
2693 		qdf_mem_set(pcfr->ibf_cal_val,
2694 			    sizeof(uint32_t) * HOST_MAX_CHAINS,
2695 			    0);
2696 		qdf_mem_set(pcfr->phase_delta,
2697 			    sizeof(uint16_t) * HOST_MAX_CHAINS * MAX_AGC_GAIN,
2698 			    0);
2699 		pcfr->max_aoa_chains = 0;
2700 	}
2701 
2702 	target_if_cfr_default_ta_ra_config(&pcfr->rcc_param,
2703 					   true, MAX_RESET_CFG_ENTRY);
2704 
2705 	status = target_if_cfr_config_rcc(pdev, &pcfr->rcc_param);
2706 	if (status == QDF_STATUS_SUCCESS) {
2707 		/* Update global configuration */
2708 		target_if_cfr_update_global_cfg(pdev);
2709 	} else {
2710 		cfr_err("Sending WMI to configure default has failed");
2711 		return status;
2712 	}
2713 
2714 	pcfr->rcc_param.modified_in_curr_session = 0;
2715 
2716 	pcfr->cfr_max_sta_count = MAX_CFR_ENABLED_CLIENTS;
2717 
2718 	if (target_type == TARGET_TYPE_QCN9000) {
2719 		pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_PINE;
2720 		pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_PINE;
2721 		pcfr->chip_type = CFR_CAPTURE_RADIO_PINE;
2722 		pcfr->max_mu_users = PINE_CFR_MU_USERS;
2723 	} else if (target_type == TARGET_TYPE_QCA5018) {
2724 		pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_MAPLE;
2725 		pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_MAPLE;
2726 		pcfr->chip_type = CFR_CAPTURE_RADIO_MAPLE;
2727 		pcfr->max_mu_users = MAPLE_CFR_MU_USERS;
2728 	} else if (target_type == TARGET_TYPE_QCN6122 ||
2729 		   target_type == TARGET_TYPE_QCN9160) {
2730 		pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_SPRUCE;
2731 		pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_SPRUCE;
2732 		pcfr->chip_type = (target_type == TARGET_TYPE_QCN6122) ?
2733 			CFR_CAPTURE_RADIO_SPRUCE : CFR_CAPTURE_RADIO_YORK;
2734 		pcfr->max_mu_users = SPRUCE_CFR_MU_USERS;
2735 	} else if (target_type == TARGET_TYPE_QCN9224) {
2736 		pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_WAIKIKI;
2737 		pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_WAIKIKI;
2738 		pcfr->chip_type = CFR_CAPTURE_RADIO_WAIKIKI;
2739 		pcfr->max_mu_users = WAIKIKI_CFR_MU_USERS;
2740 	} else if (target_type == TARGET_TYPE_QCN6432) {
2741 		pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_QCN6432;
2742 		pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_QCN6432;
2743 		pcfr->chip_type = CFR_CAPTURE_RADIO_PEBBLE;
2744 		pcfr->max_mu_users = QCN6432_CFR_MU_USERS;
2745 	} else if (target_type == TARGET_TYPE_QCA5332) {
2746 		pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_QCA5332;
2747 		pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_QCA5332;
2748 		pcfr->chip_type = CFR_CAPTURE_RADIO_MIAMI;
2749 		pcfr->max_mu_users = QCA5332_CFR_MU_USERS;
2750 	} else {
2751 		pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_CYP;
2752 		pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_CYP;
2753 		pcfr->chip_type = CFR_CAPTURE_RADIO_CYP;
2754 		pcfr->max_mu_users = CYP_CFR_MU_USERS;
2755 	}
2756 
2757 	if (!pcfr->lut_timer_init) {
2758 		qdf_timer_init(NULL,
2759 			       &(pcfr->lut_age_timer),
2760 			       lut_ageout_timer_task, (void *)pcfr,
2761 			       QDF_TIMER_TYPE_WAKE_APPS);
2762 		pcfr->lut_timer_init = 1;
2763 	}
2764 
2765 	qdf_spinlock_create(&pcfr->lut_lock);
2766 	pcfr->lut_lock_initialised = true;
2767 
2768 	return status;
2769 }
2770 
2771 /**
2772  * cfr_enh_deinit_pdev() - De-inits corresponding pdev and handlers.
2773  * @psoc: pointer to psoc object
2774  * @pdev: pointer to pdev object
2775  *
2776  * Return: De-registration status for necessary handlers
2777  */
cfr_enh_deinit_pdev(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_pdev * pdev)2778 QDF_STATUS cfr_enh_deinit_pdev(struct wlan_objmgr_psoc *psoc,
2779 			       struct wlan_objmgr_pdev *pdev)
2780 {
2781 	QDF_STATUS status;
2782 	struct pdev_cfr *pcfr;
2783 
2784 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
2785 						     WLAN_UMAC_COMP_CFR);
2786 	if (!pcfr) {
2787 		cfr_err("pcfr is NULL");
2788 		return QDF_STATUS_E_NULL_VALUE;
2789 	}
2790 
2791 	if (pcfr->lut_timer_init) {
2792 		qdf_timer_stop(&pcfr->lut_age_timer);
2793 		qdf_timer_free(&(pcfr->lut_age_timer));
2794 		pcfr->lut_timer_init = 0;
2795 	}
2796 
2797 	pcfr->tx_evt_cnt = 0;
2798 	pcfr->dbr_evt_cnt = 0;
2799 	pcfr->release_cnt = 0;
2800 	pcfr->total_tx_evt_cnt = 0;
2801 	pcfr->rx_tlv_evt_cnt = 0;
2802 	pcfr->flush_dbr_cnt = 0;
2803 	pcfr->flush_timeout_dbr_cnt = 0;
2804 	pcfr->invalid_dma_length_cnt = 0;
2805 	pcfr->clear_txrx_event = 0;
2806 	pcfr->cfr_dma_aborts = 0;
2807 	pcfr->tx_peer_status_cfr_fail = 0;
2808 	pcfr->tx_evt_status_cfr_fail = 0;
2809 	pcfr->tx_dbr_cookie_lookup_fail = 0;
2810 	qdf_mem_zero(&pcfr->rcc_param, sizeof(struct cfr_rcc_param));
2811 	qdf_mem_zero(&pcfr->global, (sizeof(struct ta_ra_cfr_cfg) *
2812 				     MAX_TA_RA_ENTRIES));
2813 	pcfr->cfr_timer_enable = 0;
2814 
2815 #ifdef DIRECT_BUF_RX_ENABLE
2816 	status = target_if_unregister_to_dbr_enh(pdev);
2817 	if (status != QDF_STATUS_SUCCESS)
2818 		cfr_err("Failed to register with dbr");
2819 #endif
2820 
2821 	status = target_if_unregister_tx_completion_enh_event_handler(psoc);
2822 	if (status != QDF_STATUS_SUCCESS)
2823 		cfr_err("Failed to register with dbr");
2824 
2825 	status = target_if_unregister_enh_phase_for_rcc_event_handler(psoc);
2826 	if (status != QDF_STATUS_SUCCESS)
2827 		cfr_err("Failed to unregister phase delta handler");
2828 
2829 	status = target_if_unregister_phase_delta_for_rcc_event_handler(psoc);
2830 	if (status != QDF_STATUS_SUCCESS)
2831 		cfr_err("Failed to unregister phase delta handler");
2832 
2833 	if (pcfr->lut_lock_initialised) {
2834 		qdf_spinlock_destroy(&pcfr->lut_lock);
2835 		pcfr->lut_lock_initialised = false;
2836 	}
2837 
2838 	return status;
2839 }
2840