xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_utils.c (revision 503663c6daafffe652fa360bde17243568cd6d2a)
1 /*
2  * Copyright (c) 2017-2019 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 	ser_debug("Destroying the timer");
131 	qdf_timer_stop(&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 	ser_enter();
165 
166 	pdev = wlan_vdev_get_pdev(vdev);
167 	if (!pdev) {
168 		QDF_BUG(0);
169 		ser_err("pdev is null");
170 		status = QDF_STATUS_E_FAILURE;
171 		goto error;
172 	}
173 
174 	psoc = wlan_pdev_get_psoc(pdev);
175 	if (!psoc) {
176 		QDF_BUG(0);
177 		ser_err("psoc is null");
178 		status = QDF_STATUS_E_FAILURE;
179 		goto error;
180 	}
181 
182 	psoc_ser_obj = wlan_serialization_get_psoc_obj(psoc);
183 
184 	if (!psoc_ser_obj) {
185 		ser_err("Invalid psoc_ser_obj");
186 		status = QDF_STATUS_E_FAILURE;
187 		goto error;
188 	}
189 
190 	wlan_serialization_acquire_lock(&psoc_ser_obj->timer_lock);
191 
192 	for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) {
193 		ser_timer = &psoc_ser_obj->timers[i];
194 		if (!ser_timer->cmd)
195 			continue;
196 		/*
197 		 * Check if the timer is for the given vdev
198 		 */
199 		if (ser_timer->cmd->vdev != vdev)
200 			continue;
201 
202 		ser_debug("Stopping the timer for vdev id[%d]",
203 			  wlan_vdev_get_id(vdev));
204 
205 		status = wlan_serialization_stop_timer(ser_timer);
206 		if (QDF_STATUS_SUCCESS != status) {
207 			/* lets not break the loop but report error */
208 			ser_err("some error in stopping timer");
209 		}
210 	}
211 
212 	wlan_serialization_release_lock(&psoc_ser_obj->timer_lock);
213 error:
214 	ser_exit();
215 	return status;
216 }
217 
218 QDF_STATUS wlan_serialization_cleanup_all_timers(
219 			struct wlan_ser_psoc_obj *psoc_ser_obj)
220 {
221 	struct wlan_serialization_timer *ser_timer;
222 	QDF_STATUS status = QDF_STATUS_SUCCESS;
223 	uint32_t i = 0;
224 
225 	ser_enter();
226 
227 	if (!psoc_ser_obj) {
228 		ser_err("Invalid psoc_ser_obj");
229 		status = QDF_STATUS_E_FAILURE;
230 		goto error;
231 	}
232 
233 	wlan_serialization_acquire_lock(&psoc_ser_obj->timer_lock);
234 
235 	for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) {
236 		ser_timer = &psoc_ser_obj->timers[i];
237 		if (!ser_timer->cmd)
238 			continue;
239 		status = wlan_serialization_stop_timer(ser_timer);
240 		if (QDF_STATUS_SUCCESS != status) {
241 			/* lets not break the loop but report error */
242 			ser_err("some error in stopping timer");
243 		}
244 	}
245 
246 	wlan_serialization_release_lock(&psoc_ser_obj->timer_lock);
247 error:
248 	ser_exit();
249 	return status;
250 }
251 
252 QDF_STATUS wlan_serialization_validate_cmdtype(
253 		 enum wlan_serialization_cmd_type cmd_type)
254 {
255 	if (cmd_type < 0 || cmd_type >= WLAN_SER_CMD_MAX) {
256 		ser_err("Invalid cmd or comp passed");
257 		return QDF_STATUS_E_INVAL;
258 	}
259 
260 	return QDF_STATUS_SUCCESS;
261 }
262 
263 QDF_STATUS wlan_serialization_validate_cmd(
264 		 enum wlan_umac_comp_id comp_id,
265 		 enum wlan_serialization_cmd_type cmd_type)
266 {
267 	QDF_STATUS status = QDF_STATUS_E_INVAL;
268 
269 	if (cmd_type < 0 || comp_id < 0 ||
270 	    cmd_type >= WLAN_SER_CMD_MAX ||
271 	   comp_id >= WLAN_UMAC_COMP_ID_MAX) {
272 		ser_err("Invalid cmd or comp passed");
273 		goto error;
274 	}
275 
276 	status = QDF_STATUS_SUCCESS;
277 error:
278 	return status;
279 }
280 
281 QDF_STATUS wlan_serialization_validate_cmd_list(
282 		struct wlan_serialization_command_list *cmd_list)
283 {
284 	QDF_STATUS status = QDF_STATUS_E_INVAL;
285 
286 	if (!cmd_list->cmd.cmd_cb) {
287 		ser_err("no cmd_cb for cmd type:%d, id: %d",
288 			cmd_list->cmd.cmd_type, cmd_list->cmd.cmd_id);
289 		QDF_ASSERT(0);
290 		goto error;
291 	}
292 
293 	if (!cmd_list->cmd.vdev) {
294 		ser_err("invalid cmd.vdev");
295 		goto error;
296 	}
297 
298 	status = QDF_STATUS_SUCCESS;
299 
300 error:
301 	return status;
302 }
303 
304 static void wlan_serialization_release_pdev_list_cmds(
305 		struct wlan_serialization_pdev_queue *pdev_queue)
306 {
307 	qdf_list_node_t *node = NULL;
308 
309 	while (!wlan_serialization_list_empty(&pdev_queue->active_list)) {
310 		wlan_serialization_remove_front(
311 				&pdev_queue->active_list, &node);
312 		wlan_serialization_insert_back(
313 				&pdev_queue->cmd_pool_list, node);
314 	}
315 
316 	while (!wlan_serialization_list_empty(&pdev_queue->pending_list)) {
317 		wlan_serialization_remove_front(
318 				&pdev_queue->pending_list, &node);
319 		wlan_serialization_insert_back(
320 				&pdev_queue->cmd_pool_list, node);
321 	}
322 
323 }
324 
325 static void wlan_serialization_release_vdev_list_cmds(qdf_list_t *list)
326 {
327 	qdf_list_node_t *node = NULL;
328 
329 
330 	while (!wlan_serialization_list_empty(list))
331 		wlan_serialization_remove_front(list, &node);
332 
333 }
334 
335 void wlan_serialization_destroy_pdev_list(
336 		struct wlan_serialization_pdev_queue *pdev_queue)
337 {
338 
339 	wlan_serialization_release_pdev_list_cmds(pdev_queue);
340 	qdf_list_destroy(&pdev_queue->pending_list);
341 	qdf_list_destroy(&pdev_queue->active_list);
342 
343 }
344 
345 void wlan_serialization_destroy_vdev_list(qdf_list_t *list)
346 {
347 	ser_enter();
348 
349 	wlan_serialization_release_vdev_list_cmds(list);
350 	qdf_list_destroy(list);
351 
352 	ser_exit();
353 }
354 
355 struct wlan_ser_psoc_obj *wlan_serialization_get_psoc_obj(
356 		struct wlan_objmgr_psoc *psoc)
357 {
358 	struct wlan_ser_psoc_obj *ser_soc_obj;
359 
360 	ser_soc_obj =
361 		wlan_objmgr_psoc_get_comp_private_obj(
362 				psoc, WLAN_UMAC_COMP_SERIALIZATION);
363 
364 	return ser_soc_obj;
365 }
366 
367 struct wlan_ser_pdev_obj *wlan_serialization_get_pdev_obj(
368 		struct wlan_objmgr_pdev *pdev)
369 {
370 	struct wlan_ser_pdev_obj *obj;
371 
372 	obj = wlan_objmgr_pdev_get_comp_private_obj(
373 			pdev, WLAN_UMAC_COMP_SERIALIZATION);
374 
375 	return obj;
376 }
377 
378 struct wlan_ser_vdev_obj *wlan_serialization_get_vdev_obj(
379 		struct wlan_objmgr_vdev *vdev)
380 {
381 	struct wlan_ser_vdev_obj *obj;
382 
383 	obj = wlan_objmgr_vdev_get_comp_private_obj(
384 			vdev, WLAN_UMAC_COMP_SERIALIZATION);
385 
386 	return obj;
387 }
388 
389 bool wlan_serialization_is_cmd_in_vdev_list(
390 		struct wlan_objmgr_vdev *vdev,
391 		qdf_list_t *queue,
392 		enum wlan_serialization_node node_type)
393 {
394 	qdf_list_node_t *node = NULL;
395 	bool cmd_found = false;
396 
397 	node = wlan_serialization_find_cmd(
398 			queue, WLAN_SER_MATCH_VDEV,
399 			NULL, 0, NULL, vdev, node_type);
400 
401 	if (node)
402 		cmd_found = true;
403 
404 	return cmd_found;
405 }
406 
407 bool wlan_serialization_is_cmd_in_pdev_list(
408 			struct wlan_objmgr_pdev *pdev,
409 			qdf_list_t *queue)
410 {
411 	qdf_list_node_t *node = NULL;
412 	bool cmd_found = false;
413 
414 	node = wlan_serialization_find_cmd(
415 			queue, WLAN_SER_MATCH_PDEV,
416 			NULL, 0, pdev, NULL,  WLAN_SER_PDEV_NODE);
417 
418 	if (node)
419 		cmd_found = true;
420 
421 	return cmd_found;
422 }
423 
424 enum wlan_serialization_cmd_status
425 wlan_serialization_is_cmd_in_active_pending(bool cmd_in_active,
426 					    bool cmd_in_pending)
427 {
428 	enum wlan_serialization_cmd_status status;
429 
430 	if (cmd_in_active && cmd_in_pending)
431 		status = WLAN_SER_CMDS_IN_ALL_LISTS;
432 	else if (cmd_in_active)
433 		status = WLAN_SER_CMD_IN_ACTIVE_LIST;
434 	else if (cmd_in_pending)
435 		status = WLAN_SER_CMD_IN_PENDING_LIST;
436 	else
437 		status = WLAN_SER_CMD_NOT_FOUND;
438 
439 	return status;
440 }
441 
442 bool
443 wlan_serialization_is_cmd_present_in_given_queue(
444 		qdf_list_t *queue,
445 		struct wlan_serialization_command *cmd,
446 		enum wlan_serialization_node node_type)
447 {
448 	qdf_list_node_t *node = NULL;
449 	bool found = false;
450 
451 	node = wlan_serialization_find_cmd(
452 			queue, WLAN_SER_MATCH_CMD_ID_VDEV,
453 			cmd, 0, NULL, cmd->vdev, node_type);
454 
455 	if (node)
456 		found = true;
457 
458 	return found;
459 }
460 
461 /**
462  * wlan_serialization_remove_cmd_from_queue() - to remove command from
463  *							given queue
464  * @queue: queue from which command needs to be removed
465  * @cmd: command to match in the queue
466  * @ser_pdev_obj: pointer to private pdev serialization object
467  *
468  * This API takes the queue, it matches the provided command from this queue
469  * and removes it. Before removing the command, it will notify the caller
470  * that if it needs to remove any memory allocated by caller.
471  *
472  * Return: none
473  */
474 QDF_STATUS
475 wlan_serialization_remove_cmd_from_queue(
476 		qdf_list_t *queue,
477 		struct wlan_serialization_command *cmd,
478 		struct wlan_serialization_command_list **pcmd_list,
479 		struct wlan_ser_pdev_obj *ser_pdev_obj,
480 		enum wlan_serialization_node node_type)
481 {
482 	struct wlan_serialization_command_list *cmd_list;
483 	qdf_list_node_t *node = NULL;
484 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
485 
486 	if (!cmd)
487 		goto error;
488 
489 	if (!queue || wlan_serialization_list_empty(queue)) {
490 		ser_debug("Empty queue");
491 		goto error;
492 	}
493 
494 	node = wlan_serialization_find_cmd(queue, WLAN_SER_MATCH_CMD_ID_VDEV,
495 					   cmd, 0, NULL, cmd->vdev, node_type);
496 
497 	if (!node)
498 		goto error;
499 
500 	if (node_type == WLAN_SER_PDEV_NODE)
501 		cmd_list =
502 			qdf_container_of(node,
503 					 struct wlan_serialization_command_list,
504 					 pdev_node);
505 	else
506 		cmd_list =
507 			qdf_container_of(node,
508 					 struct wlan_serialization_command_list,
509 					 vdev_node);
510 
511 	ser_debug("Matching command found for removal from queue");
512 	ser_debug("remove cmd: type[%d] id[%d] prio[%d] blocking[%d]",
513 		  cmd_list->cmd.cmd_type,
514 			  cmd_list->cmd.cmd_id,
515 			  cmd_list->cmd.is_high_priority,
516 			  cmd_list->cmd.is_blocking);
517 
518 	if (qdf_atomic_test_bit(CMD_MARKED_FOR_ACTIVATION,
519 				&cmd_list->cmd_in_use)) {
520 		qdf_atomic_set_bit(CMD_ACTIVE_MARKED_FOR_REMOVAL,
521 				   &cmd_list->cmd_in_use);
522 		status = QDF_STATUS_E_PENDING;
523 		goto error;
524 	}
525 
526 	status = wlan_serialization_remove_node(queue, node);
527 
528 	if (QDF_STATUS_SUCCESS != status)
529 		ser_err("Fail to add to free pool type[%d]",
530 			cmd->cmd_type);
531 
532 	*pcmd_list = cmd_list;
533 
534 error:
535 	return status;
536 }
537 
538 enum wlan_serialization_status
539 wlan_serialization_add_cmd_to_queue(
540 		qdf_list_t *queue,
541 		struct wlan_serialization_command_list *cmd_list,
542 		struct wlan_ser_pdev_obj *ser_pdev_obj,
543 		uint8_t is_cmd_for_active_queue,
544 		enum wlan_serialization_node node_type)
545 {
546 	enum wlan_serialization_status status = WLAN_SER_CMD_DENIED_UNSPECIFIED;
547 	QDF_STATUS qdf_status;
548 	qdf_list_node_t *node;
549 
550 	if (!cmd_list || !queue || !ser_pdev_obj) {
551 		ser_err("Input arguments are not valid");
552 		goto error;
553 	}
554 
555 	if (node_type == WLAN_SER_PDEV_NODE) {
556 		node = &cmd_list->pdev_node;
557 		ser_debug("pdev_queue: %pK", queue);
558 	} else {
559 		node = &cmd_list->vdev_node;
560 		ser_debug("vdev_queue: %pK", queue);
561 	}
562 
563 	ser_debug("add cmd: type[%d] id[%d] high_priority[%d] blocking[%d]",
564 		  cmd_list->cmd.cmd_type,
565 		  cmd_list->cmd.cmd_id,
566 		  cmd_list->cmd.is_high_priority,
567 		  cmd_list->cmd.is_blocking);
568 
569 	if (qdf_list_size(queue) == qdf_list_max_size(queue)) {
570 		status = WLAN_SER_CMD_DENIED_LIST_FULL;
571 		ser_err("qdf_list_size: %d is already max %d",
572 			qdf_list_size(queue), qdf_list_max_size(queue));
573 		goto error;
574 	}
575 
576 	if (cmd_list->cmd.is_high_priority)
577 		qdf_status = wlan_serialization_insert_front(queue, node);
578 	else
579 		qdf_status = wlan_serialization_insert_back(queue, node);
580 
581 	if (QDF_IS_STATUS_ERROR(qdf_status))
582 		goto error;
583 
584 	ser_debug("adding cmd to node: %pK", node);
585 
586 	if (is_cmd_for_active_queue)
587 		status = WLAN_SER_CMD_ACTIVE;
588 	else
589 		status = WLAN_SER_CMD_PENDING;
590 
591 error:
592 	return status;
593 }
594 
595 bool wlan_serialization_list_empty(qdf_list_t *queue)
596 {
597 	bool is_empty;
598 
599 	if (qdf_list_empty(queue))
600 		is_empty = true;
601 	else
602 		is_empty = false;
603 
604 	return is_empty;
605 }
606 
607 uint32_t wlan_serialization_list_size(qdf_list_t *queue)
608 {
609 	uint32_t size;
610 
611 	size = qdf_list_size(queue);
612 
613 	return size;
614 }
615 
616 QDF_STATUS wlan_serialization_remove_front(qdf_list_t *list,
617 					   qdf_list_node_t **node)
618 {
619 	QDF_STATUS status;
620 
621 	if (wlan_serialization_list_empty(list)) {
622 		ser_err("The list is empty");
623 		status = QDF_STATUS_E_EMPTY;
624 		goto error;
625 	}
626 
627 	status = qdf_list_remove_front(list, node);
628 error:
629 	return status;
630 }
631 
632 QDF_STATUS wlan_serialization_remove_node(qdf_list_t *list,
633 					  qdf_list_node_t *node)
634 {
635 	QDF_STATUS status;
636 
637 	if (wlan_serialization_list_empty(list)) {
638 		ser_err("The list is empty");
639 		status = QDF_STATUS_E_EMPTY;
640 		goto error;
641 	}
642 	status = qdf_list_remove_node(list, node);
643 
644 error:
645 	return status;
646 }
647 
648 QDF_STATUS wlan_serialization_insert_front(qdf_list_t *list,
649 					   qdf_list_node_t *node)
650 {
651 	QDF_STATUS status;
652 
653 	status = qdf_list_insert_front(list, node);
654 
655 	return status;
656 }
657 
658 QDF_STATUS wlan_serialization_insert_back(qdf_list_t *list,
659 					  qdf_list_node_t *node)
660 {
661 	QDF_STATUS status;
662 
663 	status = qdf_list_insert_back(list, node);
664 
665 	return status;
666 }
667 
668 QDF_STATUS wlan_serialization_peek_front(qdf_list_t *list,
669 					 qdf_list_node_t **node)
670 {
671 	QDF_STATUS status;
672 
673 	status = qdf_list_peek_front(list, node);
674 
675 	return status;
676 }
677 
678 QDF_STATUS wlan_serialization_peek_next(qdf_list_t *list,
679 					qdf_list_node_t *node1,
680 					qdf_list_node_t **node2)
681 {
682 	QDF_STATUS status;
683 
684 	status = qdf_list_peek_next(list, node1, node2);
685 
686 	return status;
687 }
688 
689 bool
690 wlan_serialization_match_cmd_type(qdf_list_node_t *nnode,
691 				  enum wlan_serialization_cmd_type cmd_type,
692 				  enum wlan_serialization_node node_type)
693 {
694 	struct wlan_serialization_command_list *cmd_list = NULL;
695 	bool match_found = true;
696 
697 	if (node_type == WLAN_SER_PDEV_NODE)
698 		cmd_list =
699 			qdf_container_of(nnode,
700 					 struct wlan_serialization_command_list,
701 					 pdev_node);
702 	else
703 		cmd_list =
704 			qdf_container_of(nnode,
705 					 struct wlan_serialization_command_list,
706 					 vdev_node);
707 
708 	if (cmd_list->cmd.cmd_type != cmd_type)
709 		match_found = false;
710 
711 	return match_found;
712 }
713 
714 bool
715 wlan_serialization_match_cmd_id_type(qdf_list_node_t *nnode,
716 				     struct wlan_serialization_command *cmd,
717 				     enum wlan_serialization_node node_type)
718 {
719 	struct wlan_serialization_command_list *cmd_list = NULL;
720 	bool match_found = true;
721 
722 	if (!cmd) {
723 		match_found = false;
724 		goto error;
725 	}
726 
727 	if (node_type == WLAN_SER_PDEV_NODE)
728 		cmd_list =
729 			qdf_container_of(nnode,
730 					 struct wlan_serialization_command_list,
731 					 pdev_node);
732 	else
733 		cmd_list =
734 			qdf_container_of(nnode,
735 					 struct wlan_serialization_command_list,
736 					 vdev_node);
737 
738 	if ((cmd_list->cmd.cmd_id != cmd->cmd_id) ||
739 	    (cmd_list->cmd.cmd_type != cmd->cmd_type)) {
740 		match_found = false;
741 	};
742 
743 error:
744 	return match_found;
745 }
746 
747 bool wlan_serialization_match_cmd_vdev(qdf_list_node_t *nnode,
748 				       struct wlan_objmgr_vdev *vdev,
749 				       enum wlan_serialization_node node_type)
750 {
751 	struct wlan_serialization_command_list *cmd_list = NULL;
752 	bool match_found = false;
753 
754 	if (node_type == WLAN_SER_PDEV_NODE)
755 		cmd_list =
756 			qdf_container_of(nnode,
757 					 struct wlan_serialization_command_list,
758 					 pdev_node);
759 	else
760 		cmd_list =
761 			qdf_container_of(nnode,
762 					 struct wlan_serialization_command_list,
763 					 vdev_node);
764 
765 	if (cmd_list->cmd.vdev == vdev)
766 		match_found = true;
767 
768 	ser_debug("matching cmd found(vdev:%pK): %d", vdev, match_found);
769 	return match_found;
770 }
771 
772 bool wlan_serialization_match_cmd_pdev(qdf_list_node_t *nnode,
773 				       struct wlan_objmgr_pdev *pdev,
774 				       enum wlan_serialization_node node_type)
775 {
776 	struct wlan_serialization_command_list *cmd_list = NULL;
777 	bool match_found = false;
778 	struct wlan_objmgr_pdev *node_pdev = NULL;
779 
780 	if (node_type == WLAN_SER_PDEV_NODE)
781 		cmd_list =
782 			qdf_container_of(nnode,
783 					 struct wlan_serialization_command_list,
784 					 pdev_node);
785 	else
786 		cmd_list =
787 			qdf_container_of(nnode,
788 					 struct wlan_serialization_command_list,
789 					 vdev_node);
790 
791 	node_pdev = wlan_vdev_get_pdev(cmd_list->cmd.vdev);
792 	if (node_pdev == pdev)
793 		match_found = true;
794 
795 	return match_found;
796 }
797 
798 bool wlan_serialization_match_cmd_blocking(
799 		qdf_list_node_t *nnode,
800 		enum wlan_serialization_node node_type)
801 {
802 	struct wlan_serialization_command_list *cmd_list = NULL;
803 	bool match_found = false;
804 
805 	if (node_type == WLAN_SER_PDEV_NODE)
806 		cmd_list =
807 			qdf_container_of(nnode,
808 					 struct wlan_serialization_command_list,
809 					 pdev_node);
810 	else
811 		cmd_list =
812 			qdf_container_of(nnode,
813 					 struct wlan_serialization_command_list,
814 					 vdev_node);
815 
816 	if (cmd_list->cmd.is_blocking)
817 		match_found = true;
818 
819 	return match_found;
820 }
821 
822 qdf_list_node_t *
823 wlan_serialization_find_cmd(qdf_list_t *queue,
824 			    enum wlan_serialization_match_type match_type,
825 			    struct wlan_serialization_command *cmd,
826 			    enum wlan_serialization_cmd_type cmd_type,
827 			    struct wlan_objmgr_pdev *pdev,
828 			    struct wlan_objmgr_vdev *vdev,
829 			    enum wlan_serialization_node node_type)
830 {
831 	qdf_list_node_t *cmd_node = NULL;
832 	uint32_t queuelen;
833 	qdf_list_node_t *nnode = NULL;
834 	QDF_STATUS status;
835 	bool node_found = 0;
836 
837 	queuelen = wlan_serialization_list_size(queue);
838 
839 	if (!queuelen) {
840 		ser_debug("queue empty");
841 		goto error;
842 	}
843 
844 	while (queuelen--) {
845 		status = wlan_serialization_get_cmd_from_queue(queue, &nnode);
846 		if (status != QDF_STATUS_SUCCESS)
847 			break;
848 
849 		switch (match_type) {
850 		case WLAN_SER_MATCH_PDEV:
851 			if (wlan_serialization_match_cmd_pdev(
852 					nnode, pdev, WLAN_SER_PDEV_NODE))
853 				node_found = 1;
854 			break;
855 		case WLAN_SER_MATCH_VDEV:
856 			if (wlan_serialization_match_cmd_vdev(
857 					nnode, vdev, node_type))
858 				node_found = 1;
859 			break;
860 		case WLAN_SER_MATCH_CMD_TYPE:
861 			if (wlan_serialization_match_cmd_type(
862 					nnode, cmd_type, node_type))
863 				node_found = 1;
864 			break;
865 		case WLAN_SER_MATCH_CMD_ID:
866 			if (wlan_serialization_match_cmd_id_type(
867 					nnode, cmd, node_type))
868 				node_found = 1;
869 			break;
870 		case WLAN_SER_MATCH_CMD_TYPE_VDEV:
871 			if (wlan_serialization_match_cmd_type(
872 					nnode, cmd_type, node_type) &&
873 			    wlan_serialization_match_cmd_vdev(
874 					nnode, vdev, node_type))
875 				node_found = 1;
876 			break;
877 		case WLAN_SER_MATCH_CMD_ID_VDEV:
878 			if (wlan_serialization_match_cmd_id_type(
879 					nnode, cmd, node_type) &&
880 			    wlan_serialization_match_cmd_vdev(
881 					nnode, vdev, node_type))
882 				node_found = 1;
883 			break;
884 		default:
885 			break;
886 		}
887 
888 		if (node_found) {
889 			cmd_node = nnode;
890 			break;
891 		}
892 	}
893 error:
894 	return cmd_node;
895 }
896 
897 QDF_STATUS
898 wlan_serialization_acquire_lock(qdf_spinlock_t *lock)
899 {
900 	qdf_spin_lock_bh(lock);
901 
902 	return QDF_STATUS_SUCCESS;
903 }
904 
905 QDF_STATUS
906 wlan_serialization_release_lock(qdf_spinlock_t *lock)
907 {
908 	qdf_spin_unlock_bh(lock);
909 
910 	return QDF_STATUS_SUCCESS;
911 }
912 
913 QDF_STATUS
914 wlan_serialization_create_lock(qdf_spinlock_t *lock)
915 {
916 	qdf_spinlock_create(lock);
917 
918 	return QDF_STATUS_SUCCESS;
919 }
920 
921 QDF_STATUS
922 wlan_serialization_destroy_lock(qdf_spinlock_t *lock)
923 {
924 	qdf_spinlock_destroy(lock);
925 
926 	return QDF_STATUS_SUCCESS;
927 }
928