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