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