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