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