xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_utils.c (revision 0626a4da6c07f30da06dd6747e8cc290a60371d8)
1 /*
2  * Copyright (c) 2017-2018 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  * DOC: wlan_serialization_utils.c
20  * This file defines the utility helper functions for serialization component.
21  */
22 
23 #ifdef CONFIG_SERIALIZATION_V1
24 #include "wlan_serialization_utils_i.h"
25 #include "wlan_serialization_main_i.h"
26 #include "wlan_serialization_api.h"
27 #include "wlan_objmgr_vdev_obj.h"
28 #include "wlan_objmgr_pdev_obj.h"
29 #include "qdf_mc_timer.h"
30 #include "wlan_utility.h"
31 #include "qdf_platform.h"
32 
33 QDF_STATUS
34 wlan_serialization_put_back_to_global_list(qdf_list_t *queue,
35 		struct wlan_serialization_pdev_priv_obj *ser_pdev_obj,
36 		struct wlan_serialization_command_list *cmd_list)
37 {
38 	QDF_STATUS status;
39 	uint32_t cmd_id, cmd_type;
40 
41 	if (!queue || !ser_pdev_obj || !cmd_list) {
42 		serialization_err("input parameters are invalid");
43 		return QDF_STATUS_E_FAILURE;
44 	}
45 	/*
46 	 * if the command is already removed in other context,
47 	 * then it will be marked as inactive with the same
48 	 * below code. So, test before proceeding.
49 	 */
50 	if (!qdf_atomic_test_and_clear_bit(CMD_IS_ACTIVE,
51 					   &cmd_list->cmd_in_use)) {
52 		serialization_debug("CMD is not active or being used");
53 		return QDF_STATUS_SUCCESS;
54 	}
55 	status = wlan_serialization_remove_node(queue, &cmd_list->node,
56 						ser_pdev_obj);
57 	if (QDF_STATUS_SUCCESS != status) {
58 		serialization_err("can't remove cmd from queue");
59 		/* assert to catch any leaks */
60 		QDF_ASSERT(0);
61 		return status;
62 	}
63 	cmd_id = cmd_list->cmd.cmd_id;
64 	cmd_type = cmd_list->cmd.cmd_type;
65 	qdf_mem_zero(&cmd_list->cmd, sizeof(struct wlan_serialization_command));
66 	status = wlan_serialization_insert_back(
67 			&ser_pdev_obj->global_cmd_pool_list,
68 			&cmd_list->node, ser_pdev_obj);
69 	qdf_atomic_clear_bit(CMD_MARKED_FOR_DELETE, &cmd_list->cmd_in_use);
70 	if (QDF_STATUS_SUCCESS != status) {
71 		serialization_err("can't put command back to global pool");
72 		QDF_ASSERT(0);
73 	}
74 	serialization_debug("cmd_id-%d, cmd_type-%d", cmd_id, cmd_type);
75 
76 	return status;
77 }
78 
79 struct wlan_objmgr_pdev*
80 wlan_serialization_get_pdev_from_cmd(struct wlan_serialization_command *cmd)
81 {
82 	struct wlan_objmgr_pdev *pdev = NULL;
83 
84 	if (!cmd) {
85 		serialization_err("invalid cmd");
86 		return pdev;
87 	}
88 	if (!cmd->vdev) {
89 		serialization_err("invalid cmd->vdev");
90 		return pdev;
91 	}
92 	pdev = wlan_vdev_get_pdev(cmd->vdev);
93 
94 	return pdev;
95 }
96 
97 QDF_STATUS wlan_serialization_get_cmd_from_queue(qdf_list_t *queue,
98 			qdf_list_node_t **nnode,
99 			struct wlan_serialization_pdev_priv_obj *ser_pdev_obj)
100 {
101 	QDF_STATUS status;
102 	qdf_list_node_t *pnode;
103 
104 	if (!queue || !ser_pdev_obj) {
105 		serialization_err("input parameters are invalid");
106 		return QDF_STATUS_E_FAILURE;
107 	}
108 
109 	pnode = *nnode;
110 	if (!pnode)
111 		status = wlan_serialization_peek_front(queue, nnode,
112 						       ser_pdev_obj);
113 	else
114 		status = wlan_serialization_peek_next(queue, pnode, nnode,
115 						      ser_pdev_obj);
116 
117 	if (status != QDF_STATUS_SUCCESS) {
118 		serialization_err("can't get next node from queue");
119 	}
120 
121 	return status;
122 }
123 
124 /**
125  * wlan_serialization_timer_destroy() - destroys the timer
126  * @ser_timer: pointer to particular timer
127  *
128  * This API destroys the memory allocated by timer and assigns cmd member of
129  * that timer structure to NULL
130  *
131  * Return: QDF_STATUS
132  */
133 static QDF_STATUS wlan_serialization_timer_destroy(
134 		struct wlan_serialization_timer *ser_timer)
135 {
136 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
137 
138 	if (!ser_timer || !ser_timer->cmd) {
139 		serialization_debug("Invalid ser_timer");
140 		return status;
141 	}
142 	status = qdf_mc_timer_destroy(&ser_timer->timer);
143 	if (!QDF_IS_STATUS_SUCCESS(status)) {
144 		serialization_err("Failed to destroy timer for cmd_id[%d]",
145 				ser_timer->cmd->cmd_id);
146 		QDF_ASSERT(0);
147 		return status;
148 	}
149 	ser_timer->cmd = NULL;
150 
151 	return status;
152 }
153 
154 static void wlan_serialization_non_scan_timeout_action(void)
155 {
156 	qdf_trigger_self_recovery();
157 }
158 
159 /**
160  * wlan_serialization_generic_timer_callback() - timer callback when timer fire
161  * @arg: argument that timer passes to this callback
162  *
163  * All the timers in serialization module calls this callback when they fire,
164  * and this API in turn calls command specific timeout callback and remove
165  * timed-out command from active queue and move any pending command to active
166  * queue of same cmd_type.
167  *
168  * Return: none
169  */
170 static void wlan_serialization_generic_timer_callback(void *arg)
171 {
172 	struct wlan_serialization_timer *timer = arg;
173 	struct wlan_serialization_command *cmd = timer->cmd;
174 	uint8_t vdev_id = WLAN_INVALID_VDEV_ID;
175 
176 	if (!cmd) {
177 		serialization_err("command not found");
178 		QDF_ASSERT(0);
179 		return;
180 	}
181 
182 	if (cmd->vdev)
183 		vdev_id = wlan_vdev_get_id(cmd->vdev);
184 
185 	serialization_err("active cmd timeout for cmd_type[%d] vdev_id[%d]",
186 			  cmd->cmd_type, vdev_id);
187 
188 	if (cmd->cmd_cb)
189 		cmd->cmd_cb(cmd, WLAN_SER_CB_ACTIVE_CMD_TIMEOUT);
190 
191 	if (cmd->cmd_type >= WLAN_SER_CMD_NONSCAN)
192 		wlan_serialization_non_scan_timeout_action();
193 	/*
194 	 * dequeue cmd API will cleanup and destroy the timer. If it fails to
195 	 * dequeue command then we have to destroy the timer. It will also call
196 	 * cmd callback with WLAN_SER_CB_RELEASE_MEM_CMD to free the memory.
197 	 */
198 	if (WLAN_SER_CMD_NOT_FOUND == wlan_serialization_dequeue_cmd(cmd, true))
199 		wlan_serialization_timer_destroy(timer);
200 	if (cmd->cmd_cb)
201 		cmd->cmd_cb(cmd, WLAN_SER_CB_RELEASE_MEM_CMD);
202 }
203 
204 /**
205  * wlan_serialization_stop_timer() - to stop particular timer
206  * @ser_timer: pointer to serialization timer
207  *
208  * This API stops the particular timer
209  *
210  * Return: QDF_STATUS
211  */
212 static QDF_STATUS
213 wlan_serialization_stop_timer(struct wlan_serialization_timer *ser_timer)
214 {
215 	QDF_TIMER_STATE state;
216 	QDF_STATUS status;
217 
218 	state = qdf_mc_timer_get_current_state(&ser_timer->timer);
219 	if (QDF_TIMER_STATE_RUNNING != state &&
220 			QDF_TIMER_STATE_STARTING != state) {
221 		serialization_debug("nothing to stop");
222 		wlan_serialization_timer_destroy(ser_timer);
223 		return QDF_STATUS_SUCCESS;
224 	}
225 	status = qdf_mc_timer_stop(&ser_timer->timer);
226 	if (!QDF_IS_STATUS_SUCCESS(status)) {
227 		serialization_err("Failed to stop timer");
228 		/* to catch the bug */
229 		QDF_ASSERT(0);
230 		return status;
231 	}
232 	wlan_serialization_timer_destroy(ser_timer);
233 	status = QDF_STATUS_SUCCESS;
234 
235 	return status;
236 }
237 
238 QDF_STATUS wlan_serialization_cleanup_all_timers(
239 			struct wlan_serialization_psoc_priv_obj *psoc_ser_obj)
240 {
241 	struct wlan_serialization_timer *ser_timer;
242 	QDF_STATUS status = QDF_STATUS_SUCCESS;
243 	uint32_t i = 0;
244 
245 	if (!psoc_ser_obj) {
246 		serialization_err("Invalid psoc_ser_obj");
247 		return QDF_STATUS_E_FAILURE;
248 	}
249 
250 	for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) {
251 		ser_timer = &psoc_ser_obj->timers[i];
252 		if (!ser_timer->cmd)
253 			continue;
254 		status = wlan_serialization_stop_timer(ser_timer);
255 		if (QDF_STATUS_SUCCESS != status) {
256 			/* lets not break the loop but report error */
257 			serialization_err("some error in stopping timer");
258 		}
259 	}
260 
261 	return status;
262 }
263 
264 QDF_STATUS
265 wlan_serialization_find_and_stop_timer(struct wlan_objmgr_psoc *psoc,
266 				       struct wlan_serialization_command *cmd)
267 {
268 	struct wlan_serialization_psoc_priv_obj *psoc_ser_obj;
269 	struct wlan_serialization_timer *ser_timer;
270 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
271 	int i = 0;
272 
273 	if (!psoc || !cmd) {
274 		serialization_err("invalid param");
275 		return status;
276 	}
277 
278 	if ((cmd->cmd_timeout_duration == 0) &&
279 		(wlan_is_emulation_platform(wlan_psoc_get_nif_phy_version(psoc)
280 	))) {
281 		serialization_err("[SCAN-EMULATION]: Not performing timer functions\n");
282 		return QDF_STATUS_SUCCESS;
283 	}
284 
285 	psoc_ser_obj = wlan_serialization_get_psoc_priv_obj(psoc);
286 	/*
287 	 * Here cmd_id and cmd_type are used to locate the timer being
288 	 * associated with command. For scan command, cmd_id is expected to
289 	 * be unique and For non-scan command, there should be only one active
290 	 * command per pdev
291 	 */
292 	for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) {
293 		ser_timer = &psoc_ser_obj->timers[i];
294 		if (!(ser_timer->cmd) ||
295 				(ser_timer->cmd->cmd_id != cmd->cmd_id) ||
296 				(ser_timer->cmd->cmd_type != cmd->cmd_type) ||
297 				(ser_timer->cmd->vdev != cmd->vdev))
298 			continue;
299 		status = wlan_serialization_stop_timer(ser_timer);
300 		if (QDF_STATUS_SUCCESS != status) {
301 			serialization_err("Failed to stop timer for cmd_id[%d]",
302 					cmd->cmd_id);
303 		}
304 		break;
305 	}
306 
307 	if (QDF_STATUS_SUCCESS != status) {
308 		serialization_err("can't find timer for cmd_type[%d]",
309 				cmd->cmd_type);
310 	}
311 	return status;
312 }
313 
314 QDF_STATUS
315 wlan_serialization_find_and_start_timer(struct wlan_objmgr_psoc *psoc,
316 					struct wlan_serialization_command *cmd)
317 {
318 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
319 	struct wlan_serialization_psoc_priv_obj *psoc_ser_obj;
320 	struct wlan_serialization_timer *ser_timer;
321 	int i = 0;
322 
323 	if (!psoc || !cmd) {
324 		serialization_err("invalid param");
325 		return status;
326 	}
327 
328 	if ((cmd->cmd_timeout_duration == 0) &&
329 		(wlan_is_emulation_platform(wlan_psoc_get_nif_phy_version(psoc)
330 	))) {
331 		serialization_err("[SCAN-EMULATION]: Not performing timer functions\n");
332 		return QDF_STATUS_SUCCESS;
333 	}
334 
335 
336 	psoc_ser_obj = wlan_serialization_get_psoc_priv_obj(psoc);
337 	for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) {
338 		/* Keep trying timer */
339 		ser_timer = &psoc_ser_obj->timers[i];
340 		if (ser_timer->cmd)
341 			continue;
342 		/* Remember timer is pointing to command */
343 		ser_timer->cmd = cmd;
344 		if (!QDF_IS_STATUS_SUCCESS(qdf_mc_timer_init(&ser_timer->timer,
345 				QDF_TIMER_TYPE_SW,
346 				wlan_serialization_generic_timer_callback,
347 				ser_timer))) {
348 			serialization_err("Failed to init timer cmdid [%d]",
349 					cmd->cmd_id);
350 			QDF_ASSERT(0);
351 			continue;
352 		}
353 		if (!QDF_IS_STATUS_SUCCESS(qdf_mc_timer_start(&ser_timer->timer,
354 						cmd->cmd_timeout_duration))) {
355 			serialization_err("Failed to start timer cmdid [%d]",
356 					cmd->cmd_id);
357 			wlan_serialization_timer_destroy(ser_timer);
358 			QDF_ASSERT(0);
359 			continue;
360 		}
361 		status = QDF_STATUS_SUCCESS;
362 		break;
363 	}
364 
365 	return status;
366 }
367 
368 /**
369  * wlan_serialization_active_scan_cmd_count_handler() - count active scan cmds
370  * @psoc: pointer to soc strucutre
371  * @obj : pointer to pdev object
372  * @arg: pointer to argument
373  *
374  * This API will be called while iterating each pdev object and it will count
375  * number of scan commands present in that pdev object's active queue. count
376  * will be updated in *arg
377  *
378  * Return: none
379  */
380 static void
381 wlan_serialization_active_scan_cmd_count_handler(struct wlan_objmgr_psoc *psoc,
382 						 void *obj, void *arg)
383 {
384 	struct wlan_objmgr_pdev *pdev = obj;
385 	struct wlan_serialization_pdev_priv_obj *ser_pdev_obj;
386 	uint32_t *count = arg;
387 
388 	if (!pdev) {
389 		serialization_err("invalid pdev");
390 		return;
391 	}
392 
393 	ser_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(
394 			pdev, WLAN_UMAC_COMP_SERIALIZATION);
395 	*count += wlan_serialization_list_size(&ser_pdev_obj->active_scan_list,
396 					       ser_pdev_obj);
397 }
398 
399 /**
400  * wlan_serialization_is_active_scan_cmd_allowed() - find if scan cmd allowed
401  * @pdev: pointer to pdev object
402  *
403  * This API will be called to find out if active scan cmd is allowed. It has
404  * to iterate through all pdev to find out total number of active scan cmds.
405  * If total number of active scan cmds reach to allowed threshold then don't
406  * allow more scan cmd.
407  *
408  * Return: true or false
409  */
410 static bool
411 wlan_serialization_is_active_scan_cmd_allowed(struct wlan_objmgr_pdev *pdev)
412 {
413 	uint32_t count = 0;
414 	struct wlan_objmgr_psoc *psoc;
415 
416 	if (!pdev) {
417 		serialization_err("invalid pdev");
418 		return false;
419 	}
420 
421 	psoc = wlan_pdev_get_psoc(pdev);
422 
423 	if (!psoc) {
424 		serialization_err("invalid psoc");
425 		return false;
426 	}
427 
428 	wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP,
429 			wlan_serialization_active_scan_cmd_count_handler,
430 			&count, 1, WLAN_SERIALIZATION_ID);
431 	if (count < ucfg_scan_get_max_active_scans(psoc)) {
432 		serialization_debug("count is [%d]", count);
433 		return true;
434 	}
435 
436 	return false;
437 }
438 
439 /**
440  * wlan_serialization_is_active_nonscan_cmd_allowed() - find if cmd allowed
441  * @pdev: pointer to pdev object
442  *
443  * This API will be called to find out if non scan cmd is allowed.
444  *
445  * Return: true or false
446  */
447 static bool
448 wlan_serialization_is_active_nonscan_cmd_allowed(struct wlan_objmgr_pdev *pdev)
449 {
450 	struct wlan_serialization_pdev_priv_obj *ser_pdev_obj;
451 
452 	if (!pdev) {
453 		serialization_err("invalid pdev");
454 		return false;
455 	}
456 
457 	ser_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(
458 			pdev, WLAN_UMAC_COMP_SERIALIZATION);
459 
460 	if (!ser_pdev_obj) {
461 		serialization_err("invalid ser_pdev_obj");
462 		return false;
463 	}
464 
465 	if (wlan_serialization_list_empty(&ser_pdev_obj->active_list,
466 					  ser_pdev_obj))
467 		return true;
468 
469 	return false;
470 }
471 
472 bool
473 wlan_serialization_is_active_cmd_allowed(struct wlan_serialization_command *cmd)
474 {
475 	struct wlan_objmgr_pdev *pdev;
476 
477 	pdev = wlan_serialization_get_pdev_from_cmd(cmd);
478 	if (!pdev) {
479 		serialization_err("NULL pdev");
480 		return false;
481 	}
482 
483 	if (cmd->cmd_type < WLAN_SER_CMD_NONSCAN)
484 		return wlan_serialization_is_active_scan_cmd_allowed(pdev);
485 	else
486 		return wlan_serialization_is_active_nonscan_cmd_allowed(pdev);
487 }
488 
489 QDF_STATUS wlan_serialization_validate_cmdtype(
490 		 enum wlan_serialization_cmd_type cmd_type)
491 {
492 	serialization_debug("validate cmd_type:%d", cmd_type);
493 
494 	if (cmd_type < 0 || cmd_type >= WLAN_SER_CMD_MAX) {
495 		serialization_err("Invalid cmd or comp passed");
496 		return QDF_STATUS_E_INVAL;
497 	}
498 
499 	return QDF_STATUS_SUCCESS;
500 }
501 
502 QDF_STATUS wlan_serialization_validate_cmd(
503 		 enum wlan_umac_comp_id comp_id,
504 		 enum wlan_serialization_cmd_type cmd_type)
505 {
506 	serialization_debug("validate cmd_type:%d, comp_id:%d",
507 			cmd_type, comp_id);
508 	if (cmd_type < 0 || comp_id < 0 ||
509 			cmd_type >= WLAN_SER_CMD_MAX ||
510 			comp_id >= WLAN_UMAC_COMP_ID_MAX) {
511 		serialization_err("Invalid cmd or comp passed");
512 		return QDF_STATUS_E_INVAL;
513 	}
514 
515 	return QDF_STATUS_SUCCESS;
516 }
517 
518 static void wlan_serialization_release_list_cmds(
519 		struct wlan_serialization_pdev_priv_obj *ser_pdev_obj,
520 		qdf_list_t *list)
521 {
522 	qdf_list_node_t *node = NULL;
523 
524 	while (!wlan_serialization_list_empty(list, ser_pdev_obj)) {
525 		wlan_serialization_remove_front(list, &node, ser_pdev_obj);
526 		wlan_serialization_insert_back(
527 				&ser_pdev_obj->global_cmd_pool_list,
528 				node, ser_pdev_obj);
529 	}
530 
531 	return;
532 }
533 
534 void wlan_serialization_destroy_list(
535 		struct wlan_serialization_pdev_priv_obj *ser_pdev_obj,
536 		qdf_list_t *list)
537 {
538 	wlan_serialization_release_list_cmds(ser_pdev_obj, list);
539 	qdf_list_destroy(list);
540 }
541 
542 struct wlan_serialization_psoc_priv_obj *wlan_serialization_get_psoc_priv_obj(
543 		struct wlan_objmgr_psoc *psoc)
544 {
545 	struct wlan_serialization_psoc_priv_obj *ser_soc_obj;
546 	ser_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
547 					WLAN_UMAC_COMP_SERIALIZATION);
548 
549 	return ser_soc_obj;
550 }
551 
552 struct wlan_serialization_pdev_priv_obj *wlan_serialization_get_pdev_priv_obj(
553 		struct wlan_objmgr_pdev *pdev)
554 {
555 	struct wlan_serialization_pdev_priv_obj *obj;
556 	obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
557 					WLAN_UMAC_COMP_SERIALIZATION);
558 
559 	return obj;
560 }
561 
562 struct wlan_serialization_psoc_priv_obj *
563 wlan_serialization_get_psoc_obj(struct wlan_serialization_command *cmd)
564 {
565 	struct wlan_serialization_psoc_priv_obj *ser_soc_obj = NULL;
566 	struct wlan_objmgr_psoc *psoc;
567 
568 	if (!cmd->vdev)
569 		return ser_soc_obj;
570 
571 	psoc = wlan_vdev_get_psoc(cmd->vdev);
572 	ser_soc_obj = wlan_serialization_get_psoc_priv_obj(psoc);
573 
574 	return ser_soc_obj;
575 }
576 
577 bool wlan_serialization_is_cmd_in_vdev_list(struct wlan_objmgr_vdev *vdev,
578 					    qdf_list_t *queue)
579 {
580 	uint32_t queuelen;
581 	qdf_list_node_t *nnode = NULL;
582 	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
583 	struct wlan_serialization_pdev_priv_obj *ser_pdev_obj =
584 		wlan_serialization_get_pdev_priv_obj(pdev);
585 	QDF_STATUS status;
586 
587 	queuelen = wlan_serialization_list_size(queue, ser_pdev_obj);
588 	if (!queuelen) {
589 		serialization_debug("queue empty");
590 		return false;
591 	}
592 
593 	while (queuelen--) {
594 		status = wlan_serialization_get_cmd_from_queue(queue, &nnode,
595 							       ser_pdev_obj);
596 		if (status != QDF_STATUS_SUCCESS)
597 			break;
598 		if (wlan_serialization_match_cmd_vdev(nnode, vdev))
599 			return true;
600 	}
601 
602 	return false;
603 }
604 
605 bool wlan_serialization_is_cmd_in_pdev_list(
606 			struct wlan_objmgr_pdev *pdev,
607 			qdf_list_t *queue)
608 {
609 	uint32_t queuelen;
610 	qdf_list_node_t *nnode = NULL;
611 	struct wlan_serialization_pdev_priv_obj *ser_pdev_obj =
612 		wlan_serialization_get_pdev_priv_obj(pdev);
613 	QDF_STATUS status;
614 
615 	queuelen = wlan_serialization_list_size(queue, ser_pdev_obj);
616 	if (!queuelen) {
617 		serialization_debug("queue empty");
618 		return false;
619 	}
620 
621 	while (queuelen--) {
622 		status = wlan_serialization_get_cmd_from_queue(queue, &nnode,
623 							       ser_pdev_obj);
624 		if (status != QDF_STATUS_SUCCESS)
625 			break;
626 		if (wlan_serialization_match_cmd_pdev(nnode, pdev))
627 			return true;
628 	}
629 
630 	return false;
631 }
632 
633 enum wlan_serialization_cmd_status
634 wlan_serialization_is_cmd_in_active_pending(bool cmd_in_active,
635 					    bool cmd_in_pending)
636 {
637 	if (cmd_in_active && cmd_in_pending)
638 		return WLAN_SER_CMDS_IN_ALL_LISTS;
639 	else if (cmd_in_active)
640 		return WLAN_SER_CMD_IN_ACTIVE_LIST;
641 	else if (cmd_in_pending)
642 		return WLAN_SER_CMD_IN_PENDING_LIST;
643 	else
644 		return WLAN_SER_CMD_NOT_FOUND;
645 }
646 
647 static bool wlan_serialization_is_cmd_present_in_given_queue(qdf_list_t *queue,
648 			struct wlan_serialization_command *cmd,
649 			struct wlan_serialization_pdev_priv_obj *ser_pdev_obj)
650 {
651 	uint32_t qsize;
652 	QDF_STATUS status;
653 	struct wlan_serialization_command_list *cmd_list = NULL;
654 	qdf_list_node_t *nnode = NULL, *pnode = NULL;
655 	bool found = false;
656 
657 	qsize = wlan_serialization_list_size(queue, ser_pdev_obj);
658 	while (qsize--) {
659 		if (!cmd_list)
660 			status = wlan_serialization_peek_front(queue, &nnode,
661 							       ser_pdev_obj);
662 		else
663 			status = wlan_serialization_peek_next(queue, pnode,
664 							      &nnode,
665 							      ser_pdev_obj);
666 
667 		if (status != QDF_STATUS_SUCCESS)
668 			break;
669 
670 		pnode = nnode;
671 		cmd_list = qdf_container_of(nnode,
672 				struct wlan_serialization_command_list, node);
673 		if (wlan_serialization_match_cmd_id_type(nnode, cmd,
674 							 ser_pdev_obj) &&
675 			wlan_serialization_match_cmd_vdev(nnode, cmd->vdev)) {
676 			found = true;
677 			break;
678 		}
679 		nnode = NULL;
680 	}
681 
682 	return found;
683 }
684 
685 bool wlan_serialization_is_cmd_present_queue(
686 			struct wlan_serialization_command *cmd,
687 			uint8_t is_active_queue)
688 {
689 	qdf_list_t *queue;
690 	struct wlan_objmgr_pdev *pdev;
691 	struct wlan_serialization_pdev_priv_obj *ser_pdev_obj;
692 
693 	if (!cmd) {
694 		serialization_err("invalid params");
695 		return false;
696 	}
697 	pdev = wlan_serialization_get_pdev_from_cmd(cmd);
698 	if (!pdev) {
699 		serialization_err("invalid pdev");
700 		return false;
701 	}
702 	ser_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
703 					WLAN_UMAC_COMP_SERIALIZATION);
704 	if (!ser_pdev_obj) {
705 		serialization_err("invalid ser_pdev_obj");
706 		return false;
707 	}
708 	if (!is_active_queue) {
709 		if (cmd->cmd_type < WLAN_SER_CMD_NONSCAN)
710 			queue = &ser_pdev_obj->pending_scan_list;
711 		else
712 			queue = &ser_pdev_obj->pending_list;
713 	} else {
714 		if (cmd->cmd_type < WLAN_SER_CMD_NONSCAN)
715 			queue = &ser_pdev_obj->active_scan_list;
716 		else
717 			queue = &ser_pdev_obj->active_list;
718 	}
719 
720 	return wlan_serialization_is_cmd_present_in_given_queue(queue, cmd,
721 								ser_pdev_obj);
722 }
723 
724 bool wlan_serialization_list_empty(
725 			qdf_list_t *queue,
726 			struct wlan_serialization_pdev_priv_obj *ser_pdev_obj)
727 {
728 	bool is_empty;
729 
730 	wlan_serialization_acquire_lock(ser_pdev_obj);
731 	if (qdf_list_empty(queue))
732 		is_empty = true;
733 	else
734 		is_empty = false;
735 	wlan_serialization_release_lock(ser_pdev_obj);
736 
737 	return is_empty;
738 }
739 
740 uint32_t wlan_serialization_list_size(
741 			qdf_list_t *queue,
742 			struct wlan_serialization_pdev_priv_obj *ser_pdev_obj)
743 {
744 	uint32_t size;
745 
746 	wlan_serialization_acquire_lock(ser_pdev_obj);
747 	size = qdf_list_size(queue);
748 	wlan_serialization_release_lock(ser_pdev_obj);
749 
750 	return size;
751 }
752 
753 QDF_STATUS wlan_serialization_remove_front(
754 			qdf_list_t *list,
755 			qdf_list_node_t **node,
756 			struct wlan_serialization_pdev_priv_obj *ser_pdev_obj)
757 {
758 	QDF_STATUS status;
759 
760 	wlan_serialization_acquire_lock(ser_pdev_obj);
761 	status = qdf_list_remove_front(list, node);
762 	wlan_serialization_release_lock(ser_pdev_obj);
763 
764 	return status;
765 }
766 
767 QDF_STATUS wlan_serialization_remove_node(
768 			qdf_list_t *list,
769 			qdf_list_node_t *node,
770 			struct wlan_serialization_pdev_priv_obj *ser_pdev_obj)
771 {
772 	QDF_STATUS status;
773 
774 	wlan_serialization_acquire_lock(ser_pdev_obj);
775 	status = qdf_list_remove_node(list, node);
776 	wlan_serialization_release_lock(ser_pdev_obj);
777 
778 	return status;
779 }
780 
781 QDF_STATUS wlan_serialization_insert_front(
782 			qdf_list_t *list,
783 			qdf_list_node_t *node,
784 			struct wlan_serialization_pdev_priv_obj *ser_pdev_obj)
785 {
786 	QDF_STATUS status;
787 
788 	wlan_serialization_acquire_lock(ser_pdev_obj);
789 	status = qdf_list_insert_front(list, node);
790 	wlan_serialization_release_lock(ser_pdev_obj);
791 
792 	return status;
793 }
794 
795 QDF_STATUS wlan_serialization_insert_back(
796 			qdf_list_t *list,
797 			qdf_list_node_t *node,
798 			struct wlan_serialization_pdev_priv_obj *ser_pdev_obj)
799 {
800 	QDF_STATUS status;
801 
802 	wlan_serialization_acquire_lock(ser_pdev_obj);
803 	status = qdf_list_insert_back(list, node);
804 	wlan_serialization_release_lock(ser_pdev_obj);
805 
806 	return status;
807 }
808 
809 QDF_STATUS wlan_serialization_peek_front(
810 			qdf_list_t *list,
811 			qdf_list_node_t **node,
812 			struct wlan_serialization_pdev_priv_obj *ser_pdev_obj)
813 {
814 	QDF_STATUS status;
815 
816 	wlan_serialization_acquire_lock(ser_pdev_obj);
817 	status = qdf_list_peek_front(list, node);
818 	wlan_serialization_release_lock(ser_pdev_obj);
819 
820 	return status;
821 }
822 
823 QDF_STATUS wlan_serialization_peek_next(
824 			qdf_list_t *list,
825 			qdf_list_node_t *node1, qdf_list_node_t **node2,
826 			struct wlan_serialization_pdev_priv_obj *ser_pdev_obj)
827 {
828 	QDF_STATUS status;
829 
830 	wlan_serialization_acquire_lock(ser_pdev_obj);
831 	status = qdf_list_peek_next(list, node1, node2);
832 	wlan_serialization_release_lock(ser_pdev_obj);
833 
834 	return status;
835 }
836 
837 bool wlan_serialization_match_cmd_scan_id(
838 			qdf_list_node_t *nnode,
839 			struct wlan_serialization_command **cmd,
840 			uint16_t scan_id, struct wlan_objmgr_vdev *vdev,
841 			struct wlan_serialization_pdev_priv_obj *ser_pdev_obj)
842 {
843 	struct wlan_serialization_command_list *cmd_list = NULL;
844 	bool match_found = false;
845 
846 	wlan_serialization_acquire_lock(ser_pdev_obj);
847 	cmd_list = qdf_container_of(nnode,
848 				    struct wlan_serialization_command_list,
849 				    node);
850 	if ((cmd_list->cmd.cmd_id == scan_id) &&
851 	    (cmd_list->cmd.vdev == vdev)) {
852 		*cmd = &cmd_list->cmd;
853 		match_found = true;
854 	};
855 	wlan_serialization_release_lock(ser_pdev_obj);
856 
857 	return match_found;
858 }
859 
860 bool wlan_serialization_match_cmd_id_type(
861 			qdf_list_node_t *nnode,
862 			struct wlan_serialization_command *cmd,
863 			struct wlan_serialization_pdev_priv_obj *ser_pdev_obj)
864 {
865 	struct wlan_serialization_command_list *cmd_list = NULL;
866 	bool match_found = true;
867 
868 	if (!cmd)
869 		return false;
870 	wlan_serialization_acquire_lock(ser_pdev_obj);
871 	cmd_list = qdf_container_of(nnode,
872 				    struct wlan_serialization_command_list,
873 				    node);
874 	if ((cmd_list->cmd.cmd_id != cmd->cmd_id) ||
875 	    (cmd_list->cmd.cmd_type != cmd->cmd_type)) {
876 		match_found = false;
877 	};
878 	wlan_serialization_release_lock(ser_pdev_obj);
879 
880 	return match_found;
881 }
882 
883 bool wlan_serialization_match_cmd_vdev(qdf_list_node_t *nnode,
884 				       struct wlan_objmgr_vdev *vdev)
885 {
886 	struct wlan_serialization_command_list *cmd_list = NULL;
887 	bool match_found = false;
888 	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
889 	struct wlan_serialization_pdev_priv_obj *ser_pdev_obj =
890 		wlan_serialization_get_pdev_priv_obj(pdev);
891 
892 	wlan_serialization_acquire_lock(ser_pdev_obj);
893 	cmd_list = qdf_container_of(nnode,
894 				    struct wlan_serialization_command_list,
895 				    node);
896 	if (cmd_list->cmd.vdev == vdev)
897 		match_found = true;
898 	wlan_serialization_release_lock(ser_pdev_obj);
899 
900 	return match_found;
901 }
902 
903 bool wlan_serialization_match_cmd_pdev(qdf_list_node_t *nnode,
904 				       struct wlan_objmgr_pdev *pdev)
905 {
906 	struct wlan_serialization_command_list *cmd_list = NULL;
907 	bool match_found = false;
908 	struct wlan_serialization_pdev_priv_obj *ser_pdev_obj =
909 		wlan_serialization_get_pdev_priv_obj(pdev);
910 	struct wlan_objmgr_pdev *node_pdev = NULL;
911 
912 	wlan_serialization_acquire_lock(ser_pdev_obj);
913 	cmd_list = qdf_container_of(nnode,
914 				    struct wlan_serialization_command_list,
915 				    node);
916 	node_pdev = wlan_vdev_get_pdev(cmd_list->cmd.vdev);
917 	if (node_pdev == pdev)
918 		match_found = true;
919 	wlan_serialization_release_lock(ser_pdev_obj);
920 
921 	return match_found;
922 }
923 
924 #ifdef WLAN_CMD_SERIALIZATION_LOCKING
925 QDF_STATUS
926 wlan_serialization_acquire_lock(struct wlan_serialization_pdev_priv_obj *obj)
927 {
928 	if (!obj) {
929 		serialization_err("invalid object");
930 		return QDF_STATUS_E_FAILURE;
931 	}
932 	qdf_spin_lock_bh(&obj->pdev_ser_list_lock);
933 
934 	return QDF_STATUS_SUCCESS;
935 }
936 
937 QDF_STATUS
938 wlan_serialization_release_lock(struct wlan_serialization_pdev_priv_obj *obj)
939 {
940 	if (!obj) {
941 		serialization_err("invalid object");
942 		return QDF_STATUS_E_FAILURE;
943 	}
944 	qdf_spin_unlock_bh(&obj->pdev_ser_list_lock);
945 
946 	return QDF_STATUS_SUCCESS;
947 }
948 
949 QDF_STATUS
950 wlan_serialization_create_lock(struct wlan_serialization_pdev_priv_obj *obj)
951 {
952 	if (!obj) {
953 		serialization_err("invalid object");
954 		return QDF_STATUS_E_FAILURE;
955 	}
956 	qdf_spinlock_create(&obj->pdev_ser_list_lock);
957 
958 	return QDF_STATUS_SUCCESS;
959 }
960 
961 QDF_STATUS
962 wlan_serialization_destroy_lock(struct wlan_serialization_pdev_priv_obj *obj)
963 {
964 	if (!obj) {
965 		serialization_err("invalid object");
966 		return QDF_STATUS_E_FAILURE;
967 	}
968 	qdf_spinlock_destroy(&obj->pdev_ser_list_lock);
969 
970 	return QDF_STATUS_SUCCESS;
971 }
972 #else
973 QDF_STATUS
974 wlan_serialization_acquire_lock(struct wlan_serialization_pdev_priv_obj *obj)
975 {
976 	return QDF_STATUS_SUCCESS;
977 }
978 
979 QDF_STATUS
980 wlan_serialization_release_lock(struct wlan_serialization_pdev_priv_obj *obj)
981 {
982 	return QDF_STATUS_SUCCESS;
983 }
984 
985 QDF_STATUS
986 wlan_serialization_create_lock(struct wlan_serialization_pdev_priv_obj *obj)
987 {
988 	return QDF_STATUS_SUCCESS;
989 }
990 
991 QDF_STATUS
992 wlan_serialization_destroy_lock(struct wlan_serialization_pdev_priv_obj *obj)
993 {
994 	return QDF_STATUS_SUCCESS;
995 }
996 #endif
997 #else /*New serialization code*/
998 #include <wlan_objmgr_vdev_obj.h>
999 #include <wlan_objmgr_pdev_obj.h>
1000 #include <qdf_mc_timer.h>
1001 #include <wlan_utility.h>
1002 #include "wlan_serialization_utils_i.h"
1003 #include "wlan_serialization_main_i.h"
1004 #include "wlan_serialization_queue_i.h"
1005 #include "wlan_serialization_api.h"
1006 
1007 struct wlan_objmgr_pdev*
1008 wlan_serialization_get_pdev_from_cmd(struct wlan_serialization_command *cmd)
1009 {
1010 	struct wlan_objmgr_pdev *pdev = NULL;
1011 
1012 	if (!cmd) {
1013 		ser_err("invalid cmd");
1014 		return pdev;
1015 	}
1016 	if (!cmd->vdev) {
1017 		ser_err("invalid cmd->vdev");
1018 		return pdev;
1019 	}
1020 	pdev = wlan_vdev_get_pdev(cmd->vdev);
1021 
1022 	return pdev;
1023 }
1024 
1025 struct wlan_objmgr_psoc*
1026 wlan_serialization_get_psoc_from_cmd(struct wlan_serialization_command *cmd)
1027 {
1028 	struct wlan_objmgr_psoc *psoc = NULL;
1029 
1030 	if (!cmd) {
1031 		ser_err("invalid cmd");
1032 		return psoc;
1033 	}
1034 	if (!cmd->vdev) {
1035 		ser_err("invalid cmd->vdev");
1036 		return psoc;
1037 	}
1038 	psoc = wlan_vdev_get_psoc(cmd->vdev);
1039 
1040 	return psoc;
1041 }
1042 
1043 struct wlan_objmgr_vdev*
1044 wlan_serialization_get_vdev_from_cmd(struct wlan_serialization_command *cmd)
1045 {
1046 	struct wlan_objmgr_vdev *vdev = NULL;
1047 
1048 	if (!cmd) {
1049 		ser_err("invalid cmd");
1050 		goto error;
1051 	}
1052 
1053 	vdev = cmd->vdev;
1054 
1055 error:
1056 	return vdev;
1057 }
1058 
1059 QDF_STATUS
1060 wlan_serialization_get_cmd_from_queue(qdf_list_t *queue,
1061 				      qdf_list_node_t **nnode)
1062 {
1063 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1064 	qdf_list_node_t *pnode;
1065 
1066 	if (!queue) {
1067 		ser_err("input parameters are invalid");
1068 		goto error;
1069 	}
1070 
1071 	pnode = *nnode;
1072 	if (!pnode)
1073 		status = wlan_serialization_peek_front(queue, nnode);
1074 	else
1075 		status = wlan_serialization_peek_next(queue, pnode, nnode);
1076 
1077 	if (status != QDF_STATUS_SUCCESS)
1078 		ser_err("can't get next node from queue");
1079 
1080 error:
1081 	return status;
1082 }
1083 
1084 QDF_STATUS wlan_serialization_timer_destroy(
1085 		struct wlan_serialization_timer *ser_timer)
1086 {
1087 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
1088 
1089 	if (!ser_timer || !ser_timer->cmd) {
1090 		ser_debug("Invalid ser_timer");
1091 		qdf_status =  QDF_STATUS_E_FAILURE;
1092 		goto error;
1093 	}
1094 
1095 	ser_debug("Destroying the timer");
1096 	qdf_timer_stop(&ser_timer->timer);
1097 	ser_timer->cmd = NULL;
1098 
1099 error:
1100 	return qdf_status;
1101 }
1102 
1103 /**
1104  * wlan_serialization_stop_timer() - to stop particular timer
1105  * @ser_timer: pointer to serialization timer
1106  *
1107  * This API stops the particular timer
1108  *
1109  * Return: QDF_STATUS
1110  */
1111 QDF_STATUS
1112 wlan_serialization_stop_timer(struct wlan_serialization_timer *ser_timer)
1113 {
1114 	wlan_serialization_timer_destroy(ser_timer);
1115 
1116 	return QDF_STATUS_SUCCESS;
1117 }
1118 
1119 QDF_STATUS wlan_serialization_cleanup_all_timers(
1120 			struct wlan_ser_psoc_obj *psoc_ser_obj)
1121 {
1122 	struct wlan_serialization_timer *ser_timer;
1123 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1124 	uint32_t i = 0;
1125 
1126 	ser_enter();
1127 
1128 	if (!psoc_ser_obj) {
1129 		ser_err("Invalid psoc_ser_obj");
1130 		status = QDF_STATUS_E_FAILURE;
1131 		goto error;
1132 	}
1133 
1134 	wlan_serialization_acquire_lock(&psoc_ser_obj->timer_lock);
1135 
1136 	for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) {
1137 		ser_timer = &psoc_ser_obj->timers[i];
1138 		if (!ser_timer->cmd)
1139 			continue;
1140 		status = wlan_serialization_stop_timer(ser_timer);
1141 		if (QDF_STATUS_SUCCESS != status) {
1142 			/* lets not break the loop but report error */
1143 			ser_err("some error in stopping timer");
1144 		}
1145 	}
1146 
1147 	wlan_serialization_release_lock(&psoc_ser_obj->timer_lock);
1148 error:
1149 	ser_exit();
1150 	return status;
1151 }
1152 
1153 QDF_STATUS wlan_serialization_validate_cmdtype(
1154 		 enum wlan_serialization_cmd_type cmd_type)
1155 {
1156 	if (cmd_type < 0 || cmd_type >= WLAN_SER_CMD_MAX) {
1157 		ser_err("Invalid cmd or comp passed");
1158 		return QDF_STATUS_E_INVAL;
1159 	}
1160 
1161 	return QDF_STATUS_SUCCESS;
1162 }
1163 
1164 QDF_STATUS wlan_serialization_validate_cmd(
1165 		 enum wlan_umac_comp_id comp_id,
1166 		 enum wlan_serialization_cmd_type cmd_type)
1167 {
1168 	QDF_STATUS status = QDF_STATUS_E_INVAL;
1169 
1170 	ser_debug("validate cmd_type:%d, comp_id:%d",
1171 		  cmd_type, comp_id);
1172 	if (cmd_type < 0 || comp_id < 0 ||
1173 	    cmd_type >= WLAN_SER_CMD_MAX ||
1174 	   comp_id >= WLAN_UMAC_COMP_ID_MAX) {
1175 		ser_err("Invalid cmd or comp passed");
1176 		goto error;
1177 	}
1178 
1179 	status = QDF_STATUS_SUCCESS;
1180 error:
1181 	return status;
1182 }
1183 
1184 QDF_STATUS wlan_serialization_validate_cmd_list(
1185 		struct wlan_serialization_command_list *cmd_list)
1186 {
1187 	QDF_STATUS status = QDF_STATUS_E_INVAL;
1188 
1189 	if (!cmd_list->cmd.cmd_cb) {
1190 		ser_err("no cmd_cb for cmd type:%d, id: %d",
1191 			cmd_list->cmd.cmd_type, cmd_list->cmd.cmd_id);
1192 		QDF_ASSERT(0);
1193 		goto error;
1194 	}
1195 
1196 	if (!cmd_list->cmd.vdev) {
1197 		ser_err("invalid cmd.vdev");
1198 		goto error;
1199 	}
1200 
1201 	status = QDF_STATUS_SUCCESS;
1202 
1203 error:
1204 	return status;
1205 }
1206 
1207 static void wlan_serialization_release_pdev_list_cmds(
1208 		struct wlan_serialization_pdev_queue *pdev_queue)
1209 {
1210 	qdf_list_node_t *node = NULL;
1211 
1212 	ser_enter();
1213 
1214 	while (!wlan_serialization_list_empty(&pdev_queue->active_list)) {
1215 		wlan_serialization_remove_front(
1216 				&pdev_queue->active_list, &node);
1217 		wlan_serialization_insert_back(
1218 				&pdev_queue->cmd_pool_list, node);
1219 	}
1220 
1221 	while (!wlan_serialization_list_empty(&pdev_queue->pending_list)) {
1222 		wlan_serialization_remove_front(
1223 				&pdev_queue->pending_list, &node);
1224 		wlan_serialization_insert_back(
1225 				&pdev_queue->cmd_pool_list, node);
1226 	}
1227 
1228 	ser_exit();
1229 }
1230 
1231 static void wlan_serialization_release_vdev_list_cmds(qdf_list_t *list)
1232 {
1233 	qdf_list_node_t *node = NULL;
1234 
1235 	ser_enter();
1236 
1237 	while (!wlan_serialization_list_empty(list))
1238 		wlan_serialization_remove_front(list, &node);
1239 
1240 	ser_exit();
1241 }
1242 
1243 void wlan_serialization_destroy_pdev_list(
1244 		struct wlan_serialization_pdev_queue *pdev_queue)
1245 {
1246 	ser_enter();
1247 
1248 	wlan_serialization_release_pdev_list_cmds(pdev_queue);
1249 	qdf_list_destroy(&pdev_queue->active_list);
1250 	qdf_list_destroy(&pdev_queue->pending_list);
1251 
1252 	ser_exit();
1253 }
1254 
1255 void wlan_serialization_destroy_vdev_list(qdf_list_t *list)
1256 {
1257 	ser_enter();
1258 
1259 	wlan_serialization_release_vdev_list_cmds(list);
1260 	qdf_list_destroy(list);
1261 
1262 	ser_exit();
1263 }
1264 
1265 struct wlan_ser_psoc_obj *wlan_serialization_get_psoc_obj(
1266 		struct wlan_objmgr_psoc *psoc)
1267 {
1268 	struct wlan_ser_psoc_obj *ser_soc_obj;
1269 
1270 	ser_soc_obj =
1271 		wlan_objmgr_psoc_get_comp_private_obj(
1272 				psoc, WLAN_UMAC_COMP_SERIALIZATION);
1273 
1274 	return ser_soc_obj;
1275 }
1276 
1277 struct wlan_ser_pdev_obj *wlan_serialization_get_pdev_obj(
1278 		struct wlan_objmgr_pdev *pdev)
1279 {
1280 	struct wlan_ser_pdev_obj *obj;
1281 
1282 	obj = wlan_objmgr_pdev_get_comp_private_obj(
1283 			pdev, WLAN_UMAC_COMP_SERIALIZATION);
1284 
1285 	return obj;
1286 }
1287 
1288 struct wlan_ser_vdev_obj *wlan_serialization_get_vdev_obj(
1289 		struct wlan_objmgr_vdev *vdev)
1290 {
1291 	struct wlan_ser_vdev_obj *obj;
1292 
1293 	obj = wlan_objmgr_vdev_get_comp_private_obj(
1294 			vdev, WLAN_UMAC_COMP_SERIALIZATION);
1295 
1296 	return obj;
1297 }
1298 
1299 bool wlan_serialization_is_cmd_in_vdev_list(
1300 		struct wlan_objmgr_vdev *vdev,
1301 		qdf_list_t *queue,
1302 		enum wlan_serialization_node node_type)
1303 {
1304 	qdf_list_node_t *node = NULL;
1305 	bool cmd_found = false;
1306 
1307 	ser_enter();
1308 
1309 	node = wlan_serialization_find_cmd(
1310 			queue, WLAN_SER_MATCH_VDEV,
1311 			NULL, 0, NULL, vdev, node_type);
1312 
1313 	if (node)
1314 		cmd_found = true;
1315 
1316 	ser_exit();
1317 	return cmd_found;
1318 }
1319 
1320 bool wlan_serialization_is_cmd_in_pdev_list(
1321 			struct wlan_objmgr_pdev *pdev,
1322 			qdf_list_t *queue)
1323 {
1324 	qdf_list_node_t *node = NULL;
1325 	bool cmd_found = false;
1326 
1327 	ser_enter();
1328 
1329 	node = wlan_serialization_find_cmd(
1330 			queue, WLAN_SER_MATCH_PDEV,
1331 			NULL, 0, pdev, NULL,  WLAN_SER_PDEV_NODE);
1332 
1333 	if (node)
1334 		cmd_found = true;
1335 
1336 	ser_exit();
1337 	return cmd_found;
1338 }
1339 
1340 enum wlan_serialization_cmd_status
1341 wlan_serialization_is_cmd_in_active_pending(bool cmd_in_active,
1342 					    bool cmd_in_pending)
1343 {
1344 	enum wlan_serialization_cmd_status status;
1345 
1346 	if (cmd_in_active && cmd_in_pending)
1347 		status = WLAN_SER_CMDS_IN_ALL_LISTS;
1348 	else if (cmd_in_active)
1349 		status = WLAN_SER_CMD_IN_ACTIVE_LIST;
1350 	else if (cmd_in_pending)
1351 		status = WLAN_SER_CMD_IN_PENDING_LIST;
1352 	else
1353 		status = WLAN_SER_CMD_NOT_FOUND;
1354 
1355 	return status;
1356 }
1357 
1358 bool
1359 wlan_serialization_is_cmd_present_in_given_queue(
1360 		qdf_list_t *queue,
1361 		struct wlan_serialization_command *cmd,
1362 		enum wlan_serialization_node node_type)
1363 {
1364 	qdf_list_node_t *node = NULL;
1365 	bool found = false;
1366 
1367 	node = wlan_serialization_find_cmd(
1368 			queue, WLAN_SER_MATCH_CMD_ID_VDEV,
1369 			cmd, 0, NULL, cmd->vdev, node_type);
1370 
1371 	if (node)
1372 		found = true;
1373 
1374 	return found;
1375 }
1376 
1377 /**
1378  * wlan_serialization_remove_cmd_from_queue() - to remove command from
1379  *							given queue
1380  * @queue: queue from which command needs to be removed
1381  * @cmd: command to match in the queue
1382  * @ser_pdev_obj: pointer to private pdev serialization object
1383  *
1384  * This API takes the queue, it matches the provided command from this queue
1385  * and removes it. Before removing the command, it will notify the caller
1386  * that if it needs to remove any memory allocated by caller.
1387  *
1388  * Return: none
1389  */
1390 QDF_STATUS
1391 wlan_serialization_remove_cmd_from_queue(
1392 		qdf_list_t *queue,
1393 		struct wlan_serialization_command *cmd,
1394 		struct wlan_serialization_command_list **pcmd_list,
1395 		struct wlan_ser_pdev_obj *ser_pdev_obj,
1396 		enum wlan_serialization_node node_type)
1397 {
1398 	struct wlan_serialization_command_list *cmd_list;
1399 	qdf_list_node_t *node = NULL;
1400 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1401 
1402 	if (!cmd)
1403 		goto error;
1404 
1405 	if (wlan_serialization_list_empty(queue)) {
1406 		ser_err("Empty queue");
1407 		goto error;
1408 	}
1409 
1410 	node = wlan_serialization_find_cmd(queue, WLAN_SER_MATCH_CMD_ID_VDEV,
1411 					   cmd, 0, NULL, cmd->vdev, node_type);
1412 
1413 	if (!node)
1414 		goto error;
1415 
1416 	if (node_type == WLAN_SER_PDEV_NODE)
1417 		cmd_list =
1418 			qdf_container_of(node,
1419 					 struct wlan_serialization_command_list,
1420 					 pdev_node);
1421 	else
1422 		cmd_list =
1423 			qdf_container_of(node,
1424 					 struct wlan_serialization_command_list,
1425 					 vdev_node);
1426 
1427 	ser_debug("Matching command found for removal from queue");
1428 	ser_debug("remove cmd: type[%d] id[%d] prio[%d] blocking[%d]",
1429 		  cmd_list->cmd.cmd_type,
1430 			  cmd_list->cmd.cmd_id,
1431 			  cmd_list->cmd.is_high_priority,
1432 			  cmd_list->cmd.is_blocking);
1433 
1434 	status = wlan_serialization_remove_node(queue, node);
1435 
1436 	if (QDF_STATUS_SUCCESS != status)
1437 		ser_err("Fail to add to free pool type[%d]",
1438 			cmd->cmd_type);
1439 
1440 	*pcmd_list = cmd_list;
1441 
1442 error:
1443 	return status;
1444 }
1445 
1446 enum wlan_serialization_status
1447 wlan_serialization_add_cmd_to_queue(
1448 		qdf_list_t *queue,
1449 		struct wlan_serialization_command_list *cmd_list,
1450 		struct wlan_ser_pdev_obj *ser_pdev_obj,
1451 		uint8_t is_cmd_for_active_queue,
1452 		enum wlan_serialization_node node_type)
1453 {
1454 	enum wlan_serialization_status status = WLAN_SER_CMD_DENIED_UNSPECIFIED;
1455 	QDF_STATUS qdf_status;
1456 	qdf_list_node_t *node;
1457 
1458 	if (!cmd_list || !queue || !ser_pdev_obj) {
1459 		ser_err("Input arguments are not valid");
1460 		goto error;
1461 	}
1462 
1463 	if (node_type == WLAN_SER_PDEV_NODE) {
1464 		node = &cmd_list->pdev_node;
1465 		ser_debug("pdev_queue: %pK", queue);
1466 	} else {
1467 		node = &cmd_list->vdev_node;
1468 		ser_debug("vdev_queue: %pK", queue);
1469 	}
1470 
1471 	ser_debug("add cmd: type[%d] id[%d] high_priority[%d] blocking[%d]",
1472 		  cmd_list->cmd.cmd_type,
1473 		  cmd_list->cmd.cmd_id,
1474 		  cmd_list->cmd.is_high_priority,
1475 		  cmd_list->cmd.is_blocking);
1476 
1477 	if (qdf_list_size(queue) == qdf_list_max_size(queue)) {
1478 		status = WLAN_SER_CMD_DENIED_LIST_FULL;
1479 		goto error;
1480 	}
1481 
1482 	if (cmd_list->cmd.is_high_priority)
1483 		qdf_status = wlan_serialization_insert_front(queue, node);
1484 	else
1485 		qdf_status = wlan_serialization_insert_back(queue, node);
1486 
1487 	if (QDF_IS_STATUS_ERROR(qdf_status))
1488 		goto error;
1489 
1490 	ser_debug("adding cmd to node: %pK", node);
1491 
1492 	if (is_cmd_for_active_queue)
1493 		status = WLAN_SER_CMD_ACTIVE;
1494 	else
1495 		status = WLAN_SER_CMD_PENDING;
1496 
1497 error:
1498 	return status;
1499 }
1500 
1501 bool wlan_serialization_list_empty(qdf_list_t *queue)
1502 {
1503 	bool is_empty;
1504 
1505 	if (qdf_list_empty(queue))
1506 		is_empty = true;
1507 	else
1508 		is_empty = false;
1509 
1510 	return is_empty;
1511 }
1512 
1513 uint32_t wlan_serialization_list_size(qdf_list_t *queue)
1514 {
1515 	uint32_t size;
1516 
1517 	size = qdf_list_size(queue);
1518 
1519 	return size;
1520 }
1521 
1522 QDF_STATUS wlan_serialization_remove_front(qdf_list_t *list,
1523 					   qdf_list_node_t **node)
1524 {
1525 	QDF_STATUS status;
1526 
1527 	if (wlan_serialization_list_empty(list)) {
1528 		ser_err("The list is empty");
1529 		status = QDF_STATUS_E_EMPTY;
1530 		goto error;
1531 	}
1532 
1533 	status = qdf_list_remove_front(list, node);
1534 error:
1535 	return status;
1536 }
1537 
1538 QDF_STATUS wlan_serialization_remove_node(qdf_list_t *list,
1539 					  qdf_list_node_t *node)
1540 {
1541 	QDF_STATUS status;
1542 
1543 	if (wlan_serialization_list_empty(list)) {
1544 		ser_err("The list is empty");
1545 		status = QDF_STATUS_E_EMPTY;
1546 		goto error;
1547 	}
1548 	status = qdf_list_remove_node(list, node);
1549 
1550 error:
1551 	return status;
1552 }
1553 
1554 QDF_STATUS wlan_serialization_insert_front(qdf_list_t *list,
1555 					   qdf_list_node_t *node)
1556 {
1557 	QDF_STATUS status;
1558 
1559 	status = qdf_list_insert_front(list, node);
1560 
1561 	return status;
1562 }
1563 
1564 QDF_STATUS wlan_serialization_insert_back(qdf_list_t *list,
1565 					  qdf_list_node_t *node)
1566 {
1567 	QDF_STATUS status;
1568 
1569 	status = qdf_list_insert_back(list, node);
1570 
1571 	return status;
1572 }
1573 
1574 QDF_STATUS wlan_serialization_peek_front(qdf_list_t *list,
1575 					 qdf_list_node_t **node)
1576 {
1577 	QDF_STATUS status;
1578 
1579 	status = qdf_list_peek_front(list, node);
1580 
1581 	return status;
1582 }
1583 
1584 QDF_STATUS wlan_serialization_peek_next(qdf_list_t *list,
1585 					qdf_list_node_t *node1,
1586 					qdf_list_node_t **node2)
1587 {
1588 	QDF_STATUS status;
1589 
1590 	status = qdf_list_peek_next(list, node1, node2);
1591 
1592 	return status;
1593 }
1594 
1595 bool
1596 wlan_serialization_match_cmd_type(qdf_list_node_t *nnode,
1597 				  enum wlan_serialization_cmd_type cmd_type,
1598 				  enum wlan_serialization_node node_type)
1599 {
1600 	struct wlan_serialization_command_list *cmd_list = NULL;
1601 	bool match_found = true;
1602 
1603 	if (node_type == WLAN_SER_PDEV_NODE)
1604 		cmd_list =
1605 			qdf_container_of(nnode,
1606 					 struct wlan_serialization_command_list,
1607 					 pdev_node);
1608 	else
1609 		cmd_list =
1610 			qdf_container_of(nnode,
1611 					 struct wlan_serialization_command_list,
1612 					 vdev_node);
1613 
1614 	if (cmd_list->cmd.cmd_type != cmd_type)
1615 		match_found = false;
1616 
1617 	return match_found;
1618 }
1619 
1620 bool
1621 wlan_serialization_match_cmd_id_type(qdf_list_node_t *nnode,
1622 				     struct wlan_serialization_command *cmd,
1623 				     enum wlan_serialization_node node_type)
1624 {
1625 	struct wlan_serialization_command_list *cmd_list = NULL;
1626 	bool match_found = true;
1627 
1628 	if (!cmd) {
1629 		match_found = false;
1630 		goto error;
1631 	}
1632 
1633 	if (node_type == WLAN_SER_PDEV_NODE)
1634 		cmd_list =
1635 			qdf_container_of(nnode,
1636 					 struct wlan_serialization_command_list,
1637 					 pdev_node);
1638 	else
1639 		cmd_list =
1640 			qdf_container_of(nnode,
1641 					 struct wlan_serialization_command_list,
1642 					 vdev_node);
1643 
1644 	if ((cmd_list->cmd.cmd_id != cmd->cmd_id) ||
1645 	    (cmd_list->cmd.cmd_type != cmd->cmd_type)) {
1646 		match_found = false;
1647 	};
1648 
1649 error:
1650 	return match_found;
1651 }
1652 
1653 bool wlan_serialization_match_cmd_vdev(qdf_list_node_t *nnode,
1654 				       struct wlan_objmgr_vdev *vdev,
1655 				       enum wlan_serialization_node node_type)
1656 {
1657 	struct wlan_serialization_command_list *cmd_list = NULL;
1658 	bool match_found = false;
1659 
1660 	if (node_type == WLAN_SER_PDEV_NODE)
1661 		cmd_list =
1662 			qdf_container_of(nnode,
1663 					 struct wlan_serialization_command_list,
1664 					 pdev_node);
1665 	else
1666 		cmd_list =
1667 			qdf_container_of(nnode,
1668 					 struct wlan_serialization_command_list,
1669 					 vdev_node);
1670 
1671 	if (cmd_list->cmd.vdev == vdev)
1672 		match_found = true;
1673 
1674 	ser_debug("matching cmd found(vdev:%pK): %d", vdev, match_found);
1675 	return match_found;
1676 }
1677 
1678 bool wlan_serialization_match_cmd_pdev(qdf_list_node_t *nnode,
1679 				       struct wlan_objmgr_pdev *pdev,
1680 				       enum wlan_serialization_node node_type)
1681 {
1682 	struct wlan_serialization_command_list *cmd_list = NULL;
1683 	bool match_found = false;
1684 	struct wlan_objmgr_pdev *node_pdev = NULL;
1685 
1686 	if (node_type == WLAN_SER_PDEV_NODE)
1687 		cmd_list =
1688 			qdf_container_of(nnode,
1689 					 struct wlan_serialization_command_list,
1690 					 pdev_node);
1691 	else
1692 		cmd_list =
1693 			qdf_container_of(nnode,
1694 					 struct wlan_serialization_command_list,
1695 					 vdev_node);
1696 
1697 	node_pdev = wlan_vdev_get_pdev(cmd_list->cmd.vdev);
1698 	if (node_pdev == pdev)
1699 		match_found = true;
1700 
1701 	return match_found;
1702 }
1703 
1704 qdf_list_node_t *
1705 wlan_serialization_find_cmd(qdf_list_t *queue,
1706 			    enum wlan_serialization_match_type match_type,
1707 			    struct wlan_serialization_command *cmd,
1708 			    enum wlan_serialization_cmd_type cmd_type,
1709 			    struct wlan_objmgr_pdev *pdev,
1710 			    struct wlan_objmgr_vdev *vdev,
1711 			    enum wlan_serialization_node node_type)
1712 {
1713 	qdf_list_node_t *cmd_node = NULL;
1714 	uint32_t queuelen;
1715 	qdf_list_node_t *nnode = NULL;
1716 	QDF_STATUS status;
1717 	bool node_found = 0;
1718 
1719 	queuelen = wlan_serialization_list_size(queue);
1720 
1721 	if (!queuelen) {
1722 		ser_debug("queue empty");
1723 		goto error;
1724 	}
1725 
1726 	while (queuelen--) {
1727 		status = wlan_serialization_get_cmd_from_queue(queue, &nnode);
1728 		if (status != QDF_STATUS_SUCCESS)
1729 			break;
1730 
1731 		switch (match_type) {
1732 		case WLAN_SER_MATCH_PDEV:
1733 			if (wlan_serialization_match_cmd_pdev(
1734 					nnode, pdev, WLAN_SER_PDEV_NODE))
1735 				node_found = 1;
1736 			break;
1737 		case WLAN_SER_MATCH_VDEV:
1738 			if (wlan_serialization_match_cmd_vdev(
1739 					nnode, vdev, node_type))
1740 				node_found = 1;
1741 			break;
1742 		case WLAN_SER_MATCH_CMD_TYPE:
1743 			if (wlan_serialization_match_cmd_type(
1744 					nnode, cmd_type, node_type))
1745 				node_found = 1;
1746 			break;
1747 		case WLAN_SER_MATCH_CMD_ID:
1748 			if (wlan_serialization_match_cmd_id_type(
1749 					nnode, cmd, node_type))
1750 				node_found = 1;
1751 			break;
1752 		case WLAN_SER_MATCH_CMD_TYPE_VDEV:
1753 			if (wlan_serialization_match_cmd_type(
1754 					nnode, cmd_type, node_type) &&
1755 			    wlan_serialization_match_cmd_vdev(
1756 					nnode, vdev, node_type))
1757 				node_found = 1;
1758 			break;
1759 		case WLAN_SER_MATCH_CMD_ID_VDEV:
1760 			if (wlan_serialization_match_cmd_id_type(
1761 					nnode, cmd, node_type) &&
1762 			    wlan_serialization_match_cmd_vdev(
1763 					nnode, vdev, node_type))
1764 				node_found = 1;
1765 			break;
1766 		default:
1767 			break;
1768 		}
1769 
1770 		if (node_found) {
1771 			cmd_node = nnode;
1772 			break;
1773 		}
1774 	}
1775 error:
1776 	return cmd_node;
1777 }
1778 
1779 QDF_STATUS
1780 wlan_serialization_acquire_lock(qdf_spinlock_t *lock)
1781 {
1782 	qdf_spin_lock_bh(lock);
1783 
1784 	return QDF_STATUS_SUCCESS;
1785 }
1786 
1787 QDF_STATUS
1788 wlan_serialization_release_lock(qdf_spinlock_t *lock)
1789 {
1790 	qdf_spin_unlock_bh(lock);
1791 
1792 	return QDF_STATUS_SUCCESS;
1793 }
1794 
1795 QDF_STATUS
1796 wlan_serialization_create_lock(qdf_spinlock_t *lock)
1797 {
1798 	qdf_spinlock_create(lock);
1799 
1800 	return QDF_STATUS_SUCCESS;
1801 }
1802 
1803 QDF_STATUS
1804 wlan_serialization_destroy_lock(qdf_spinlock_t *lock)
1805 {
1806 	qdf_spinlock_destroy(lock);
1807 
1808 	return QDF_STATUS_SUCCESS;
1809 }
1810 #endif
1811