xref: /wlan-dirver/qca-wifi-host-cmn/umac/cmn_services/serialization/src/wlan_serialization_api.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 /**
20  * DOC: wlan_serialization_api.c
21  * This file provides an interface for the external components
22  * to utilize the services provided by the serialization
23  * component.
24  */
25 
26 #include <wlan_objmgr_psoc_obj.h>
27 #include <wlan_objmgr_pdev_obj.h>
28 #include <wlan_objmgr_vdev_obj.h>
29 #include "wlan_serialization_main_i.h"
30 #include "wlan_serialization_utils_i.h"
31 #include "wlan_serialization_queue_i.h"
32 #include "wlan_serialization_scan_i.h"
33 #include "wlan_serialization_internal_i.h"
34 
35 bool wlan_serialization_is_cmd_present_in_pending_queue(
36 		struct wlan_objmgr_psoc *psoc,
37 		struct wlan_serialization_command *cmd)
38 {
39 	bool status = false;
40 	struct wlan_objmgr_pdev *pdev;
41 	struct wlan_ser_pdev_obj *ser_pdev_obj;
42 	struct wlan_serialization_pdev_queue *pdev_queue;
43 
44 	if (!cmd) {
45 		ser_err("invalid cmd");
46 		goto error;
47 	}
48 
49 	pdev = wlan_serialization_get_pdev_from_cmd(cmd);
50 	if (!pdev) {
51 		ser_err("invalid pdev");
52 		goto error;
53 	}
54 
55 	ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev);
56 	if (!ser_pdev_obj) {
57 		ser_err("invalid ser pdev obj");
58 		goto error;
59 	}
60 
61 	pdev_queue = wlan_serialization_get_pdev_queue_obj(ser_pdev_obj,
62 							   cmd->cmd_type);
63 	if (!pdev_queue) {
64 		ser_err("pdev_queue is invalid");
65 		goto error;
66 	}
67 
68 	wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock);
69 
70 	status = wlan_serialization_is_cmd_present_queue(cmd, false);
71 
72 	wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
73 error:
74 	return status;
75 }
76 
77 bool wlan_serialization_is_cmd_present_in_active_queue(
78 		struct wlan_objmgr_psoc *psoc,
79 		struct wlan_serialization_command *cmd)
80 {
81 	bool status = false;
82 	struct wlan_objmgr_pdev *pdev;
83 	struct wlan_ser_pdev_obj *ser_pdev_obj;
84 	struct wlan_serialization_pdev_queue *pdev_queue;
85 
86 	if (!cmd) {
87 		ser_err("invalid cmd");
88 		goto error;
89 	}
90 
91 	pdev = wlan_serialization_get_pdev_from_cmd(cmd);
92 	if (!pdev) {
93 		ser_err("invalid pdev");
94 		goto error;
95 	}
96 
97 	ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev);
98 	if (!ser_pdev_obj) {
99 		ser_err("invalid ser pdev obj");
100 		goto error;
101 	}
102 
103 	pdev_queue = wlan_serialization_get_pdev_queue_obj(ser_pdev_obj,
104 							   cmd->cmd_type);
105 	if (!pdev_queue) {
106 		ser_err("pdev_queue is invalid");
107 		goto error;
108 	}
109 
110 	wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock);
111 
112 	status = wlan_serialization_is_cmd_present_queue(cmd, true);
113 
114 	wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
115 
116 error:
117 	return status;
118 }
119 
120 QDF_STATUS
121 wlan_serialization_register_apply_rules_cb(
122 		struct wlan_objmgr_psoc *psoc,
123 		enum wlan_serialization_cmd_type cmd_type,
124 		wlan_serialization_apply_rules_cb cb)
125 {
126 	struct wlan_ser_psoc_obj *ser_soc_obj;
127 	QDF_STATUS status;
128 
129 	status = wlan_serialization_validate_cmdtype(cmd_type);
130 	if (QDF_IS_STATUS_ERROR(status)) {
131 		ser_err("invalid cmd_type %d", cmd_type);
132 		goto error;
133 	}
134 
135 	ser_soc_obj = wlan_serialization_get_psoc_obj(psoc);
136 	if (!ser_soc_obj) {
137 		ser_err("invalid ser_soc_obj");
138 		status = QDF_STATUS_E_FAILURE;
139 		goto error;
140 	}
141 
142 	ser_soc_obj->apply_rules_cb[cmd_type] = cb;
143 	status = QDF_STATUS_SUCCESS;
144 
145 error:
146 	return status;
147 }
148 
149 QDF_STATUS
150 wlan_serialization_deregister_apply_rules_cb(
151 		struct wlan_objmgr_psoc *psoc,
152 		enum wlan_serialization_cmd_type cmd_type)
153 {
154 	struct wlan_ser_psoc_obj *ser_soc_obj;
155 	QDF_STATUS status;
156 
157 	status = wlan_serialization_validate_cmdtype(cmd_type);
158 	if (QDF_IS_STATUS_ERROR(status)) {
159 		ser_err("invalid cmd_type %d", cmd_type);
160 		goto error;
161 	}
162 	ser_soc_obj = wlan_serialization_get_psoc_obj(psoc);
163 	if (!ser_soc_obj) {
164 		ser_err("invalid ser_soc_obj");
165 		status = QDF_STATUS_E_FAILURE;
166 		goto error;
167 	}
168 	ser_soc_obj->apply_rules_cb[cmd_type] = NULL;
169 	status = QDF_STATUS_SUCCESS;
170 
171 error:
172 	return status;
173 }
174 
175 QDF_STATUS
176 wlan_serialization_register_comp_info_cb(
177 		struct wlan_objmgr_psoc *psoc,
178 		enum wlan_umac_comp_id comp_id,
179 		enum wlan_serialization_cmd_type cmd_type,
180 		wlan_serialization_comp_info_cb cb)
181 {
182 	struct wlan_ser_psoc_obj *ser_soc_obj;
183 	QDF_STATUS status;
184 
185 	status = wlan_serialization_validate_cmd(comp_id, cmd_type);
186 	if (QDF_IS_STATUS_ERROR(status)) {
187 		ser_err("invalid comp_id %d or cmd_type %d",
188 			comp_id, cmd_type);
189 		goto error;
190 	}
191 	ser_soc_obj = wlan_serialization_get_psoc_obj(psoc);
192 	if (!ser_soc_obj) {
193 		ser_err("invalid ser_soc_obj");
194 		status = QDF_STATUS_E_FAILURE;
195 		goto error;
196 	}
197 	ser_soc_obj->comp_info_cb[cmd_type][comp_id] = cb;
198 	status = QDF_STATUS_SUCCESS;
199 
200 error:
201 	return status;
202 }
203 
204 QDF_STATUS
205 wlan_serialization_deregister_comp_info_cb(struct wlan_objmgr_psoc *psoc,
206 					   enum wlan_umac_comp_id comp_id,
207 		enum wlan_serialization_cmd_type cmd_type)
208 {
209 	struct wlan_ser_psoc_obj *ser_soc_obj;
210 	QDF_STATUS status;
211 
212 	status = wlan_serialization_validate_cmd(comp_id, cmd_type);
213 	if (QDF_IS_STATUS_ERROR(status)) {
214 		ser_err("invalid comp_id %d or cmd_type %d",
215 			comp_id, cmd_type);
216 		goto error;
217 	}
218 	ser_soc_obj = wlan_serialization_get_psoc_obj(psoc);
219 	if (!ser_soc_obj) {
220 		ser_err("invalid ser_soc_obj");
221 		status = QDF_STATUS_E_FAILURE;
222 		goto error;
223 	}
224 	ser_soc_obj->comp_info_cb[cmd_type][comp_id] = NULL;
225 	status = QDF_STATUS_SUCCESS;
226 
227 error:
228 	return status;
229 }
230 
231 enum wlan_serialization_cmd_status
232 wlan_serialization_non_scan_cmd_status(
233 		struct wlan_objmgr_pdev *pdev,
234 		enum wlan_serialization_cmd_type cmd_type)
235 {
236 	bool cmd_in_active = 0;
237 	bool cmd_in_pending = 0;
238 	struct wlan_ser_pdev_obj *ser_pdev_obj =
239 		wlan_serialization_get_pdev_obj(pdev);
240 	enum wlan_serialization_cmd_status cmd_status = WLAN_SER_CMD_NOT_FOUND;
241 	struct wlan_serialization_pdev_queue *pdev_q;
242 	qdf_list_node_t *node = NULL;
243 	qdf_list_t *queue = NULL;
244 
245 	pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN];
246 
247 	/* Look in the pdev non scan active queue */
248 	queue = &pdev_q->active_list;
249 
250 	wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
251 
252 	node = wlan_serialization_find_cmd(
253 			queue, WLAN_SER_MATCH_CMD_TYPE,
254 			NULL, cmd_type, NULL, NULL,  WLAN_SER_PDEV_NODE);
255 
256 	if (node)
257 		cmd_in_active = true;
258 
259 	node = NULL;
260 
261 	/* Look in the pdev non scan pending queue */
262 	queue = &pdev_q->pending_list;
263 
264 	node = wlan_serialization_find_cmd(
265 			queue, WLAN_SER_MATCH_CMD_TYPE,
266 			NULL, cmd_type, NULL, NULL,  WLAN_SER_PDEV_NODE);
267 
268 	if (node)
269 		cmd_in_pending = true;
270 
271 	cmd_status = wlan_serialization_is_cmd_in_active_pending(
272 			cmd_in_active, cmd_in_pending);
273 
274 	wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
275 
276 	return cmd_status;
277 }
278 
279 enum wlan_serialization_cmd_status
280 wlan_serialization_cancel_request(
281 		struct wlan_serialization_queued_cmd_info *req)
282 {
283 	QDF_STATUS status;
284 	enum wlan_serialization_cmd_status cmd_status;
285 
286 	struct wlan_serialization_command cmd;
287 	struct wlan_objmgr_pdev *pdev;
288 	struct wlan_ser_pdev_obj *ser_pdev_obj;
289 	struct wlan_serialization_pdev_queue *pdev_queue;
290 
291 	if (!req) {
292 		ser_err("given request is empty");
293 		cmd_status = WLAN_SER_CMD_NOT_FOUND;
294 		goto error;
295 	}
296 
297 	status = wlan_serialization_validate_cmd(req->requestor, req->cmd_type);
298 	if (QDF_IS_STATUS_ERROR(status)) {
299 		ser_err("req is not valid");
300 		cmd_status = WLAN_SER_CMD_NOT_FOUND;
301 		goto error;
302 	}
303 
304 	cmd.cmd_type = req->cmd_type;
305 	cmd.cmd_id = req->cmd_id;
306 	cmd.source = req->requestor;
307 	cmd.vdev = req->vdev;
308 
309 	ser_debug("Type %d id %d source %d req type %d queue type %d",
310 		  cmd.cmd_type, cmd.cmd_id, cmd.source, req->req_type,
311 		  req->queue_type);
312 	pdev = wlan_serialization_get_pdev_from_cmd(&cmd);
313 	if (!pdev) {
314 		ser_err("pdev is invalid");
315 		cmd_status = WLAN_SER_CMD_NOT_FOUND;
316 		goto error;
317 	}
318 
319 	ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev);
320 
321 	pdev_queue = wlan_serialization_get_pdev_queue_obj(ser_pdev_obj,
322 							   cmd.cmd_type);
323 
324 	if (!pdev_queue) {
325 		ser_err("pdev_queue is invalid");
326 		cmd_status = WLAN_SER_CMD_NOT_FOUND;
327 		goto error;
328 	}
329 
330 	cmd_status = wlan_serialization_find_and_cancel_cmd(
331 			&cmd, req->req_type, req->queue_type);
332 
333 error:
334 
335 	return cmd_status;
336 }
337 
338 void wlan_serialization_remove_cmd(
339 		struct wlan_serialization_queued_cmd_info *cmd_info)
340 {
341 	QDF_STATUS status;
342 	enum wlan_serialization_cmd_status ser_status;
343 	struct wlan_serialization_command cmd = {0};
344 
345 	if (!cmd_info) {
346 		ser_err("given request is empty");
347 		QDF_ASSERT(0);
348 		return;
349 	}
350 	status = wlan_serialization_validate_cmd(cmd_info->requestor,
351 						 cmd_info->cmd_type);
352 	if (QDF_IS_STATUS_ERROR(status)) {
353 		ser_err("cmd type %d is not valid", cmd_info->cmd_type);
354 		QDF_ASSERT(0);
355 		return;
356 	}
357 
358 	cmd.cmd_type = cmd_info->cmd_type;
359 	cmd.cmd_id = cmd_info->cmd_id;
360 	cmd.source = cmd_info->requestor;
361 	cmd.vdev = cmd_info->vdev;
362 
363 	ser_status = wlan_serialization_dequeue_cmd(
364 			&cmd, SER_REMOVE, true);
365 
366 	if (ser_status != WLAN_SER_CMD_IN_ACTIVE_LIST) {
367 		if (ser_status != WLAN_SER_CMD_MARKED_FOR_ACTIVATION)
368 			ser_debug("Can't dequeue requested id %d type %d requestor %d",
369 				  cmd.cmd_id, cmd.cmd_type,
370 				  cmd_info->requestor);
371 	}
372 }
373 
374 enum wlan_serialization_status
375 wlan_serialization_request(struct wlan_serialization_command *cmd)
376 {
377 	QDF_STATUS status;
378 	enum wlan_serialization_status serialization_status;
379 	uint8_t comp_id;
380 	struct wlan_ser_psoc_obj *ser_soc_obj;
381 	union wlan_serialization_rules_info info;
382 	struct wlan_objmgr_psoc *psoc;
383 
384 	serialization_status = WLAN_SER_CMD_DENIED_UNSPECIFIED;
385 
386 	if (!cmd) {
387 		ser_err("serialization cmd is null");
388 		goto error;
389 	}
390 	status = wlan_serialization_validate_cmd(cmd->source, cmd->cmd_type);
391 	if (QDF_IS_STATUS_ERROR(status))
392 		goto error;
393 
394 	psoc = wlan_serialization_get_psoc_from_cmd(cmd);
395 	if (!psoc) {
396 		ser_err("psoc _obj is invalid");
397 		return WLAN_SER_CMD_DENIED_UNSPECIFIED;
398 	}
399 	ser_soc_obj = wlan_serialization_get_psoc_obj(psoc);
400 
401 	if (!ser_soc_obj) {
402 		ser_err("ser_soc_obj is invalid");
403 		return WLAN_SER_CMD_DENIED_UNSPECIFIED;
404 	}
405 
406 	/*
407 	 * Get Component Info callback by calling
408 	 * each registered module
409 	 */
410 	for (comp_id = 0; comp_id < WLAN_UMAC_COMP_ID_MAX; comp_id++) {
411 		if (!ser_soc_obj->comp_info_cb[cmd->cmd_type][comp_id])
412 			continue;
413 		ser_soc_obj->comp_info_cb[cmd->cmd_type][comp_id](cmd->vdev,
414 			&info, cmd);
415 		if (!ser_soc_obj->apply_rules_cb[cmd->cmd_type])
416 			continue;
417 		if (!ser_soc_obj->apply_rules_cb[cmd->cmd_type](&info, comp_id))
418 			return WLAN_SER_CMD_DENIED_RULES_FAILED;
419 	}
420 
421 	serialization_status = wlan_serialization_enqueue_cmd(cmd, SER_REQUEST);
422 
423 error:
424 	return serialization_status;
425 }
426 
427 QDF_STATUS
428 wlan_serialization_update_timer(struct wlan_serialization_command *cmd)
429 {
430 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
431 	struct wlan_objmgr_pdev *pdev;
432 	struct wlan_objmgr_psoc *psoc;
433 
434 	if (!cmd) {
435 		ser_err("NULL command");
436 		goto error;
437 	}
438 
439 	pdev = wlan_serialization_get_pdev_from_cmd(cmd);
440 	if (!pdev) {
441 		ser_err("invalid pdev");
442 		goto error;
443 	}
444 
445 	psoc = wlan_pdev_get_psoc(pdev);
446 	if (!psoc) {
447 		ser_err("invalid psoc");
448 		goto error;
449 	}
450 
451 	status = wlan_serialization_find_and_update_timer(psoc, cmd);
452 
453 error:
454 	return status;
455 }
456 
457 enum wlan_serialization_cmd_status
458 wlan_serialization_vdev_scan_status(struct wlan_objmgr_vdev *vdev)
459 {
460 	bool cmd_in_active = 0, cmd_in_pending = 0;
461 	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
462 	struct wlan_ser_pdev_obj *ser_pdev_obj =
463 		wlan_serialization_get_pdev_obj(pdev);
464 	struct wlan_serialization_pdev_queue *pdev_q;
465 	enum wlan_serialization_cmd_status status;
466 
467 	pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN];
468 
469 	wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
470 
471 	cmd_in_active =
472 	wlan_serialization_is_cmd_in_vdev_list(
473 			vdev, &pdev_q->active_list, WLAN_SER_PDEV_NODE);
474 
475 	cmd_in_pending =
476 	wlan_serialization_is_cmd_in_vdev_list(
477 			vdev, &pdev_q->pending_list, WLAN_SER_PDEV_NODE);
478 
479 	status = wlan_serialization_is_cmd_in_active_pending(
480 			cmd_in_active, cmd_in_pending);
481 
482 	wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
483 
484 	return status;
485 }
486 
487 enum wlan_serialization_cmd_status
488 wlan_serialization_pdev_scan_status(struct wlan_objmgr_pdev *pdev)
489 {
490 	bool cmd_in_active, cmd_in_pending;
491 	struct wlan_ser_pdev_obj *ser_pdev_obj =
492 		wlan_serialization_get_pdev_obj(pdev);
493 	struct wlan_serialization_pdev_queue *pdev_q;
494 	enum wlan_serialization_cmd_status status;
495 
496 	pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN];
497 
498 	wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
499 
500 	cmd_in_active = !qdf_list_empty(&pdev_q->active_list);
501 	cmd_in_pending = !qdf_list_empty(&pdev_q->pending_list);
502 
503 	status = wlan_serialization_is_cmd_in_active_pending(
504 			cmd_in_active, cmd_in_pending);
505 
506 	wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
507 
508 	return status;
509 }
510 
511 struct wlan_serialization_command*
512 wlan_serialization_get_scan_cmd_using_scan_id(
513 		struct wlan_objmgr_psoc *psoc,
514 		uint8_t vdev_id, uint16_t scan_id,
515 		uint8_t is_scan_cmd_from_active_queue)
516 {
517 	struct wlan_objmgr_vdev *vdev;
518 	struct wlan_objmgr_pdev *pdev;
519 	struct wlan_ser_pdev_obj *ser_pdev_obj;
520 	struct wlan_serialization_command cmd = {0};
521 	struct wlan_serialization_command *pcmd = NULL;
522 	struct wlan_serialization_command_list *cmd_list;
523 	qdf_list_node_t *node = NULL;
524 	qdf_list_t *queue;
525 	struct wlan_serialization_pdev_queue *pdev_q;
526 
527 	if (!psoc) {
528 		ser_err("invalid psoc");
529 		goto error;
530 	}
531 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
532 						    WLAN_SERIALIZATION_ID);
533 	if (!vdev) {
534 		ser_err("invalid vdev");
535 		goto error;
536 	}
537 
538 	pdev = wlan_vdev_get_pdev(vdev);
539 	if (!pdev) {
540 		ser_err("invalid pdev");
541 		goto release_vdev_ref;
542 	}
543 
544 	ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev);
545 	if (!ser_pdev_obj) {
546 		ser_err("invalid ser_pdev_obj");
547 		goto release_vdev_ref;
548 	}
549 
550 	pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN];
551 
552 	wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
553 
554 	if (is_scan_cmd_from_active_queue)
555 		queue = &pdev_q->active_list;
556 	else
557 		queue = &pdev_q->pending_list;
558 
559 	cmd.cmd_type = WLAN_SER_CMD_SCAN;
560 	cmd.cmd_id = scan_id;
561 	cmd.vdev = vdev;
562 
563 	node = wlan_serialization_find_cmd(
564 			queue, WLAN_SER_MATCH_CMD_ID_VDEV,
565 			&cmd, 0, NULL, vdev,  WLAN_SER_PDEV_NODE);
566 
567 	if (node) {
568 		cmd_list = qdf_container_of(
569 				node,
570 				struct wlan_serialization_command_list,
571 				pdev_node);
572 
573 		pcmd = &cmd_list->cmd;
574 	}
575 
576 	wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
577 
578 release_vdev_ref:
579 	wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID);
580 error:
581 	return pcmd;
582 }
583 
584 void *wlan_serialization_get_active_cmd(
585 		struct wlan_objmgr_psoc *psoc,
586 		uint8_t vdev_id,
587 		enum wlan_serialization_cmd_type cmd_type)
588 {
589 	struct wlan_objmgr_vdev *vdev;
590 	struct wlan_objmgr_pdev *pdev;
591 	struct wlan_ser_pdev_obj *ser_pdev_obj;
592 	struct wlan_serialization_command_list *cmd_list = NULL;
593 	void *umac_cmd = NULL;
594 	qdf_list_node_t *node = NULL;
595 	qdf_list_t *queue;
596 	struct wlan_serialization_pdev_queue *pdev_q;
597 
598 	if (!psoc) {
599 		ser_err("invalid psoc");
600 		goto error;
601 	}
602 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
603 						    WLAN_SERIALIZATION_ID);
604 	if (!vdev) {
605 		ser_err("invalid vdev");
606 		goto error;
607 	}
608 
609 	pdev = wlan_vdev_get_pdev(vdev);
610 	if (!pdev) {
611 		ser_err("invalid pdev");
612 		goto release_vdev_ref;
613 	}
614 
615 	ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev);
616 	if (!ser_pdev_obj) {
617 		ser_err("invalid ser_pdev_obj");
618 		goto release_vdev_ref;
619 	}
620 
621 	pdev_q = wlan_serialization_get_pdev_queue_obj(ser_pdev_obj, cmd_type);
622 
623 	wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
624 
625 	queue = &pdev_q->active_list;
626 
627 	node = wlan_serialization_find_cmd(
628 			queue, WLAN_SER_MATCH_CMD_TYPE_VDEV,
629 			NULL, cmd_type, NULL, vdev,  WLAN_SER_PDEV_NODE);
630 
631 	if (node) {
632 		cmd_list = qdf_container_of(
633 				node,
634 				struct wlan_serialization_command_list,
635 				pdev_node);
636 
637 		umac_cmd = cmd_list->cmd.umac_cmd;
638 	}
639 
640 	wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
641 
642 release_vdev_ref:
643 	wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID);
644 error:
645 
646 	return umac_cmd;
647 }
648 
649 enum wlan_serialization_cmd_type
650 wlan_serialization_get_vdev_active_cmd_type(struct wlan_objmgr_vdev *vdev)
651 {
652 	enum wlan_serialization_cmd_type cmd_type = WLAN_SER_CMD_MAX;
653 	struct wlan_ser_pdev_obj *ser_pdev_obj;
654 	struct wlan_ser_vdev_obj *ser_vdev_obj;
655 	struct wlan_serialization_pdev_queue *pdev_queue;
656 	struct wlan_serialization_vdev_queue *vdev_queue;
657 	struct wlan_serialization_command_list *cmd_list = NULL;
658 	qdf_list_node_t *node;
659 
660 	ser_pdev_obj = wlan_serialization_get_pdev_obj(
661 			wlan_vdev_get_pdev(vdev));
662 
663 	if (!ser_pdev_obj) {
664 		ser_err("invalid ser_pdev_obj");
665 		goto error;
666 	}
667 	pdev_queue = wlan_serialization_get_pdev_queue_obj(
668 			ser_pdev_obj, cmd_type);
669 
670 	ser_vdev_obj = wlan_serialization_get_vdev_obj(vdev);
671 	if (!ser_vdev_obj) {
672 		ser_err("invalid ser_vdev_obj");
673 		goto error;
674 	}
675 	vdev_queue = wlan_serialization_get_vdev_queue_obj(
676 			ser_vdev_obj, WLAN_SER_CMD_NONSCAN);
677 
678 	wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock);
679 
680 	if (wlan_serialization_peek_front(
681 		&vdev_queue->active_list, &node) == QDF_STATUS_SUCCESS) {
682 		cmd_list = qdf_container_of(
683 				node,
684 				struct wlan_serialization_command_list,
685 				vdev_node);
686 
687 		cmd_type = cmd_list->cmd.cmd_type;
688 	}
689 
690 	wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
691 
692 error:
693 	return cmd_type;
694 }
695 
696 bool wlan_ser_is_vdev_queue_enabled(struct wlan_objmgr_vdev *vdev)
697 {
698 	struct wlan_ser_vdev_obj *ser_vdev_obj;
699 	struct wlan_serialization_vdev_queue *vdev_queue;
700 
701 	ser_vdev_obj = wlan_serialization_get_vdev_obj(vdev);
702 	if (!ser_vdev_obj) {
703 		ser_err("invalid ser_vdev_obj");
704 		return false;
705 	}
706 
707 	vdev_queue = wlan_serialization_get_vdev_queue_obj(
708 			ser_vdev_obj, WLAN_SER_CMD_NONSCAN);
709 	if (vdev_queue->queue_disable)
710 		return false;
711 	else
712 		return true;
713 }
714 
715 QDF_STATUS
716 wlan_ser_get_cmd_activation_status(struct wlan_objmgr_vdev *vdev)
717 {
718 	struct wlan_ser_pdev_obj *ser_pdev_obj;
719 	struct wlan_ser_vdev_obj *ser_vdev_obj;
720 	struct wlan_serialization_pdev_queue *pdev_queue;
721 	struct wlan_serialization_vdev_queue *vdev_queue;
722 	struct wlan_serialization_command_list *cmd_list = NULL;
723 	qdf_list_node_t *node;
724 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
725 
726 	ser_pdev_obj = wlan_serialization_get_pdev_obj(
727 			wlan_vdev_get_pdev(vdev));
728 
729 	if (!ser_pdev_obj) {
730 		ser_err("invalid ser_pdev_obj");
731 		return QDF_STATUS_E_FAILURE;
732 	}
733 
734 	pdev_queue = wlan_serialization_get_pdev_queue_obj(
735 			ser_pdev_obj, WLAN_SER_CMD_NONSCAN);
736 
737 	ser_vdev_obj = wlan_serialization_get_vdev_obj(vdev);
738 	if (!ser_vdev_obj) {
739 		ser_err("invalid ser_vdev_obj");
740 		return QDF_STATUS_E_FAILURE;
741 	}
742 	vdev_queue = wlan_serialization_get_vdev_queue_obj(
743 			ser_vdev_obj, WLAN_SER_CMD_NONSCAN);
744 
745 	wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock);
746 
747 	if (wlan_serialization_peek_front(
748 		&vdev_queue->active_list, &node) == QDF_STATUS_SUCCESS) {
749 		cmd_list = qdf_container_of(
750 				node,
751 				struct wlan_serialization_command_list,
752 				vdev_node);
753 
754 		if (qdf_atomic_test_bit(CMD_MARKED_FOR_ACTIVATION,
755 					&cmd_list->cmd_in_use))
756 			status = QDF_STATUS_SUCCESS;
757 	}
758 
759 	wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
760 
761 	return status;
762 }
763 
764 QDF_STATUS
765 wlan_ser_validate_umac_cmd(struct wlan_objmgr_vdev *vdev,
766 			   enum wlan_serialization_cmd_type cmd_type,
767 			   wlan_ser_umac_cmd_cb umac_cmd_cb)
768 {
769 	struct wlan_objmgr_pdev *pdev;
770 	struct wlan_ser_pdev_obj *ser_pdev_obj;
771 	struct wlan_serialization_command_list *cmd_list = NULL;
772 	void *umac_cmd = NULL;
773 	qdf_list_node_t *node = NULL;
774 	qdf_list_t *queue;
775 	struct wlan_serialization_pdev_queue *pdev_q;
776 	QDF_STATUS status = QDF_STATUS_E_INVAL;
777 
778 	if (!vdev) {
779 		ser_err("invalid vdev");
780 		return QDF_STATUS_E_INVAL;
781 	}
782 
783 	pdev = wlan_vdev_get_pdev(vdev);
784 	if (!pdev) {
785 		ser_err("invalid pdev");
786 		return QDF_STATUS_E_INVAL;
787 	}
788 
789 	ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev);
790 	if (!ser_pdev_obj) {
791 		ser_err("invalid ser_pdev_obj");
792 		return QDF_STATUS_E_INVAL;
793 	}
794 
795 	pdev_q = wlan_serialization_get_pdev_queue_obj(ser_pdev_obj, cmd_type);
796 
797 	wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
798 
799 	queue = &pdev_q->active_list;
800 	node = wlan_serialization_find_cmd(
801 			queue, WLAN_SER_MATCH_CMD_TYPE_VDEV,
802 			NULL, cmd_type, NULL, vdev,  WLAN_SER_PDEV_NODE);
803 	if (node) {
804 		cmd_list = qdf_container_of(
805 				node,
806 				struct wlan_serialization_command_list,
807 				pdev_node);
808 
809 		umac_cmd = cmd_list->cmd.umac_cmd;
810 		status = umac_cmd_cb(umac_cmd);
811 	}
812 
813 	wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
814 
815 	return status;
816 }
817 
818 void wlan_serialization_purge_all_pdev_cmd(struct wlan_objmgr_pdev *pdev)
819 {
820 	struct wlan_ser_pdev_obj *ser_pdev_obj;
821 
822 	if (!pdev) {
823 		ser_err("NULL pdev");
824 		return;
825 	}
826 
827 	ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev);
828 	if (!ser_pdev_obj) {
829 		ser_err("invalid ser_pdev_obj");
830 		return;
831 	}
832 
833 	wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, NULL, NULL,
834 				 WLAN_SER_CMD_SCAN, false);
835 	wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, NULL, NULL,
836 				 WLAN_SER_CMD_SCAN, true);
837 	wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, NULL, NULL,
838 				     WLAN_SER_CMD_NONSCAN, false,
839 				     WLAN_SER_CMD_ATTR_NONE);
840 	wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, NULL, NULL,
841 				     WLAN_SER_CMD_NONSCAN, true,
842 				     WLAN_SER_CMD_ATTR_NONE);
843 }
844 
845 static inline
846 void wlan_ser_purge_pdev_cmd_cb(struct wlan_objmgr_psoc *psoc,
847 				void *object, void *arg)
848 {
849 	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object;
850 
851 	wlan_serialization_purge_all_pdev_cmd(pdev);
852 }
853 
854 void wlan_serialization_purge_all_cmd(struct wlan_objmgr_psoc *psoc)
855 {
856 	wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP,
857 				     wlan_ser_purge_pdev_cmd_cb, NULL, 1,
858 				     WLAN_SERIALIZATION_ID);
859 }
860 
861 void wlan_serialization_purge_all_pending_cmd_by_vdev_id(
862 					struct wlan_objmgr_pdev *pdev,
863 					uint8_t vdev_id)
864 {
865 	struct wlan_objmgr_vdev *vdev;
866 	struct wlan_ser_pdev_obj *ser_pdev_obj;
867 
868 	if (!pdev) {
869 		ser_err("Invalid pdev");
870 		return;
871 	}
872 
873 	ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev);
874 	if (!ser_pdev_obj) {
875 		ser_err("invalid ser_pdev_obj");
876 		return;
877 	}
878 
879 	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
880 						    WLAN_SERIALIZATION_ID);
881 	if (!vdev) {
882 		ser_err("Invalid vdev");
883 		return;
884 	}
885 
886 	wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, vdev, NULL,
887 				 WLAN_SER_CMD_SCAN, false);
888 	wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, vdev, NULL,
889 				     WLAN_SER_CMD_NONSCAN, false,
890 				     WLAN_SER_CMD_ATTR_NONE);
891 
892 	wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID);
893 }
894 
895 void wlan_serialization_purge_all_cmd_by_vdev_id(struct wlan_objmgr_pdev *pdev,
896 						 uint8_t vdev_id)
897 {
898 	struct wlan_objmgr_vdev *vdev;
899 	struct wlan_ser_pdev_obj *ser_pdev_obj;
900 
901 	if (!pdev) {
902 		ser_err("Invalid pdev");
903 		return;
904 	}
905 
906 	ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev);
907 	if (!ser_pdev_obj) {
908 		ser_err("invalid ser_pdev_obj");
909 		return;
910 	}
911 
912 	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
913 						    WLAN_SERIALIZATION_ID);
914 	if (!vdev) {
915 		ser_err("Invalid vdev");
916 		return;
917 	}
918 
919 	wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, vdev, NULL,
920 				 WLAN_SER_CMD_SCAN, false);
921 	wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, vdev, NULL,
922 				 WLAN_SER_CMD_SCAN, true);
923 	wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, vdev, NULL,
924 				     WLAN_SER_CMD_NONSCAN, false,
925 				     WLAN_SER_CMD_ATTR_NONE);
926 	wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, vdev, NULL,
927 				     WLAN_SER_CMD_NONSCAN, true,
928 				     WLAN_SER_CMD_ATTR_NONE);
929 
930 	wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID);
931 }
932 
933 void wlan_serialization_purge_all_scan_cmd_by_vdev_id(
934 					struct wlan_objmgr_pdev *pdev,
935 					uint8_t vdev_id)
936 {
937 	struct wlan_objmgr_vdev *vdev;
938 	struct wlan_ser_pdev_obj *ser_pdev_obj;
939 
940 	if (!pdev) {
941 		ser_err("Invalid pdev");
942 		return;
943 	}
944 
945 	ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev);
946 	if (!ser_pdev_obj) {
947 		ser_err("invalid ser_pdev_obj");
948 		return;
949 	}
950 
951 	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
952 						    WLAN_SERIALIZATION_ID);
953 	if (!vdev) {
954 		ser_err("Invalid vdev");
955 		return;
956 	}
957 
958 	wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, vdev, NULL,
959 				 WLAN_SER_CMD_SCAN, false);
960 	wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, vdev, NULL,
961 				 WLAN_SER_CMD_SCAN, true);
962 
963 	wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID);
964 }
965 
966 QDF_STATUS wlan_ser_vdev_queue_disable(struct wlan_objmgr_vdev *vdev)
967 {
968 	struct wlan_objmgr_pdev *pdev;
969 	struct wlan_ser_vdev_obj *ser_vdev_obj;
970 	struct wlan_serialization_vdev_queue *vdev_queue;
971 	struct wlan_ser_pdev_obj *ser_pdev_obj;
972 	struct wlan_serialization_pdev_queue *pdev_q;
973 
974 	pdev = wlan_vdev_get_pdev(vdev);
975 	if (!pdev) {
976 		ser_err("invalid PDEV object");
977 		return QDF_STATUS_E_INVAL;
978 	}
979 
980 	ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev);
981 	if (!ser_pdev_obj) {
982 		ser_err("invalid ser_pdev_obj");
983 		return QDF_STATUS_E_INVAL;
984 	}
985 
986 	ser_vdev_obj = wlan_serialization_get_vdev_obj(vdev);
987 	if (!ser_vdev_obj) {
988 		ser_err("invalid ser_vdev_obj");
989 		return QDF_STATUS_E_INVAL;
990 	}
991 
992 	pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN];
993 
994 	vdev_queue = wlan_serialization_get_vdev_queue_obj(
995 			ser_vdev_obj, WLAN_SER_CMD_NONSCAN);
996 	if (!vdev_queue) {
997 		ser_err("invalid vdev_queue object");
998 		return QDF_STATUS_E_INVAL;
999 	}
1000 
1001 	wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
1002 	vdev_queue->queue_disable = true;
1003 	wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
1004 	ser_debug("Disabling the serialization for vdev:%d",
1005 		  wlan_vdev_get_id(vdev));
1006 
1007 	return QDF_STATUS_SUCCESS;
1008 }
1009