xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_utils.c (revision 70a19e16789e308182f63b15c75decec7bf0b342)
1 /*
2  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * DOC: wlan_serialization_utils.c
22  * This file defines the utility helper functions for serialization component.
23  */
24 
25 #include <wlan_objmgr_vdev_obj.h>
26 #include <wlan_objmgr_pdev_obj.h>
27 #include <qdf_mc_timer.h>
28 #include <wlan_utility.h>
29 #include "wlan_serialization_utils_i.h"
30 #include "wlan_serialization_main_i.h"
31 #include "wlan_serialization_queue_i.h"
32 #include "wlan_serialization_api.h"
33 
34 #ifndef WLAN_SER_DEBUG
35 void wlan_ser_update_cmd_history(
36 		struct wlan_serialization_pdev_queue *pdev_queue,
37 		struct wlan_serialization_command *cmd,
38 		enum ser_queue_reason ser_reason,
39 		bool add_remove,
40 		bool active_queue){ }
41 #endif
42 
43 struct wlan_objmgr_pdev*
44 wlan_serialization_get_pdev_from_cmd(struct wlan_serialization_command *cmd)
45 {
46 	struct wlan_objmgr_pdev *pdev = NULL;
47 
48 	if (!cmd) {
49 		ser_err("invalid cmd");
50 		return pdev;
51 	}
52 	if (!cmd->vdev) {
53 		ser_err("invalid cmd->vdev");
54 		return pdev;
55 	}
56 	pdev = wlan_vdev_get_pdev(cmd->vdev);
57 
58 	return pdev;
59 }
60 
61 struct wlan_objmgr_psoc*
62 wlan_serialization_get_psoc_from_cmd(struct wlan_serialization_command *cmd)
63 {
64 	struct wlan_objmgr_psoc *psoc = NULL;
65 
66 	if (!cmd) {
67 		ser_err("invalid cmd");
68 		return psoc;
69 	}
70 	if (!cmd->vdev) {
71 		ser_err("invalid cmd->vdev");
72 		return psoc;
73 	}
74 	psoc = wlan_vdev_get_psoc(cmd->vdev);
75 
76 	return psoc;
77 }
78 
79 struct wlan_objmgr_vdev*
80 wlan_serialization_get_vdev_from_cmd(struct wlan_serialization_command *cmd)
81 {
82 	struct wlan_objmgr_vdev *vdev = NULL;
83 
84 	if (!cmd) {
85 		ser_err("invalid cmd");
86 		goto error;
87 	}
88 
89 	vdev = cmd->vdev;
90 
91 error:
92 	return vdev;
93 }
94 
95 QDF_STATUS
96 wlan_serialization_get_cmd_from_queue(qdf_list_t *queue,
97 				      qdf_list_node_t **nnode)
98 {
99 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
100 	qdf_list_node_t *pnode;
101 
102 	if (!queue) {
103 		ser_err("input parameters are invalid");
104 		goto error;
105 	}
106 
107 	pnode = *nnode;
108 	if (!pnode)
109 		status = wlan_serialization_peek_front(queue, nnode);
110 	else
111 		status = wlan_serialization_peek_next(queue, pnode, nnode);
112 
113 	if (status != QDF_STATUS_SUCCESS)
114 		ser_err("can't get next node from queue");
115 
116 error:
117 	return status;
118 }
119 
120 QDF_STATUS wlan_serialization_timer_destroy(
121 		struct wlan_serialization_timer *ser_timer)
122 {
123 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
124 
125 	if (!ser_timer || !ser_timer->cmd) {
126 		ser_debug("Invalid ser_timer");
127 		qdf_status =  QDF_STATUS_E_FAILURE;
128 		goto error;
129 	}
130 	/* Wait till timeout CB is completed */
131 	qdf_timer_sync_cancel(&ser_timer->timer);
132 	ser_timer->cmd = NULL;
133 
134 error:
135 	return qdf_status;
136 }
137 
138 /**
139  * wlan_serialization_stop_timer() - to stop particular timer
140  * @ser_timer: pointer to serialization timer
141  *
142  * This API stops the particular timer
143  *
144  * Return: QDF_STATUS
145  */
146 QDF_STATUS
147 wlan_serialization_stop_timer(struct wlan_serialization_timer *ser_timer)
148 {
149 	wlan_serialization_timer_destroy(ser_timer);
150 
151 	return QDF_STATUS_SUCCESS;
152 }
153 
154 QDF_STATUS wlan_serialization_cleanup_vdev_timers(
155 			struct wlan_objmgr_vdev *vdev)
156 {
157 	struct wlan_ser_psoc_obj *psoc_ser_obj;
158 	struct wlan_serialization_timer *ser_timer;
159 	QDF_STATUS status = QDF_STATUS_SUCCESS;
160 	uint32_t i = 0;
161 	struct wlan_objmgr_pdev *pdev = NULL;
162 	struct wlan_objmgr_psoc *psoc = NULL;
163 
164 	pdev = wlan_vdev_get_pdev(vdev);
165 	if (!pdev) {
166 		QDF_BUG(0);
167 		ser_err("pdev is null");
168 		status = QDF_STATUS_E_FAILURE;
169 		goto error;
170 	}
171 
172 	psoc = wlan_pdev_get_psoc(pdev);
173 	if (!psoc) {
174 		QDF_BUG(0);
175 		ser_err("psoc is null");
176 		status = QDF_STATUS_E_FAILURE;
177 		goto error;
178 	}
179 
180 	psoc_ser_obj = wlan_serialization_get_psoc_obj(psoc);
181 
182 	if (!psoc_ser_obj) {
183 		ser_err("Invalid psoc_ser_obj");
184 		status = QDF_STATUS_E_FAILURE;
185 		goto error;
186 	}
187 
188 	wlan_serialization_acquire_lock(&psoc_ser_obj->timer_lock);
189 
190 	for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) {
191 		ser_timer = &psoc_ser_obj->timers[i];
192 		if (!ser_timer->cmd)
193 			continue;
194 		/*
195 		 * Check if the timer is for the given vdev
196 		 */
197 		if (ser_timer->cmd->vdev != vdev)
198 			continue;
199 
200 		ser_debug("Stopping the timer for vdev id[%d]",
201 			  wlan_vdev_get_id(vdev));
202 
203 		status = wlan_serialization_stop_timer(ser_timer);
204 		if (QDF_STATUS_SUCCESS != status) {
205 			/* lets not break the loop but report error */
206 			ser_err("some error in stopping timer");
207 		}
208 	}
209 
210 	wlan_serialization_release_lock(&psoc_ser_obj->timer_lock);
211 error:
212 	return status;
213 }
214 
215 QDF_STATUS wlan_serialization_cleanup_all_timers(
216 			struct wlan_ser_psoc_obj *psoc_ser_obj)
217 {
218 	struct wlan_serialization_timer *ser_timer;
219 	QDF_STATUS status = QDF_STATUS_SUCCESS;
220 	uint32_t i = 0;
221 
222 	if (!psoc_ser_obj) {
223 		ser_err("Invalid psoc_ser_obj");
224 		status = QDF_STATUS_E_FAILURE;
225 		goto error;
226 	}
227 
228 	wlan_serialization_acquire_lock(&psoc_ser_obj->timer_lock);
229 
230 	for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) {
231 		ser_timer = &psoc_ser_obj->timers[i];
232 		if (!ser_timer->cmd)
233 			continue;
234 		status = wlan_serialization_stop_timer(ser_timer);
235 		if (QDF_STATUS_SUCCESS != status) {
236 			/* lets not break the loop but report error */
237 			ser_err("some error in stopping timer");
238 		}
239 	}
240 
241 	wlan_serialization_release_lock(&psoc_ser_obj->timer_lock);
242 error:
243 
244 	return status;
245 }
246 
247 QDF_STATUS wlan_serialization_validate_cmdtype(
248 		 enum wlan_serialization_cmd_type cmd_type)
249 {
250 	if (cmd_type < 0 || cmd_type >= WLAN_SER_CMD_MAX) {
251 		ser_err("Invalid cmd %d passed", cmd_type);
252 		return QDF_STATUS_E_INVAL;
253 	}
254 
255 	return QDF_STATUS_SUCCESS;
256 }
257 
258 QDF_STATUS wlan_serialization_validate_cmd(
259 		 enum wlan_umac_comp_id comp_id,
260 		 enum wlan_serialization_cmd_type cmd_type)
261 {
262 	QDF_STATUS status = QDF_STATUS_E_INVAL;
263 
264 	if (cmd_type < 0 || comp_id < 0 || cmd_type >= WLAN_SER_CMD_MAX ||
265 	    comp_id >= WLAN_UMAC_COMP_ID_MAX) {
266 		ser_err("Invalid cmd or comp passed comp %d type %d",
267 			comp_id, cmd_type);
268 		goto error;
269 	}
270 
271 	status = QDF_STATUS_SUCCESS;
272 error:
273 	return status;
274 }
275 
276 QDF_STATUS wlan_serialization_validate_cmd_list(
277 		struct wlan_serialization_command_list *cmd_list)
278 {
279 	QDF_STATUS status = QDF_STATUS_E_INVAL;
280 
281 	if (!cmd_list->cmd.cmd_cb) {
282 		ser_err("no cmd_cb for cmd type:%d, id: %d",
283 			cmd_list->cmd.cmd_type, cmd_list->cmd.cmd_id);
284 		QDF_ASSERT(0);
285 		goto error;
286 	}
287 
288 	if (!cmd_list->cmd.vdev) {
289 		ser_err("invalid cmd.vdev");
290 		goto error;
291 	}
292 
293 	status = QDF_STATUS_SUCCESS;
294 
295 error:
296 	return status;
297 }
298 
299 static void wlan_serialization_release_pdev_list_cmds(
300 		struct wlan_serialization_pdev_queue *pdev_queue)
301 {
302 	qdf_list_node_t *node = NULL;
303 
304 	while (!wlan_serialization_list_empty(&pdev_queue->active_list)) {
305 		wlan_serialization_remove_front(
306 				&pdev_queue->active_list, &node);
307 		wlan_serialization_insert_back(
308 				&pdev_queue->cmd_pool_list, node);
309 	}
310 
311 	while (!wlan_serialization_list_empty(&pdev_queue->pending_list)) {
312 		wlan_serialization_remove_front(
313 				&pdev_queue->pending_list, &node);
314 		wlan_serialization_insert_back(
315 				&pdev_queue->cmd_pool_list, node);
316 	}
317 
318 }
319 
320 static void wlan_serialization_release_vdev_list_cmds(qdf_list_t *list)
321 {
322 	qdf_list_node_t *node = NULL;
323 
324 
325 	while (!wlan_serialization_list_empty(list))
326 		wlan_serialization_remove_front(list, &node);
327 
328 }
329 
330 void wlan_serialization_destroy_pdev_list(
331 		struct wlan_serialization_pdev_queue *pdev_queue)
332 {
333 
334 	wlan_serialization_release_pdev_list_cmds(pdev_queue);
335 	qdf_list_destroy(&pdev_queue->pending_list);
336 	qdf_list_destroy(&pdev_queue->active_list);
337 
338 }
339 
340 void wlan_serialization_destroy_vdev_list(qdf_list_t *list)
341 {
342 
343 	wlan_serialization_release_vdev_list_cmds(list);
344 	qdf_list_destroy(list);
345 
346 }
347 
348 struct wlan_ser_psoc_obj *wlan_serialization_get_psoc_obj(
349 		struct wlan_objmgr_psoc *psoc)
350 {
351 	struct wlan_ser_psoc_obj *ser_soc_obj;
352 
353 	ser_soc_obj =
354 		wlan_objmgr_psoc_get_comp_private_obj(
355 				psoc, WLAN_UMAC_COMP_SERIALIZATION);
356 
357 	return ser_soc_obj;
358 }
359 
360 struct wlan_ser_pdev_obj *wlan_serialization_get_pdev_obj(
361 		struct wlan_objmgr_pdev *pdev)
362 {
363 	struct wlan_ser_pdev_obj *obj;
364 
365 	obj = wlan_objmgr_pdev_get_comp_private_obj(
366 			pdev, WLAN_UMAC_COMP_SERIALIZATION);
367 
368 	return obj;
369 }
370 
371 struct wlan_ser_vdev_obj *wlan_serialization_get_vdev_obj(
372 		struct wlan_objmgr_vdev *vdev)
373 {
374 	struct wlan_ser_vdev_obj *obj;
375 
376 	obj = wlan_objmgr_vdev_get_comp_private_obj(
377 			vdev, WLAN_UMAC_COMP_SERIALIZATION);
378 
379 	return obj;
380 }
381 
382 bool wlan_serialization_is_cmd_in_vdev_list(
383 		struct wlan_objmgr_vdev *vdev,
384 		qdf_list_t *queue,
385 		enum wlan_serialization_node node_type)
386 {
387 	qdf_list_node_t *node = NULL;
388 	bool cmd_found = false;
389 
390 	node = wlan_serialization_find_cmd(
391 			queue, WLAN_SER_MATCH_VDEV,
392 			NULL, 0, NULL, vdev, node_type);
393 
394 	if (node)
395 		cmd_found = true;
396 
397 	return cmd_found;
398 }
399 
400 bool wlan_serialization_is_cmd_in_pdev_list(
401 			struct wlan_objmgr_pdev *pdev,
402 			qdf_list_t *queue)
403 {
404 	qdf_list_node_t *node = NULL;
405 	bool cmd_found = false;
406 
407 	node = wlan_serialization_find_cmd(
408 			queue, WLAN_SER_MATCH_PDEV,
409 			NULL, 0, pdev, NULL,  WLAN_SER_PDEV_NODE);
410 
411 	if (node)
412 		cmd_found = true;
413 
414 	return cmd_found;
415 }
416 
417 enum wlan_serialization_cmd_status
418 wlan_serialization_is_cmd_in_active_pending(bool cmd_in_active,
419 					    bool cmd_in_pending)
420 {
421 	enum wlan_serialization_cmd_status status;
422 
423 	if (cmd_in_active && cmd_in_pending)
424 		status = WLAN_SER_CMDS_IN_ALL_LISTS;
425 	else if (cmd_in_active)
426 		status = WLAN_SER_CMD_IN_ACTIVE_LIST;
427 	else if (cmd_in_pending)
428 		status = WLAN_SER_CMD_IN_PENDING_LIST;
429 	else
430 		status = WLAN_SER_CMD_NOT_FOUND;
431 
432 	return status;
433 }
434 
435 bool
436 wlan_serialization_is_cmd_present_in_given_queue(
437 		qdf_list_t *queue,
438 		struct wlan_serialization_command *cmd,
439 		enum wlan_serialization_node node_type)
440 {
441 	qdf_list_node_t *node = NULL;
442 	bool found = false;
443 
444 	node = wlan_serialization_find_cmd(
445 			queue, WLAN_SER_MATCH_CMD_ID_VDEV,
446 			cmd, 0, NULL, cmd->vdev, node_type);
447 
448 	if (node)
449 		found = true;
450 
451 	return found;
452 }
453 
454 /**
455  * wlan_serialization_remove_cmd_from_queue() - to remove command from
456  *							given queue
457  * @queue: queue from which command needs to be removed
458  * @cmd: command to match in the queue
459  * @ser_pdev_obj: pointer to private pdev serialization object
460  *
461  * This API takes the queue, it matches the provided command from this queue
462  * and removes it. Before removing the command, it will notify the caller
463  * that if it needs to remove any memory allocated by caller.
464  *
465  * Return: none
466  */
467 QDF_STATUS
468 wlan_serialization_remove_cmd_from_queue(
469 		qdf_list_t *queue,
470 		struct wlan_serialization_command *cmd,
471 		struct wlan_serialization_command_list **pcmd_list,
472 		struct wlan_ser_pdev_obj *ser_pdev_obj,
473 		enum wlan_serialization_node node_type)
474 {
475 	struct wlan_serialization_command_list *cmd_list;
476 	qdf_list_node_t *node = NULL;
477 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
478 
479 	if (!cmd)
480 		goto error;
481 
482 	if (!queue || wlan_serialization_list_empty(queue)) {
483 		ser_debug("Empty queue");
484 		goto error;
485 	}
486 
487 	node = wlan_serialization_find_cmd(queue, WLAN_SER_MATCH_CMD_ID_VDEV,
488 					   cmd, 0, NULL, cmd->vdev, node_type);
489 
490 	if (!node) {
491 		ser_info("fail to find node %d for removal", node_type);
492 		goto error;
493 	}
494 
495 	if (node_type == WLAN_SER_PDEV_NODE)
496 		cmd_list =
497 			qdf_container_of(node,
498 					 struct wlan_serialization_command_list,
499 					 pdev_node);
500 	else
501 		cmd_list =
502 			qdf_container_of(node,
503 					 struct wlan_serialization_command_list,
504 					 vdev_node);
505 
506 	if (qdf_atomic_test_bit(CMD_MARKED_FOR_ACTIVATION,
507 				&cmd_list->cmd_in_use)) {
508 		qdf_atomic_set_bit(CMD_ACTIVE_MARKED_FOR_REMOVAL,
509 				   &cmd_list->cmd_in_use);
510 		status = QDF_STATUS_E_PENDING;
511 		goto error;
512 	}
513 
514 	status = wlan_serialization_remove_node(queue, node);
515 
516 	if (QDF_STATUS_SUCCESS != status)
517 		ser_err("Fail to add to free pool type %d",
518 			cmd->cmd_type);
519 
520 	*pcmd_list = cmd_list;
521 
522 error:
523 	return status;
524 }
525 
526 enum wlan_serialization_status
527 wlan_serialization_add_cmd_to_queue(
528 		qdf_list_t *queue,
529 		struct wlan_serialization_command_list *cmd_list,
530 		struct wlan_ser_pdev_obj *ser_pdev_obj,
531 		uint8_t is_cmd_for_active_queue,
532 		enum wlan_serialization_node node_type)
533 {
534 	enum wlan_serialization_status status = WLAN_SER_CMD_DENIED_UNSPECIFIED;
535 	QDF_STATUS qdf_status;
536 	qdf_list_node_t *node;
537 
538 	if (!cmd_list || !queue || !ser_pdev_obj) {
539 		ser_err("Input arguments are not valid");
540 		goto error;
541 	}
542 
543 	if (node_type == WLAN_SER_PDEV_NODE)
544 		node = &cmd_list->pdev_node;
545 	else
546 		node = &cmd_list->vdev_node;
547 
548 	if (qdf_list_size(queue) == qdf_list_max_size(queue)) {
549 		status = WLAN_SER_CMD_DENIED_LIST_FULL;
550 		ser_err("Queue size reached max %d, fail to add type %d id %d",
551 			qdf_list_max_size(queue), cmd_list->cmd.cmd_type,
552 			cmd_list->cmd.cmd_id);
553 		goto error;
554 	}
555 
556 	if (cmd_list->cmd.is_high_priority)
557 		qdf_status = wlan_serialization_insert_front(queue, node);
558 	else
559 		qdf_status = wlan_serialization_insert_back(queue, node);
560 
561 	if (QDF_IS_STATUS_ERROR(qdf_status))
562 		goto error;
563 
564 	if (is_cmd_for_active_queue)
565 		status = WLAN_SER_CMD_ACTIVE;
566 	else
567 		status = WLAN_SER_CMD_PENDING;
568 
569 error:
570 	return status;
571 }
572 
573 bool wlan_serialization_list_empty(qdf_list_t *queue)
574 {
575 	bool is_empty;
576 
577 	if (qdf_list_empty(queue))
578 		is_empty = true;
579 	else
580 		is_empty = false;
581 
582 	return is_empty;
583 }
584 
585 uint32_t wlan_serialization_list_size(qdf_list_t *queue)
586 {
587 	uint32_t size;
588 
589 	size = qdf_list_size(queue);
590 
591 	return size;
592 }
593 
594 QDF_STATUS wlan_serialization_remove_front(qdf_list_t *list,
595 					   qdf_list_node_t **node)
596 {
597 	QDF_STATUS status;
598 
599 	if (wlan_serialization_list_empty(list)) {
600 		ser_err("The list is empty");
601 		status = QDF_STATUS_E_EMPTY;
602 		goto error;
603 	}
604 
605 	status = qdf_list_remove_front(list, node);
606 error:
607 	return status;
608 }
609 
610 QDF_STATUS wlan_serialization_remove_node(qdf_list_t *list,
611 					  qdf_list_node_t *node)
612 {
613 	QDF_STATUS status;
614 
615 	if (wlan_serialization_list_empty(list)) {
616 		ser_err("The list is empty");
617 		status = QDF_STATUS_E_EMPTY;
618 		goto error;
619 	}
620 	status = qdf_list_remove_node(list, node);
621 
622 error:
623 	return status;
624 }
625 
626 QDF_STATUS wlan_serialization_insert_front(qdf_list_t *list,
627 					   qdf_list_node_t *node)
628 {
629 	QDF_STATUS status;
630 
631 	status = qdf_list_insert_front(list, node);
632 
633 	return status;
634 }
635 
636 QDF_STATUS wlan_serialization_insert_back(qdf_list_t *list,
637 					  qdf_list_node_t *node)
638 {
639 	QDF_STATUS status;
640 
641 	status = qdf_list_insert_back(list, node);
642 
643 	return status;
644 }
645 
646 QDF_STATUS wlan_serialization_peek_front(qdf_list_t *list,
647 					 qdf_list_node_t **node)
648 {
649 	QDF_STATUS status;
650 
651 	status = qdf_list_peek_front(list, node);
652 
653 	return status;
654 }
655 
656 QDF_STATUS wlan_serialization_peek_next(qdf_list_t *list,
657 					qdf_list_node_t *node1,
658 					qdf_list_node_t **node2)
659 {
660 	QDF_STATUS status;
661 
662 	status = qdf_list_peek_next(list, node1, node2);
663 
664 	return status;
665 }
666 
667 bool
668 wlan_serialization_match_cmd_type(qdf_list_node_t *nnode,
669 				  enum wlan_serialization_cmd_type cmd_type,
670 				  enum wlan_serialization_node node_type)
671 {
672 	struct wlan_serialization_command_list *cmd_list = NULL;
673 	bool match_found = true;
674 
675 	if (node_type == WLAN_SER_PDEV_NODE)
676 		cmd_list =
677 			qdf_container_of(nnode,
678 					 struct wlan_serialization_command_list,
679 					 pdev_node);
680 	else
681 		cmd_list =
682 			qdf_container_of(nnode,
683 					 struct wlan_serialization_command_list,
684 					 vdev_node);
685 
686 	if (cmd_list->cmd.cmd_type != cmd_type)
687 		match_found = false;
688 
689 	return match_found;
690 }
691 
692 bool
693 wlan_serialization_match_cmd_id_type(qdf_list_node_t *nnode,
694 				     struct wlan_serialization_command *cmd,
695 				     enum wlan_serialization_node node_type)
696 {
697 	struct wlan_serialization_command_list *cmd_list = NULL;
698 	bool match_found = true;
699 
700 	if (!cmd) {
701 		match_found = false;
702 		goto error;
703 	}
704 
705 	if (node_type == WLAN_SER_PDEV_NODE)
706 		cmd_list =
707 			qdf_container_of(nnode,
708 					 struct wlan_serialization_command_list,
709 					 pdev_node);
710 	else
711 		cmd_list =
712 			qdf_container_of(nnode,
713 					 struct wlan_serialization_command_list,
714 					 vdev_node);
715 
716 	if ((cmd_list->cmd.cmd_id != cmd->cmd_id) ||
717 	    (cmd_list->cmd.cmd_type != cmd->cmd_type)) {
718 		match_found = false;
719 	};
720 
721 error:
722 	return match_found;
723 }
724 
725 bool wlan_serialization_match_cmd_vdev(qdf_list_node_t *nnode,
726 				       struct wlan_objmgr_vdev *vdev,
727 				       enum wlan_serialization_node node_type)
728 {
729 	struct wlan_serialization_command_list *cmd_list = NULL;
730 	bool match_found = false;
731 
732 	if (node_type == WLAN_SER_PDEV_NODE)
733 		cmd_list =
734 			qdf_container_of(nnode,
735 					 struct wlan_serialization_command_list,
736 					 pdev_node);
737 	else
738 		cmd_list =
739 			qdf_container_of(nnode,
740 					 struct wlan_serialization_command_list,
741 					 vdev_node);
742 
743 	if (cmd_list->cmd.vdev == vdev)
744 		match_found = true;
745 
746 	if (!match_found)
747 		ser_debug("matching cmd not found for (vdev:%pK)", vdev);
748 
749 	return match_found;
750 }
751 
752 bool wlan_serialization_match_cmd_pdev(qdf_list_node_t *nnode,
753 				       struct wlan_objmgr_pdev *pdev,
754 				       enum wlan_serialization_node node_type)
755 {
756 	struct wlan_serialization_command_list *cmd_list = NULL;
757 	bool match_found = false;
758 	struct wlan_objmgr_pdev *node_pdev = NULL;
759 
760 	if (node_type == WLAN_SER_PDEV_NODE)
761 		cmd_list =
762 			qdf_container_of(nnode,
763 					 struct wlan_serialization_command_list,
764 					 pdev_node);
765 	else
766 		cmd_list =
767 			qdf_container_of(nnode,
768 					 struct wlan_serialization_command_list,
769 					 vdev_node);
770 
771 	node_pdev = wlan_vdev_get_pdev(cmd_list->cmd.vdev);
772 	if (node_pdev == pdev)
773 		match_found = true;
774 
775 	return match_found;
776 }
777 
778 bool wlan_serialization_match_cmd_blocking(
779 		qdf_list_node_t *nnode,
780 		enum wlan_serialization_node node_type)
781 {
782 	struct wlan_serialization_command_list *cmd_list = NULL;
783 	bool match_found = false;
784 
785 	if (node_type == WLAN_SER_PDEV_NODE)
786 		cmd_list =
787 			qdf_container_of(nnode,
788 					 struct wlan_serialization_command_list,
789 					 pdev_node);
790 	else
791 		cmd_list =
792 			qdf_container_of(nnode,
793 					 struct wlan_serialization_command_list,
794 					 vdev_node);
795 
796 	if (cmd_list->cmd.is_blocking)
797 		match_found = true;
798 
799 	return match_found;
800 }
801 
802 qdf_list_node_t *
803 wlan_serialization_find_cmd(qdf_list_t *queue,
804 			    enum wlan_serialization_match_type match_type,
805 			    struct wlan_serialization_command *cmd,
806 			    enum wlan_serialization_cmd_type cmd_type,
807 			    struct wlan_objmgr_pdev *pdev,
808 			    struct wlan_objmgr_vdev *vdev,
809 			    enum wlan_serialization_node node_type)
810 {
811 	qdf_list_node_t *cmd_node = NULL;
812 	uint32_t queuelen;
813 	qdf_list_node_t *nnode = NULL;
814 	QDF_STATUS status;
815 	bool node_found = 0;
816 
817 	queuelen = wlan_serialization_list_size(queue);
818 
819 	if (!queuelen)
820 		goto error;
821 
822 	while (queuelen--) {
823 		status = wlan_serialization_get_cmd_from_queue(queue, &nnode);
824 		if (status != QDF_STATUS_SUCCESS)
825 			break;
826 
827 		switch (match_type) {
828 		case WLAN_SER_MATCH_PDEV:
829 			if (wlan_serialization_match_cmd_pdev(
830 					nnode, pdev, WLAN_SER_PDEV_NODE))
831 				node_found = 1;
832 			break;
833 		case WLAN_SER_MATCH_VDEV:
834 			if (wlan_serialization_match_cmd_vdev(
835 					nnode, vdev, node_type))
836 				node_found = 1;
837 			break;
838 		case WLAN_SER_MATCH_CMD_TYPE_VDEV:
839 			if (wlan_serialization_match_cmd_type(
840 					nnode, cmd_type, node_type) &&
841 			    wlan_serialization_match_cmd_vdev(
842 					nnode, vdev, node_type))
843 				node_found = 1;
844 			break;
845 		case WLAN_SER_MATCH_CMD_ID_VDEV:
846 			if (wlan_serialization_match_cmd_id_type(
847 					nnode, cmd, node_type) &&
848 			    wlan_serialization_match_cmd_vdev(
849 					nnode, vdev, node_type))
850 				node_found = 1;
851 			break;
852 		default:
853 			break;
854 		}
855 
856 		if (node_found) {
857 			cmd_node = nnode;
858 			break;
859 		}
860 	}
861 error:
862 	return cmd_node;
863 }
864 
865 QDF_STATUS
866 wlan_serialization_acquire_lock(qdf_spinlock_t *lock)
867 {
868 	qdf_spin_lock_bh(lock);
869 
870 	return QDF_STATUS_SUCCESS;
871 }
872 
873 QDF_STATUS
874 wlan_serialization_release_lock(qdf_spinlock_t *lock)
875 {
876 	qdf_spin_unlock_bh(lock);
877 
878 	return QDF_STATUS_SUCCESS;
879 }
880 
881 QDF_STATUS
882 wlan_serialization_create_lock(qdf_spinlock_t *lock)
883 {
884 	qdf_spinlock_create(lock);
885 
886 	return QDF_STATUS_SUCCESS;
887 }
888 
889 QDF_STATUS
890 wlan_serialization_destroy_lock(qdf_spinlock_t *lock)
891 {
892 	qdf_spinlock_destroy(lock);
893 
894 	return QDF_STATUS_SUCCESS;
895 }
896 
897 bool wlan_serialization_any_vdev_cmd_active(
898 		struct wlan_serialization_pdev_queue *pdev_queue)
899 {
900 	uint32_t vdev_bitmap_size;
901 
902 	vdev_bitmap_size =
903 		(QDF_CHAR_BIT * sizeof(pdev_queue->vdev_active_cmd_bitmap));
904 
905 	return !qdf_bitmap_empty(pdev_queue->vdev_active_cmd_bitmap,
906 				 vdev_bitmap_size);
907 }
908