1 /*
2  * Copyright (c) 2018 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * DOC: wlan_cp_stats_utils_api.c
22  *
23  * This file provide public API definitions for other accessing other UMAC
24  * components
25  */
26 #include <cfg_ucfg_api.h>
27 #include "../../core/src/wlan_cp_stats_defs.h"
28 #include "../../core/src/wlan_cp_stats_obj_mgr_handler.h"
29 #include "../../core/src/wlan_cp_stats_comp_handler.h"
30 #include <wlan_cp_stats_utils_api.h>
31 #include <wlan_cp_stats_ucfg_api.h>
32 #include <wlan_cp_stats_chipset_stats.h>
33 
wlan_cp_stats_init(void)34 QDF_STATUS wlan_cp_stats_init(void)
35 {
36 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
37 
38 	status = wlan_objmgr_register_psoc_create_handler
39 				(WLAN_UMAC_COMP_CP_STATS,
40 				 wlan_cp_stats_psoc_obj_create_handler,
41 				 NULL);
42 	if (QDF_IS_STATUS_ERROR(status)) {
43 		cp_stats_err("Failed to register psoc create handler");
44 		goto wlan_cp_stats_psoc_init_fail1;
45 	}
46 
47 	status = wlan_objmgr_register_psoc_destroy_handler
48 				(WLAN_UMAC_COMP_CP_STATS,
49 				 wlan_cp_stats_psoc_obj_destroy_handler,
50 				 NULL);
51 	if (QDF_IS_STATUS_ERROR(status)) {
52 		cp_stats_err("Failed to register psoc destroy handler");
53 		goto wlan_cp_stats_psoc_init_fail2;
54 	}
55 
56 	status = wlan_objmgr_register_pdev_create_handler
57 				(WLAN_UMAC_COMP_CP_STATS,
58 				 wlan_cp_stats_pdev_obj_create_handler,
59 				 NULL);
60 	if (QDF_IS_STATUS_ERROR(status)) {
61 		cp_stats_err("Failed to register pdev create handler");
62 		goto wlan_cp_stats_pdev_init_fail1;
63 	}
64 
65 	status = wlan_objmgr_register_pdev_destroy_handler
66 				(WLAN_UMAC_COMP_CP_STATS,
67 				 wlan_cp_stats_pdev_obj_destroy_handler,
68 				 NULL);
69 	if (QDF_IS_STATUS_ERROR(status)) {
70 		cp_stats_err("Failed to register pdev destroy handler");
71 		goto wlan_cp_stats_pdev_init_fail2;
72 	}
73 
74 	status = wlan_objmgr_register_vdev_create_handler
75 				(WLAN_UMAC_COMP_CP_STATS,
76 				 wlan_cp_stats_vdev_obj_create_handler,
77 				 NULL);
78 	if (QDF_IS_STATUS_ERROR(status)) {
79 		cp_stats_err("Failed to register vdev create handler");
80 		goto wlan_cp_stats_vdev_init_fail1;
81 	}
82 
83 	status = wlan_objmgr_register_vdev_destroy_handler
84 				(WLAN_UMAC_COMP_CP_STATS,
85 				 wlan_cp_stats_vdev_obj_destroy_handler,
86 				 NULL);
87 	if (QDF_IS_STATUS_ERROR(status)) {
88 		cp_stats_err("Failed to register vdev destroy handler");
89 		goto wlan_cp_stats_vdev_init_fail2;
90 	}
91 
92 	status = wlan_objmgr_register_peer_create_handler
93 				(WLAN_UMAC_COMP_CP_STATS,
94 				 wlan_cp_stats_peer_obj_create_handler,
95 				 NULL);
96 	if (QDF_IS_STATUS_ERROR(status)) {
97 		cp_stats_err("Failed to register peer create handler");
98 		goto wlan_cp_stats_peer_init_fail1;
99 	}
100 
101 	status = wlan_objmgr_register_peer_destroy_handler
102 				(WLAN_UMAC_COMP_CP_STATS,
103 				 wlan_cp_stats_peer_obj_destroy_handler,
104 				 NULL);
105 	if (QDF_IS_STATUS_ERROR(status)) {
106 		cp_stats_err("Failed to register peer destroy handler");
107 		goto wlan_cp_stats_peer_init_fail2;
108 	}
109 
110 	return QDF_STATUS_SUCCESS;
111 
112 wlan_cp_stats_peer_init_fail2:
113 	wlan_objmgr_unregister_peer_create_handler
114 		(WLAN_UMAC_COMP_CP_STATS,
115 		 wlan_cp_stats_peer_obj_create_handler,
116 		 NULL);
117 wlan_cp_stats_peer_init_fail1:
118 	wlan_objmgr_unregister_vdev_destroy_handler
119 		(WLAN_UMAC_COMP_CP_STATS,
120 		 wlan_cp_stats_vdev_obj_destroy_handler,
121 		 NULL);
122 wlan_cp_stats_vdev_init_fail2:
123 	wlan_objmgr_unregister_vdev_create_handler
124 		(WLAN_UMAC_COMP_CP_STATS,
125 		 wlan_cp_stats_vdev_obj_create_handler,
126 		 NULL);
127 wlan_cp_stats_vdev_init_fail1:
128 	wlan_objmgr_unregister_pdev_destroy_handler
129 		(WLAN_UMAC_COMP_CP_STATS,
130 		 wlan_cp_stats_pdev_obj_destroy_handler,
131 		 NULL);
132 wlan_cp_stats_pdev_init_fail2:
133 	wlan_objmgr_unregister_pdev_create_handler
134 		(WLAN_UMAC_COMP_CP_STATS,
135 		 wlan_cp_stats_pdev_obj_create_handler,
136 		 NULL);
137 wlan_cp_stats_pdev_init_fail1:
138 	wlan_objmgr_unregister_psoc_destroy_handler
139 		(WLAN_UMAC_COMP_CP_STATS,
140 		 wlan_cp_stats_psoc_obj_destroy_handler,
141 		 NULL);
142 wlan_cp_stats_psoc_init_fail2:
143 	wlan_objmgr_unregister_psoc_create_handler
144 		(WLAN_UMAC_COMP_CP_STATS,
145 		 wlan_cp_stats_psoc_obj_create_handler,
146 		 NULL);
147 wlan_cp_stats_psoc_init_fail1:
148 	return status;
149 }
150 
wlan_cp_stats_deinit(void)151 QDF_STATUS wlan_cp_stats_deinit(void)
152 {
153 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
154 
155 	status = wlan_objmgr_unregister_psoc_create_handler
156 				(WLAN_UMAC_COMP_CP_STATS,
157 				 wlan_cp_stats_psoc_obj_create_handler,
158 				 NULL);
159 	if (QDF_IS_STATUS_ERROR(status))
160 		cp_stats_err("Failed to unregister psoc create handler");
161 
162 	status = wlan_objmgr_unregister_psoc_destroy_handler
163 				(WLAN_UMAC_COMP_CP_STATS,
164 				 wlan_cp_stats_psoc_obj_destroy_handler,
165 				 NULL);
166 	if (QDF_IS_STATUS_ERROR(status))
167 		cp_stats_err("Failed to unregister psoc destroy handler");
168 
169 	status = wlan_objmgr_unregister_pdev_create_handler
170 				(WLAN_UMAC_COMP_CP_STATS,
171 				 wlan_cp_stats_pdev_obj_create_handler,
172 				 NULL);
173 	if (QDF_IS_STATUS_ERROR(status))
174 		cp_stats_err("Failed to unregister pdev create handler");
175 
176 	status = wlan_objmgr_unregister_pdev_destroy_handler
177 				(WLAN_UMAC_COMP_CP_STATS,
178 				 wlan_cp_stats_pdev_obj_destroy_handler,
179 				 NULL);
180 	if (QDF_IS_STATUS_ERROR(status))
181 		cp_stats_err("Failed to unregister pdev destroy handler");
182 
183 	status = wlan_objmgr_unregister_vdev_create_handler
184 				(WLAN_UMAC_COMP_CP_STATS,
185 				 wlan_cp_stats_vdev_obj_create_handler,
186 				 NULL);
187 	if (QDF_IS_STATUS_ERROR(status))
188 		cp_stats_err("Failed to unregister vdev create handler");
189 
190 	status = wlan_objmgr_unregister_vdev_destroy_handler
191 				(WLAN_UMAC_COMP_CP_STATS,
192 				 wlan_cp_stats_vdev_obj_destroy_handler,
193 				 NULL);
194 	if (QDF_IS_STATUS_ERROR(status))
195 		cp_stats_err("Failed to unregister vdev destroy handler");
196 
197 	status = wlan_objmgr_unregister_peer_create_handler
198 				(WLAN_UMAC_COMP_CP_STATS,
199 				 wlan_cp_stats_peer_obj_create_handler,
200 				 NULL);
201 	if (QDF_IS_STATUS_ERROR(status))
202 		cp_stats_err("Failed to unregister peer create handler");
203 
204 	status = wlan_objmgr_unregister_peer_destroy_handler
205 				(WLAN_UMAC_COMP_CP_STATS,
206 				 wlan_cp_stats_peer_obj_destroy_handler,
207 				 NULL);
208 	if (QDF_IS_STATUS_ERROR(status))
209 		cp_stats_err("Failed to unregister peer destroy handler");
210 
211 	return status;
212 }
213 
214 /* DA/OL specific call back initialization */
wlan_cp_stats_open(struct wlan_objmgr_psoc * psoc)215 QDF_STATUS wlan_cp_stats_open(struct wlan_objmgr_psoc *psoc)
216 {
217 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
218 	struct cp_stats_context *csc;
219 
220 	if (!psoc) {
221 		cp_stats_err("PSOC is null!");
222 		return QDF_STATUS_E_INVAL;
223 	}
224 	csc =
225 	wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_CP_STATS);
226 	if (!csc) {
227 		cp_stats_err("cp_stats_context is null!");
228 		return QDF_STATUS_E_FAILURE;
229 	}
230 
231 	if (csc->cp_stats_open)
232 		status = csc->cp_stats_open(psoc);
233 
234 	qdf_spinlock_create(&csc->csc_lock);
235 	return status;
236 }
237 
wlan_cp_stats_close(struct wlan_objmgr_psoc * psoc)238 QDF_STATUS wlan_cp_stats_close(struct wlan_objmgr_psoc *psoc)
239 {
240 	struct cp_stats_context *csc;
241 
242 	if (!psoc) {
243 		cp_stats_err("PSOC is null!");
244 		return QDF_STATUS_E_INVAL;
245 	}
246 	csc =
247 	wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_CP_STATS);
248 	if (csc && csc->cp_stats_close) {
249 		csc->cp_stats_close(psoc);
250 		qdf_spinlock_destroy(&csc->csc_lock);
251 	}
252 
253 	return QDF_STATUS_SUCCESS;
254 }
255 
256 /* WMI registrations stage */
wlan_cp_stats_enable(struct wlan_objmgr_psoc * psoc)257 QDF_STATUS wlan_cp_stats_enable(struct wlan_objmgr_psoc *psoc)
258 {
259 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
260 	struct cp_stats_context *csc;
261 
262 	if (!psoc) {
263 		cp_stats_err("PSOC is null!");
264 		return QDF_STATUS_E_INVAL;
265 	}
266 	csc =
267 	wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_CP_STATS);
268 	if (!csc) {
269 		cp_stats_err("cp_stats_context is null!");
270 		return QDF_STATUS_E_FAILURE;
271 	}
272 
273 	if (csc->cp_stats_enable)
274 		status = csc->cp_stats_enable(psoc);
275 
276 	return status;
277 }
278 
wlan_cp_stats_disable(struct wlan_objmgr_psoc * psoc)279 QDF_STATUS wlan_cp_stats_disable(struct wlan_objmgr_psoc *psoc)
280 {
281 	struct cp_stats_context *csc;
282 
283 	if (!psoc) {
284 		cp_stats_err("PSOC is null!\n");
285 		return QDF_STATUS_E_INVAL;
286 	}
287 	csc =
288 	wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_CP_STATS);
289 	if (csc && csc->cp_stats_disable)
290 		csc->cp_stats_disable(psoc);
291 
292 	return QDF_STATUS_SUCCESS;
293 }
294 
295 QDF_STATUS
wlan_cp_stats_comp_obj_cfg(enum wlan_objmgr_obj_type obj_type,enum wlan_cp_stats_cfg_state cfg_state,enum wlan_umac_comp_id comp_id,void * cmn_obj,void * data)296 wlan_cp_stats_comp_obj_cfg(enum wlan_objmgr_obj_type obj_type,
297 			   enum wlan_cp_stats_cfg_state cfg_state,
298 			   enum wlan_umac_comp_id comp_id,
299 			   void *cmn_obj, void *data)
300 {
301 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
302 	struct cp_stats_context *csc;
303 	struct wlan_objmgr_psoc *psoc;
304 	struct wlan_objmgr_pdev *pdev;
305 	struct wlan_objmgr_vdev *vdev;
306 	struct wlan_objmgr_peer *peer;
307 	enum wlan_cp_stats_comp_id cp_stats_comp_id;
308 
309 	if (!cmn_obj) {
310 		cp_stats_err("common object is null!");
311 		return QDF_STATUS_E_INVAL;
312 	}
313 
314 	cp_stats_comp_id = wlan_cp_stats_get_comp_id(comp_id);
315 	if (cp_stats_comp_id >= WLAN_CP_STATS_MAX_COMPONENTS) {
316 		cp_stats_err("Invalid UMAC id provided to cp_stats");
317 		return QDF_STATUS_E_INVAL;
318 	}
319 
320 	switch (obj_type) {
321 	case WLAN_PSOC_OP:
322 		psoc = (struct wlan_objmgr_psoc *)cmn_obj;
323 		csc =
324 		wlan_objmgr_psoc_get_comp_private_obj
325 				(psoc, WLAN_UMAC_COMP_CP_STATS);
326 		break;
327 	case WLAN_PDEV_OP:
328 		pdev = (struct wlan_objmgr_pdev *)cmn_obj;
329 		csc = wlan_cp_stats_ctx_get_from_pdev(pdev);
330 		break;
331 	case WLAN_VDEV_OP:
332 		vdev = (struct wlan_objmgr_vdev *)cmn_obj;
333 		csc = wlan_cp_stats_ctx_get_from_vdev(vdev);
334 		break;
335 	case WLAN_PEER_OP:
336 		peer = (struct wlan_objmgr_peer *)cmn_obj;
337 		csc = wlan_cp_stats_ctx_get_from_peer(peer);
338 		break;
339 	default:
340 		cp_stats_err("Invalid common object type");
341 		return QDF_STATUS_E_INVAL;
342 	}
343 
344 	if (!csc) {
345 		cp_stats_err("cp_stats_context is null!");
346 		return QDF_STATUS_E_FAILURE;
347 	}
348 
349 	if (csc->cp_stats_comp_obj_config)
350 		status = csc->cp_stats_comp_obj_config(obj_type, cfg_state,
351 							cp_stats_comp_id,
352 							cmn_obj, data);
353 
354 	return status;
355 }
356 
wlan_cp_stats_vdev_mcast_rx_pnerr(struct wlan_objmgr_vdev * vdev)357 void wlan_cp_stats_vdev_mcast_rx_pnerr(struct wlan_objmgr_vdev *vdev)
358 {
359 	struct vdev_cp_stats *vdev_cs = wlan_cp_stats_get_vdev_stats_obj(vdev);
360 
361 	if (vdev_cs && vdev_cs->mcast_rx_pnerr_stats_inc)
362 		vdev_cs->mcast_rx_pnerr_stats_inc(vdev, 1);
363 }
364 
wlan_cp_stats_peer_rx_pnerr(struct wlan_objmgr_peer * peer)365 void wlan_cp_stats_peer_rx_pnerr(struct wlan_objmgr_peer *peer)
366 {
367 	struct peer_cp_stats *peer_cs = wlan_cp_stats_get_peer_stats_obj(peer);
368 
369 	if (peer_cs && peer_cs->rx_pnerr_stats_inc)
370 		peer_cs->rx_pnerr_stats_inc(peer, 1);
371 }
372 
373 #if defined(WLAN_SUPPORT_TWT) && defined(WLAN_TWT_CONV_SUPPORTED)
374 QDF_STATUS
tgt_cp_stats_twt_get_session_evt_handler(struct wlan_objmgr_psoc * psoc,struct twt_session_stats_info * twt_params)375 tgt_cp_stats_twt_get_session_evt_handler(
376 				struct wlan_objmgr_psoc *psoc,
377 				struct twt_session_stats_info *twt_params)
378 {
379 	return wlan_cp_stats_twt_get_session_evt_handler(psoc, twt_params);
380 }
381 #endif
382