xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_main.c (revision 45a38684b07295822dc8eba39e293408f203eec8)
1 /*
2  * Copyright (c) 2017-2020 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_serialization_main.c
21  * This file defines the important functions pertinent to
22  * serialization to initialize and de-initialize the
23  * component.
24  */
25 #include <qdf_status.h>
26 #include <qdf_list.h>
27 #include <wlan_objmgr_cmn.h>
28 #include <wlan_objmgr_global_obj.h>
29 #include <wlan_objmgr_psoc_obj.h>
30 #include "wlan_serialization_main_i.h"
31 #include "wlan_serialization_rules_i.h"
32 #include "wlan_serialization_utils_i.h"
33 
34 QDF_STATUS wlan_serialization_psoc_disable(struct wlan_objmgr_psoc *psoc)
35 {
36 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
37 	struct wlan_ser_psoc_obj *ser_soc_obj =
38 		wlan_serialization_get_psoc_obj(psoc);
39 
40 	if (!ser_soc_obj) {
41 		ser_err("invalid ser_soc_obj");
42 		goto error;
43 	}
44 
45 	/*
46 	 * purge all serialization command if there are any pending to make
47 	 * sure memory and vdev ref are freed.
48 	 */
49 	wlan_serialization_purge_all_cmd(psoc);
50 	/* clean up all timers before exiting */
51 	status = wlan_serialization_cleanup_all_timers(ser_soc_obj);
52 	if (status != QDF_STATUS_SUCCESS)
53 		ser_err("ser cleanning up all timer failed");
54 
55 	/* Use lock to free to avoid any race where timer is still in use */
56 	wlan_serialization_acquire_lock(&ser_soc_obj->timer_lock);
57 	qdf_mem_free(ser_soc_obj->timers);
58 	ser_soc_obj->timers = NULL;
59 	ser_soc_obj->max_active_cmds = 0;
60 	wlan_serialization_release_lock(&ser_soc_obj->timer_lock);
61 error:
62 	return status;
63 }
64 
65 QDF_STATUS wlan_serialization_psoc_enable(struct wlan_objmgr_psoc *psoc)
66 {
67 	uint8_t pdev_count;
68 	struct wlan_ser_psoc_obj *ser_soc_obj =
69 		wlan_serialization_get_psoc_obj(psoc);
70 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
71 
72 	if (!ser_soc_obj) {
73 		ser_err("invalid ser_soc_obj");
74 		goto error;
75 	}
76 
77 	pdev_count = wlan_psoc_get_pdev_count(psoc);
78 	ser_soc_obj->max_active_cmds = WLAN_SER_MAX_ACTIVE_SCAN_CMDS +
79 					(pdev_count * WLAN_SER_MAX_VDEVS);
80 
81 	ser_debug("max_active_cmds %d", ser_soc_obj->max_active_cmds);
82 
83 	ser_soc_obj->timers =
84 		qdf_mem_malloc(sizeof(struct wlan_serialization_timer) *
85 				ser_soc_obj->max_active_cmds);
86 	if (!ser_soc_obj->timers) {
87 		status = QDF_STATUS_E_NOMEM;
88 		goto error;
89 	}
90 
91 	status = QDF_STATUS_SUCCESS;
92 
93 error:
94 	return status;
95 }
96 
97 /**
98  * wlan_serialization_psoc_create_handler() - PSOC obj create callback
99  * @psoc: PSOC object
100  * @arg_list: Variable argument list
101  *
102  * This callback is registered with object manager during initialization and
103  * when obj manager gets its turn to create the object, it would notify each
104  * component with the corresponding callback registered to inform the
105  * completion of the creation of the respective object.
106  *
107  * Return: QDF Status
108  */
109 static QDF_STATUS wlan_serialization_psoc_create_handler(
110 		struct wlan_objmgr_psoc *psoc, void *arg_list)
111 {
112 	struct wlan_ser_psoc_obj *soc_ser_obj;
113 	QDF_STATUS status = QDF_STATUS_E_NOMEM;
114 
115 	soc_ser_obj =
116 		qdf_mem_malloc(sizeof(*soc_ser_obj));
117 	if (!soc_ser_obj)
118 		goto error;
119 
120 	status = wlan_objmgr_psoc_component_obj_attach(
121 					psoc,
122 					WLAN_UMAC_COMP_SERIALIZATION,
123 					soc_ser_obj,
124 					QDF_STATUS_SUCCESS);
125 	if (QDF_IS_STATUS_ERROR(status)) {
126 		qdf_mem_free(soc_ser_obj);
127 		ser_err("Obj attach failed");
128 		goto error;
129 	}
130 	wlan_serialization_create_lock(&soc_ser_obj->timer_lock);
131 	ser_debug("ser psoc obj created");
132 	status = QDF_STATUS_SUCCESS;
133 
134 error:
135 	return status;
136 }
137 
138 /**
139  * wlan_serialization_destroy_cmd_pool() - Destroy the global cmd pool
140  * @ser_pdev_obj: Serialization private pdev object
141  *
142  * Return: None
143  */
144 static void wlan_serialization_destroy_cmd_pool(
145 		struct wlan_serialization_pdev_queue *pdev_queue)
146 {
147 	qdf_list_node_t *node = NULL;
148 	struct wlan_serialization_command_list *cmd_list;
149 
150 	ser_debug("Destroy cmd pool list %pK, size %d",
151 		  &pdev_queue->cmd_pool_list,
152 		  qdf_list_size(&pdev_queue->cmd_pool_list));
153 	while (!qdf_list_empty(&pdev_queue->cmd_pool_list)) {
154 		qdf_list_remove_front(&pdev_queue->cmd_pool_list,
155 				      &node);
156 		cmd_list = (struct wlan_serialization_command_list *)node;
157 		qdf_mem_free(cmd_list);
158 	}
159 
160 	qdf_list_destroy(&pdev_queue->cmd_pool_list);
161 
162 }
163 
164 /**
165  * wlan_serialization_create_cmd_pool() - Create the global cmd pool
166  * @pdev: PDEV Object
167  * @ser_pdev_obj: Serialization private pdev object
168  *
169  * Global command pool of memory is created here.
170  * It is safe to allocate memory individually for each command rather than
171  * requesting for a huge chunk of memory at once.
172  *
173  * The individual command nodes allocated above will keep moving between
174  * the active, pending and global pool lists dynamically, but all the
175  * memory will be freed during driver unload only.
176  *
177  * Return: QDF Status
178  */
179 static QDF_STATUS
180 wlan_serialization_create_cmd_pool(
181 		struct wlan_serialization_pdev_queue *pdev_queue,
182 		uint16_t cmd_pool_size)
183 {
184 	struct wlan_serialization_command_list *cmd_list_ptr;
185 	uint8_t i;
186 	QDF_STATUS status = QDF_STATUS_E_NOMEM;
187 
188 	qdf_list_create(&pdev_queue->cmd_pool_list, cmd_pool_size);
189 
190 	for (i = 0; i < cmd_pool_size; i++) {
191 		cmd_list_ptr = qdf_mem_malloc(sizeof(*cmd_list_ptr));
192 		if (!cmd_list_ptr) {
193 			wlan_serialization_destroy_cmd_pool(pdev_queue);
194 			goto error;
195 		}
196 
197 		qdf_mem_zero(cmd_list_ptr, sizeof(*cmd_list_ptr));
198 		qdf_list_insert_back(
199 				     &pdev_queue->cmd_pool_list,
200 				     &cmd_list_ptr->pdev_node);
201 		cmd_list_ptr->cmd_in_use = 0;
202 	}
203 
204 	ser_debug("Create cmd pool list %pK, size %d",
205 		  &pdev_queue->cmd_pool_list,
206 		  qdf_list_size(&pdev_queue->cmd_pool_list));
207 
208 	status = QDF_STATUS_SUCCESS;
209 
210 error:
211 	return status;
212 }
213 
214 /**
215  * wlan_serialization_pdev_create_handler() - PDEV obj create callback
216  * @pdev: PDEV object
217  * @arg_list: Variable argument list
218  *
219  * This callback is registered with object manager during initialization and
220  * when obj manager gets its turn to create the object, it would notify each
221  * component with the corresponding callback registered to inform the
222  * completion of the creation of the respective object.
223  *
224  * Return: QDF Status
225  */
226 static QDF_STATUS wlan_serialization_pdev_create_handler(
227 		struct wlan_objmgr_pdev *pdev, void *arg_list)
228 {
229 	struct wlan_ser_pdev_obj *ser_pdev_obj;
230 	struct wlan_serialization_pdev_queue *pdev_queue;
231 	QDF_STATUS status = QDF_STATUS_E_NOMEM;
232 	uint8_t index;
233 	uint8_t free_index;
234 	uint8_t max_active_cmds;
235 	uint8_t max_pending_cmds;
236 	uint16_t cmd_pool_size;
237 
238 	ser_pdev_obj =
239 		qdf_mem_malloc(sizeof(*ser_pdev_obj));
240 	if (!ser_pdev_obj)
241 		goto error;
242 
243 	for (index = 0; index < SER_PDEV_QUEUE_COMP_MAX; index++) {
244 		pdev_queue = &ser_pdev_obj->pdev_q[index];
245 
246 		wlan_serialization_create_lock(&pdev_queue->pdev_queue_lock);
247 
248 		switch (index) {
249 		case SER_PDEV_QUEUE_COMP_SCAN:
250 			max_active_cmds = WLAN_SER_MAX_ACTIVE_SCAN_CMDS;
251 			max_pending_cmds = WLAN_SER_MAX_PENDING_SCAN_CMDS;
252 			cmd_pool_size = max_active_cmds + max_pending_cmds;
253 			break;
254 
255 		case SER_PDEV_QUEUE_COMP_NON_SCAN:
256 			max_active_cmds = WLAN_SER_MAX_ACTIVE_CMDS;
257 			max_pending_cmds = WLAN_SER_MAX_PENDING_CMDS;
258 			cmd_pool_size = max_active_cmds + max_pending_cmds;
259 			ser_debug("max_active_cmds %d max_pending_cmds %d",
260 				  max_active_cmds, max_pending_cmds);
261 			break;
262 		}
263 		qdf_list_create(&pdev_queue->active_list,
264 				max_active_cmds);
265 		qdf_list_create(&pdev_queue->pending_list,
266 				max_pending_cmds);
267 
268 		status = wlan_serialization_create_cmd_pool(pdev_queue,
269 							    cmd_pool_size);
270 		if (status != QDF_STATUS_SUCCESS) {
271 			ser_err("Create cmd pool failed, status %d", status);
272 			goto error_free;
273 		}
274 
275 		qdf_mem_zero(pdev_queue->vdev_active_cmd_bitmap,
276 			     sizeof(pdev_queue->vdev_active_cmd_bitmap));
277 
278 		pdev_queue->blocking_cmd_active = 0;
279 		pdev_queue->blocking_cmd_waiting = 0;
280 	}
281 
282 	status = wlan_objmgr_pdev_component_obj_attach(
283 			pdev, WLAN_UMAC_COMP_SERIALIZATION,
284 			ser_pdev_obj, QDF_STATUS_SUCCESS);
285 
286 	if (status != QDF_STATUS_SUCCESS) {
287 		ser_err("Pdev obj attach failed, status %d", status);
288 		goto error_free;
289 	}
290 
291 	return QDF_STATUS_SUCCESS;
292 
293 error_free:
294 	for (free_index = 0; free_index <= index; free_index++) {
295 		pdev_queue = &ser_pdev_obj->pdev_q[free_index];
296 
297 		wlan_serialization_destroy_cmd_pool(pdev_queue);
298 		qdf_list_destroy(&pdev_queue->pending_list);
299 		qdf_list_destroy(&pdev_queue->active_list);
300 		wlan_serialization_destroy_lock(&pdev_queue->pdev_queue_lock);
301 	}
302 error:
303 	return status;
304 }
305 
306 /**
307  * wlan_serialization_psoc_destroy_handler() - PSOC obj delete callback
308  * @psoc: PSOC object
309  * @arg_list: Variable argument list
310  *
311  * This callback is registered with object manager during initialization and
312  * when obj manager gets its turn to delete the object, it would notify each
313  * component with the corresponding callback registered to inform the
314  * completion of the deletion of the respective object.
315  *
316  * Return: QDF Status
317  */
318 static QDF_STATUS
319 wlan_serialization_psoc_destroy_handler(struct wlan_objmgr_psoc *psoc,
320 					void *arg_list)
321 {
322 	QDF_STATUS status = QDF_STATUS_E_FAULT;
323 	struct wlan_ser_psoc_obj *ser_soc_obj =
324 		wlan_serialization_get_psoc_obj(psoc);
325 
326 	if (!ser_soc_obj) {
327 		ser_err("invalid ser_soc_obj");
328 		goto error;
329 	}
330 	status = wlan_objmgr_psoc_component_obj_detach(
331 			psoc, WLAN_UMAC_COMP_SERIALIZATION, ser_soc_obj);
332 	if (status != QDF_STATUS_SUCCESS)
333 		ser_err("ser psoc private obj detach failed");
334 
335 	wlan_serialization_destroy_lock(&ser_soc_obj->timer_lock);
336 	ser_debug("ser psoc obj deleted with status %d", status);
337 	qdf_mem_free(ser_soc_obj);
338 
339 error:
340 	return status;
341 }
342 
343 /**
344  * wlan_serialization_pdev_destroy_handler() - PDEV obj delete callback
345  * @pdev: PDEV object
346  * @arg_list: Variable argument list
347  *
348  * This callback is registered with object manager during initialization and
349  * when obj manager gets its turn to delete the object, it would notify each
350  * component with the corresponding callback registered to inform the
351  * completion of the deletion of the respective object.
352  *
353  * Return: QDF Status
354  */
355 static QDF_STATUS wlan_serialization_pdev_destroy_handler(
356 		struct wlan_objmgr_pdev *pdev, void *arg_list)
357 {
358 	QDF_STATUS status;
359 	struct wlan_serialization_pdev_queue *pdev_queue;
360 	struct wlan_ser_pdev_obj *ser_pdev_obj =
361 		wlan_serialization_get_pdev_obj(pdev);
362 	uint8_t index;
363 
364 	if (!ser_pdev_obj) {
365 		ser_err("ser_pdev_obj NULL");
366 		return QDF_STATUS_E_INVAL;
367 	}
368 	status = wlan_objmgr_pdev_component_obj_detach(
369 			pdev, WLAN_UMAC_COMP_SERIALIZATION, ser_pdev_obj);
370 
371 	for (index = 0; index < SER_PDEV_QUEUE_COMP_MAX; index++) {
372 		pdev_queue = &ser_pdev_obj->pdev_q[index];
373 
374 		wlan_serialization_destroy_pdev_list(pdev_queue);
375 		wlan_serialization_destroy_cmd_pool(pdev_queue);
376 
377 		wlan_serialization_destroy_lock(&pdev_queue->pdev_queue_lock);
378 	}
379 	qdf_mem_free(ser_pdev_obj);
380 
381 	return status;
382 }
383 
384 /**
385  * wlan_serialization_vdev_create_handler() - VDEV obj create callback
386  * @vdev: VDEV object
387  * @arg_list: Variable argument list
388  *
389  * This callback is registered with object manager during initialization and
390  * when obj manager gets its turn to create the object, it would notify each
391  * component with the corresponding callback registered to inform the
392  * completion of the creation of the respective object.
393  *
394  * Return: QDF Status
395  */
396 static QDF_STATUS
397 wlan_serialization_vdev_create_handler(struct wlan_objmgr_vdev *vdev,
398 				       void *arg_list)
399 {
400 	struct wlan_ser_vdev_obj *ser_vdev_obj;
401 	struct wlan_serialization_vdev_queue *vdev_q;
402 	QDF_STATUS status = QDF_STATUS_E_NOMEM;
403 	uint8_t index;
404 	uint8_t max_active_cmds;
405 	uint8_t max_pending_cmds;
406 
407 	ser_vdev_obj = qdf_mem_malloc(sizeof(*ser_vdev_obj));
408 	if (!ser_vdev_obj)
409 		goto error;
410 
411 	for (index = 0; index < SER_VDEV_QUEUE_COMP_MAX; index++) {
412 		vdev_q = &ser_vdev_obj->vdev_q[index];
413 
414 		switch (index) {
415 		case SER_VDEV_QUEUE_COMP_NON_SCAN:
416 			max_active_cmds = WLAN_SER_MAX_ACTIVE_CMDS /
417 				WLAN_SER_MAX_VDEVS;
418 			if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE ||
419 			    wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE)
420 				max_pending_cmds = WLAN_SER_MAX_PENDING_CMDS_AP;
421 			else
422 				max_pending_cmds =
423 						WLAN_SER_MAX_PENDING_CMDS_STA;
424 
425 			ser_debug("Vdev type %d max_pending_cmds %d",
426 				  wlan_vdev_mlme_get_opmode(vdev),
427 				  max_pending_cmds);
428 			break;
429 		}
430 
431 		qdf_list_create(&vdev_q->active_list,
432 				max_active_cmds);
433 		qdf_list_create(&vdev_q->pending_list,
434 				max_pending_cmds);
435 	}
436 
437 	status = wlan_objmgr_vdev_component_obj_attach(
438 			vdev, WLAN_UMAC_COMP_SERIALIZATION, ser_vdev_obj,
439 			QDF_STATUS_SUCCESS);
440 
441 	if (status != QDF_STATUS_SUCCESS) {
442 		for (index = 0; index < SER_VDEV_QUEUE_COMP_MAX; index++) {
443 			vdev_q = &ser_vdev_obj->vdev_q[index];
444 			qdf_list_destroy(&vdev_q->pending_list);
445 			qdf_list_destroy(&vdev_q->active_list);
446 		}
447 		qdf_mem_free(ser_vdev_obj);
448 		ser_err("serialization vdev obj attach failed");
449 	}
450 error:
451 	return status;
452 }
453 
454 /**
455  * wlan_serialization_vdev_destroy_handler() - vdev obj delete callback
456  * @vdev: VDEV object
457  * @arg_list: Variable argument list
458  *
459  * This callback is registered with object manager during initialization and
460  * when obj manager gets its turn to delete the object, it would notify each
461  * component with the corresponding callback registered to inform the
462  * completion of the deletion of the respective object.
463  *
464  * Return: QDF Status
465  */
466 static QDF_STATUS wlan_serialization_vdev_destroy_handler(
467 		struct wlan_objmgr_vdev *vdev, void *arg_list)
468 {
469 	QDF_STATUS status = QDF_STATUS_SUCCESS;
470 	struct wlan_serialization_vdev_queue *vdev_q;
471 	struct wlan_ser_vdev_obj *ser_vdev_obj =
472 		wlan_serialization_get_vdev_obj(vdev);
473 	uint8_t index;
474 
475 	if (!ser_vdev_obj) {
476 		ser_err("ser_vdev_obj NULL");
477 		return QDF_STATUS_E_INVAL;
478 	}
479 
480 	status = wlan_objmgr_vdev_component_obj_detach(
481 			vdev, WLAN_UMAC_COMP_SERIALIZATION, ser_vdev_obj);
482 
483 	/*Clean up serialization timers if any for this vdev*/
484 	wlan_serialization_cleanup_vdev_timers(vdev);
485 
486 	for (index = 0; index < SER_VDEV_QUEUE_COMP_MAX; index++) {
487 		vdev_q = &ser_vdev_obj->vdev_q[index];
488 		wlan_serialization_destroy_vdev_list(&vdev_q->pending_list);
489 		wlan_serialization_destroy_vdev_list(&vdev_q->active_list);
490 	}
491 
492 	qdf_mem_free(ser_vdev_obj);
493 
494 	return status;
495 }
496 
497 QDF_STATUS wlan_serialization_init(void)
498 {
499 	QDF_STATUS status = QDF_STATUS_SUCCESS;
500 
501 	status = wlan_objmgr_register_psoc_create_handler(
502 			WLAN_UMAC_COMP_SERIALIZATION,
503 			wlan_serialization_psoc_create_handler, NULL);
504 	if (status != QDF_STATUS_SUCCESS) {
505 		ser_err("Failed to reg soc ser obj create handler");
506 		goto err_psoc_create;
507 	}
508 
509 	status = wlan_objmgr_register_psoc_destroy_handler(
510 			WLAN_UMAC_COMP_SERIALIZATION,
511 			wlan_serialization_psoc_destroy_handler, NULL);
512 	if (status != QDF_STATUS_SUCCESS) {
513 		ser_err("Failed to reg soc ser obj delete handler");
514 		goto err_psoc_delete;
515 	}
516 
517 	status = wlan_objmgr_register_pdev_create_handler(
518 			WLAN_UMAC_COMP_SERIALIZATION,
519 			wlan_serialization_pdev_create_handler, NULL);
520 	if (status != QDF_STATUS_SUCCESS) {
521 		ser_err("Failed to reg pdev ser obj create handler");
522 		goto err_pdev_create;
523 	}
524 
525 	status = wlan_objmgr_register_pdev_destroy_handler(
526 			WLAN_UMAC_COMP_SERIALIZATION,
527 			wlan_serialization_pdev_destroy_handler, NULL);
528 	if (status != QDF_STATUS_SUCCESS) {
529 		ser_err("Failed to reg pdev ser obj delete handler");
530 		goto err_pdev_delete;
531 	}
532 
533 	status = wlan_objmgr_register_vdev_create_handler(
534 			WLAN_UMAC_COMP_SERIALIZATION,
535 			wlan_serialization_vdev_create_handler, NULL);
536 	if (status != QDF_STATUS_SUCCESS) {
537 		ser_err("Failed to reg vdev ser obj create handler");
538 		goto err_vdev_create;
539 	}
540 
541 	status = wlan_objmgr_register_vdev_destroy_handler(
542 			WLAN_UMAC_COMP_SERIALIZATION,
543 			wlan_serialization_vdev_destroy_handler, NULL);
544 	if (status != QDF_STATUS_SUCCESS) {
545 		ser_err("Failed to reg vdev ser obj delete handler");
546 		goto err_vdev_delete;
547 	}
548 
549 	status = QDF_STATUS_SUCCESS;
550 	goto exit;
551 
552 err_vdev_delete:
553 	wlan_objmgr_unregister_vdev_create_handler(
554 			WLAN_UMAC_COMP_SERIALIZATION,
555 			wlan_serialization_vdev_create_handler,
556 			NULL);
557 err_vdev_create:
558 	wlan_objmgr_unregister_pdev_destroy_handler(
559 			WLAN_UMAC_COMP_SERIALIZATION,
560 			wlan_serialization_pdev_destroy_handler,
561 			NULL);
562 err_pdev_delete:
563 	wlan_objmgr_unregister_pdev_create_handler(
564 			WLAN_UMAC_COMP_SERIALIZATION,
565 			wlan_serialization_pdev_create_handler,
566 			NULL);
567 err_pdev_create:
568 	wlan_objmgr_unregister_psoc_destroy_handler(
569 			WLAN_UMAC_COMP_SERIALIZATION,
570 			wlan_serialization_psoc_destroy_handler,
571 			NULL);
572 err_psoc_delete:
573 	wlan_objmgr_unregister_psoc_create_handler(
574 			WLAN_UMAC_COMP_SERIALIZATION,
575 			wlan_serialization_psoc_create_handler,
576 			NULL);
577 err_psoc_create:
578 exit:
579 	return status;
580 }
581 
582 QDF_STATUS wlan_serialization_deinit(void)
583 {
584 	QDF_STATUS status;
585 	QDF_STATUS ret_status = QDF_STATUS_SUCCESS;
586 
587 	status = wlan_objmgr_unregister_psoc_create_handler(
588 			WLAN_UMAC_COMP_SERIALIZATION,
589 			wlan_serialization_psoc_create_handler,
590 			NULL);
591 
592 	if (status != QDF_STATUS_SUCCESS) {
593 		ser_err("unreg fail for psoc ser obj create notf:%d", status);
594 		ret_status = QDF_STATUS_E_FAILURE;
595 	}
596 	status = wlan_objmgr_unregister_psoc_destroy_handler(
597 			WLAN_UMAC_COMP_SERIALIZATION,
598 			wlan_serialization_psoc_destroy_handler,
599 			NULL);
600 
601 	if (status != QDF_STATUS_SUCCESS) {
602 		ser_err("unreg fail for psoc ser obj destroy notf:%d", status);
603 		ret_status = QDF_STATUS_E_FAILURE;
604 	}
605 
606 	status = wlan_objmgr_unregister_pdev_create_handler(
607 			WLAN_UMAC_COMP_SERIALIZATION,
608 			wlan_serialization_pdev_create_handler,
609 			NULL);
610 	if (status != QDF_STATUS_SUCCESS) {
611 		ser_err("unreg fail for pdev ser obj create notf:%d", status);
612 		ret_status = QDF_STATUS_E_FAILURE;
613 	}
614 
615 	status = wlan_objmgr_unregister_pdev_destroy_handler(
616 			WLAN_UMAC_COMP_SERIALIZATION,
617 			wlan_serialization_pdev_destroy_handler,
618 			NULL);
619 
620 	if (status != QDF_STATUS_SUCCESS) {
621 		ser_err("unreg fail for pdev ser destroy notf:%d", status);
622 		ret_status = QDF_STATUS_E_FAILURE;
623 	}
624 
625 	ser_debug("deregistered callbacks with obj mgr successfully");
626 
627 	return ret_status;
628 }
629