xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_non_scan.c (revision 97f44cd39e4ff816eaa1710279d28cf6b9e65ad9)
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 	if (!ser_pdev_obj) {
250 		ser_err("Can't find ser_pdev_obj");
251 		goto error;
252 	}
253 
254 	pdev_queue = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN];
255 
256 	ser_vdev_obj = wlan_serialization_get_vdev_obj(vdev);
257 
258 	if (!ser_vdev_obj) {
259 		ser_err("Can't find ser_vdev_obj");
260 		goto error;
261 	}
262 
263 	vdev_queue = &ser_vdev_obj->vdev_q[SER_VDEV_QUEUE_COMP_NON_SCAN];
264 
265 	wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock);
266 
267 	blocking_cmd_waiting = pdev_queue->blocking_cmd_waiting;
268 
269 	if (!blocking_cmd_removed && !blocking_cmd_waiting) {
270 		pending_queue = &vdev_queue->pending_list;
271 		vdev_queue_lookup = true;
272 	} else {
273 		pending_queue = &pdev_queue->pending_list;
274 	}
275 
276 	qsize =  wlan_serialization_list_size(pending_queue);
277 	if (!qsize) {
278 		wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
279 		goto error;
280 	}
281 
282 	qdf_status = wlan_serialization_peek_front(pending_queue,
283 						   &pending_node);
284 	if (qdf_status != QDF_STATUS_SUCCESS) {
285 		ser_err("can't peek cmd");
286 		wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
287 		goto error;
288 	}
289 
290 	while (qsize--) {
291 		if (vdev_queue_lookup) {
292 			pending_cmd_list =
293 				qdf_container_of(
294 				pending_node,
295 				struct wlan_serialization_command_list,
296 				vdev_node);
297 		} else {
298 			pending_cmd_list =
299 				qdf_container_of(
300 				pending_node,
301 				struct wlan_serialization_command_list,
302 				pdev_node);
303 		}
304 
305 		if (!pending_cmd_list) {
306 			wlan_serialization_release_lock(
307 				&pdev_queue->pdev_queue_lock);
308 			ser_debug(
309 				"non scan cmd cannot move frm pendin to actv");
310 			goto error;
311 		}
312 
313 		vdev_id = wlan_vdev_get_id(pending_cmd_list->cmd.vdev);
314 		vdev_cmd_active = qdf_test_bit(
315 				vdev_id, pdev_queue->vdev_active_cmd_bitmap);
316 
317 		if (!vdev_queue_lookup) {
318 			if (pending_cmd_list->cmd.is_blocking &&
319 			    wlan_serialization_any_vdev_cmd_active(
320 					pdev_queue)) {
321 				break;
322 			}
323 			/*
324 			 * For the last node we dont need the next node
325 			 */
326 			if (qsize) {
327 				qdf_status = wlan_serialization_peek_next(
328 					pending_queue,
329 					pending_node,
330 					&next_node);
331 
332 				if (qdf_status != QDF_STATUS_SUCCESS) {
333 					ser_err("can't peek cmd");
334 					break;
335 				}
336 
337 				pending_node = next_node;
338 
339 				next_cmd_list = qdf_container_of(
340 					next_node,
341 					struct wlan_serialization_command_list,
342 					pdev_node);
343 
344 				qdf_atomic_set_bit(CMD_MARKED_FOR_MOVEMENT,
345 						   &next_cmd_list->cmd_in_use);
346 			}
347 
348 			if (vdev_cmd_active) {
349 				qdf_atomic_clear_bit(CMD_MARKED_FOR_MOVEMENT,
350 						     &pending_cmd_list->cmd_in_use);
351 				continue;
352 			}
353 		} else {
354 			if (vdev_cmd_active)
355 				break;
356 
357 			if (qdf_atomic_test_bit(
358 					CMD_MARKED_FOR_MOVEMENT,
359 					&pending_cmd_list->cmd_in_use)) {
360 				break;
361 			}
362 		}
363 
364 		qdf_mem_copy(&cmd_to_remove, &pending_cmd_list->cmd,
365 			     sizeof(struct wlan_serialization_command));
366 
367 		qdf_status = wlan_ser_remove_non_scan_cmd(ser_pdev_obj,
368 							  &pending_cmd_list,
369 							  &cmd_to_remove,
370 							  false);
371 
372 		wlan_ser_update_cmd_history(
373 				pdev_queue, &pending_cmd_list->cmd,
374 				SER_PENDING_TO_ACTIVE,
375 				false, false);
376 
377 		if (QDF_STATUS_SUCCESS != qdf_status) {
378 			wlan_serialization_release_lock(
379 					&pdev_queue->pdev_queue_lock);
380 			ser_err("Can't remove cmd from pendingQ id-%d type-%d",
381 				pending_cmd_list->cmd.cmd_id,
382 				pending_cmd_list->cmd.cmd_type);
383 			QDF_ASSERT(0);
384 			status = WLAN_SER_CMD_DENIED_UNSPECIFIED;
385 			goto error;
386 		}
387 
388 		active_cmd_list = pending_cmd_list;
389 
390 		status = wlan_ser_add_non_scan_cmd(
391 				ser_pdev_obj, active_cmd_list, true);
392 
393 		if (WLAN_SER_CMD_ACTIVE != status) {
394 			wlan_serialization_release_lock(
395 					&pdev_queue->pdev_queue_lock);
396 			ser_err("Can't move cmd to activeQ id-%d type-%d",
397 				pending_cmd_list->cmd.cmd_id,
398 				pending_cmd_list->cmd.cmd_type);
399 			wlan_serialization_insert_back(
400 				&pdev_queue->cmd_pool_list,
401 				&active_cmd_list->pdev_node);
402 			status = WLAN_SER_CMD_DENIED_UNSPECIFIED;
403 			QDF_ASSERT(0);
404 			goto error;
405 		}
406 
407 		wlan_ser_update_cmd_history(
408 				pdev_queue, &active_cmd_list->cmd,
409 				SER_PENDING_TO_ACTIVE,
410 				true, true);
411 
412 		qdf_atomic_set_bit(CMD_MARKED_FOR_ACTIVATION,
413 				   &active_cmd_list->cmd_in_use);
414 
415 		if (active_cmd_list->cmd.is_blocking)
416 			pdev_queue->blocking_cmd_waiting--;
417 
418 		wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
419 
420 		wlan_serialization_activate_cmd(active_cmd_list, ser_pdev_obj,
421 						SER_PENDING_TO_ACTIVE);
422 
423 		wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock);
424 
425 		if (vdev_queue_lookup || pdev_queue->blocking_cmd_active)
426 			break;
427 
428 		qsize =  wlan_serialization_list_size(pending_queue);
429 		if (!qsize) {
430 			wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
431 			goto error;
432 		}
433 
434 		qdf_status = wlan_serialization_peek_front(pending_queue,
435 							   &pending_node);
436 		if (qdf_status != QDF_STATUS_SUCCESS) {
437 			ser_err("can't peek cmd");
438 			wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
439 			goto error;
440 		}
441 	}
442 
443 	wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
444 error:
445 
446 	return status;
447 }
448 
449 QDF_STATUS wlan_ser_remove_non_scan_cmd(
450 		struct wlan_ser_pdev_obj *ser_pdev_obj,
451 		struct wlan_serialization_command_list **pcmd_list,
452 		struct wlan_serialization_command *cmd,
453 		uint8_t is_active_cmd)
454 {
455 	QDF_STATUS pdev_status, vdev_status;
456 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
457 	uint32_t vdev_id;
458 	bool blocking_cmd_removed = 0;
459 	struct wlan_serialization_pdev_queue *pdev_queue;
460 
461 	vdev_status =
462 		wlan_serialization_remove_cmd_from_vdev_queue(ser_pdev_obj,
463 							      pcmd_list,
464 							      cmd,
465 							      is_active_cmd);
466 
467 	/* Here command removal can fail for 2 reasons
468 	 * 1. The cmd is not present
469 	 * 2. The command had not returned from activation
470 	 *    and will not be removed now.
471 	 *
472 	 *  In the second case, we should not flag it as error
473 	 *  since it will removed after the activation completes.
474 	 */
475 
476 	if (vdev_status != QDF_STATUS_SUCCESS) {
477 		status = vdev_status;
478 		if (vdev_status != QDF_STATUS_E_PENDING)
479 			ser_debug("Failed to remove type %d id %d from vdev queue",
480 				  cmd->cmd_type, cmd->cmd_id);
481 		goto error;
482 	}
483 
484 	pdev_status =
485 		wlan_serialization_remove_cmd_from_pdev_queue(ser_pdev_obj,
486 							      pcmd_list,
487 							      cmd,
488 							      is_active_cmd);
489 
490 	if (pdev_status != QDF_STATUS_SUCCESS) {
491 		ser_debug("Failed to remove type %d id %d from pdev active/pending queue",
492 			  cmd->cmd_type, cmd->cmd_id);
493 		goto error;
494 	}
495 
496 	if (is_active_cmd) {
497 		blocking_cmd_removed = (*pcmd_list)->cmd.is_blocking;
498 		pdev_queue = wlan_serialization_get_pdev_queue_obj(
499 				ser_pdev_obj, (*pcmd_list)->cmd.cmd_type);
500 
501 		if (blocking_cmd_removed)
502 			pdev_queue->blocking_cmd_active = 0;
503 
504 		vdev_id = wlan_vdev_get_id(cmd->vdev);
505 		qdf_clear_bit(vdev_id, pdev_queue->vdev_active_cmd_bitmap);
506 	}
507 
508 	status = QDF_STATUS_SUCCESS;
509 
510 error:
511 	return status;
512 }
513 
514 enum wlan_serialization_cmd_status
515 wlan_ser_cancel_non_scan_cmd(
516 		struct wlan_ser_pdev_obj *ser_pdev_obj,
517 		struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev,
518 		struct wlan_serialization_command *cmd,
519 		enum wlan_serialization_cmd_type cmd_type,
520 		uint8_t is_active_queue, enum wlan_ser_cmd_attr cmd_attr)
521 {
522 	qdf_list_t *pdev_queue;
523 	qdf_list_t *vdev_queue;
524 	struct wlan_serialization_pdev_queue *pdev_q;
525 	uint32_t qsize;
526 	uint8_t vdev_id;
527 	bool is_blocking;
528 	struct wlan_serialization_command_list *cmd_list = NULL;
529 	struct wlan_serialization_command cmd_bkup;
530 	qdf_list_node_t *nnode = NULL, *pnode = NULL;
531 	enum wlan_serialization_cmd_status status = WLAN_SER_CMD_NOT_FOUND;
532 	struct wlan_objmgr_psoc *psoc = NULL;
533 	QDF_STATUS qdf_status;
534 	QDF_STATUS pdev_status, vdev_status;
535 	struct wlan_ser_vdev_obj *ser_vdev_obj;
536 
537 	pdev_q = wlan_serialization_get_pdev_queue_obj(ser_pdev_obj, cmd_type);
538 
539 	pdev_queue = wlan_serialization_get_list_from_pdev_queue(
540 			ser_pdev_obj, cmd_type, is_active_queue);
541 
542 	if (pdev)
543 		psoc = wlan_pdev_get_psoc(pdev);
544 	else if (vdev)
545 		psoc = wlan_vdev_get_psoc(vdev);
546 	else if (cmd && cmd->vdev)
547 		psoc = wlan_vdev_get_psoc(cmd->vdev);
548 	else
549 		ser_debug("Can't find psoc");
550 
551 	wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
552 
553 	qsize = wlan_serialization_list_size(pdev_queue);
554 	while (!wlan_serialization_list_empty(pdev_queue) && qsize--) {
555 		if (wlan_serialization_get_cmd_from_queue(pdev_queue, &nnode)
556 		    != QDF_STATUS_SUCCESS) {
557 			ser_err("can't read cmd from queue");
558 			status = WLAN_SER_CMD_NOT_FOUND;
559 			break;
560 		}
561 		cmd_list =
562 			qdf_container_of(nnode,
563 					 struct wlan_serialization_command_list,
564 					 pdev_node);
565 		if (cmd && !wlan_serialization_match_cmd_id_type(
566 							nnode, cmd,
567 							WLAN_SER_PDEV_NODE)) {
568 			pnode = nnode;
569 			continue;
570 		}
571 
572 		if (vdev &&
573 		    !wlan_serialization_match_cmd_vdev(nnode,
574 						      vdev,
575 						      WLAN_SER_PDEV_NODE)) {
576 			pnode = nnode;
577 			continue;
578 		}
579 
580 		if (pdev &&
581 		    !wlan_serialization_match_cmd_pdev(nnode,
582 						       pdev,
583 						       WLAN_SER_PDEV_NODE)) {
584 			pnode = nnode;
585 			continue;
586 		}
587 
588 		if (cmd_type > WLAN_SER_CMD_NONSCAN && vdev &&
589 		    (!wlan_serialization_match_cmd_type(nnode, cmd_type,
590 							WLAN_SER_PDEV_NODE) ||
591 		    !wlan_serialization_match_cmd_vdev(nnode, vdev,
592 						       WLAN_SER_PDEV_NODE))) {
593 			pnode = nnode;
594 			continue;
595 		}
596 
597 		/*
598 		 * If a non-blocking cmd is required to be cancelled, but
599 		 * the nnode cmd is a blocking cmd then continue with the
600 		 * next command in the list else proceed with cmd cancel.
601 		 */
602 		if ((cmd_attr == WLAN_SER_CMD_ATTR_NONBLOCK) &&
603 		    wlan_serialization_match_cmd_blocking(nnode,
604 							  WLAN_SER_PDEV_NODE)) {
605 			pnode = nnode;
606 			continue;
607 		}
608 
609 		/*
610 		 * active queue can't be removed directly, requester needs to
611 		 * wait for active command response and send remove request for
612 		 * active command separately
613 		 */
614 		if (is_active_queue) {
615 			if (!psoc || !cmd_list) {
616 				ser_err("psoc:0x%pK, cmd_list:0x%pK",
617 					psoc, cmd_list);
618 				status = WLAN_SER_CMD_NOT_FOUND;
619 				break;
620 			}
621 
622 			/* Cancel request received for a cmd in active
623 			 * queue which has not been activated yet, we mark
624 			 * it as CMD_ACTIVE_MARKED_FOR_CANCEL and remove
625 			 * the cmd after activation
626 			 */
627 			if (qdf_atomic_test_bit(CMD_MARKED_FOR_ACTIVATION,
628 						&cmd_list->cmd_in_use)) {
629 				qdf_atomic_set_bit(CMD_ACTIVE_MARKED_FOR_CANCEL,
630 						   &cmd_list->cmd_in_use);
631 				status = WLAN_SER_CMD_MARKED_FOR_ACTIVATION;
632 				continue;
633 			}
634 
635 			qdf_status = wlan_serialization_find_and_stop_timer(
636 							psoc, &cmd_list->cmd,
637 							SER_CANCEL);
638 			if (QDF_IS_STATUS_ERROR(qdf_status)) {
639 				ser_err("Can't find timer for active cmd");
640 				status = WLAN_SER_CMD_NOT_FOUND;
641 				/*
642 				 * This should not happen, as an active command
643 				 * should always have the timer.
644 				 */
645 				QDF_BUG(0);
646 				break;
647 			}
648 
649 			status = WLAN_SER_CMD_IN_ACTIVE_LIST;
650 		}
651 
652 		qdf_mem_copy(&cmd_bkup, &cmd_list->cmd,
653 			     sizeof(struct wlan_serialization_command));
654 
655 		pdev_status =
656 			wlan_serialization_remove_node(pdev_queue,
657 						       &cmd_list->pdev_node);
658 
659 		ser_vdev_obj = wlan_serialization_get_vdev_obj(
660 					cmd_list->cmd.vdev);
661 
662 		vdev_queue = wlan_serialization_get_list_from_vdev_queue(
663 			ser_vdev_obj, cmd_type, is_active_queue);
664 
665 		vdev_status =
666 			wlan_serialization_remove_node(vdev_queue,
667 						       &cmd_list->vdev_node);
668 
669 		if (pdev_status != QDF_STATUS_SUCCESS ||
670 		    vdev_status != QDF_STATUS_SUCCESS) {
671 			ser_err("can't remove cmd from pdev/vdev queue");
672 			status = WLAN_SER_CMD_NOT_FOUND;
673 			break;
674 		}
675 
676 		qdf_mem_zero(&cmd_list->cmd,
677 			     sizeof(struct wlan_serialization_command));
678 		cmd_list->cmd_in_use = 0;
679 		qdf_status = wlan_serialization_insert_back(
680 			&pdev_q->cmd_pool_list,
681 			&cmd_list->pdev_node);
682 
683 		if (QDF_STATUS_SUCCESS != qdf_status) {
684 			ser_err("can't remove cmd from queue");
685 			status = WLAN_SER_CMD_NOT_FOUND;
686 			break;
687 		}
688 		nnode = pnode;
689 
690 		vdev_id = wlan_vdev_get_id(cmd_bkup.vdev);
691 		is_blocking = cmd_bkup.is_blocking;
692 
693 		wlan_ser_update_cmd_history(pdev_q, &cmd_bkup,
694 					    SER_CANCEL, false, is_active_queue);
695 
696 		wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
697 		/*
698 		 * call pending cmd's callback to notify that
699 		 * it is being removed
700 		 */
701 		if (cmd_bkup.cmd_cb) {
702 			/* caller should now do necessary clean up */
703 			ser_debug("Cancel command: type %d id %d and Release memory",
704 				  cmd_bkup.cmd_type, cmd_bkup.cmd_id);
705 			cmd_bkup.cmd_cb(&cmd_bkup, WLAN_SER_CB_CANCEL_CMD);
706 			/* caller should release the memory */
707 			cmd_bkup.cmd_cb(&cmd_bkup, WLAN_SER_CB_RELEASE_MEM_CMD);
708 		}
709 
710 		wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
711 
712 		if (is_active_queue) {
713 			if (is_blocking)
714 				pdev_q->blocking_cmd_active = 0;
715 
716 			qdf_clear_bit(vdev_id, pdev_q->vdev_active_cmd_bitmap);
717 
718 			ser_debug("active_cmd_bitmap after resetting vdev %d",
719 				  vdev_id);
720 			ser_debug_hex(pdev_q->vdev_active_cmd_bitmap,
721 				      sizeof(pdev_q->vdev_active_cmd_bitmap));
722 
723 		} else {
724 			if (is_blocking)
725 				pdev_q->blocking_cmd_waiting--;
726 
727 			status = WLAN_SER_CMD_IN_PENDING_LIST;
728 		}
729 
730 
731 		if (!vdev && !pdev)
732 			break;
733 	}
734 
735 	wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
736 
737 	return status;
738 }
739