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