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