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