xref: /wlan-dirver/qca-wifi-host-cmn/umac/cp_stats/core/src/wlan_cp_stats_obj_mgr_handler.c (revision 2f4b444fb7e689b83a4ab0e7b3b38f0bf4def8e0)
1 /*
2  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /**
20  * Doc: wlan_cp_stats_om_handler.c
21  *
22  * This file provide definitions to APIs invoked on receiving common object
23  * repective create/destroy event notifications, which further
24  * (de)allocate cp specific objects and (de)attach to specific
25  * common object
26  */
27 #include "wlan_cp_stats_obj_mgr_handler.h"
28 #include "wlan_cp_stats_defs.h"
29 #include "wlan_cp_stats_ol_api.h"
30 #include <wlan_cp_stats_ucfg_api.h>
31 #include "wlan_cp_stats_utils_api.h"
32 #include <target_if_cp_stats.h>
33 
34 QDF_STATUS
35 wlan_cp_stats_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc, void *arg)
36 {
37 	WLAN_DEV_TYPE dev_type;
38 	struct cp_stats_context *csc = NULL;
39 	struct psoc_cp_stats *psoc_cs = NULL;
40 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
41 
42 	if (!psoc) {
43 		cp_stats_err("PSOC is NULL");
44 		status = QDF_STATUS_E_INVAL;
45 		goto wlan_cp_stats_psoc_obj_create_handler_return;
46 	}
47 
48 	csc = qdf_mem_malloc(sizeof(*csc));
49 	if (!csc) {
50 		status = QDF_STATUS_E_NOMEM;
51 		goto wlan_cp_stats_psoc_obj_create_handler_return;
52 	}
53 
54 	csc->psoc_obj = psoc;
55 	dev_type = wlan_objmgr_psoc_get_dev_type(csc->psoc_obj);
56 	if (dev_type == WLAN_DEV_INVALID) {
57 		cp_stats_err("Failed to init cp stats ctx, bad device type");
58 		status = QDF_STATUS_E_INVAL;
59 		goto wlan_cp_stats_psoc_obj_create_handler_return;
60 	} else if (WLAN_DEV_OL == dev_type) {
61 		csc->cp_stats_ctx_init = wlan_cp_stats_ctx_init_ol;
62 		csc->cp_stats_ctx_deinit = wlan_cp_stats_ctx_deinit_ol;
63 	}
64 
65 	if (QDF_STATUS_SUCCESS != csc->cp_stats_ctx_init(csc)) {
66 		cp_stats_err("Failed to init global ctx call back handlers");
67 		goto wlan_cp_stats_psoc_obj_create_handler_return;
68 	}
69 
70 	psoc_cs = qdf_mem_malloc(sizeof(*psoc_cs));
71 	if (!psoc_cs) {
72 		status = QDF_STATUS_E_NOMEM;
73 		goto wlan_cp_stats_psoc_obj_create_handler_return;
74 	}
75 
76 	psoc_cs->psoc_obj = psoc;
77 	csc->psoc_cs = psoc_cs;
78 	if (csc->cp_stats_psoc_obj_init) {
79 		if (QDF_STATUS_SUCCESS !=
80 				csc->cp_stats_psoc_obj_init(psoc_cs)) {
81 			cp_stats_err("Failed to initialize psoc handlers");
82 			goto wlan_cp_stats_psoc_obj_create_handler_return;
83 		}
84 	}
85 
86 	status = wlan_objmgr_psoc_component_obj_attach(psoc,
87 						       WLAN_UMAC_COMP_CP_STATS,
88 						       csc,
89 						       QDF_STATUS_SUCCESS);
90 
91 wlan_cp_stats_psoc_obj_create_handler_return:
92 	if (QDF_IS_STATUS_ERROR(status)) {
93 		if (csc) {
94 			if (csc->cp_stats_psoc_obj_deinit && psoc_cs)
95 				csc->cp_stats_psoc_obj_deinit(psoc_cs);
96 
97 			if (csc->psoc_cs) {
98 				qdf_mem_free(csc->psoc_cs);
99 				csc->psoc_cs = NULL;
100 			}
101 
102 			if (csc->cp_stats_ctx_deinit)
103 				csc->cp_stats_ctx_deinit(csc);
104 
105 			qdf_mem_free(csc);
106 			csc = NULL;
107 		}
108 		return status;
109 	}
110 
111 	cp_stats_debug("cp stats context attach at psoc");
112 	return status;
113 }
114 
115 QDF_STATUS
116 wlan_cp_stats_psoc_obj_destroy_handler(struct wlan_objmgr_psoc *psoc, void *arg)
117 {
118 	struct cp_stats_context *csc;
119 
120 	if (!psoc) {
121 		cp_stats_err("PSOC is NULL");
122 		return QDF_STATUS_E_NOMEM;
123 	}
124 	csc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
125 						    WLAN_UMAC_COMP_CP_STATS);
126 	if (!csc) {
127 		cp_stats_err("cp_stats context is NULL!");
128 		return QDF_STATUS_E_INVAL;
129 	}
130 
131 	wlan_objmgr_psoc_component_obj_detach(psoc,
132 					      WLAN_UMAC_COMP_CP_STATS, csc);
133 	if (csc->cp_stats_psoc_obj_deinit)
134 		csc->cp_stats_psoc_obj_deinit(csc->psoc_cs);
135 	qdf_mem_free(csc->psoc_cs);
136 	if (csc->cp_stats_ctx_deinit)
137 		csc->cp_stats_ctx_deinit(csc);
138 	qdf_mem_free(csc);
139 
140 	cp_stats_debug("cp stats context dettached at psoc");
141 	return QDF_STATUS_SUCCESS;
142 }
143 
144 QDF_STATUS
145 wlan_cp_stats_pdev_obj_create_handler(struct wlan_objmgr_pdev *pdev, void *arg)
146 {
147 	struct cp_stats_context *csc = NULL;
148 	struct pdev_cp_stats *pdev_cs = NULL;
149 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
150 
151 	if (!pdev) {
152 		cp_stats_err("PDEV is NULL");
153 		status = QDF_STATUS_E_INVAL;
154 		goto wlan_cp_stats_pdev_obj_create_handler_return;
155 	}
156 
157 	pdev_cs = qdf_mem_malloc(sizeof(*pdev_cs));
158 	if (!pdev_cs) {
159 		status = QDF_STATUS_E_NOMEM;
160 		goto wlan_cp_stats_pdev_obj_create_handler_return;
161 	}
162 	csc = wlan_cp_stats_ctx_get_from_pdev(pdev);
163 	if (!csc) {
164 		cp_stats_err("cp_stats context is NULL!");
165 		status = QDF_STATUS_E_INVAL;
166 		goto wlan_cp_stats_pdev_obj_create_handler_return;
167 	}
168 	pdev_cs->pdev_obj = pdev;
169 	if (csc->cp_stats_pdev_obj_init) {
170 		if (QDF_STATUS_SUCCESS !=
171 				csc->cp_stats_pdev_obj_init(pdev_cs)) {
172 			cp_stats_err("Failed to initialize pdev handlers");
173 			goto wlan_cp_stats_pdev_obj_create_handler_return;
174 		}
175 	}
176 
177 	status = wlan_objmgr_pdev_component_obj_attach(pdev,
178 						       WLAN_UMAC_COMP_CP_STATS,
179 						       pdev_cs,
180 						       QDF_STATUS_SUCCESS);
181 
182 	cp_stats_debug("pdev cp stats object attached");
183 wlan_cp_stats_pdev_obj_create_handler_return:
184 	if (QDF_IS_STATUS_ERROR(status)) {
185 		if (csc) {
186 			if (csc->cp_stats_pdev_obj_deinit)
187 				csc->cp_stats_pdev_obj_deinit(pdev_cs);
188 		}
189 
190 		if (pdev_cs)
191 			qdf_mem_free(pdev_cs);
192 	}
193 
194 	return status;
195 }
196 
197 QDF_STATUS
198 wlan_cp_stats_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev, void *arg)
199 {
200 	struct pdev_cp_stats *pdev_cs;
201 	struct cp_stats_context *csc;
202 
203 	if (!pdev) {
204 		cp_stats_err("pdev is NULL");
205 		return QDF_STATUS_E_INVAL;
206 	}
207 
208 	pdev_cs = wlan_objmgr_pdev_get_comp_private_obj(pdev,
209 						WLAN_UMAC_COMP_CP_STATS);
210 	if (!pdev_cs) {
211 		cp_stats_err("pdev is NULL");
212 		return QDF_STATUS_E_INVAL;
213 	}
214 	csc = wlan_cp_stats_ctx_get_from_pdev(pdev);
215 	if (!csc) {
216 		cp_stats_err("cp_stats context is NULL!");
217 		return QDF_STATUS_E_INVAL;
218 	}
219 
220 	if (csc->cp_stats_pdev_obj_deinit)
221 		csc->cp_stats_pdev_obj_deinit(pdev_cs);
222 
223 	wlan_objmgr_pdev_component_obj_detach(pdev, WLAN_UMAC_COMP_CP_STATS,
224 					      pdev_cs);
225 
226 	qdf_mem_free(pdev_cs);
227 	cp_stats_debug("pdev cp stats object dettached");
228 	return QDF_STATUS_SUCCESS;
229 }
230 
231 QDF_STATUS
232 wlan_cp_stats_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, void *arg)
233 {
234 	struct cp_stats_context *csc = NULL;
235 	struct vdev_cp_stats *vdev_cs = NULL;
236 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
237 
238 	if (!vdev) {
239 		cp_stats_err("vdev is NULL");
240 		status = QDF_STATUS_E_INVAL;
241 		goto wlan_cp_stats_vdev_obj_create_handler_return;
242 	}
243 
244 	vdev_cs = qdf_mem_malloc(sizeof(*vdev_cs));
245 	if (!vdev_cs) {
246 		status = QDF_STATUS_E_NOMEM;
247 		goto wlan_cp_stats_vdev_obj_create_handler_return;
248 	}
249 	csc = wlan_cp_stats_ctx_get_from_vdev(vdev);
250 	if (!csc) {
251 		cp_stats_err("cp_stats context is NULL!");
252 		status = QDF_STATUS_E_INVAL;
253 		goto wlan_cp_stats_vdev_obj_create_handler_return;
254 	}
255 	vdev_cs->vdev_obj = vdev;
256 	if (csc->cp_stats_vdev_obj_init) {
257 		if (QDF_STATUS_SUCCESS !=
258 				csc->cp_stats_vdev_obj_init(vdev_cs)) {
259 			cp_stats_err("Failed to initialize vdev handlers");
260 			goto wlan_cp_stats_vdev_obj_create_handler_return;
261 		}
262 	}
263 
264 	status = wlan_objmgr_vdev_component_obj_attach(vdev,
265 						       WLAN_UMAC_COMP_CP_STATS,
266 						       vdev_cs,
267 						       QDF_STATUS_SUCCESS);
268 
269 wlan_cp_stats_vdev_obj_create_handler_return:
270 	if (QDF_IS_STATUS_ERROR(status)) {
271 		if (csc) {
272 			if (csc->cp_stats_vdev_obj_deinit)
273 				csc->cp_stats_vdev_obj_deinit(vdev_cs);
274 		}
275 
276 		if (vdev_cs)
277 			qdf_mem_free(vdev_cs);
278 	}
279 
280 	cp_stats_debug("vdev cp stats object attach");
281 	return status;
282 }
283 
284 QDF_STATUS
285 wlan_cp_stats_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev, void *arg)
286 {
287 	struct vdev_cp_stats *vdev_cs;
288 	struct cp_stats_context *csc;
289 
290 	if (!vdev) {
291 		cp_stats_err("vdev is NULL");
292 		return QDF_STATUS_E_INVAL;
293 	}
294 
295 	vdev_cs = wlan_objmgr_vdev_get_comp_private_obj(vdev,
296 						WLAN_UMAC_COMP_CP_STATS);
297 	if (!vdev_cs) {
298 		cp_stats_err("vdev is NULL");
299 		return QDF_STATUS_E_INVAL;
300 	}
301 	csc = wlan_cp_stats_ctx_get_from_vdev(vdev);
302 	if (!csc) {
303 		cp_stats_err("cp_stats context is NULL!");
304 		return QDF_STATUS_E_INVAL;
305 	}
306 
307 	if (csc->cp_stats_vdev_obj_deinit)
308 		csc->cp_stats_vdev_obj_deinit(vdev_cs);
309 
310 	wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_CP_STATS,
311 					      vdev_cs);
312 
313 	qdf_mem_free(vdev_cs);
314 	cp_stats_debug("vdev cp stats object dettach");
315 	return QDF_STATUS_SUCCESS;
316 }
317 
318 QDF_STATUS
319 wlan_cp_stats_peer_obj_create_handler(struct wlan_objmgr_peer *peer, void *arg)
320 {
321 	struct cp_stats_context *csc = NULL;
322 	struct peer_cp_stats *peer_cs = NULL;
323 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
324 
325 	if (!peer) {
326 		cp_stats_err("peer is NULL");
327 		status = QDF_STATUS_E_INVAL;
328 		goto wlan_cp_stats_peer_obj_create_handler_return;
329 	}
330 
331 	peer_cs = qdf_mem_malloc(sizeof(*peer_cs));
332 	if (!peer_cs) {
333 		status = QDF_STATUS_E_NOMEM;
334 		goto wlan_cp_stats_peer_obj_create_handler_return;
335 	}
336 	csc = wlan_cp_stats_ctx_get_from_peer(peer);
337 	if (!csc) {
338 		cp_stats_err("cp_stats context is NULL!");
339 		status = QDF_STATUS_E_INVAL;
340 		goto wlan_cp_stats_peer_obj_create_handler_return;
341 	}
342 	peer_cs->peer_obj = peer;
343 	if (csc->cp_stats_peer_obj_init) {
344 		if (QDF_STATUS_SUCCESS !=
345 				csc->cp_stats_peer_obj_init(peer_cs)) {
346 			cp_stats_err("Failed to initialize peer handlers");
347 			goto wlan_cp_stats_peer_obj_create_handler_return;
348 		}
349 	}
350 
351 	status = wlan_objmgr_peer_component_obj_attach(peer,
352 						       WLAN_UMAC_COMP_CP_STATS,
353 						       peer_cs,
354 						       QDF_STATUS_SUCCESS);
355 
356 wlan_cp_stats_peer_obj_create_handler_return:
357 	if (QDF_IS_STATUS_ERROR(status)) {
358 		if (csc) {
359 			if (csc->cp_stats_peer_obj_deinit)
360 				csc->cp_stats_peer_obj_deinit(peer_cs);
361 		}
362 
363 		if (peer_cs)
364 			qdf_mem_free(peer_cs);
365 	}
366 
367 	cp_stats_debug("peer cp stats object attach");
368 	return status;
369 }
370 
371 QDF_STATUS
372 wlan_cp_stats_peer_obj_destroy_handler(struct wlan_objmgr_peer *peer, void *arg)
373 {
374 	struct peer_cp_stats *peer_cs;
375 	struct cp_stats_context *csc;
376 
377 	if (!peer) {
378 		cp_stats_err("peer is NULL");
379 		return QDF_STATUS_E_INVAL;
380 	}
381 
382 	peer_cs = wlan_objmgr_peer_get_comp_private_obj(peer,
383 						WLAN_UMAC_COMP_CP_STATS);
384 	if (!peer_cs) {
385 		cp_stats_err("peer is NULL");
386 		return QDF_STATUS_E_INVAL;
387 	}
388 	csc = wlan_cp_stats_ctx_get_from_peer(peer);
389 	if (!csc) {
390 		cp_stats_err("cp_stats context is NULL!");
391 		return QDF_STATUS_E_INVAL;
392 	}
393 
394 	if (csc->cp_stats_peer_obj_deinit)
395 		csc->cp_stats_peer_obj_deinit(peer_cs);
396 
397 	wlan_objmgr_peer_component_obj_detach(peer, WLAN_UMAC_COMP_CP_STATS,
398 					      peer_cs);
399 
400 	qdf_mem_free(peer_cs);
401 	cp_stats_debug("peer cp stats object dettached");
402 	return QDF_STATUS_SUCCESS;
403 }
404 
405 #ifdef WLAN_SUPPORT_INFRA_CTRL_PATH_STATS
406 QDF_STATUS
407 wlan_cp_stats_infra_cp_register_resp_cb(struct wlan_objmgr_psoc *psoc,
408 					struct infra_cp_stats_cmd_info *req)
409 {
410 	struct psoc_cp_stats *psoc_cp_stats_priv;
411 
412 	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
413 	if (!psoc_cp_stats_priv) {
414 		cp_stats_err("psoc cp stats object is null");
415 		return QDF_STATUS_E_NULL_VALUE;
416 	}
417 
418 	wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv);
419 	psoc_cp_stats_priv->get_infra_cp_stats = req->infra_cp_stats_resp_cb;
420 	psoc_cp_stats_priv->infra_cp_stats_req_context = req->request_cookie;
421 	wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv);
422 
423 	return QDF_STATUS_SUCCESS;
424 }
425 
426 QDF_STATUS
427 wlan_cp_stats_infra_cp_get_context(struct wlan_objmgr_psoc *psoc,
428 				   get_infra_cp_stats_cb *resp_cb,
429 				   void **context)
430 {
431 	struct psoc_cp_stats *psoc_cp_stats_priv;
432 
433 	psoc_cp_stats_priv = wlan_cp_stats_get_psoc_stats_obj(psoc);
434 	if (!psoc_cp_stats_priv) {
435 		cp_stats_err("psoc cp stats object is null");
436 		return QDF_STATUS_E_NULL_VALUE;
437 	}
438 
439 	wlan_cp_stats_psoc_obj_lock(psoc_cp_stats_priv);
440 	*resp_cb = psoc_cp_stats_priv->get_infra_cp_stats;
441 	*context = psoc_cp_stats_priv->infra_cp_stats_req_context;
442 	wlan_cp_stats_psoc_obj_unlock(psoc_cp_stats_priv);
443 
444 	return QDF_STATUS_SUCCESS;
445 }
446 
447 QDF_STATUS
448 wlan_cp_stats_send_infra_cp_req(struct wlan_objmgr_psoc *psoc,
449 				struct infra_cp_stats_cmd_info *req)
450 {
451 	struct wlan_lmac_if_cp_stats_tx_ops *tx_ops;
452 
453 	tx_ops = target_if_cp_stats_get_tx_ops(psoc);
454 	if (!tx_ops) {
455 		cp_stats_err("could not get tx_ops");
456 		return QDF_STATUS_E_NULL_VALUE;
457 	}
458 
459 	if (!tx_ops->send_req_infra_cp_stats) {
460 		cp_stats_err("could not get send_req_infra_twt_stats");
461 		return QDF_STATUS_E_NULL_VALUE;
462 	}
463 	return tx_ops->send_req_infra_cp_stats(psoc, req);
464 }
465 #endif /* WLAN_SUPPORT_INFRA_CTRL_PATH_STATS */
466 
467