xref: /wlan-dirver/qca-wifi-host-cmn/target_if/cfr/src/target_if_cfr_enh.c (revision ea172ef154f8781b39809b88f37271c196c4c332)
1 /*
2  * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2022 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 		   target_type == TARGET_TYPE_QCN9160) {
721 		if (lut->header_length <= SPRUCE_MAX_HEADER_LENGTH_WORDS &&
722 		    lut->payload_length <= SPRUCE_MAX_DATA_LENGTH_BYTES) {
723 			return QDF_STATUS_SUCCESS;
724 		}
725 	} else if (target_type == TARGET_TYPE_QCA5018) {
726 		if (lut->header_length <= MAPLE_MAX_HEADER_LENGTH_WORDS &&
727 		    lut->payload_length <= MAPLE_MAX_DATA_LENGTH_BYTES) {
728 			return QDF_STATUS_SUCCESS;
729 		}
730 	} else if (target_type == TARGET_TYPE_QCN9224) {
731 		if (lut->header_length <= WAIKIKI_MAX_HEADER_LENGTH_WORDS &&
732 		    lut->payload_length <= WAIKIKI_MAX_DATA_LENGTH_BYTES) {
733 			return QDF_STATUS_SUCCESS;
734 		}
735 	} else {
736 		if (lut->header_length <= CYP_MAX_HEADER_LENGTH_WORDS &&
737 		    lut->payload_length <= CYP_MAX_DATA_LENGTH_BYTES) {
738 			return QDF_STATUS_SUCCESS;
739 		}
740 	}
741 	return QDF_STATUS_E_FAILURE;
742 }
743 
744 /**
745  * correlate_and_relay_enh() - Correlate TXRX and DBR events and stream CFR
746  * data to userspace
747  * @pdev: objmgr PDEV
748  * @cookie: Index into lookup table
749  * @lut: pointer to lookup table
750  * @module_id: ID of the event received
751  *  0 - DBR event
752  *  1 - TXRX event
753  *
754  * Return:
755  *	- STATUS_ERROR
756  *	- STATUS_HOLD
757  *	- STATUS_STREAM_AND_RELEASE
758  */
759 static int correlate_and_relay_enh(struct wlan_objmgr_pdev *pdev,
760 				   uint32_t cookie,
761 				   struct look_up_table *lut,
762 				   uint8_t module_id)
763 {
764 	struct pdev_cfr *pcfr;
765 	uint64_t diff;
766 	int status = STATUS_ERROR;
767 	struct wlan_objmgr_psoc *psoc;
768 	uint32_t target_type;
769 
770 	if (module_id > 1) {
771 		cfr_err("Received request with invalid mod id. Investigate!!");
772 		QDF_ASSERT(0);
773 		status = STATUS_ERROR;
774 		goto done;
775 	}
776 
777 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
778 						     WLAN_UMAC_COMP_CFR);
779 
780 	psoc = wlan_pdev_get_psoc(pdev);
781 	if (qdf_unlikely(!psoc)) {
782 		cfr_err("psoc is null\n");
783 		status = STATUS_ERROR;
784 		goto done;
785 	}
786 
787 	target_type = target_if_cfr_get_target_type(psoc);
788 
789 	if (module_id == CORRELATE_TX_EV_MODULE_ID) {
790 		if (lut->tx_recv)
791 			pcfr->cfr_dma_aborts++;
792 		lut->tx_recv = true;
793 	} else if (module_id == CORRELATE_DBR_MODULE_ID) {
794 		pcfr->dbr_evt_cnt++;
795 		lut->dbr_recv = true;
796 	}
797 
798 	if ((lut->dbr_recv) && (lut->tx_recv)) {
799 		if (lut->dbr_ppdu_id == lut->tx_ppdu_id) {
800 			pcfr->last_success_tstamp = lut->dbr_tstamp;
801 			if (lut->dbr_tstamp > lut->txrx_tstamp) {
802 				diff = lut->dbr_tstamp - lut->txrx_tstamp;
803 				cfr_debug("<CORRELATE><%u>: "
804 					  "TXRX evt -> DBR evt"
805 					  "(delay = %llu ms)\n", cookie, diff);
806 			} else if (lut->txrx_tstamp > lut->dbr_tstamp) {
807 				diff = lut->txrx_tstamp - lut->dbr_tstamp;
808 				cfr_debug("<CORRELATE><%u>: "
809 					  "DBR evt -> TXRX evt"
810 					  "(delay = %llu ms)\n", cookie, diff);
811 			}
812 
813 			/*
814 			 * Flush pending dbr events, if newer PPDU TLV is
815 			 * received
816 			 */
817 			cfr_free_pending_dbr_events(pdev);
818 
819 			if (check_dma_length(lut, target_type) ==
820 					QDF_STATUS_SUCCESS) {
821 				pcfr->release_cnt++;
822 				cfr_debug("<CORRELATE><%u>:Stream and release "
823 					  "CFR data for "
824 					  "ppdu_id:0x%04x\n", cookie,
825 					  lut->tx_ppdu_id);
826 				status = STATUS_STREAM_AND_RELEASE;
827 				goto done;
828 			} else {
829 				pcfr->invalid_dma_length_cnt++;
830 				cfr_err("<CORRELATE><%u>:CFR buffers "
831 					"received with invalid length "
832 					"header_length_words = %d "
833 					"cfr_payload_length_bytes = %d "
834 					"ppdu_id:0x%04x\n",
835 					cookie,
836 					lut->header_length,
837 					lut->payload_length,
838 					lut->tx_ppdu_id);
839 				/*
840 				 * Assert here as length exceeding the allowed
841 				 * limit would anyway manifest as random crash
842 				 */
843 				QDF_ASSERT(0);
844 				status = STATUS_ERROR;
845 				goto done;
846 			}
847 		} else {
848 			/*
849 			 * When there is a ppdu id mismatch, discard the TXRX
850 			 * event since multiple PPDUs are likely to have same
851 			 * dma addr, due to ucode aborts
852 			 */
853 			cfr_debug("Received new dbr event for same "
854 				  "cookie %u",
855 				  cookie);
856 			lut->tx_recv = false;
857 			lut->tx_ppdu_id = 0;
858 			pcfr->clear_txrx_event++;
859 			pcfr->cfr_dma_aborts++;
860 			status = STATUS_HOLD;
861 		}
862 	} else {
863 		status = STATUS_HOLD;
864 	}
865 done:
866 	return status;
867 }
868 
869 /**
870  * target_if_cfr_rx_tlv_process() - Process PPDU status TLVs and store info in
871  * lookup table
872  * @pdev_obj: PDEV object
873  * @nbuf: ppdu info
874  *
875  * Return: none
876  */
877 void target_if_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf)
878 {
879 	struct cdp_rx_indication_ppdu *cdp_rx_ppdu;
880 	struct cdp_rx_stats_ppdu_user *rx_stats_peruser;
881 	struct cdp_rx_ppdu_cfr_info *cfr_info;
882 	qdf_dma_addr_t buf_addr = 0, buf_addr_extn = 0;
883 	struct pdev_cfr *pcfr;
884 	struct look_up_table *lut = NULL;
885 	struct csi_cfr_header *header = NULL;
886 	uint32_t cookie;
887 	struct wlan_objmgr_psoc *psoc;
888 	struct wlan_channel *bss_chan;
889 	enum wlan_phymode ch_phymode;
890 	uint16_t ch_freq;
891 	uint32_t ch_cfreq1;
892 	uint32_t ch_cfreq2;
893 	struct wlan_objmgr_vdev *vdev = NULL;
894 	int i, status = 0;
895 	QDF_STATUS retval = 0;
896 	struct wlan_lmac_if_cfr_rx_ops *cfr_rx_ops = NULL;
897 	struct enh_cfr_metadata *meta = NULL;
898 	uint8_t srng_id = 0;
899 	struct wlan_lmac_if_rx_ops *rx_ops;
900 	uint32_t target_type;
901 	uint16_t pdelta, gain;
902 	uint16_t gain_info[HOST_MAX_CHAINS];
903 	bool invalid_gain_table_idx = false;
904 
905 	if (qdf_unlikely(!pdev)) {
906 		cfr_err("pdev is null\n");
907 		qdf_nbuf_free(nbuf);
908 		return;
909 	}
910 
911 	retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID);
912 	if (qdf_unlikely(retval != QDF_STATUS_SUCCESS)) {
913 		cfr_err("failed to get pdev reference");
914 		qdf_nbuf_free(nbuf);
915 		return;
916 	}
917 
918 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
919 						     WLAN_UMAC_COMP_CFR);
920 	if (qdf_unlikely(!pcfr)) {
921 		cfr_err("pdev object for CFR is NULL");
922 		goto relref;
923 	}
924 
925 	cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)qdf_nbuf_data(nbuf);
926 	cfr_info = &cdp_rx_ppdu->cfr_info;
927 
928 	if (!cfr_info->bb_captured_channel)
929 		goto relref;
930 
931 	psoc = wlan_pdev_get_psoc(pdev);
932 	if (qdf_unlikely(!psoc)) {
933 		cfr_err("psoc is null\n");
934 		goto relref;
935 	}
936 
937 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
938 	if (!rx_ops) {
939 		cfr_err("rx_ops is NULL");
940 		goto relref;
941 	}
942 	target_type = target_if_cfr_get_target_type(psoc);
943 	cfr_rx_ops = &rx_ops->cfr_rx_ops;
944 	buf_addr_extn = cfr_info->rtt_che_buffer_pointer_high8 & 0xF;
945 	buf_addr = (cfr_info->rtt_che_buffer_pointer_low32 |
946 		    ((uint64_t)buf_addr_extn << 32));
947 
948 	srng_id = pcfr->rcc_param.srng_id;
949 	if (target_if_dbr_cookie_lookup(pdev, DBR_MODULE_CFR, buf_addr,
950 					&cookie, srng_id)) {
951 		cfr_debug("Cookie lookup failure for addr: 0x%pK",
952 			  (void *)((uintptr_t)buf_addr));
953 		goto relref;
954 	}
955 
956 	cfr_debug("<RXTLV><%u>:buffer address: 0x%pK\n"
957 		  "<WIFIRX_PPDU_START_E> ppdu_id: 0x%04x\n"
958 		  "<WIFIRXPCU_PPDU_END_INFO_E> BB_CAPTURED_CHANNEL = %d\n"
959 		  "<WIFIPHYRX_PKT_END_E> RX_LOCATION_INFO_VALID = %d\n"
960 		  "<WIFIPHYRX_PKT_END_E> RTT_CHE_BUFFER_POINTER_LOW32 = %x\n"
961 		  "<WIFIPHYRX_PKT_END_E> RTT_CHE_BUFFER_POINTER_HIGH8 = %x\n"
962 		  "<WIFIPHYRX_PKT_END_E> CHAN_CAPTURE_STATUS = %d\n",
963 		  cookie,
964 		  (void *)((uintptr_t)buf_addr),
965 		  cdp_rx_ppdu->ppdu_id,
966 		  cfr_info->bb_captured_channel,
967 		  cfr_info->rx_location_info_valid,
968 		  cfr_info->rtt_che_buffer_pointer_low32,
969 		  cfr_info->rtt_che_buffer_pointer_high8,
970 		  cfr_info->chan_capture_status);
971 
972 	qdf_spin_lock_bh(&pcfr->lut_lock);
973 
974 	lut = get_lut_entry(pcfr, cookie);
975 	if (qdf_unlikely(!lut)) {
976 		cfr_err("lut is NULL");
977 		goto unlock;
978 	}
979 
980 	if (pcfr->rcc_param.vdev_id == CFR_INVALID_VDEV_ID)
981 		vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_CFR_ID);
982 	else
983 		vdev = wlan_objmgr_get_vdev_by_id_from_pdev(
984 				pdev, pcfr->rcc_param.vdev_id, WLAN_CFR_ID);
985 	if (qdf_unlikely(!vdev)) {
986 		cfr_debug("vdev is null\n");
987 		goto unlock;
988 	}
989 
990 	bss_chan = wlan_vdev_mlme_get_bss_chan(vdev);
991 	ch_freq = bss_chan->ch_freq;
992 	ch_cfreq1 = bss_chan->ch_cfreq1;
993 	ch_cfreq2 = bss_chan->ch_cfreq2;
994 	ch_phymode = bss_chan->ch_phymode;
995 	wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
996 
997 	pcfr->rx_tlv_evt_cnt++;
998 	lut->tx_ppdu_id = cdp_rx_ppdu->ppdu_id;
999 	lut->tx_address1 = cfr_info->rtt_che_buffer_pointer_low32;
1000 	lut->tx_address2 = cfr_info->rtt_che_buffer_pointer_high8;
1001 	lut->txrx_tstamp = qdf_ktime_to_ms(qdf_ktime_get());
1002 	header = &lut->header;
1003 	meta = &header->u.meta_enh;
1004 
1005 	target_if_cfr_fill_header(header, false, target_type, true);
1006 
1007 	meta->status       = 1;
1008 	meta->phy_mode = ch_phymode;
1009 	meta->prim20_chan  = ch_freq;
1010 	meta->center_freq1 = ch_cfreq1;
1011 	meta->center_freq2 = ch_cfreq2;
1012 	meta->capture_mode = 0;
1013 
1014 	meta->timestamp = cdp_rx_ppdu->timestamp;
1015 	meta->is_mu_ppdu = (cdp_rx_ppdu->u.ppdu_type == CDP_RX_TYPE_SU) ? 0 : 1;
1016 	meta->num_mu_users = (meta->is_mu_ppdu) ? (cdp_rx_ppdu->num_users) : 0;
1017 
1018 	meta->rtt_cfo_measurement = cfr_info->rtt_cfo_measurement;
1019 	meta->rx_start_ts = cfr_info->rx_start_ts;
1020 
1021 	gain_info[0] = get_u16_lsb(cfr_info->agc_gain_info0);
1022 	gain_info[1] = get_u16_msb(cfr_info->agc_gain_info0);
1023 	gain_info[2] = get_u16_lsb(cfr_info->agc_gain_info1);
1024 	gain_info[3] = get_u16_msb(cfr_info->agc_gain_info1);
1025 	gain_info[4] = get_u16_lsb(cfr_info->agc_gain_info2);
1026 	gain_info[5] = get_u16_msb(cfr_info->agc_gain_info2);
1027 	gain_info[6] = get_u16_lsb(cfr_info->agc_gain_info3);
1028 	gain_info[7] = get_u16_msb(cfr_info->agc_gain_info3);
1029 
1030 	for (i = 0; i < HOST_MAX_CHAINS; i++) {
1031 		meta->agc_gain[i] = get_gain_db(gain_info[i]);
1032 		meta->agc_gain_tbl_index[i] = get_gain_table_idx(gain_info[i]);
1033 
1034 		if (pcfr->is_aoa_for_rcc_support &&
1035 		    (i < pcfr->max_aoa_chains) &&
1036 		    (meta->agc_gain_tbl_index[i] != 0)) {
1037 			cfr_debug("Invalid gain table index reported");
1038 			invalid_gain_table_idx = true;
1039 		}
1040 
1041 		if (meta->agc_gain[i] > MAX_AGC_GAIN)
1042 			meta->agc_gain[i] = MAX_AGC_GAIN;
1043 	}
1044 
1045 	/**
1046 	 * Do not derive the chain phase when capability is not set Or
1047 	 * when an invalid gain table index is reported by Hardware.
1048 	 */
1049 	if (pcfr->is_aoa_for_rcc_support && !invalid_gain_table_idx) {
1050 		for (i = 0; i < pcfr->max_aoa_chains; i++) {
1051 			/**
1052 			 * phase delta stored in reverse order by FW.
1053 			 * Hence, index accordingly
1054 			 */
1055 			gain = meta->agc_gain[i];
1056 			if (gain < MAX_AGC_GAIN) {
1057 				pdelta = pcfr->phase_delta[i][MAX_AGC_GAIN -
1058 							      1 -
1059 							      gain];
1060 			} else {
1061 				pdelta = 0;
1062 			}
1063 			/**
1064 			 * FW sets 0xFFFF as invalid phase delta in
1065 			 * invalid cases. Retain same in HOST as well.
1066 			 * In case of valid phase, add the ibf cal value
1067 			 * to the delta & ensure the derived phase value
1068 			 * is in the range of 0 - 1024 indicating 0 - 360
1069 			 * degrees
1070 			 */
1071 			if (pdelta == INVALID_PHASE_DELTA)
1072 				meta->chain_phase[i] = INVALID_PHASE_DELTA;
1073 			else
1074 				meta->chain_phase[i] = ((pcfr->ibf_cal_val[i] +
1075 							pdelta) & 0x3FF);
1076 		}
1077 	} else if (pcfr->is_aoa_for_rcc_support) {
1078 		/**
1079 		 * When AoA is enabled but invalid gain table index is reported
1080 		 * by HW, it indicates the AoA result is not reliable. Hence,
1081 		 * set the chain_phase to 0xFFFF indicating an error.
1082 		 */
1083 		for (i = 0; i < pcfr->max_aoa_chains; i++) {
1084 			meta->chain_phase[i] = INVALID_PHASE_DELTA;
1085 		}
1086 	}
1087 
1088 	meta->mcs_rate = cfr_info->mcs_rate;
1089 	meta->gi_type = cfr_info->gi_type;
1090 	meta->sig_info.ltf_size = cdp_rx_ppdu->u.ltf_size;
1091 	meta->sig_info.stbc = cdp_rx_ppdu->u.stbc;
1092 	meta->sig_info.sgi = (cdp_rx_ppdu->u.gi == CDP_SGI_0_4_US) ? 1 : 0;
1093 	meta->sig_info.dcm = cdp_rx_ppdu->u.dcm;
1094 	meta->sig_info.coding = cdp_rx_ppdu->u.ldpc;
1095 	meta->sig_info.beamformed = cdp_rx_ppdu->beamformed;
1096 
1097 	if (meta->num_mu_users > pcfr->max_mu_users)
1098 		meta->num_mu_users = pcfr->max_mu_users;
1099 
1100 	for (i = 0; i < MAX_CHAIN; i++)
1101 		meta->chain_rssi[i] =
1102 			snr_to_signal_strength(cdp_rx_ppdu->per_chain_rssi[i]);
1103 
1104 	if (cdp_rx_ppdu->u.ppdu_type != CDP_RX_TYPE_SU) {
1105 		for (i = 0 ; i < meta->num_mu_users; i++) {
1106 			rx_stats_peruser = &cdp_rx_ppdu->user[i];
1107 			qdf_mem_copy(meta->peer_addr.mu_peer_addr[i],
1108 				     rx_stats_peruser->mac_addr,
1109 				     QDF_MAC_ADDR_SIZE);
1110 		}
1111 	}
1112 	status = correlate_and_relay_enh(pdev, cookie, lut,
1113 					 CORRELATE_TX_EV_MODULE_ID);
1114 	if (status == STATUS_STREAM_AND_RELEASE) {
1115 		if (cfr_rx_ops->cfr_info_send)
1116 			status = cfr_rx_ops->cfr_info_send(pdev,
1117 							   &lut->header,
1118 							   sizeof(struct
1119 							   csi_cfr_header),
1120 							   lut->data,
1121 							   lut->data_len,
1122 							   &end_magic, 4);
1123 		dump_metadata(header, cookie);
1124 		release_lut_entry_enh(pdev, lut);
1125 		target_if_dbr_buf_release(pdev, DBR_MODULE_CFR, buf_addr,
1126 					  cookie, srng_id);
1127 	}
1128 
1129 unlock:
1130 	qdf_spin_unlock_bh(&pcfr->lut_lock);
1131 relref:
1132 	qdf_nbuf_free(nbuf);
1133 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1134 }
1135 
1136 /**
1137  * freeze_reason_to_capture_type() - Convert capture type enum in freeze tlv
1138  * to the cfr type enum shared with userspace
1139  * @freeze_tlv: pointer to MACRX_FREEZE_CAPTURE_CHANNEL TLV
1140  *
1141  * Return: cfr type enum
1142  */
1143 static uint8_t freeze_reason_to_capture_type(void *freeze_tlv)
1144 {
1145 	/*
1146 	 * Capture_reason field position is common between freeze_tlv v1
1147 	 * and v2, hence typecasting to any one is fine
1148 	 */
1149 	struct macrx_freeze_capture_channel *freeze =
1150 		(struct macrx_freeze_capture_channel *)freeze_tlv;
1151 
1152 	switch (freeze->capture_reason) {
1153 	case FREEZE_REASON_TM:
1154 		return CFR_TYPE_METHOD_TM;
1155 	case FREEZE_REASON_FTM:
1156 		return CFR_TYPE_METHOD_FTM;
1157 	case FREEZE_REASON_TA_RA_TYPE_FILTER:
1158 		return CFR_TYPE_METHOD_TA_RA_TYPE_FILTER;
1159 	case FREEZE_REASON_NDPA_NDP:
1160 		return CFR_TYPE_METHOD_NDPA_NDP;
1161 	case FREEZE_REASON_ALL_PACKET:
1162 		return CFR_TYPE_METHOD_ALL_PACKET;
1163 	case FREEZE_REASON_ACK_RESP_TO_TM_FTM:
1164 		return CFR_TYPE_METHOD_ACK_RESP_TO_TM_FTM;
1165 	default:
1166 		return CFR_TYPE_METHOD_AUTO;
1167 	}
1168 	return CFR_TYPE_METHOD_AUTO;
1169 }
1170 
1171 #ifdef DIRECT_BUF_RX_ENABLE
1172 /**
1173  * enh_cfr_dbr_event_handler() - Process DBR event for CFR data DMA completion
1174  * @pdev: PDEV object
1175  * @payload: pointer to CFR data
1176  *
1177  * Return: status
1178  */
1179 static bool enh_cfr_dbr_event_handler(struct wlan_objmgr_pdev *pdev,
1180 				      struct direct_buf_rx_data *payload)
1181 {
1182 	uint8_t *data = NULL;
1183 	uint32_t cookie = 0;
1184 	struct whal_cfir_enhanced_hdr dma_hdr = {0};
1185 	int  length, status = 0;
1186 	struct wlan_objmgr_psoc *psoc;
1187 	struct pdev_cfr *pcfr;
1188 	struct look_up_table *lut = NULL;
1189 	struct csi_cfr_header *header = NULL;
1190 	void *mu_rx_user_info = NULL, *freeze_tlv = NULL;
1191 	uint8_t capture_type = CFR_TYPE_METHOD_AUTO;
1192 	uint8_t *peer_macaddr = NULL;
1193 	struct wlan_lmac_if_cfr_rx_ops *cfr_rx_ops = NULL;
1194 	struct enh_cfr_metadata *meta = NULL;
1195 	struct wlan_lmac_if_rx_ops *rx_ops;
1196 
1197 	if ((!pdev) || (!payload)) {
1198 		cfr_err("pdev or payload is null");
1199 		return true;
1200 	}
1201 
1202 	psoc = wlan_pdev_get_psoc(pdev);
1203 	if (!psoc) {
1204 		cfr_err("psoc is null");
1205 		return true;
1206 	}
1207 
1208 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
1209 	if (!rx_ops) {
1210 		cfr_err("rx_ops is NULL");
1211 		return true;
1212 	}
1213 	cfr_rx_ops = &rx_ops->cfr_rx_ops;
1214 
1215 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
1216 						     WLAN_UMAC_COMP_CFR);
1217 	if (!pcfr) {
1218 		cfr_err("pdev object for CFR is null");
1219 		return true;
1220 	}
1221 
1222 	data = payload->vaddr;
1223 	cookie = payload->cookie;
1224 
1225 	cfr_debug("<DBRCOMP><%u>:bufferaddr: 0x%pK cookie: %u\n", cookie,
1226 		  (void *)((uintptr_t)payload->paddr), cookie);
1227 
1228 	qdf_mem_copy(&dma_hdr, &data[0],
1229 		     sizeof(struct whal_cfir_enhanced_hdr));
1230 
1231 	if (dma_hdr.freeze_data_incl) {
1232 		freeze_tlv = data + sizeof(struct whal_cfir_enhanced_hdr);
1233 		capture_type = freeze_reason_to_capture_type(freeze_tlv);
1234 	}
1235 
1236 	if (dma_hdr.mu_rx_data_incl) {
1237 		uint8_t freeze_tlv_len;
1238 
1239 		if (dma_hdr.freeze_tlv_version == MACRX_FREEZE_TLV_VERSION_3) {
1240 			freeze_tlv_len =
1241 				sizeof(struct macrx_freeze_capture_channel_v3);
1242 		} else if (dma_hdr.freeze_tlv_version ==
1243 				MACRX_FREEZE_TLV_VERSION_5) {
1244 			freeze_tlv_len =
1245 				sizeof(struct macrx_freeze_capture_channel_v5);
1246 		} else {
1247 			freeze_tlv_len =
1248 				sizeof(struct macrx_freeze_capture_channel);
1249 		}
1250 		mu_rx_user_info = data +
1251 			sizeof(struct whal_cfir_enhanced_hdr) +
1252 			(dma_hdr.freeze_data_incl ? freeze_tlv_len : 0);
1253 	}
1254 
1255 	length  = dma_hdr.length * 4;
1256 	length += dma_hdr.total_bytes; /* size of cfr data */
1257 
1258 	qdf_spin_lock_bh(&pcfr->lut_lock);
1259 
1260 	lut = get_lut_entry(pcfr, cookie);
1261 	if (!lut) {
1262 		cfr_err("lut is NULL");
1263 		qdf_spin_unlock_bh(&pcfr->lut_lock);
1264 		return true;
1265 	}
1266 
1267 	lut->data = data;
1268 	lut->data_len = length;
1269 	lut->dbr_ppdu_id = dma_hdr.phy_ppdu_id;
1270 	lut->dbr_address = payload->paddr;
1271 	lut->dbr_tstamp = qdf_ktime_to_ms(qdf_ktime_get());
1272 	lut->header_length = dma_hdr.length;
1273 	lut->payload_length = dma_hdr.total_bytes;
1274 	qdf_mem_copy(&lut->dma_hdr, &dma_hdr,
1275 		     sizeof(struct whal_cfir_dma_hdr));
1276 
1277 	header = &lut->header;
1278 	header->cmn.chip_type = pcfr->chip_type;
1279 	meta = &header->u.meta_enh;
1280 	meta->channel_bw = dma_hdr.upload_pkt_bw;
1281 	meta->num_rx_chain = NUM_CHAINS_FW_TO_HOST(dma_hdr.num_chains);
1282 	meta->length = length;
1283 	/* For Tx based captures, capture type is sent from FW */
1284 	if (capture_type != CFR_TYPE_METHOD_ACK_RESP_TO_TM_FTM) {
1285 		meta->capture_type = capture_type;
1286 		meta->sts_count = (dma_hdr.nss + 1);
1287 		if (!dma_hdr.mu_rx_data_incl) {
1288 			/* extract peer addr from freeze tlv */
1289 			peer_macaddr = meta->peer_addr.su_peer_addr;
1290 			if (dma_hdr.freeze_data_incl) {
1291 				extract_peer_mac_from_freeze_tlv(freeze_tlv,
1292 								 peer_macaddr);
1293 			}
1294 		}
1295 	}
1296 
1297 	if (dma_hdr.freeze_data_incl) {
1298 		dump_enh_dma_hdr(&dma_hdr, freeze_tlv, mu_rx_user_info,
1299 				 header, 0, cookie);
1300 	}
1301 
1302 	status = correlate_and_relay_enh(pdev, cookie, lut,
1303 					 CORRELATE_DBR_MODULE_ID);
1304 	if (status == STATUS_STREAM_AND_RELEASE) {
1305 		/*
1306 		 * Message format
1307 		 *  Meta data Header + actual payload + trailer
1308 		 */
1309 		if (cfr_rx_ops->cfr_info_send)
1310 			status = cfr_rx_ops->cfr_info_send(pdev,
1311 							   &lut->header,
1312 							   sizeof(struct
1313 							   csi_cfr_header),
1314 							   lut->data,
1315 							   lut->data_len,
1316 							   &end_magic, 4);
1317 		dump_metadata(header, cookie);
1318 		release_lut_entry_enh(pdev, lut);
1319 		status = true;
1320 	} else if (status == STATUS_HOLD) {
1321 		status = false;
1322 	} else {
1323 		status = true;
1324 	}
1325 
1326 	qdf_spin_unlock_bh(&pcfr->lut_lock);
1327 	return status;
1328 }
1329 
1330 /**
1331  * target_if_register_to_dbr_enh() - Initialize DBR ring and register callback
1332  * for DBR events
1333  * @pdev: PDEV object
1334  *
1335  * Return: status
1336  */
1337 static QDF_STATUS
1338 target_if_register_to_dbr_enh(struct wlan_objmgr_pdev *pdev)
1339 {
1340 	struct wlan_objmgr_psoc *psoc;
1341 	struct wlan_lmac_if_direct_buf_rx_tx_ops *dbr_tx_ops = NULL;
1342 	struct dbr_module_config dbr_config;
1343 	struct wlan_lmac_if_tx_ops *tx_ops;
1344 
1345 	psoc = wlan_pdev_get_psoc(pdev);
1346 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
1347 	if (!tx_ops) {
1348 		cfr_err("tx_ops is NULL");
1349 		return QDF_STATUS_SUCCESS;
1350 	}
1351 	dbr_tx_ops = &tx_ops->dbr_tx_ops;
1352 	dbr_config.num_resp_per_event = DBR_NUM_RESP_PER_EVENT_CFR;
1353 	dbr_config.event_timeout_in_ms = DBR_EVENT_TIMEOUT_IN_MS_CFR;
1354 	if (dbr_tx_ops->direct_buf_rx_module_register) {
1355 		return dbr_tx_ops->direct_buf_rx_module_register
1356 			(pdev, DBR_MODULE_CFR, &dbr_config,
1357 			 enh_cfr_dbr_event_handler);
1358 	}
1359 
1360 	return QDF_STATUS_SUCCESS;
1361 }
1362 
1363 /**
1364  * target_if_unregister_to_dbr_enh() - Unregister callback for DBR events
1365  * @pdev: PDEV object
1366  *
1367  * Return: status
1368  */
1369 static QDF_STATUS
1370 target_if_unregister_to_dbr_enh(struct wlan_objmgr_pdev *pdev)
1371 {
1372 	struct wlan_objmgr_psoc *psoc;
1373 	struct wlan_lmac_if_direct_buf_rx_tx_ops *dbr_tx_ops = NULL;
1374 	struct wlan_lmac_if_tx_ops *tx_ops;
1375 
1376 	psoc = wlan_pdev_get_psoc(pdev);
1377 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
1378 	if (!tx_ops) {
1379 		cfr_err("tx_ops is NULL");
1380 		return QDF_STATUS_SUCCESS;
1381 	}
1382 	dbr_tx_ops = &tx_ops->dbr_tx_ops;
1383 	if (dbr_tx_ops->direct_buf_rx_module_unregister) {
1384 		return dbr_tx_ops->direct_buf_rx_module_unregister
1385 			(pdev, DBR_MODULE_CFR);
1386 	}
1387 
1388 	return QDF_STATUS_SUCCESS;
1389 }
1390 #endif
1391 
1392 /**
1393  * dump_cfr_peer_tx_event_enh() - Dump TX completion event
1394  * @event: ptr to WMI TX completion event for QOS frames sent during
1395  * one-shot capture
1396  * @cookie: Index into lookup table
1397  *
1398  * Return: none
1399  */
1400 static void dump_cfr_peer_tx_event_enh(wmi_cfr_peer_tx_event_param *event,
1401 				       uint32_t cookie)
1402 {
1403 	cfr_debug("<TXCOMP><%u>CFR capture method: %d vdev_id: %d mac: "
1404 		  QDF_MAC_ADDR_FMT, cookie,
1405 		  event->capture_method, event->vdev_id,
1406 		  QDF_MAC_ADDR_REF(event->peer_mac_addr.bytes));
1407 
1408 	cfr_debug("<TXCOMP><%u>Chan: %d bw: %d phymode: %d cfreq1: %d cfrq2: %d "
1409 		  "nss: %d\n",
1410 		  cookie,
1411 		  event->primary_20mhz_chan, event->bandwidth,
1412 		  event->phy_mode, event->band_center_freq1,
1413 		  event->band_center_freq2, event->spatial_streams);
1414 
1415 	cfr_debug("<TXCOMP><%u>Correlation_info1: 0x%08x "
1416 		  "Correlation_info2: 0x%08x\n",
1417 		  cookie,
1418 		  event->correlation_info_1, event->correlation_info_2);
1419 
1420 	cfr_debug("<TXCOMP><%u>status: 0x%x ts: %d counter: %d rssi0: 0x%08x\n",
1421 		  cookie,
1422 		  event->status, event->timestamp_us, event->counter,
1423 		  event->chain_rssi[0]);
1424 }
1425 
1426 static void
1427 populate_phase_delta(struct pdev_cfr *pcfr,
1428 		     struct wmi_cfr_phase_delta_param param)
1429 {
1430 	int c, g, pc, pg;
1431 	uint32_t c_mask = param.chain_phase_mask;
1432 
1433 	pc = 0;
1434 
1435 	/* populate phase delta for max chains indicated by target */
1436 	for (c = 0; c < pcfr->max_aoa_chains; c++) {
1437 		pg = 0;
1438 		if (((0x1 << c) & c_mask) && (pc < WMI_MAX_CHAINS_PHASE)) {
1439 			pcfr->ibf_cal_val[c] = param.ibf_cal_val[pc];
1440 			for (g = 0; g < MAX_AGC_GAIN; g = g + 2) {
1441 				if (pg < WMI_MAX_AOA_PHASE_DELTA) {
1442 					pcfr->phase_delta[c][g] = get_u16_lsb
1443 						(param.phase_delta[pc][pg]);
1444 					pcfr->phase_delta[c][g + 1] = get_u16_msb
1445 						(param.phase_delta[pc][pg]);
1446 					pg++;
1447 				}
1448 			}
1449 			pc++;
1450 		}
1451 	}
1452 }
1453 
1454 static int
1455 target_if_pdev_aoa_phasedaelta_event_handler(ol_scn_t sc,
1456 					     uint8_t *data,
1457 					     uint32_t datalen)
1458 {
1459 	struct wmi_unified *wmi_handle;
1460 	struct wlan_objmgr_psoc *psoc;
1461 	struct wlan_objmgr_pdev *pdev;
1462 	struct pdev_cfr *pcfr;
1463 	QDF_STATUS retval = 0;
1464 	struct wmi_cfr_phase_delta_param param = {0};
1465 
1466 	if (!sc || !data) {
1467 		cfr_err("sc or data is null");
1468 		return -EINVAL;
1469 	}
1470 
1471 	psoc = target_if_get_psoc_from_scn_hdl(sc);
1472 	if (!psoc) {
1473 		cfr_err("psoc is null");
1474 		return -EINVAL;
1475 	}
1476 
1477 	retval = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_CFR_ID);
1478 	if (QDF_IS_STATUS_ERROR(retval)) {
1479 		cfr_err("unable to get psoc reference");
1480 		return -EINVAL;
1481 	}
1482 
1483 	wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
1484 	if (!wmi_handle) {
1485 		cfr_err("wmi_handle is null");
1486 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1487 		return -EINVAL;
1488 	}
1489 
1490 	retval = wmi_extract_cfr_pdev_phase_delta_event
1491 			(wmi_handle, data, &param);
1492 
1493 	if (QDF_IS_STATUS_ERROR(retval)) {
1494 		cfr_err("Failed to extract phase params");
1495 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1496 		return -EINVAL;
1497 	}
1498 
1499 	pdev = wlan_objmgr_get_pdev_by_id(psoc, param.pdev_id, WLAN_CFR_ID);
1500 	if (!pdev) {
1501 		cfr_err("pdev is null");
1502 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1503 		return -EINVAL;
1504 	}
1505 
1506 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
1507 	if (!pcfr) {
1508 		cfr_err("pdev object for CFR is NULL");
1509 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1510 		wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1511 		return -EINVAL;
1512 	}
1513 
1514 	if (!pcfr->is_aoa_for_rcc_support) {
1515 		cfr_err("AoA data event from unsupported target");
1516 	}
1517 
1518 	pcfr->freq = param.freq;
1519 	pcfr->max_aoa_chains = (param.max_chains <= HOST_MAX_CHAINS) ?
1520 				param.max_chains : HOST_MAX_CHAINS;
1521 
1522 	populate_phase_delta(pcfr, param);
1523 
1524 	wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1525 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1526 
1527 	return retval;
1528 }
1529 
1530 #ifdef DIRECT_BUF_RX_ENABLE
1531 /**
1532  * enh_prepare_cfr_header_txstatus() - Prepare CFR metadata for TX failures
1533  * @tx_evt_param: ptr to WMI TX completion event
1534  * @header: pointer to metadata
1535  *
1536  * Return: none
1537  */
1538 static void enh_prepare_cfr_header_txstatus(wmi_cfr_peer_tx_event_param
1539 					    *tx_evt_param,
1540 					    struct csi_cfr_header *header,
1541 					    uint32_t target_type)
1542 {
1543 	target_if_cfr_fill_header(header, false, target_type, false);
1544 	header->u.meta_enh.status       = 0; /* failure */
1545 	header->u.meta_enh.length       = 0;
1546 	header->u.meta_enh.rtt_cfo_measurement = tx_evt_param->cfo_measurement;
1547 	header->u.meta_enh.rx_start_ts = tx_evt_param->rx_start_ts;
1548 
1549 	qdf_mem_copy(&header->u.meta_enh.peer_addr.su_peer_addr[0],
1550 		     &tx_evt_param->peer_mac_addr.bytes[0], QDF_MAC_ADDR_SIZE);
1551 }
1552 
1553 /**
1554  * target_if_peer_capture_event() - WMI TX completion event for one-shot
1555  * capture
1556  * @sc: pointer to offload soc object
1557  * @data: WMI TX completion event buffer
1558  * @datalen: WMI Tx completion event buffer length
1559  *
1560  * Return: status
1561  */
1562 static int
1563 target_if_peer_capture_event(ol_scn_t sc, uint8_t *data, uint32_t datalen)
1564 {
1565 	QDF_STATUS retval = 0;
1566 	struct wmi_unified *wmi_handle;
1567 	struct wlan_objmgr_psoc *psoc;
1568 	struct wlan_objmgr_pdev *pdev;
1569 	struct wlan_objmgr_vdev *vdev;
1570 	uint32_t cookie;
1571 	struct pdev_cfr *pcfr;
1572 	struct look_up_table *lut = NULL;
1573 	struct csi_cfr_header *header = NULL;
1574 	struct csi_cfr_header header_error = {{0} };
1575 	wmi_cfr_peer_tx_event_param tx_evt_param = {0};
1576 	qdf_dma_addr_t buf_addr = 0, buf_addr_temp = 0;
1577 	int status;
1578 	struct wlan_channel *bss_chan;
1579 	struct wlan_lmac_if_cfr_rx_ops *cfr_rx_ops = NULL;
1580 	struct wlan_lmac_if_rx_ops *rx_ops;
1581 	uint32_t target_type;
1582 
1583 	if (!sc || !data) {
1584 		cfr_err("sc or data is null");
1585 		return -EINVAL;
1586 	}
1587 
1588 	psoc = target_if_get_psoc_from_scn_hdl(sc);
1589 	if (!psoc) {
1590 		cfr_err("psoc is null");
1591 		return -EINVAL;
1592 	}
1593 
1594 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
1595 	if (!rx_ops) {
1596 		cfr_err("rx_ops is NULL");
1597 		return -EINVAL;
1598 	}
1599 	cfr_rx_ops = &rx_ops->cfr_rx_ops;
1600 
1601 	retval = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_CFR_ID);
1602 	if (QDF_IS_STATUS_ERROR(retval)) {
1603 		cfr_err("unable to get psoc reference");
1604 		return -EINVAL;
1605 	}
1606 
1607 	wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
1608 	if (!wmi_handle) {
1609 		cfr_err("wmi_handle is null");
1610 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1611 		return -EINVAL;
1612 	}
1613 
1614 	retval = wmi_extract_cfr_peer_tx_event_param(wmi_handle, data,
1615 						     &tx_evt_param);
1616 
1617 	if (retval != QDF_STATUS_SUCCESS) {
1618 		cfr_err("Failed to extract cfr tx event param");
1619 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1620 		return -EINVAL;
1621 	}
1622 
1623 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, tx_evt_param.vdev_id,
1624 						    WLAN_CFR_ID);
1625 	if (!vdev) {
1626 		cfr_err("vdev is null");
1627 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1628 		return -EINVAL;
1629 	}
1630 
1631 	pdev = wlan_vdev_get_pdev(vdev);
1632 	if (!pdev) {
1633 		cfr_err("pdev is null");
1634 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1635 		wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
1636 		return -EINVAL;
1637 	}
1638 
1639 	retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID);
1640 	if (retval != QDF_STATUS_SUCCESS) {
1641 		cfr_err("failed to get pdev reference");
1642 		wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1643 		wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
1644 		return -EINVAL;
1645 	}
1646 
1647 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
1648 						     WLAN_UMAC_COMP_CFR);
1649 	if (!pcfr) {
1650 		cfr_err("pdev object for CFR is NULL");
1651 		retval = -EINVAL;
1652 		goto relref;
1653 	}
1654 
1655 	target_type = target_if_cfr_get_target_type(psoc);
1656 
1657 	if (tx_evt_param.status & PEER_CFR_CAPTURE_EVT_PS_STATUS_MASK) {
1658 		cfr_err("CFR capture failed as peer is in powersave: "
1659 			QDF_MAC_ADDR_FMT,
1660 			QDF_MAC_ADDR_REF(tx_evt_param.peer_mac_addr.bytes));
1661 
1662 		enh_prepare_cfr_header_txstatus(&tx_evt_param,
1663 						&header_error,
1664 						target_type);
1665 		if (cfr_rx_ops->cfr_info_send)
1666 			cfr_rx_ops->cfr_info_send(pdev,
1667 						  &header_error,
1668 						  sizeof(struct
1669 							 csi_cfr_header),
1670 						  NULL, 0, &end_magic, 4);
1671 
1672 		retval = -EINVAL;
1673 		goto relref;
1674 	}
1675 
1676 	if ((tx_evt_param.status & PEER_CFR_CAPTURE_EVT_STATUS_MASK) == 0) {
1677 		cfr_debug("CFR capture failed for peer: " QDF_MAC_ADDR_FMT,
1678 			  QDF_MAC_ADDR_REF(tx_evt_param.peer_mac_addr.bytes));
1679 		pcfr->tx_peer_status_cfr_fail++;
1680 		retval = -EINVAL;
1681 		goto relref;
1682 	}
1683 
1684 	if (tx_evt_param.status & CFR_TX_EVT_STATUS_MASK) {
1685 		cfr_debug("TX packet returned status %d for peer: "
1686 			  QDF_MAC_ADDR_FMT,
1687 			  tx_evt_param.status & CFR_TX_EVT_STATUS_MASK,
1688 			  QDF_MAC_ADDR_REF(tx_evt_param.peer_mac_addr.bytes));
1689 		pcfr->tx_evt_status_cfr_fail++;
1690 		retval = -EINVAL;
1691 		goto relref;
1692 	}
1693 
1694 	buf_addr_temp = (tx_evt_param.correlation_info_2 & 0x0f);
1695 	buf_addr = (tx_evt_param.correlation_info_1 |
1696 		    ((uint64_t)buf_addr_temp << 32));
1697 
1698 	if (target_if_dbr_cookie_lookup(pdev, DBR_MODULE_CFR, buf_addr,
1699 					&cookie, 0)) {
1700 		cfr_debug("Cookie lookup failure for addr: 0x%pK status: 0x%x",
1701 			  (void *)((uintptr_t)buf_addr), tx_evt_param.status);
1702 		pcfr->tx_dbr_cookie_lookup_fail++;
1703 		retval = -EINVAL;
1704 		goto relref;
1705 	}
1706 
1707 	cfr_debug("buffer address: 0x%pK cookie: %u",
1708 		  (void *)((uintptr_t)buf_addr), cookie);
1709 
1710 	dump_cfr_peer_tx_event_enh(&tx_evt_param, cookie);
1711 
1712 	qdf_spin_lock_bh(&pcfr->lut_lock);
1713 
1714 	lut = get_lut_entry(pcfr, cookie);
1715 	if (!lut) {
1716 		cfr_err("lut is NULL\n");
1717 		retval = -EINVAL;
1718 		goto unlock;
1719 	}
1720 
1721 	pcfr->tx_evt_cnt++;
1722 	pcfr->total_tx_evt_cnt++;
1723 
1724 	lut->tx_ppdu_id = (tx_evt_param.correlation_info_2 >> 16);
1725 	lut->tx_address1 = tx_evt_param.correlation_info_1;
1726 	lut->tx_address2 = tx_evt_param.correlation_info_2;
1727 	lut->txrx_tstamp = qdf_ktime_to_ms(qdf_ktime_get());
1728 
1729 	header = &lut->header;
1730 	target_if_cfr_fill_header(header, false, target_type, false);
1731 	header->u.meta_enh.status       = (tx_evt_param.status &
1732 					   PEER_CFR_CAPTURE_EVT_STATUS_MASK) ?
1733 					   1 : 0;
1734 	header->u.meta_enh.capture_bw   = tx_evt_param.bandwidth;
1735 
1736 	bss_chan = wlan_vdev_mlme_get_bss_chan(vdev);
1737 	header->u.meta_enh.phy_mode     = bss_chan->ch_phymode;
1738 
1739 	header->u.meta_enh.prim20_chan  = tx_evt_param.primary_20mhz_chan;
1740 	header->u.meta_enh.center_freq1 = tx_evt_param.band_center_freq1;
1741 	header->u.meta_enh.center_freq2 = tx_evt_param.band_center_freq2;
1742 
1743 	/* Currently CFR data is captured on ACK of a Qos NULL frame.
1744 	 * For 20 MHz, ACK is Legacy and for 40/80/160, ACK is DUP Legacy.
1745 	 */
1746 	header->u.meta_enh.capture_mode = tx_evt_param.bandwidth ?
1747 		CFR_DUP_LEGACY_ACK : CFR_LEGACY_ACK;
1748 	header->u.meta_enh.capture_type = tx_evt_param.capture_method;
1749 	header->u.meta_enh.num_rx_chain = wlan_vdev_mlme_get_rxchainmask(vdev);
1750 	header->u.meta_enh.sts_count    = tx_evt_param.spatial_streams;
1751 	header->u.meta_enh.timestamp    = tx_evt_param.timestamp_us;
1752 
1753 	qdf_mem_copy(&header->u.meta_enh.peer_addr.su_peer_addr[0],
1754 		     &tx_evt_param.peer_mac_addr.bytes[0], QDF_MAC_ADDR_SIZE);
1755 	qdf_mem_copy(&header->u.meta_enh.chain_rssi[0],
1756 		     &tx_evt_param.chain_rssi[0],
1757 		     HOST_MAX_CHAINS * sizeof(tx_evt_param.chain_rssi[0]));
1758 	qdf_mem_copy(&header->u.meta_enh.chain_phase[0],
1759 		     &tx_evt_param.chain_phase[0],
1760 		     HOST_MAX_CHAINS * sizeof(tx_evt_param.chain_phase[0]));
1761 	qdf_mem_copy(&header->u.meta_enh.agc_gain[0],
1762 		     &tx_evt_param.agc_gain[0],
1763 		     HOST_MAX_CHAINS * sizeof(tx_evt_param.agc_gain[0]));
1764 	qdf_mem_copy(&header->u.meta_enh.agc_gain_tbl_index[0],
1765 		     &tx_evt_param.agc_gain_tbl_index[0],
1766 		     (HOST_MAX_CHAINS *
1767 		      sizeof(tx_evt_param.agc_gain_tbl_index[0])));
1768 
1769 	header->u.meta_enh.rtt_cfo_measurement = tx_evt_param.cfo_measurement;
1770 	header->u.meta_enh.rx_start_ts = tx_evt_param.rx_start_ts;
1771 	header->u.meta_enh.mcs_rate    = tx_evt_param.mcs_rate;
1772 	header->u.meta_enh.gi_type     = tx_evt_param.gi_type;
1773 
1774 	status = correlate_and_relay_enh(pdev, cookie, lut,
1775 					 CORRELATE_TX_EV_MODULE_ID);
1776 	if (status == STATUS_STREAM_AND_RELEASE) {
1777 		if (cfr_rx_ops->cfr_info_send)
1778 			status = cfr_rx_ops->cfr_info_send(pdev,
1779 							   &lut->header,
1780 							   sizeof(
1781 							   struct
1782 							   csi_cfr_header),
1783 							   lut->data,
1784 							   lut->data_len,
1785 							   &end_magic, 4);
1786 		dump_metadata(header, cookie);
1787 		release_lut_entry_enh(pdev, lut);
1788 		target_if_dbr_buf_release(pdev, DBR_MODULE_CFR, buf_addr,
1789 					  cookie, 0);
1790 	} else {
1791 		retval = -EINVAL;
1792 	}
1793 
1794 unlock:
1795 	qdf_spin_unlock_bh(&pcfr->lut_lock);
1796 relref:
1797 
1798 	wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
1799 	wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
1800 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1801 
1802 	return retval;
1803 }
1804 #else
1805 static int
1806 target_if_peer_capture_event(ol_scn_t sc, uint8_t *data, uint32_t datalen)
1807 {
1808 	return 0;
1809 }
1810 #endif
1811 
1812 /**
1813  * target_if_register_phase_delta_for_rcc_event_handler() - Register callback
1814  * for WMI phase delta event
1815  * @psoc: PSOC object
1816  *
1817  * Return: Success/Failure status
1818  */
1819 static QDF_STATUS
1820 target_if_register_phase_delta_for_rcc_event_handler(struct wlan_objmgr_psoc
1821 						     *psoc)
1822 {
1823 	wmi_unified_t wmi_hdl;
1824 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
1825 
1826 	wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc);
1827 	if (!wmi_hdl) {
1828 		cfr_err("Unable to get wmi handle");
1829 		return QDF_STATUS_E_NULL_VALUE;
1830 	}
1831 
1832 	ret = wmi_unified_register_event_handler
1833 		(wmi_hdl, wmi_pdev_aoa_phasedelta_event_id,
1834 		 target_if_pdev_aoa_phasedaelta_event_handler,
1835 		 WMI_RX_UMAC_CTX);
1836 
1837 	/*
1838 	 * Event registration is called per pdev
1839 	 * Ignore error if event is already registered.
1840 	 */
1841 	if (ret == QDF_STATUS_E_FAILURE)
1842 		ret = QDF_STATUS_SUCCESS;
1843 
1844 	return ret;
1845 }
1846 
1847 /**
1848  * target_if_unregister_phase_delta_for_rcc_event_handler() - Unregister
1849  * call back for WMI phase delta for rcc event
1850  * @psoc: PSOC object
1851  *
1852  * Return Success/Failure status
1853  */
1854 static QDF_STATUS
1855 target_if_unregister_phase_delta_for_rcc_event_handler(struct wlan_objmgr_psoc
1856 						       *psoc)
1857 {
1858 	wmi_unified_t wmi_hdl;
1859 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1860 
1861 	wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc);
1862 	if (!wmi_hdl) {
1863 		cfr_err("Unable to get wmi handle");
1864 		return QDF_STATUS_E_NULL_VALUE;
1865 	}
1866 
1867 	status = wmi_unified_unregister_event
1868 		(wmi_hdl, wmi_pdev_aoa_phasedelta_event_id);
1869 
1870 	return status;
1871 }
1872 
1873 /**
1874  * target_if_register_tx_completion_enh_event_handler() - Register callback for
1875  * WMI TX completion event
1876  * @psoc: PSOC object
1877  *
1878  * Return: Success/Failure status
1879  */
1880 static QDF_STATUS
1881 target_if_register_tx_completion_enh_event_handler(struct wlan_objmgr_psoc
1882 						   *psoc)
1883 {
1884 	/* Register completion handler here */
1885 	wmi_unified_t wmi_hdl;
1886 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
1887 
1888 	wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc);
1889 	if (!wmi_hdl) {
1890 		cfr_err("Unable to get wmi handle");
1891 		return QDF_STATUS_E_NULL_VALUE;
1892 	}
1893 
1894 	ret = wmi_unified_register_event_handler(wmi_hdl,
1895 						 wmi_peer_cfr_capture_event_id,
1896 						 target_if_peer_capture_event,
1897 						 WMI_RX_UMAC_CTX);
1898 	/*
1899 	 * Event registration is called per pdev
1900 	 * Ignore error if event is already registered.
1901 	 */
1902 	if (ret == QDF_STATUS_E_FAILURE)
1903 		ret = QDF_STATUS_SUCCESS;
1904 
1905 	return ret;
1906 }
1907 
1908 /**
1909  * target_if_unregister_tx_completion_enh_event_handler() - Unregister callback
1910  * for WMI TX completion event
1911  * @psoc: PSOC object
1912  *
1913  * Return: Success/Failure status
1914  */
1915 static QDF_STATUS
1916 target_if_unregister_tx_completion_enh_event_handler(struct wlan_objmgr_psoc
1917 						     *psoc)
1918 {
1919 	/* Unregister completion handler here */
1920 	wmi_unified_t wmi_hdl;
1921 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1922 
1923 	wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc);
1924 	if (!wmi_hdl) {
1925 		cfr_err("Unable to get wmi handle");
1926 		return QDF_STATUS_E_NULL_VALUE;
1927 	}
1928 
1929 	status = wmi_unified_unregister_event(wmi_hdl,
1930 					      wmi_peer_cfr_capture_event_id);
1931 	return status;
1932 }
1933 
1934 /**
1935  * lut_ageout_timer_task() - Timer to flush pending TXRX/DBR events
1936  *
1937  * Return: none
1938  */
1939 static os_timer_func(lut_ageout_timer_task)
1940 {
1941 	int i = 0;
1942 	struct pdev_cfr *pcfr = NULL;
1943 	struct wlan_objmgr_pdev *pdev = NULL;
1944 	struct look_up_table *lut = NULL;
1945 	uint64_t diff, cur_tstamp;
1946 	uint8_t srng_id = 0;
1947 
1948 	OS_GET_TIMER_ARG(pcfr, struct pdev_cfr*);
1949 
1950 	if (!pcfr) {
1951 		cfr_err("pdev object for CFR is null");
1952 		return;
1953 	}
1954 
1955 	pdev = pcfr->pdev_obj;
1956 	if (!pdev) {
1957 		cfr_err("pdev is null");
1958 		return;
1959 	}
1960 
1961 	srng_id = pcfr->rcc_param.srng_id;
1962 	if (wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID)
1963 	    != QDF_STATUS_SUCCESS) {
1964 		cfr_err("failed to get pdev reference");
1965 		return;
1966 	}
1967 
1968 	cur_tstamp = qdf_ktime_to_ms(qdf_ktime_get());
1969 
1970 	qdf_spin_lock_bh(&pcfr->lut_lock);
1971 
1972 	for (i = 0; i < pcfr->lut_num; i++) {
1973 		lut = get_lut_entry(pcfr, i);
1974 		if (!lut)
1975 			continue;
1976 
1977 		if (lut->dbr_recv && !lut->tx_recv) {
1978 			diff = cur_tstamp - lut->dbr_tstamp;
1979 			if (diff > LUT_AGE_THRESHOLD) {
1980 				target_if_dbr_buf_release(pdev, DBR_MODULE_CFR,
1981 							  lut->dbr_address,
1982 							  i, srng_id);
1983 				pcfr->flush_timeout_dbr_cnt++;
1984 				release_lut_entry_enh(pdev, lut);
1985 			}
1986 		}
1987 	}
1988 
1989 	qdf_spin_unlock_bh(&pcfr->lut_lock);
1990 
1991 	if (pcfr->lut_timer_init)
1992 		qdf_timer_mod(&pcfr->lut_age_timer, LUT_AGE_TIMER);
1993 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1994 }
1995 
1996 /**
1997  * target_if_cfr_start_lut_age_timer() - Start timer to flush aged-out LUT
1998  * entries
1999  * @pdev: pointer to pdev object
2000  *
2001  * Return: None
2002  */
2003 void target_if_cfr_start_lut_age_timer(struct wlan_objmgr_pdev *pdev)
2004 {
2005 	struct pdev_cfr *pcfr;
2006 
2007 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
2008 						     WLAN_UMAC_COMP_CFR);
2009 	if (pcfr->lut_timer_init)
2010 		qdf_timer_mod(&pcfr->lut_age_timer, LUT_AGE_TIMER);
2011 }
2012 
2013 /**
2014  * target_if_cfr_stop_lut_age_timer() - Stop timer to flush aged-out LUT
2015  * entries
2016  * @pdev: pointer to pdev object
2017  *
2018  * Return: None
2019  */
2020 void target_if_cfr_stop_lut_age_timer(struct wlan_objmgr_pdev *pdev)
2021 {
2022 	struct pdev_cfr *pcfr;
2023 
2024 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
2025 						     WLAN_UMAC_COMP_CFR);
2026 	if (pcfr->lut_timer_init)
2027 		qdf_timer_stop(&pcfr->lut_age_timer);
2028 }
2029 
2030 /**
2031  * target_if_cfr_update_global_cfg() - Update global config after a successful
2032  * commit
2033  * @pdev: pointer to pdev object
2034  *
2035  * Return: None
2036  */
2037 void target_if_cfr_update_global_cfg(struct wlan_objmgr_pdev *pdev)
2038 {
2039 	int grp_id;
2040 	struct pdev_cfr *pcfr;
2041 	struct ta_ra_cfr_cfg *curr_cfg = NULL;
2042 	struct ta_ra_cfr_cfg *glbl_cfg = NULL;
2043 
2044 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
2045 						     WLAN_UMAC_COMP_CFR);
2046 
2047 	for (grp_id = 0; grp_id < MAX_TA_RA_ENTRIES; grp_id++) {
2048 		if (qdf_test_bit(grp_id,
2049 				 &pcfr->rcc_param.modified_in_curr_session)) {
2050 			/* Populating global config based on user's input */
2051 			glbl_cfg = &pcfr->global[grp_id];
2052 			curr_cfg = &pcfr->rcc_param.curr[grp_id];
2053 
2054 			if (curr_cfg->valid_ta)
2055 				qdf_mem_copy(glbl_cfg->tx_addr,
2056 					     curr_cfg->tx_addr,
2057 					     QDF_MAC_ADDR_SIZE);
2058 
2059 			if (curr_cfg->valid_ra)
2060 				qdf_mem_copy(glbl_cfg->rx_addr,
2061 					     curr_cfg->rx_addr,
2062 					     QDF_MAC_ADDR_SIZE);
2063 
2064 			if (curr_cfg->valid_ta_mask)
2065 				qdf_mem_copy(glbl_cfg->tx_addr_mask,
2066 					     curr_cfg->tx_addr_mask,
2067 					     QDF_MAC_ADDR_SIZE);
2068 
2069 			if (curr_cfg->valid_ra_mask)
2070 				qdf_mem_copy(glbl_cfg->rx_addr_mask,
2071 					     curr_cfg->rx_addr_mask,
2072 					     QDF_MAC_ADDR_SIZE);
2073 
2074 			if (curr_cfg->valid_bw_mask)
2075 				glbl_cfg->bw = curr_cfg->bw;
2076 
2077 			if (curr_cfg->valid_nss_mask)
2078 				glbl_cfg->nss = curr_cfg->nss;
2079 
2080 			if (curr_cfg->valid_mgmt_subtype)
2081 				glbl_cfg->mgmt_subtype_filter =
2082 					curr_cfg->mgmt_subtype_filter;
2083 
2084 			if (curr_cfg->valid_ctrl_subtype)
2085 				glbl_cfg->ctrl_subtype_filter =
2086 					curr_cfg->ctrl_subtype_filter;
2087 
2088 			if (curr_cfg->valid_data_subtype)
2089 				glbl_cfg->data_subtype_filter =
2090 					curr_cfg->data_subtype_filter;
2091 		}
2092 	}
2093 }
2094 
2095 /**
2096  * cfr_enh_init_pdev() - Inits cfr pdev and registers necessary handlers.
2097  * @psoc: pointer to psoc object
2098  * @pdev: pointer to pdev object
2099  *
2100  * Return: Registration status for necessary handlers
2101  */
2102 QDF_STATUS cfr_enh_init_pdev(struct wlan_objmgr_psoc *psoc,
2103 			     struct wlan_objmgr_pdev *pdev)
2104 {
2105 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2106 	struct pdev_cfr *pcfr;
2107 	uint32_t target_type;
2108 	struct psoc_cfr *cfr_sc;
2109 
2110 	if (!pdev) {
2111 		cfr_err("PDEV is NULL!");
2112 		return QDF_STATUS_E_NULL_VALUE;
2113 	}
2114 
2115 	if (!psoc) {
2116 		cfr_err("PSOC is NULL");
2117 		return QDF_STATUS_E_NULL_VALUE;
2118 	}
2119 
2120 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
2121 						     WLAN_UMAC_COMP_CFR);
2122 	if (!pcfr) {
2123 		cfr_err("pcfr is NULL!");
2124 		return QDF_STATUS_E_NULL_VALUE;
2125 	}
2126 
2127 	cfr_sc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
2128 						       WLAN_UMAC_COMP_CFR);
2129 
2130 	if (!cfr_sc) {
2131 		cfr_err("cfr_sc is NULL");
2132 		return QDF_STATUS_E_NULL_VALUE;
2133 	}
2134 
2135 	target_type = target_if_cfr_get_target_type(psoc);
2136 
2137 #if DIRECT_BUF_RX_ENABLE
2138 	status = target_if_register_to_dbr_enh(pdev);
2139 	if (status != QDF_STATUS_SUCCESS) {
2140 		cfr_err("Failed to register with dbr");
2141 		return status;
2142 	}
2143 #endif
2144 
2145 	status = target_if_register_tx_completion_enh_event_handler(psoc);
2146 	if (status != QDF_STATUS_SUCCESS) {
2147 		cfr_err("Failed to register with tx event handler");
2148 		return status;
2149 	}
2150 
2151 	status = target_if_register_phase_delta_for_rcc_event_handler(psoc);
2152 	if (status != QDF_STATUS_SUCCESS) {
2153 		cfr_err("Failed to register with phase delta event handler");
2154 		return status;
2155 	}
2156 
2157 	pcfr->is_cfr_rcc_capable = 1;
2158 	pcfr->rcc_param.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
2159 	pcfr->rcc_param.modified_in_curr_session = MAX_RESET_CFG_ENTRY;
2160 	pcfr->rcc_param.num_grp_tlvs = MAX_TA_RA_ENTRIES;
2161 	pcfr->rcc_param.vdev_id = CFR_INVALID_VDEV_ID;
2162 	pcfr->rcc_param.srng_id = DEFAULT_SRNGID_CFR;
2163 	pcfr->is_cap_interval_mode_sel_support =
2164 				cfr_sc->is_cap_interval_mode_sel_support;
2165 	pcfr->is_mo_marking_support = cfr_sc->is_mo_marking_support;
2166 	pcfr->is_aoa_for_rcc_support = cfr_sc->is_aoa_for_rcc_support;
2167 
2168 	if (pcfr->is_aoa_for_rcc_support) {
2169 		qdf_mem_set(pcfr->ibf_cal_val,
2170 			    sizeof(uint32_t) * HOST_MAX_CHAINS,
2171 			    0);
2172 		qdf_mem_set(pcfr->phase_delta,
2173 			    sizeof(uint16_t) * HOST_MAX_CHAINS * MAX_AGC_GAIN,
2174 			    0);
2175 		pcfr->max_aoa_chains = 0;
2176 	}
2177 
2178 	target_if_cfr_default_ta_ra_config(&pcfr->rcc_param,
2179 					   true, MAX_RESET_CFG_ENTRY);
2180 
2181 	status = target_if_cfr_config_rcc(pdev, &pcfr->rcc_param);
2182 	if (status == QDF_STATUS_SUCCESS) {
2183 		/* Update global configuration */
2184 		target_if_cfr_update_global_cfg(pdev);
2185 	} else {
2186 		cfr_err("Sending WMI to configure default has failed");
2187 		return status;
2188 	}
2189 
2190 	pcfr->rcc_param.modified_in_curr_session = 0;
2191 
2192 	pcfr->cfr_max_sta_count = MAX_CFR_ENABLED_CLIENTS;
2193 
2194 	if (target_type == TARGET_TYPE_QCN9000) {
2195 		pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_PINE;
2196 		pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_PINE;
2197 		pcfr->chip_type = CFR_CAPTURE_RADIO_PINE;
2198 		pcfr->max_mu_users = PINE_CFR_MU_USERS;
2199 	} else if (target_type == TARGET_TYPE_QCA5018) {
2200 		pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_MAPLE;
2201 		pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_MAPLE;
2202 		pcfr->chip_type = CFR_CAPTURE_RADIO_MAPLE;
2203 		pcfr->max_mu_users = MAPLE_CFR_MU_USERS;
2204 	} else if (target_type == TARGET_TYPE_QCN6122 ||
2205 		   target_type == TARGET_TYPE_QCN9160) {
2206 		pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_SPRUCE;
2207 		pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_SPRUCE;
2208 		pcfr->chip_type = CFR_CAPTURE_RADIO_SPRUCE;
2209 		pcfr->max_mu_users = SPRUCE_CFR_MU_USERS;
2210 	} else if (target_type == TARGET_TYPE_QCN9224) {
2211 		pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_WAIKIKI;
2212 		pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_WAIKIKI;
2213 		pcfr->chip_type = CFR_CAPTURE_RADIO_WAIKIKI;
2214 		pcfr->max_mu_users = WAIKIKI_CFR_MU_USERS;
2215 	} else {
2216 		pcfr->subbuf_size = STREAMFS_MAX_SUBBUF_CYP;
2217 		pcfr->num_subbufs = STREAMFS_NUM_SUBBUF_CYP;
2218 		pcfr->chip_type = CFR_CAPTURE_RADIO_CYP;
2219 		pcfr->max_mu_users = CYP_CFR_MU_USERS;
2220 	}
2221 
2222 	if (!pcfr->lut_timer_init) {
2223 		qdf_timer_init(NULL,
2224 			       &(pcfr->lut_age_timer),
2225 			       lut_ageout_timer_task, (void *)pcfr,
2226 			       QDF_TIMER_TYPE_WAKE_APPS);
2227 		pcfr->lut_timer_init = 1;
2228 	}
2229 
2230 	qdf_spinlock_create(&pcfr->lut_lock);
2231 
2232 	return status;
2233 }
2234 
2235 /**
2236  * cfr_enh_deinit_pdev() - De-inits corresponding pdev and handlers.
2237  * @psoc: pointer to psoc object
2238  * @pdev: pointer to pdev object
2239  *
2240  * Return: De-registration status for necessary handlers
2241  */
2242 QDF_STATUS cfr_enh_deinit_pdev(struct wlan_objmgr_psoc *psoc,
2243 			       struct wlan_objmgr_pdev *pdev)
2244 {
2245 	QDF_STATUS status;
2246 	struct pdev_cfr *pcfr;
2247 
2248 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
2249 						     WLAN_UMAC_COMP_CFR);
2250 	if (!pcfr) {
2251 		cfr_err("pcfr is NULL");
2252 		return QDF_STATUS_E_NULL_VALUE;
2253 	}
2254 
2255 	if (pcfr->lut_timer_init) {
2256 		qdf_timer_stop(&pcfr->lut_age_timer);
2257 		qdf_timer_free(&(pcfr->lut_age_timer));
2258 		pcfr->lut_timer_init = 0;
2259 	}
2260 
2261 	pcfr->tx_evt_cnt = 0;
2262 	pcfr->dbr_evt_cnt = 0;
2263 	pcfr->release_cnt = 0;
2264 	pcfr->total_tx_evt_cnt = 0;
2265 	pcfr->rx_tlv_evt_cnt = 0;
2266 	pcfr->flush_dbr_cnt = 0;
2267 	pcfr->flush_timeout_dbr_cnt = 0;
2268 	pcfr->invalid_dma_length_cnt = 0;
2269 	pcfr->clear_txrx_event = 0;
2270 	pcfr->cfr_dma_aborts = 0;
2271 	pcfr->tx_peer_status_cfr_fail = 0;
2272 	pcfr->tx_evt_status_cfr_fail = 0;
2273 	pcfr->tx_dbr_cookie_lookup_fail = 0;
2274 	qdf_mem_zero(&pcfr->rcc_param, sizeof(struct cfr_rcc_param));
2275 	qdf_mem_zero(&pcfr->global, (sizeof(struct ta_ra_cfr_cfg) *
2276 				     MAX_TA_RA_ENTRIES));
2277 	pcfr->cfr_timer_enable = 0;
2278 
2279 #ifdef DIRECT_BUF_RX_ENABLE
2280 	status = target_if_unregister_to_dbr_enh(pdev);
2281 	if (status != QDF_STATUS_SUCCESS)
2282 		cfr_err("Failed to register with dbr");
2283 #endif
2284 
2285 	status = target_if_unregister_tx_completion_enh_event_handler(psoc);
2286 	if (status != QDF_STATUS_SUCCESS)
2287 		cfr_err("Failed to register with dbr");
2288 
2289 	status = target_if_unregister_phase_delta_for_rcc_event_handler(psoc);
2290 	if (status != QDF_STATUS_SUCCESS)
2291 		cfr_err("Failed to unregister phase delta handler");
2292 
2293 	qdf_spinlock_destroy(&pcfr->lut_lock);
2294 
2295 	return status;
2296 }
2297