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