xref: /wlan-driver/qca-wifi-host-cmn/target_if/cp_stats/src/target_if_cp_stats.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2018, 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 /**
21*5113495bSYour Name  * DOC: target_if_cp_stats.c
22*5113495bSYour Name  *
23*5113495bSYour Name  * This file provide definition for APIs registered through lmac Tx Ops
24*5113495bSYour Name  */
25*5113495bSYour Name 
26*5113495bSYour Name #include <qdf_mem.h>
27*5113495bSYour Name #include <qdf_status.h>
28*5113495bSYour Name #include <target_if_cp_stats.h>
29*5113495bSYour Name #include <wmi_unified_priv.h>
30*5113495bSYour Name #include <wmi_unified_param.h>
31*5113495bSYour Name #include <target_if.h>
32*5113495bSYour Name #include <wlan_tgt_def_config.h>
33*5113495bSYour Name #include <wmi_unified_api.h>
34*5113495bSYour Name #include <wlan_osif_priv.h>
35*5113495bSYour Name #include <wlan_cp_stats_utils_api.h>
36*5113495bSYour Name #include <wlan_objmgr_peer_obj.h>
37*5113495bSYour Name #ifdef WLAN_FEATURE_MIB_STATS
38*5113495bSYour Name #include <wlan_cp_stats_mc_defs.h>
39*5113495bSYour Name #endif
40*5113495bSYour Name #include "cp_stats/core/src/wlan_cp_stats_defs.h"
41*5113495bSYour Name #include "cdp_txrx_cmn_struct.h"
42*5113495bSYour Name #include "cdp_txrx_ctrl.h"
43*5113495bSYour Name #include "cp_stats/core/src/wlan_cp_stats_comp_handler.h"
44*5113495bSYour Name 
45*5113495bSYour Name #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
46*5113495bSYour Name #ifdef WLAN_SUPPORT_TWT
47*5113495bSYour Name /**
48*5113495bSYour Name  * target_if_infra_cp_stats_twt_event_free() - Free event buffer
49*5113495bSYour Name  * @ev: pointer to infra cp stats event structure
50*5113495bSYour Name  *
51*5113495bSYour Name  * Return: None
52*5113495bSYour Name  */
53*5113495bSYour Name static
target_if_infra_cp_stats_twt_event_free(struct infra_cp_stats_event * ev)54*5113495bSYour Name void target_if_infra_cp_stats_twt_event_free(struct infra_cp_stats_event *ev)
55*5113495bSYour Name {
56*5113495bSYour Name 	qdf_mem_free(ev->twt_infra_cp_stats);
57*5113495bSYour Name 	ev->twt_infra_cp_stats = NULL;
58*5113495bSYour Name }
59*5113495bSYour Name 
60*5113495bSYour Name /**
61*5113495bSYour Name  * target_if_infra_cp_stats_twt_event_alloc() - Allocate event buffer for TWT
62*5113495bSYour Name  * parameters
63*5113495bSYour Name  * @ev: pointer to infra cp stats event structure
64*5113495bSYour Name  *
65*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes on
66*5113495bSYour Name  * failure
67*5113495bSYour Name  */
68*5113495bSYour Name static QDF_STATUS
target_if_infra_cp_stats_twt_event_alloc(struct infra_cp_stats_event * ev)69*5113495bSYour Name target_if_infra_cp_stats_twt_event_alloc(struct infra_cp_stats_event *ev)
70*5113495bSYour Name {
71*5113495bSYour Name 	ev->twt_infra_cp_stats =
72*5113495bSYour Name 			qdf_mem_malloc(sizeof(*ev->twt_infra_cp_stats) *
73*5113495bSYour Name 			INFRA_CP_STATS_MAX_RESP_TWT_DIALOG_ID);
74*5113495bSYour Name 	if (!ev->twt_infra_cp_stats) {
75*5113495bSYour Name 		cp_stats_err("mem alloc failed for ev.twt_infra_cp_stats");
76*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
77*5113495bSYour Name 	}
78*5113495bSYour Name 
79*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
80*5113495bSYour Name }
81*5113495bSYour Name 
82*5113495bSYour Name #else
83*5113495bSYour Name static inline
target_if_infra_cp_stats_twt_event_free(struct infra_cp_stats_event * ev)84*5113495bSYour Name void target_if_infra_cp_stats_twt_event_free(struct infra_cp_stats_event *ev)
85*5113495bSYour Name {
86*5113495bSYour Name }
87*5113495bSYour Name 
88*5113495bSYour Name static inline QDF_STATUS
target_if_infra_cp_stats_twt_event_alloc(struct infra_cp_stats_event * ev)89*5113495bSYour Name target_if_infra_cp_stats_twt_event_alloc(struct infra_cp_stats_event *ev)
90*5113495bSYour Name {
91*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
92*5113495bSYour Name }
93*5113495bSYour Name 
94*5113495bSYour Name static inline
target_if_infra_cp_stats_free_stats_event(struct infra_cp_stats_event * ev)95*5113495bSYour Name void target_if_infra_cp_stats_free_stats_event(struct infra_cp_stats_event *ev)
96*5113495bSYour Name {
97*5113495bSYour Name }
98*5113495bSYour Name #endif /* WLAN_SUPPORT_TWT */
99*5113495bSYour Name 
100*5113495bSYour Name static
target_if_infra_cp_stats_rrm_sta_stats_event_free(struct infra_cp_stats_event * ev)101*5113495bSYour Name void target_if_infra_cp_stats_rrm_sta_stats_event_free(
102*5113495bSYour Name 					struct infra_cp_stats_event *ev)
103*5113495bSYour Name {
104*5113495bSYour Name 	qdf_mem_free(ev->sta_stats);
105*5113495bSYour Name 	ev->sta_stats = NULL;
106*5113495bSYour Name }
107*5113495bSYour Name 
108*5113495bSYour Name static QDF_STATUS
target_if_infra_cp_stats_rrm_sta_stats_event_alloc(struct infra_cp_stats_event * ev)109*5113495bSYour Name target_if_infra_cp_stats_rrm_sta_stats_event_alloc(
110*5113495bSYour Name 			struct infra_cp_stats_event *ev)
111*5113495bSYour Name {
112*5113495bSYour Name 	ev->sta_stats =
113*5113495bSYour Name 	qdf_mem_malloc(sizeof(*ev->sta_stats));
114*5113495bSYour Name 	if (!ev->sta_stats) {
115*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
116*5113495bSYour Name 	}
117*5113495bSYour Name 
118*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
119*5113495bSYour Name }
120*5113495bSYour Name #ifdef CONFIG_WLAN_BMISS
121*5113495bSYour Name 
122*5113495bSYour Name /**
123*5113495bSYour Name  * target_if_infra_cp_stats_bmiss_event_free() - Free event buffer
124*5113495bSYour Name  * @ev: pointer to infra cp stats event structure
125*5113495bSYour Name  *
126*5113495bSYour Name  * Return: None
127*5113495bSYour Name  */
128*5113495bSYour Name static
target_if_infra_cp_stats_bmiss_event_free(struct infra_cp_stats_event * ev)129*5113495bSYour Name void target_if_infra_cp_stats_bmiss_event_free(struct infra_cp_stats_event *ev)
130*5113495bSYour Name {
131*5113495bSYour Name 	qdf_mem_free(ev->bmiss_infra_cp_stats);
132*5113495bSYour Name 	ev->bmiss_infra_cp_stats = NULL;
133*5113495bSYour Name }
134*5113495bSYour Name 
135*5113495bSYour Name /**
136*5113495bSYour Name  * target_if_infra_cp_stats_bmiss_event_alloc() - Allocate buffer for bmiss
137*5113495bSYour Name  * parameters
138*5113495bSYour Name  * @ev: pointer to infra cp stats event structure
139*5113495bSYour Name  *
140*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes on
141*5113495bSYour Name  * failure
142*5113495bSYour Name  */
143*5113495bSYour Name static QDF_STATUS
target_if_infra_cp_stats_bmiss_event_alloc(struct infra_cp_stats_event * ev)144*5113495bSYour Name target_if_infra_cp_stats_bmiss_event_alloc(struct infra_cp_stats_event *ev)
145*5113495bSYour Name {
146*5113495bSYour Name 	ev->bmiss_infra_cp_stats =
147*5113495bSYour Name 	qdf_mem_malloc(sizeof(*ev->bmiss_infra_cp_stats));
148*5113495bSYour Name 	if (!ev->bmiss_infra_cp_stats) {
149*5113495bSYour Name 		cp_stats_err("mem alloc failed for ev.bmiss_infra_cp_stats");
150*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
151*5113495bSYour Name 	}
152*5113495bSYour Name 
153*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
154*5113495bSYour Name }
155*5113495bSYour Name #else
156*5113495bSYour Name 
157*5113495bSYour Name static inline
target_if_infra_cp_stats_bmiss_event_free(struct infra_cp_stats_event * ev)158*5113495bSYour Name void target_if_infra_cp_stats_bmiss_event_free(struct infra_cp_stats_event *ev)
159*5113495bSYour Name {
160*5113495bSYour Name }
161*5113495bSYour Name 
162*5113495bSYour Name static inline QDF_STATUS
target_if_infra_cp_stats_bmiss_event_alloc(struct infra_cp_stats_event * ev)163*5113495bSYour Name target_if_infra_cp_stats_bmiss_event_alloc(struct infra_cp_stats_event *ev)
164*5113495bSYour Name {
165*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
166*5113495bSYour Name }
167*5113495bSYour Name #endif /* CONFIG_WLAN_BMISS */
168*5113495bSYour Name 
169*5113495bSYour Name /**
170*5113495bSYour Name  * target_if_infra_cp_stats_event_free() - Free event buffer
171*5113495bSYour Name  * @ev: pointer to infra cp stats event structure
172*5113495bSYour Name  *
173*5113495bSYour Name  * Return : None
174*5113495bSYour Name  */
175*5113495bSYour Name static
target_if_infra_cp_stats_event_free(struct infra_cp_stats_event * ev)176*5113495bSYour Name void target_if_infra_cp_stats_event_free(struct infra_cp_stats_event *ev)
177*5113495bSYour Name {
178*5113495bSYour Name 	target_if_infra_cp_stats_twt_event_free(ev);
179*5113495bSYour Name 	target_if_infra_cp_stats_bmiss_event_free(ev);
180*5113495bSYour Name 	target_if_infra_cp_stats_rrm_sta_stats_event_free(ev);
181*5113495bSYour Name }
182*5113495bSYour Name 
183*5113495bSYour Name /**
184*5113495bSYour Name  * target_if_infra_cp_stats_event_alloc() - Allocate buffer for event
185*5113495bSYour Name  * parameters
186*5113495bSYour Name  * @ev: pointer to infra cp stats event structure
187*5113495bSYour Name  *
188*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes on
189*5113495bSYour Name  * failure
190*5113495bSYour Name  */
191*5113495bSYour Name static QDF_STATUS
target_if_infra_cp_stats_event_alloc(struct infra_cp_stats_event * ev)192*5113495bSYour Name target_if_infra_cp_stats_event_alloc(struct infra_cp_stats_event *ev)
193*5113495bSYour Name {
194*5113495bSYour Name 	QDF_STATUS status;
195*5113495bSYour Name 
196*5113495bSYour Name 	status = target_if_infra_cp_stats_twt_event_alloc(ev);
197*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
198*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
199*5113495bSYour Name 
200*5113495bSYour Name 	status = target_if_infra_cp_stats_bmiss_event_alloc(ev);
201*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
202*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
203*5113495bSYour Name 
204*5113495bSYour Name 	status = target_if_infra_cp_stats_rrm_sta_stats_event_alloc(ev);
205*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
206*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
207*5113495bSYour Name 
208*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
209*5113495bSYour Name }
210*5113495bSYour Name 
211*5113495bSYour Name /**
212*5113495bSYour Name  * target_if_extract_infra_cp_stats_event() - Extract data from stats event
213*5113495bSYour Name  * @wmi_hdl: WMI Handle
214*5113495bSYour Name  * @data: pointer to event data buffer from firmware
215*5113495bSYour Name  * @data_len: length of the data buffer
216*5113495bSYour Name  * @ev: pointer of output structure to be filled with extracted values
217*5113495bSYour Name  *
218*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes
219*5113495bSYour Name  * on failure
220*5113495bSYour Name  */
221*5113495bSYour Name static QDF_STATUS
target_if_extract_infra_cp_stats_event(struct wmi_unified * wmi_hdl,uint8_t * data,uint32_t data_len,struct infra_cp_stats_event * ev)222*5113495bSYour Name target_if_extract_infra_cp_stats_event(struct wmi_unified *wmi_hdl,
223*5113495bSYour Name 				       uint8_t *data, uint32_t data_len,
224*5113495bSYour Name 				       struct infra_cp_stats_event *ev)
225*5113495bSYour Name {
226*5113495bSYour Name 	QDF_STATUS status;
227*5113495bSYour Name 	uint32_t more_flag = 0;
228*5113495bSYour Name 
229*5113495bSYour Name 	status = wmi_unified_extract_cp_stats_more_pending(wmi_hdl, data,
230*5113495bSYour Name 							   &more_flag);
231*5113495bSYour Name 
232*5113495bSYour Name 	status = wmi_unified_extract_infra_cp_stats(wmi_hdl, data,
233*5113495bSYour Name 						    data_len, ev);
234*5113495bSYour Name 
235*5113495bSYour Name 	cp_stats_debug("request_id %d", ev->request_id);
236*5113495bSYour Name 
237*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
238*5113495bSYour Name }
239*5113495bSYour Name 
240*5113495bSYour Name /**
241*5113495bSYour Name  * target_if_infra_cp_stats_event_handler() - Handle
242*5113495bSYour Name  * wmi_pdev_cp_fwstats_eventid
243*5113495bSYour Name  * @scn: opaque scn handle
244*5113495bSYour Name  * @data: event buffer received from fw
245*5113495bSYour Name  * @datalen: length of event buffer
246*5113495bSYour Name  *
247*5113495bSYour Name  * Return: 0 for success or non zero error codes for failure
248*5113495bSYour Name  */
249*5113495bSYour Name static
target_if_infra_cp_stats_event_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)250*5113495bSYour Name int target_if_infra_cp_stats_event_handler(ol_scn_t scn, uint8_t *data,
251*5113495bSYour Name 					   uint32_t datalen)
252*5113495bSYour Name {
253*5113495bSYour Name 	QDF_STATUS status;
254*5113495bSYour Name 	struct infra_cp_stats_event ev = {0};
255*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
256*5113495bSYour Name 	struct wmi_unified *wmi_handle;
257*5113495bSYour Name 	struct wlan_lmac_if_cp_stats_rx_ops *rx_ops;
258*5113495bSYour Name 
259*5113495bSYour Name 	cp_stats_debug("Enter");
260*5113495bSYour Name 
261*5113495bSYour Name 	if (!scn || !data) {
262*5113495bSYour Name 		cp_stats_err("scn: 0x%pK, data: 0x%pK", scn, data);
263*5113495bSYour Name 		return -EINVAL;
264*5113495bSYour Name 	}
265*5113495bSYour Name 
266*5113495bSYour Name 	psoc = target_if_get_psoc_from_scn_hdl(scn);
267*5113495bSYour Name 	if (!psoc) {
268*5113495bSYour Name 		cp_stats_err("null psoc");
269*5113495bSYour Name 		return -EINVAL;
270*5113495bSYour Name 	}
271*5113495bSYour Name 
272*5113495bSYour Name 	rx_ops = target_if_cp_stats_get_rx_ops(psoc);
273*5113495bSYour Name 	if (!rx_ops || !rx_ops->process_stats_event) {
274*5113495bSYour Name 		cp_stats_err("callback not registered");
275*5113495bSYour Name 		return -EINVAL;
276*5113495bSYour Name 	}
277*5113495bSYour Name 
278*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
279*5113495bSYour Name 	if (!wmi_handle) {
280*5113495bSYour Name 		cp_stats_err("wmi_handle is null");
281*5113495bSYour Name 		return -EINVAL;
282*5113495bSYour Name 	}
283*5113495bSYour Name 	status = target_if_infra_cp_stats_event_alloc(&ev);
284*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
285*5113495bSYour Name 		cp_stats_err("Alloc event mem failed");
286*5113495bSYour Name 		goto end;
287*5113495bSYour Name 	}
288*5113495bSYour Name 
289*5113495bSYour Name 	status = target_if_extract_infra_cp_stats_event(wmi_handle, data,
290*5113495bSYour Name 							datalen, &ev);
291*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
292*5113495bSYour Name 		cp_stats_err("extract event failed");
293*5113495bSYour Name 		goto end;
294*5113495bSYour Name 	}
295*5113495bSYour Name 
296*5113495bSYour Name 	status = rx_ops->process_infra_stats_event(psoc, &ev);
297*5113495bSYour Name 
298*5113495bSYour Name end:
299*5113495bSYour Name 	target_if_infra_cp_stats_event_free(&ev);
300*5113495bSYour Name 	return qdf_status_to_os_return(status);
301*5113495bSYour Name }
302*5113495bSYour Name #else
303*5113495bSYour Name static
target_if_infra_cp_stats_event_handler(ol_scn_t scn,uint8_t * data,uint32_t datalen)304*5113495bSYour Name int target_if_infra_cp_stats_event_handler(ol_scn_t scn, uint8_t *data,
305*5113495bSYour Name 					   uint32_t datalen)
306*5113495bSYour Name {
307*5113495bSYour Name 	return 0;
308*5113495bSYour Name }
309*5113495bSYour Name #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */
310*5113495bSYour Name 
311*5113495bSYour Name #if defined(WLAN_SUPPORT_TWT) && defined(WLAN_TWT_CONV_SUPPORTED)
312*5113495bSYour Name static int
target_if_twt_session_params_event_handler(ol_scn_t scn,uint8_t * evt_buf,uint32_t evt_data_len)313*5113495bSYour Name target_if_twt_session_params_event_handler(ol_scn_t scn,
314*5113495bSYour Name 					   uint8_t *evt_buf,
315*5113495bSYour Name 					   uint32_t evt_data_len)
316*5113495bSYour Name {
317*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
318*5113495bSYour Name 	struct wlan_objmgr_peer *peer_obj;
319*5113495bSYour Name 	struct wmi_unified *wmi_hdl;
320*5113495bSYour Name 	struct twt_session_stats_info twt_params;
321*5113495bSYour Name 	struct twt_session_stats_event_param params = {0};
322*5113495bSYour Name 	struct peer_cp_stats *peer_cp_stats;
323*5113495bSYour Name 	int i;
324*5113495bSYour Name 	QDF_STATUS status;
325*5113495bSYour Name 	uint32_t ev;
326*5113495bSYour Name 	cdp_config_param_type val = {0};
327*5113495bSYour Name 	ol_txrx_soc_handle soc_txrx_handle;
328*5113495bSYour Name 	struct wlan_lmac_if_rx_ops *rx_ops;
329*5113495bSYour Name 
330*5113495bSYour Name 	TARGET_IF_ENTER();
331*5113495bSYour Name 
332*5113495bSYour Name 	if (!scn || !evt_buf) {
333*5113495bSYour Name 		target_if_err("scn: 0x%pK, evt_buf: 0x%pK", scn, evt_buf);
334*5113495bSYour Name 		return -EINVAL;
335*5113495bSYour Name 	}
336*5113495bSYour Name 
337*5113495bSYour Name 	psoc = target_if_get_psoc_from_scn_hdl(scn);
338*5113495bSYour Name 	if (!psoc) {
339*5113495bSYour Name 		target_if_err("psoc object is null!");
340*5113495bSYour Name 		return -EINVAL;
341*5113495bSYour Name 	}
342*5113495bSYour Name 
343*5113495bSYour Name 	soc_txrx_handle = wlan_psoc_get_dp_handle(psoc);
344*5113495bSYour Name 	if (!soc_txrx_handle)
345*5113495bSYour Name 		return -EINVAL;
346*5113495bSYour Name 
347*5113495bSYour Name 	wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc);
348*5113495bSYour Name 	if (!wmi_hdl) {
349*5113495bSYour Name 		target_if_err("wmi_handle is null!");
350*5113495bSYour Name 		return -EINVAL;
351*5113495bSYour Name 	}
352*5113495bSYour Name 
353*5113495bSYour Name 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
354*5113495bSYour Name 	if (!rx_ops) {
355*5113495bSYour Name 		target_if_err("No valid twt session stats rx ops");
356*5113495bSYour Name 		return -EINVAL;
357*5113495bSYour Name 	}
358*5113495bSYour Name 
359*5113495bSYour Name 	status = wmi_extract_twt_session_stats_event(wmi_hdl, evt_buf, &params);
360*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
361*5113495bSYour Name 		target_if_err("Could not extract twt session stats event");
362*5113495bSYour Name 		return qdf_status_to_os_return(status);
363*5113495bSYour Name 	}
364*5113495bSYour Name 
365*5113495bSYour Name 	if (params.num_sessions > WLAN_MAX_TWT_SESSIONS_PER_PEER) {
366*5113495bSYour Name 		target_if_err("Number of twt sessions exceeded, num:%d max:%d",
367*5113495bSYour Name 			      params.num_sessions, WLAN_MAX_TWT_SESSIONS_PER_PEER);
368*5113495bSYour Name 		return -EINVAL;
369*5113495bSYour Name 	}
370*5113495bSYour Name 
371*5113495bSYour Name 	for (i = 0; i < params.num_sessions; i++) {
372*5113495bSYour Name 		status = wmi_extract_twt_session_stats_data(wmi_hdl, evt_buf,
373*5113495bSYour Name 							    &params,
374*5113495bSYour Name 							    &twt_params, i);
375*5113495bSYour Name 
376*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status)) {
377*5113495bSYour Name 			target_if_err("Unable to extract twt params for idx %d",
378*5113495bSYour Name 				      i);
379*5113495bSYour Name 			return -EINVAL;
380*5113495bSYour Name 		}
381*5113495bSYour Name 		peer_obj = wlan_objmgr_get_peer_by_mac(psoc,
382*5113495bSYour Name 						twt_params.peer_mac.bytes,
383*5113495bSYour Name 						WLAN_CP_STATS_ID);
384*5113495bSYour Name 		if (!peer_obj) {
385*5113495bSYour Name 			target_if_err("peer obj not found for "QDF_MAC_ADDR_FMT,
386*5113495bSYour Name 				      QDF_MAC_ADDR_REF(twt_params.peer_mac.bytes));
387*5113495bSYour Name 			continue;
388*5113495bSYour Name 		}
389*5113495bSYour Name 
390*5113495bSYour Name 		ev = twt_params.event_type;
391*5113495bSYour Name 		if (ev == HOST_TWT_SESSION_SETUP)
392*5113495bSYour Name 			val.cdp_peer_param_in_twt = 1;
393*5113495bSYour Name 		else if (ev == HOST_TWT_SESSION_TEARDOWN)
394*5113495bSYour Name 			val.cdp_peer_param_in_twt = 0;
395*5113495bSYour Name 
396*5113495bSYour Name 		cdp_txrx_set_peer_param(soc_txrx_handle, twt_params.vdev_id,
397*5113495bSYour Name 					twt_params.peer_mac.bytes,
398*5113495bSYour Name 					CDP_CONFIG_IN_TWT, val);
399*5113495bSYour Name 
400*5113495bSYour Name 		peer_cp_stats = wlan_cp_stats_get_peer_stats_obj(peer_obj);
401*5113495bSYour Name 		if (!peer_cp_stats) {
402*5113495bSYour Name 			target_if_err("peer_cp_stats is null");
403*5113495bSYour Name 			continue;
404*5113495bSYour Name 		}
405*5113495bSYour Name 
406*5113495bSYour Name 		wlan_cp_stats_peer_obj_lock(peer_cp_stats);
407*5113495bSYour Name 
408*5113495bSYour Name 		rx_ops->cp_stats_rx_ops.twt_get_session_param_resp(psoc,
409*5113495bSYour Name 								 &twt_params);
410*5113495bSYour Name 
411*5113495bSYour Name 		wlan_cp_stats_peer_obj_unlock(peer_cp_stats);
412*5113495bSYour Name 		wlan_objmgr_peer_release_ref(peer_obj, WLAN_CP_STATS_ID);
413*5113495bSYour Name 	}
414*5113495bSYour Name 	return 0;
415*5113495bSYour Name }
416*5113495bSYour Name 
417*5113495bSYour Name static QDF_STATUS
target_if_cp_stats_register_twt_session_event(struct wmi_unified * wmi_handle)418*5113495bSYour Name target_if_cp_stats_register_twt_session_event(struct wmi_unified *wmi_handle)
419*5113495bSYour Name {
420*5113495bSYour Name 	QDF_STATUS ret_val;
421*5113495bSYour Name 
422*5113495bSYour Name 	ret_val = wmi_unified_register_event_handler(wmi_handle,
423*5113495bSYour Name 				wmi_twt_session_stats_event_id,
424*5113495bSYour Name 				target_if_twt_session_params_event_handler,
425*5113495bSYour Name 				WMI_RX_WORK_CTX);
426*5113495bSYour Name 
427*5113495bSYour Name 	return ret_val;
428*5113495bSYour Name }
429*5113495bSYour Name 
430*5113495bSYour Name static void
target_if_cp_stats_unregister_twt_session_event(struct wmi_unified * wmi_handle)431*5113495bSYour Name target_if_cp_stats_unregister_twt_session_event(struct wmi_unified *wmi_handle)
432*5113495bSYour Name {
433*5113495bSYour Name 	wmi_unified_unregister_event_handler(wmi_handle,
434*5113495bSYour Name 					     wmi_twt_session_stats_event_id);
435*5113495bSYour Name }
436*5113495bSYour Name #else
437*5113495bSYour Name static QDF_STATUS
target_if_cp_stats_register_twt_session_event(struct wmi_unified * wmi_handle)438*5113495bSYour Name target_if_cp_stats_register_twt_session_event(struct wmi_unified *wmi_handle)
439*5113495bSYour Name {
440*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
441*5113495bSYour Name }
442*5113495bSYour Name 
443*5113495bSYour Name static void
target_if_cp_stats_unregister_twt_session_event(struct wmi_unified * wmi_handle)444*5113495bSYour Name target_if_cp_stats_unregister_twt_session_event(struct wmi_unified *wmi_handle)
445*5113495bSYour Name {
446*5113495bSYour Name }
447*5113495bSYour Name #endif /*  WLAN_SUPPORT_TWT && WLAN_TWT_CONV_SUPPORTED*/
448*5113495bSYour Name 
449*5113495bSYour Name #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
450*5113495bSYour Name static QDF_STATUS
target_if_cp_stats_infra_register_event_handler(struct wlan_objmgr_psoc * psoc,struct wmi_unified * wmi_handle)451*5113495bSYour Name target_if_cp_stats_infra_register_event_handler(struct wlan_objmgr_psoc *psoc,
452*5113495bSYour Name 						struct wmi_unified *wmi_handle)
453*5113495bSYour Name {
454*5113495bSYour Name 	QDF_STATUS ret_val;
455*5113495bSYour Name 
456*5113495bSYour Name 	if (!psoc) {
457*5113495bSYour Name 		cp_stats_err("PSOC is NULL!");
458*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
459*5113495bSYour Name 	}
460*5113495bSYour Name 
461*5113495bSYour Name 	if (!wmi_handle) {
462*5113495bSYour Name 		cp_stats_err("wmi_handle is null");
463*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
464*5113495bSYour Name 	}
465*5113495bSYour Name 
466*5113495bSYour Name 	ret_val = wmi_unified_register_event_handler(wmi_handle,
467*5113495bSYour Name 						     wmi_pdev_cp_fwstats_eventid,
468*5113495bSYour Name 						     target_if_infra_cp_stats_event_handler,
469*5113495bSYour Name 						     WMI_RX_WORK_CTX);
470*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret_val)) {
471*5113495bSYour Name 		cp_stats_err("Failed to register for pdev_cp_fwstats_event");
472*5113495bSYour Name 		return ret_val;
473*5113495bSYour Name 	}
474*5113495bSYour Name 
475*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
476*5113495bSYour Name }
477*5113495bSYour Name #else
478*5113495bSYour Name static QDF_STATUS
target_if_cp_stats_infra_register_event_handler(struct wlan_objmgr_psoc * psoc,struct wmi_unified * wmi_handle)479*5113495bSYour Name target_if_cp_stats_infra_register_event_handler(struct wlan_objmgr_psoc *psoc,
480*5113495bSYour Name 						struct wmi_unified *wmi_handle)
481*5113495bSYour Name {
482*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
483*5113495bSYour Name }
484*5113495bSYour Name #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */
485*5113495bSYour Name 
486*5113495bSYour Name static QDF_STATUS
target_if_cp_stats_register_event_handler(struct wlan_objmgr_psoc * psoc)487*5113495bSYour Name target_if_cp_stats_register_event_handler(struct wlan_objmgr_psoc *psoc)
488*5113495bSYour Name {
489*5113495bSYour Name 	struct wmi_unified *wmi_handle;
490*5113495bSYour Name 	QDF_STATUS ret_val;
491*5113495bSYour Name 
492*5113495bSYour Name 	if (!psoc) {
493*5113495bSYour Name 		cp_stats_err("PSOC is NULL!");
494*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
495*5113495bSYour Name 	}
496*5113495bSYour Name 
497*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
498*5113495bSYour Name 	if (!wmi_handle) {
499*5113495bSYour Name 		cp_stats_err("wmi_handle is null");
500*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
501*5113495bSYour Name 	}
502*5113495bSYour Name 
503*5113495bSYour Name 	ret_val = target_if_cp_stats_infra_register_event_handler(psoc,
504*5113495bSYour Name 								  wmi_handle);
505*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret_val)) {
506*5113495bSYour Name 		cp_stats_err("Failed to register for pdev_cp_fwstats_event");
507*5113495bSYour Name 		return ret_val;
508*5113495bSYour Name 	}
509*5113495bSYour Name 
510*5113495bSYour Name 	ret_val = target_if_cp_stats_register_twt_session_event(wmi_handle);
511*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret_val)) {
512*5113495bSYour Name 		cp_stats_err("Failed to register twt session stats event");
513*5113495bSYour Name 		return ret_val;
514*5113495bSYour Name 	}
515*5113495bSYour Name 
516*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
517*5113495bSYour Name }
518*5113495bSYour Name 
519*5113495bSYour Name static QDF_STATUS
target_if_cp_stats_unregister_event_handler(struct wlan_objmgr_psoc * psoc)520*5113495bSYour Name target_if_cp_stats_unregister_event_handler(struct wlan_objmgr_psoc *psoc)
521*5113495bSYour Name {
522*5113495bSYour Name 	struct wmi_unified *wmi_handle;
523*5113495bSYour Name 
524*5113495bSYour Name 	if (!psoc) {
525*5113495bSYour Name 		cp_stats_err("PSOC is NULL!");
526*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
527*5113495bSYour Name 	}
528*5113495bSYour Name 
529*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
530*5113495bSYour Name 	if (!wmi_handle) {
531*5113495bSYour Name 		cp_stats_err("wmi_handle is null");
532*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
533*5113495bSYour Name 	}
534*5113495bSYour Name 
535*5113495bSYour Name 	wmi_unified_unregister_event_handler(wmi_handle,
536*5113495bSYour Name 					     wmi_pdev_cp_fwstats_eventid);
537*5113495bSYour Name 	target_if_cp_stats_unregister_twt_session_event(wmi_handle);
538*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
539*5113495bSYour Name }
540*5113495bSYour Name 
541*5113495bSYour Name #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
542*5113495bSYour Name /**
543*5113495bSYour Name  * target_if_infra_cp_stats_req() - API to send stats request to wmi
544*5113495bSYour Name  * @psoc: pointer to psoc object
545*5113495bSYour Name  * @req: pointer to object containing stats request parameters
546*5113495bSYour Name  *
547*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on success, else other qdf error values
548*5113495bSYour Name  */
549*5113495bSYour Name static
target_if_infra_cp_stats_req(struct wlan_objmgr_psoc * psoc,struct infra_cp_stats_cmd_info * req)550*5113495bSYour Name QDF_STATUS target_if_infra_cp_stats_req(struct wlan_objmgr_psoc *psoc,
551*5113495bSYour Name 					struct infra_cp_stats_cmd_info *req)
552*5113495bSYour Name 
553*5113495bSYour Name {
554*5113495bSYour Name 	struct wmi_unified *wmi_handle;
555*5113495bSYour Name 
556*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
557*5113495bSYour Name 	if (!wmi_handle) {
558*5113495bSYour Name 		cp_stats_err("wmi_handle is null.");
559*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
560*5113495bSYour Name 	}
561*5113495bSYour Name 
562*5113495bSYour Name 	return wmi_unified_infra_cp_stats_request_send(wmi_handle, req);
563*5113495bSYour Name }
564*5113495bSYour Name 
target_if_register_infra_cp_stats_txops(struct wlan_lmac_if_cp_stats_tx_ops * tx_ops)565*5113495bSYour Name static void target_if_register_infra_cp_stats_txops(
566*5113495bSYour Name 				struct wlan_lmac_if_cp_stats_tx_ops *tx_ops)
567*5113495bSYour Name {
568*5113495bSYour Name 	tx_ops->send_req_infra_cp_stats = target_if_infra_cp_stats_req;
569*5113495bSYour Name }
570*5113495bSYour Name #else
target_if_register_infra_cp_stats_txops(struct wlan_lmac_if_cp_stats_tx_ops * tx_ops)571*5113495bSYour Name static void target_if_register_infra_cp_stats_txops(
572*5113495bSYour Name 				struct wlan_lmac_if_cp_stats_tx_ops *tx_ops)
573*5113495bSYour Name {
574*5113495bSYour Name }
575*5113495bSYour Name #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */
576*5113495bSYour Name 
577*5113495bSYour Name #ifdef WLAN_CONFIG_TELEMETRY_AGENT
578*5113495bSYour Name /**
579*5113495bSYour Name  * target_if_telemetry_cp_stats_req() - API to send stats request to wmi
580*5113495bSYour Name  * @pdev: pointer to pdev object
581*5113495bSYour Name  * @req: pointer to object containing stats request parameters
582*5113495bSYour Name  *
583*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on success, else other qdf error values
584*5113495bSYour Name  */
585*5113495bSYour Name static
target_if_telemetry_cp_stats_req(struct wlan_objmgr_pdev * pdev,struct infra_cp_stats_cmd_info * req)586*5113495bSYour Name QDF_STATUS target_if_telemetry_cp_stats_req(struct wlan_objmgr_pdev *pdev,
587*5113495bSYour Name 					    struct infra_cp_stats_cmd_info *req)
588*5113495bSYour Name {
589*5113495bSYour Name 	struct wmi_unified *wmi_handle;
590*5113495bSYour Name 
591*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_pdev(pdev);
592*5113495bSYour Name 	if (!wmi_handle) {
593*5113495bSYour Name 		cp_stats_err("wmi_handle is null.");
594*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
595*5113495bSYour Name 	}
596*5113495bSYour Name 	return wmi_unified_infra_cp_stats_request_send(wmi_handle, req);
597*5113495bSYour Name }
598*5113495bSYour Name 
target_if_register_telemetry_cp_stats_txops(struct wlan_lmac_if_cp_stats_tx_ops * tx_ops)599*5113495bSYour Name static void target_if_register_telemetry_cp_stats_txops(
600*5113495bSYour Name 				struct wlan_lmac_if_cp_stats_tx_ops *tx_ops)
601*5113495bSYour Name {
602*5113495bSYour Name 	tx_ops->send_req_telemetry_cp_stats = target_if_telemetry_cp_stats_req;
603*5113495bSYour Name }
604*5113495bSYour Name #else
target_if_register_telemetry_cp_stats_txops(struct wlan_lmac_if_cp_stats_tx_ops * tx_ops)605*5113495bSYour Name static void target_if_register_telemetry_cp_stats_txops(
606*5113495bSYour Name 				struct wlan_lmac_if_cp_stats_tx_ops *tx_ops)
607*5113495bSYour Name { }
608*5113495bSYour Name #endif
609*5113495bSYour Name #ifdef WLAN_CHIPSET_STATS
610*5113495bSYour Name QDF_STATUS
target_if_cp_stats_is_service_cstats_enabled(struct wlan_objmgr_psoc * psoc,bool * is_fw_support_cstats)611*5113495bSYour Name target_if_cp_stats_is_service_cstats_enabled(struct wlan_objmgr_psoc *psoc,
612*5113495bSYour Name 					     bool *is_fw_support_cstats)
613*5113495bSYour Name {
614*5113495bSYour Name 	struct wmi_unified *wmi_handle;
615*5113495bSYour Name 
616*5113495bSYour Name 	if (!psoc) {
617*5113495bSYour Name 		cp_stats_err("psoc is NULL!");
618*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
619*5113495bSYour Name 	}
620*5113495bSYour Name 
621*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
622*5113495bSYour Name 	if (!wmi_handle) {
623*5113495bSYour Name 		cp_stats_err("wmi_handle is null");
624*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
625*5113495bSYour Name 	}
626*5113495bSYour Name 
627*5113495bSYour Name 	*is_fw_support_cstats =
628*5113495bSYour Name 		wmi_service_enabled(wmi_handle,
629*5113495bSYour Name 				    wmi_service_chipset_logging_support);
630*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
631*5113495bSYour Name }
632*5113495bSYour Name 
633*5113495bSYour Name static QDF_STATUS
target_if_cp_stats_enable_cstats(struct wlan_objmgr_psoc * psoc,uint32_t param_val,uint8_t mac_id)634*5113495bSYour Name target_if_cp_stats_enable_cstats(struct wlan_objmgr_psoc *psoc,
635*5113495bSYour Name 				 uint32_t param_val, uint8_t mac_id)
636*5113495bSYour Name {
637*5113495bSYour Name 	struct wmi_unified *wmi_handle;
638*5113495bSYour Name 	struct pdev_params params = {0};
639*5113495bSYour Name 
640*5113495bSYour Name 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
641*5113495bSYour Name 	if (!wmi_handle) {
642*5113495bSYour Name 		cp_stats_err("wmi_handle is null");
643*5113495bSYour Name 		return QDF_STATUS_E_NULL_VALUE;
644*5113495bSYour Name 	}
645*5113495bSYour Name 
646*5113495bSYour Name 	params.param_id = WMI_PDEV_PARAM_ENABLE_CHIPSET_LOGGING;
647*5113495bSYour Name 	params.param_value = param_val;
648*5113495bSYour Name 
649*5113495bSYour Name 	return wmi_unified_pdev_param_send(wmi_handle, &params, mac_id);
650*5113495bSYour Name }
651*5113495bSYour Name 
652*5113495bSYour Name /**
653*5113495bSYour Name  * target_if_register_cstats_enable_txops() - Register cstats enable in txops
654*5113495bSYour Name  *
655*5113495bSYour Name  * @ops: pointer to wlan_lmac_if_cp_stats_tx_ops
656*5113495bSYour Name  *
657*5113495bSYour Name  * Return: void
658*5113495bSYour Name  */
659*5113495bSYour Name static void
target_if_register_cstats_enable_txops(struct wlan_lmac_if_cp_stats_tx_ops * ops)660*5113495bSYour Name target_if_register_cstats_enable_txops(struct wlan_lmac_if_cp_stats_tx_ops *ops)
661*5113495bSYour Name {
662*5113495bSYour Name 	ops->send_cstats_enable = target_if_cp_stats_enable_cstats;
663*5113495bSYour Name }
664*5113495bSYour Name #else
665*5113495bSYour Name static void
target_if_register_cstats_enable_txops(struct wlan_lmac_if_cp_stats_tx_ops * ops)666*5113495bSYour Name target_if_register_cstats_enable_txops(struct wlan_lmac_if_cp_stats_tx_ops *ops)
667*5113495bSYour Name {
668*5113495bSYour Name }
669*5113495bSYour Name #endif
670*5113495bSYour Name 
671*5113495bSYour Name QDF_STATUS
target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops * tx_ops)672*5113495bSYour Name target_if_cp_stats_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
673*5113495bSYour Name {
674*5113495bSYour Name 	struct wlan_lmac_if_cp_stats_tx_ops *cp_stats_tx_ops;
675*5113495bSYour Name 
676*5113495bSYour Name 	if (!tx_ops) {
677*5113495bSYour Name 		cp_stats_err("lmac tx ops is NULL!");
678*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
679*5113495bSYour Name 	}
680*5113495bSYour Name 
681*5113495bSYour Name 	cp_stats_tx_ops = &tx_ops->cp_stats_tx_ops;
682*5113495bSYour Name 	if (!cp_stats_tx_ops) {
683*5113495bSYour Name 		cp_stats_err("lmac tx ops is NULL!");
684*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
685*5113495bSYour Name 	}
686*5113495bSYour Name 
687*5113495bSYour Name 	target_if_register_cstats_enable_txops(cp_stats_tx_ops);
688*5113495bSYour Name 
689*5113495bSYour Name 	target_if_register_infra_cp_stats_txops(cp_stats_tx_ops);
690*5113495bSYour Name 	target_if_register_telemetry_cp_stats_txops(cp_stats_tx_ops);
691*5113495bSYour Name 
692*5113495bSYour Name 	cp_stats_tx_ops->cp_stats_attach =
693*5113495bSYour Name 		target_if_cp_stats_register_event_handler;
694*5113495bSYour Name 	cp_stats_tx_ops->cp_stats_detach =
695*5113495bSYour Name 		target_if_cp_stats_unregister_event_handler;
696*5113495bSYour Name 	cp_stats_tx_ops->cp_stats_legacy_attach =
697*5113495bSYour Name 		target_if_cp_stats_register_legacy_event_handler;
698*5113495bSYour Name 	cp_stats_tx_ops->cp_stats_legacy_detach =
699*5113495bSYour Name 		target_if_cp_stats_unregister_legacy_event_handler;
700*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
701*5113495bSYour Name }
702*5113495bSYour Name 
703