xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_non_scan.c (revision a86b23ee68a2491aede2e03991f3fb37046f4e41)
1 /*
2  * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 /**
19  * DOC: wlan_serialization_non_scan.c
20  * This file defines the functions which deals with
21  * serialization non scan commands.
22  */
23 
24 #include <wlan_objmgr_psoc_obj.h>
25 #include <wlan_objmgr_pdev_obj.h>
26 #include <wlan_objmgr_vdev_obj.h>
27 #include "wlan_serialization_main_i.h"
28 #include "wlan_serialization_utils_i.h"
29 #include "wlan_serialization_non_scan_i.h"
30 #include "qdf_util.h"
31 
32 bool
33 wlan_serialization_is_non_scan_pending_queue_empty(
34 		struct wlan_serialization_command *cmd)
35 {
36 	struct wlan_objmgr_vdev *vdev = NULL;
37 	struct wlan_ser_vdev_obj *ser_vdev_obj = NULL;
38 	struct wlan_serialization_vdev_queue *vdev_q;
39 	bool status = false;
40 
41 	vdev = wlan_serialization_get_vdev_from_cmd(cmd);
42 
43 	if (!vdev) {
44 		ser_err("vdev object  is invalid");
45 		goto error;
46 	}
47 
48 	ser_vdev_obj = wlan_serialization_get_vdev_obj(vdev);
49 	vdev_q = &ser_vdev_obj->vdev_q[SER_VDEV_QUEUE_COMP_NON_SCAN];
50 
51 	if (qdf_list_empty(&vdev_q->pending_list))
52 		status = true;
53 
54 error:
55 	return status;
56 }
57 
58 /**
59  * wlan_serialization_is_active_nonscan_cmd_allowed() - find if cmd allowed
60  * @pdev: pointer to pdev object
61  *
62  * This API will be called to find out if non scan cmd is allowed.
63  *
64  * Return: true or false
65  */
66 
67 bool
68 wlan_serialization_is_active_non_scan_cmd_allowed(
69 		struct wlan_serialization_command *cmd)
70 {
71 	struct wlan_serialization_pdev_queue *pdev_queue;
72 	struct wlan_ser_pdev_obj *ser_pdev_obj;
73 	unsigned long *vdev_active_cmd_bitmap;
74 	bool blocking_cmd_active = 0;
75 	uint8_t blocking_cmd_waiting = 0;
76 	bool status = false;
77 	uint32_t vdev_id;
78 
79 	ser_pdev_obj = wlan_serialization_get_pdev_obj(
80 			wlan_serialization_get_pdev_from_cmd(cmd));
81 
82 	pdev_queue = wlan_serialization_get_pdev_queue_obj(ser_pdev_obj,
83 							   cmd->cmd_type);
84 
85 	vdev_active_cmd_bitmap = pdev_queue->vdev_active_cmd_bitmap;
86 
87 	blocking_cmd_active = pdev_queue->blocking_cmd_active;
88 	blocking_cmd_waiting = pdev_queue->blocking_cmd_waiting;
89 
90 	/*
91 	 * Command is blocking
92 	 */
93 	if (cmd->is_blocking) {
94 		/*
95 		 * For blocking commands, no other
96 		 * commands from any vdev should be active
97 		 */
98 
99 		if (wlan_serialization_any_vdev_cmd_active(pdev_queue)) {
100 			status = false;
101 			pdev_queue->blocking_cmd_waiting++;
102 		} else {
103 			status = true;
104 		}
105 	} else {
106 		/*
107 		 * Command is non blocking
108 		 * For activating non blocking commands, if there any blocking
109 		 * commands, waiting or active, put it to pending queue
110 		 */
111 		if (blocking_cmd_active || blocking_cmd_waiting) {
112 			status = false;
113 		} else {
114 		/*
115 		 * For non blocking command, and no blocking commands
116 		 * waiting or active, check if a cmd for that vdev is active
117 		 * If not active, put to active else pending queue
118 		 */
119 			vdev_id = wlan_vdev_get_id(cmd->vdev);
120 			status = qdf_test_bit(vdev_id, vdev_active_cmd_bitmap)
121 						? false : true;
122 
123 			ser_debug_hex(
124 				vdev_active_cmd_bitmap,
125 				sizeof(pdev_queue->vdev_active_cmd_bitmap));
126 
127 		}
128 	}
129 	return status;
130 }
131 
132 enum wlan_serialization_status wlan_ser_add_non_scan_cmd(
133 		struct wlan_ser_pdev_obj *ser_pdev_obj,
134 		struct wlan_serialization_command_list *cmd_list,
135 		uint8_t is_cmd_for_active_queue)
136 {
137 	enum wlan_serialization_status pdev_status, vdev_status;
138 	enum wlan_serialization_status status = WLAN_SER_CMD_DENIED_UNSPECIFIED;
139 	struct wlan_serialization_command_list *pcmd_list;
140 	uint8_t vdev_id;
141 	struct wlan_serialization_pdev_queue *pdev_queue;
142 
143 	vdev_status = wlan_serialization_add_cmd_to_vdev_queue(
144 			ser_pdev_obj, cmd_list, is_cmd_for_active_queue);
145 
146 	if (vdev_status == WLAN_SER_CMD_DENIED_LIST_FULL) {
147 		ser_err_rl("List is full cannot add type %d cmd id %d",
148 			   cmd_list->cmd.cmd_type, cmd_list->cmd.cmd_id);
149 		status = vdev_status;
150 		goto vdev_error;
151 	}
152 
153 	if (is_cmd_for_active_queue) {
154 		if (vdev_status != WLAN_SER_CMD_ACTIVE) {
155 			ser_err("Failed to add type %d cmd id %d to vdev active queue",
156 				cmd_list->cmd.cmd_type, cmd_list->cmd.cmd_id);
157 			QDF_ASSERT(0);
158 			goto vdev_error;
159 		}
160 	} else {
161 		if (vdev_status != WLAN_SER_CMD_PENDING) {
162 			ser_err("Failed to add type %d cmd id %d to vdev pending queue",
163 				cmd_list->cmd.cmd_type, cmd_list->cmd.cmd_id);
164 			QDF_ASSERT(0);
165 			goto vdev_error;
166 		}
167 	}
168 
169 	pdev_status = wlan_serialization_add_cmd_to_pdev_queue(
170 			ser_pdev_obj, cmd_list, is_cmd_for_active_queue);
171 
172 	if (pdev_status == WLAN_SER_CMD_DENIED_LIST_FULL) {
173 		ser_err_rl("pdev List is full cannot add type %d cmd id %d",
174 			   cmd_list->cmd.cmd_type, cmd_list->cmd.cmd_id);
175 		status = pdev_status;
176 		goto pdev_error;
177 	}
178 
179 	if (is_cmd_for_active_queue) {
180 		if (pdev_status != WLAN_SER_CMD_ACTIVE) {
181 			ser_err("Failed to add type %d cmd id %d to pdev active queue",
182 				cmd_list->cmd.cmd_type, cmd_list->cmd.cmd_id);
183 			QDF_ASSERT(0);
184 			goto pdev_error;
185 		}
186 	} else {
187 		if (pdev_status != WLAN_SER_CMD_PENDING) {
188 			ser_err("Failed to add type %d cmd id %d to pdev pending queue",
189 				cmd_list->cmd.cmd_type, cmd_list->cmd.cmd_id);
190 			QDF_ASSERT(0);
191 			goto pdev_error;
192 		}
193 	}
194 pdev_error:
195 	/*
196 	 * If cmd added to vdev queue, but failed while
197 	 * adding to pdev queue, remove cmd from vdev queue as well
198 	 */
199 	if (pdev_status != vdev_status) {
200 		wlan_serialization_remove_cmd_from_vdev_queue(
201 			ser_pdev_obj, &pcmd_list,
202 			&cmd_list->cmd,
203 			is_cmd_for_active_queue);
204 		goto vdev_error;
205 	} else {
206 		status = pdev_status;
207 	}
208 
209 	if (is_cmd_for_active_queue) {
210 		pdev_queue = wlan_serialization_get_pdev_queue_obj(
211 				ser_pdev_obj, cmd_list->cmd.cmd_type);
212 		vdev_id = wlan_vdev_get_id(cmd_list->cmd.vdev);
213 		qdf_set_bit(vdev_id, pdev_queue->vdev_active_cmd_bitmap);
214 
215 		if (cmd_list->cmd.is_blocking)
216 			pdev_queue->blocking_cmd_active = 1;
217 	}
218 
219 vdev_error:
220 	return status;
221 }
222 
223 enum wlan_serialization_status
224 wlan_ser_move_non_scan_pending_to_active(
225 		struct wlan_ser_pdev_obj *ser_pdev_obj,
226 		struct wlan_objmgr_vdev *vdev,
227 		bool blocking_cmd_removed)
228 {
229 	struct wlan_serialization_command_list *pending_cmd_list = NULL;
230 	struct wlan_serialization_command_list *next_cmd_list = NULL;
231 	struct wlan_serialization_command_list *active_cmd_list;
232 	struct wlan_serialization_command cmd_to_remove;
233 	enum wlan_serialization_status status = WLAN_SER_CMD_DENIED_UNSPECIFIED;
234 	struct wlan_serialization_pdev_queue *pdev_queue;
235 	struct wlan_serialization_vdev_queue *vdev_queue;
236 
237 	struct wlan_ser_vdev_obj *ser_vdev_obj;
238 
239 	qdf_list_t *pending_queue;
240 	qdf_list_node_t *pending_node = NULL;
241 	qdf_list_node_t *next_node = NULL;
242 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
243 	uint32_t blocking_cmd_waiting = 0;
244 	uint32_t vdev_id;
245 	uint32_t qsize;
246 	bool vdev_cmd_active = 0;
247 	bool vdev_queue_lookup = false;
248 
249 	pdev_queue = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN];
250 
251 	ser_vdev_obj = wlan_serialization_get_vdev_obj(vdev);
252 	vdev_queue = &ser_vdev_obj->vdev_q[SER_VDEV_QUEUE_COMP_NON_SCAN];
253 
254 	if (!ser_pdev_obj) {
255 		ser_err("Can't find ser_pdev_obj");
256 		goto error;
257 	}
258 
259 	wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock);
260 
261 	blocking_cmd_waiting = pdev_queue->blocking_cmd_waiting;
262 
263 	if (!blocking_cmd_removed && !blocking_cmd_waiting) {
264 		pending_queue = &vdev_queue->pending_list;
265 		vdev_queue_lookup = true;
266 	} else {
267 		pending_queue = &pdev_queue->pending_list;
268 	}
269 
270 	qsize =  wlan_serialization_list_size(pending_queue);
271 	if (!qsize) {
272 		wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
273 		goto error;
274 	}
275 
276 	qdf_status = wlan_serialization_peek_front(pending_queue,
277 						   &pending_node);
278 	if (qdf_status != QDF_STATUS_SUCCESS) {
279 		ser_err("can't peek cmd");
280 		wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
281 		goto error;
282 	}
283 
284 	while (qsize--) {
285 		if (vdev_queue_lookup) {
286 			pending_cmd_list =
287 				qdf_container_of(
288 				pending_node,
289 				struct wlan_serialization_command_list,
290 				vdev_node);
291 		} else {
292 			pending_cmd_list =
293 				qdf_container_of(
294 				pending_node,
295 				struct wlan_serialization_command_list,
296 				pdev_node);
297 		}
298 
299 		if (!pending_cmd_list) {
300 			wlan_serialization_release_lock(
301 				&pdev_queue->pdev_queue_lock);
302 			ser_debug(
303 				"non scan cmd cannot move frm pendin to actv");
304 			goto error;
305 		}
306 
307 		vdev_id = wlan_vdev_get_id(pending_cmd_list->cmd.vdev);
308 		vdev_cmd_active = qdf_test_bit(
309 				vdev_id, pdev_queue->vdev_active_cmd_bitmap);
310 
311 		if (!vdev_queue_lookup) {
312 			if (pending_cmd_list->cmd.is_blocking &&
313 			    wlan_serialization_any_vdev_cmd_active(
314 					pdev_queue)) {
315 				break;
316 			}
317 			/*
318 			 * For the last node we dont need the next node
319 			 */
320 			if (qsize) {
321 				qdf_status = wlan_serialization_peek_next(
322 					pending_queue,
323 					pending_node,
324 					&next_node);
325 
326 				if (qdf_status != QDF_STATUS_SUCCESS) {
327 					ser_err("can't peek cmd");
328 					break;
329 				}
330 
331 				pending_node = next_node;
332 
333 				next_cmd_list = qdf_container_of(
334 					next_node,
335 					struct wlan_serialization_command_list,
336 					pdev_node);
337 
338 				qdf_atomic_set_bit(CMD_MARKED_FOR_MOVEMENT,
339 						   &next_cmd_list->cmd_in_use);
340 			}
341 
342 			if (vdev_cmd_active)
343 				continue;
344 
345 		} else {
346 			if (vdev_cmd_active)
347 				break;
348 
349 			if (qdf_atomic_test_bit(
350 					CMD_MARKED_FOR_MOVEMENT,
351 					&pending_cmd_list->cmd_in_use)) {
352 				break;
353 			}
354 		}
355 
356 		qdf_mem_copy(&cmd_to_remove, &pending_cmd_list->cmd,
357 			     sizeof(struct wlan_serialization_command));
358 
359 		qdf_status = wlan_ser_remove_non_scan_cmd(ser_pdev_obj,
360 							  &pending_cmd_list,
361 							  &cmd_to_remove,
362 							  false);
363 
364 		wlan_ser_update_cmd_history(
365 				pdev_queue, &pending_cmd_list->cmd,
366 				SER_PENDING_TO_ACTIVE,
367 				false, false);
368 
369 		if (QDF_STATUS_SUCCESS != qdf_status) {
370 			wlan_serialization_release_lock(
371 					&pdev_queue->pdev_queue_lock);
372 			ser_err("Can't remove cmd from pendingQ id-%d type-%d",
373 				pending_cmd_list->cmd.cmd_id,
374 				pending_cmd_list->cmd.cmd_type);
375 			QDF_ASSERT(0);
376 			status = WLAN_SER_CMD_DENIED_UNSPECIFIED;
377 			goto error;
378 		}
379 
380 		active_cmd_list = pending_cmd_list;
381 
382 		status = wlan_ser_add_non_scan_cmd(
383 				ser_pdev_obj, active_cmd_list, true);
384 
385 		if (WLAN_SER_CMD_ACTIVE != status) {
386 			wlan_serialization_release_lock(
387 					&pdev_queue->pdev_queue_lock);
388 			ser_err("Can't move cmd to activeQ id-%d type-%d",
389 				pending_cmd_list->cmd.cmd_id,
390 				pending_cmd_list->cmd.cmd_type);
391 			wlan_serialization_insert_back(
392 				&pdev_queue->cmd_pool_list,
393 				&active_cmd_list->pdev_node);
394 			status = WLAN_SER_CMD_DENIED_UNSPECIFIED;
395 			QDF_ASSERT(0);
396 			goto error;
397 		}
398 
399 		wlan_ser_update_cmd_history(
400 				pdev_queue, &active_cmd_list->cmd,
401 				SER_PENDING_TO_ACTIVE,
402 				true, true);
403 
404 		qdf_atomic_set_bit(CMD_MARKED_FOR_ACTIVATION,
405 				   &active_cmd_list->cmd_in_use);
406 
407 		if (active_cmd_list->cmd.is_blocking)
408 			pdev_queue->blocking_cmd_waiting--;
409 
410 		wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
411 
412 		wlan_serialization_activate_cmd(active_cmd_list, ser_pdev_obj,
413 						SER_PENDING_TO_ACTIVE);
414 
415 		wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock);
416 
417 		if (vdev_queue_lookup || pdev_queue->blocking_cmd_active)
418 			break;
419 
420 		if (next_cmd_list) {
421 			qdf_atomic_clear_bit(CMD_MARKED_FOR_MOVEMENT,
422 					     &next_cmd_list->cmd_in_use);
423 		}
424 
425 		next_cmd_list = NULL;
426 	}
427 
428 	wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
429 error:
430 
431 	return status;
432 }
433 
434 QDF_STATUS wlan_ser_remove_non_scan_cmd(
435 		struct wlan_ser_pdev_obj *ser_pdev_obj,
436 		struct wlan_serialization_command_list **pcmd_list,
437 		struct wlan_serialization_command *cmd,
438 		uint8_t is_active_cmd)
439 {
440 	QDF_STATUS pdev_status, vdev_status;
441 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
442 	uint32_t vdev_id;
443 	bool blocking_cmd_removed = 0;
444 	struct wlan_serialization_pdev_queue *pdev_queue;
445 
446 	vdev_status =
447 		wlan_serialization_remove_cmd_from_vdev_queue(ser_pdev_obj,
448 							      pcmd_list,
449 							      cmd,
450 							      is_active_cmd);
451 
452 	/* Here command removal can fail for 2 reasons
453 	 * 1. The cmd is not present
454 	 * 2. The command had not returned from activation
455 	 *    and will not be removed now.
456 	 *
457 	 *  In the second case, we should not flag it as error
458 	 *  since it will removed after the activation completes.
459 	 */
460 
461 	if (vdev_status != QDF_STATUS_SUCCESS) {
462 		status = vdev_status;
463 		if (vdev_status != QDF_STATUS_E_PENDING)
464 			ser_debug("Failed to remove type %d id %d from vdev queue",
465 				  cmd->cmd_type, cmd->cmd_id);
466 		goto error;
467 	}
468 
469 	pdev_status =
470 		wlan_serialization_remove_cmd_from_pdev_queue(ser_pdev_obj,
471 							      pcmd_list,
472 							      cmd,
473 							      is_active_cmd);
474 
475 	if (pdev_status != QDF_STATUS_SUCCESS) {
476 		ser_debug("Failed to remove type %d id %d from pdev active/pending queue",
477 			  cmd->cmd_type, cmd->cmd_id);
478 		goto error;
479 	}
480 
481 	if (is_active_cmd) {
482 		blocking_cmd_removed = (*pcmd_list)->cmd.is_blocking;
483 		pdev_queue = wlan_serialization_get_pdev_queue_obj(
484 				ser_pdev_obj, (*pcmd_list)->cmd.cmd_type);
485 
486 		if (blocking_cmd_removed)
487 			pdev_queue->blocking_cmd_active = 0;
488 
489 		vdev_id = wlan_vdev_get_id(cmd->vdev);
490 		qdf_clear_bit(vdev_id, pdev_queue->vdev_active_cmd_bitmap);
491 	}
492 
493 	status = QDF_STATUS_SUCCESS;
494 
495 error:
496 	return status;
497 }
498 
499 enum wlan_serialization_cmd_status
500 wlan_ser_cancel_non_scan_cmd(
501 		struct wlan_ser_pdev_obj *ser_pdev_obj,
502 		struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev,
503 		struct wlan_serialization_command *cmd,
504 		enum wlan_serialization_cmd_type cmd_type,
505 		uint8_t is_active_queue, enum wlan_ser_cmd_attr cmd_attr)
506 {
507 	qdf_list_t *pdev_queue;
508 	qdf_list_t *vdev_queue;
509 	struct wlan_serialization_pdev_queue *pdev_q;
510 	uint32_t qsize;
511 	uint8_t vdev_id;
512 	bool is_blocking;
513 	struct wlan_serialization_command_list *cmd_list = NULL;
514 	struct wlan_serialization_command cmd_bkup;
515 	qdf_list_node_t *nnode = NULL, *pnode = NULL;
516 	enum wlan_serialization_cmd_status status = WLAN_SER_CMD_NOT_FOUND;
517 	struct wlan_objmgr_psoc *psoc = NULL;
518 	QDF_STATUS qdf_status;
519 	QDF_STATUS pdev_status, vdev_status;
520 	struct wlan_ser_vdev_obj *ser_vdev_obj;
521 
522 	pdev_q = wlan_serialization_get_pdev_queue_obj(ser_pdev_obj, cmd_type);
523 
524 	pdev_queue = wlan_serialization_get_list_from_pdev_queue(
525 			ser_pdev_obj, cmd_type, is_active_queue);
526 
527 	if (pdev)
528 		psoc = wlan_pdev_get_psoc(pdev);
529 	else if (vdev)
530 		psoc = wlan_vdev_get_psoc(vdev);
531 	else if (cmd && cmd->vdev)
532 		psoc = wlan_vdev_get_psoc(cmd->vdev);
533 	else
534 		ser_debug("Can't find psoc");
535 
536 	wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
537 
538 	qsize = wlan_serialization_list_size(pdev_queue);
539 	while (!wlan_serialization_list_empty(pdev_queue) && qsize--) {
540 		if (wlan_serialization_get_cmd_from_queue(pdev_queue, &nnode)
541 		    != QDF_STATUS_SUCCESS) {
542 			ser_err("can't read cmd from queue");
543 			status = WLAN_SER_CMD_NOT_FOUND;
544 			break;
545 		}
546 		cmd_list =
547 			qdf_container_of(nnode,
548 					 struct wlan_serialization_command_list,
549 					 pdev_node);
550 		if (cmd && !wlan_serialization_match_cmd_id_type(
551 							nnode, cmd,
552 							WLAN_SER_PDEV_NODE)) {
553 			pnode = nnode;
554 			continue;
555 		}
556 
557 		if (vdev &&
558 		    !wlan_serialization_match_cmd_vdev(nnode,
559 						      vdev,
560 						      WLAN_SER_PDEV_NODE)) {
561 			pnode = nnode;
562 			continue;
563 		}
564 
565 		if (pdev &&
566 		    !wlan_serialization_match_cmd_pdev(nnode,
567 						       pdev,
568 						       WLAN_SER_PDEV_NODE)) {
569 			pnode = nnode;
570 			continue;
571 		}
572 
573 		if (cmd_type > WLAN_SER_CMD_NONSCAN && vdev &&
574 		    (!wlan_serialization_match_cmd_type(nnode, cmd_type,
575 							WLAN_SER_PDEV_NODE) ||
576 		    !wlan_serialization_match_cmd_vdev(nnode, vdev,
577 						       WLAN_SER_PDEV_NODE))) {
578 			pnode = nnode;
579 			continue;
580 		}
581 
582 		/*
583 		 * If a non-blocking cmd is required to be cancelled, but
584 		 * the nnode cmd is a blocking cmd then continue with the
585 		 * next command in the list else proceed with cmd cancel.
586 		 */
587 		if ((cmd_attr == WLAN_SER_CMD_ATTR_NONBLOCK) &&
588 		    wlan_serialization_match_cmd_blocking(nnode,
589 							  WLAN_SER_PDEV_NODE)) {
590 			pnode = nnode;
591 			continue;
592 		}
593 
594 		/*
595 		 * active queue can't be removed directly, requester needs to
596 		 * wait for active command response and send remove request for
597 		 * active command separately
598 		 */
599 		if (is_active_queue) {
600 			if (!psoc || !cmd_list) {
601 				ser_err("psoc:0x%pK, cmd_list:0x%pK",
602 					psoc, cmd_list);
603 				status = WLAN_SER_CMD_NOT_FOUND;
604 				break;
605 			}
606 
607 			/* Cancel request received for a cmd in active
608 			 * queue which has not been activated yet, we mark
609 			 * it as CMD_ACTIVE_MARKED_FOR_CANCEL and remove
610 			 * the cmd after activation
611 			 */
612 			if (qdf_atomic_test_bit(CMD_MARKED_FOR_ACTIVATION,
613 						&cmd_list->cmd_in_use)) {
614 				qdf_atomic_set_bit(CMD_ACTIVE_MARKED_FOR_CANCEL,
615 						   &cmd_list->cmd_in_use);
616 				status = WLAN_SER_CMD_MARKED_FOR_ACTIVATION;
617 				continue;
618 			}
619 
620 			qdf_status = wlan_serialization_find_and_stop_timer(
621 							psoc, &cmd_list->cmd,
622 							SER_CANCEL);
623 			if (QDF_IS_STATUS_ERROR(qdf_status)) {
624 				ser_err("Can't find timer for active cmd");
625 				status = WLAN_SER_CMD_NOT_FOUND;
626 				/*
627 				 * This should not happen, as an active command
628 				 * should always have the timer.
629 				 */
630 				QDF_BUG(0);
631 				break;
632 			}
633 
634 			status = WLAN_SER_CMD_IN_ACTIVE_LIST;
635 		}
636 
637 		qdf_mem_copy(&cmd_bkup, &cmd_list->cmd,
638 			     sizeof(struct wlan_serialization_command));
639 
640 		pdev_status =
641 			wlan_serialization_remove_node(pdev_queue,
642 						       &cmd_list->pdev_node);
643 
644 		ser_vdev_obj = wlan_serialization_get_vdev_obj(
645 					cmd_list->cmd.vdev);
646 
647 		vdev_queue = wlan_serialization_get_list_from_vdev_queue(
648 			ser_vdev_obj, cmd_type, is_active_queue);
649 
650 		vdev_status =
651 			wlan_serialization_remove_node(vdev_queue,
652 						       &cmd_list->vdev_node);
653 
654 		if (pdev_status != QDF_STATUS_SUCCESS ||
655 		    vdev_status != QDF_STATUS_SUCCESS) {
656 			ser_err("can't remove cmd from pdev/vdev queue");
657 			status = WLAN_SER_CMD_NOT_FOUND;
658 			break;
659 		}
660 
661 		qdf_mem_zero(&cmd_list->cmd,
662 			     sizeof(struct wlan_serialization_command));
663 		cmd_list->cmd_in_use = 0;
664 		qdf_status = wlan_serialization_insert_back(
665 			&pdev_q->cmd_pool_list,
666 			&cmd_list->pdev_node);
667 
668 		if (QDF_STATUS_SUCCESS != qdf_status) {
669 			ser_err("can't remove cmd from queue");
670 			status = WLAN_SER_CMD_NOT_FOUND;
671 			break;
672 		}
673 		nnode = pnode;
674 
675 		vdev_id = wlan_vdev_get_id(cmd_bkup.vdev);
676 		is_blocking = cmd_bkup.is_blocking;
677 
678 		wlan_ser_update_cmd_history(pdev_q, &cmd_bkup,
679 					    SER_CANCEL, false, is_active_queue);
680 
681 		wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
682 		/*
683 		 * call pending cmd's callback to notify that
684 		 * it is being removed
685 		 */
686 		if (cmd_bkup.cmd_cb) {
687 			/* caller should now do necessary clean up */
688 			ser_debug("Cancel command: type %d id %d and Release memory",
689 				  cmd_bkup.cmd_type, cmd_bkup.cmd_id);
690 			cmd_bkup.cmd_cb(&cmd_bkup, WLAN_SER_CB_CANCEL_CMD);
691 			/* caller should release the memory */
692 			cmd_bkup.cmd_cb(&cmd_bkup, WLAN_SER_CB_RELEASE_MEM_CMD);
693 		}
694 
695 		wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
696 
697 		if (is_active_queue) {
698 			if (is_blocking)
699 				pdev_q->blocking_cmd_active = 0;
700 
701 			qdf_clear_bit(vdev_id, pdev_q->vdev_active_cmd_bitmap);
702 
703 			ser_debug("active_cmd_bitmap after resetting vdev %d",
704 				  vdev_id);
705 			ser_debug_hex(pdev_q->vdev_active_cmd_bitmap,
706 				      sizeof(pdev_q->vdev_active_cmd_bitmap));
707 
708 		} else {
709 			if (is_blocking)
710 				pdev_q->blocking_cmd_waiting--;
711 
712 			status = WLAN_SER_CMD_IN_PENDING_LIST;
713 		}
714 
715 
716 		if (!vdev && !pdev)
717 			break;
718 	}
719 
720 	wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
721 
722 	return status;
723 }
724