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