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