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