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