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