xref: /wlan-dirver/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_manager.c (revision 6d768494e5ce14eb1603a695c86739d12ecc6ec2)
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: contains scan manager functionality
21  */
22 
23 #include <wlan_serialization_api.h>
24 #include <wlan_scan_ucfg_api.h>
25 #include <wlan_scan_tgt_api.h>
26 #include "wlan_scan_main.h"
27 #include "wlan_scan_manager.h"
28 #include "wlan_utility.h"
29 #include <wlan_reg_services_api.h>
30 #ifdef FEATURE_WLAN_SCAN_PNO
31 #include <host_diag_core_event.h>
32 #endif
33 #ifdef WLAN_POLICY_MGR_ENABLE
34 #include <wlan_policy_mgr_api.h>
35 #endif
36 #include <wlan_dfs_utils_api.h>
37 #include <wlan_scan_cfg.h>
38 
39 /* Beacon/probe weightage multiplier */
40 #define BCN_PROBE_WEIGHTAGE 5
41 
42 /* Saved profile weightage multiplier */
43 #define SAVED_PROFILE_WEIGHTAGE 10
44 
45 /* maximum number of 6ghz hints can be sent per scan request */
46 #define MAX_HINTS_PER_SCAN_REQ 15
47 
48 /* maximum number of hints can be sent per 6ghz channel */
49 #define MAX_HINTS_PER_CHANNEL 4
50 
51 QDF_STATUS
52 scm_scan_free_scan_request_mem(struct scan_start_request *req)
53 {
54 	void *ie;
55 
56 	if (!req) {
57 		scm_err("null request");
58 		QDF_ASSERT(0);
59 		return QDF_STATUS_E_FAILURE;
60 	}
61 	/* Free vendor(extra) ie */
62 	ie = req->scan_req.extraie.ptr;
63 	if (ie) {
64 		req->scan_req.extraie.ptr = NULL;
65 		req->scan_req.extraie.len = 0;
66 		qdf_mem_free(ie);
67 	}
68 
69 	/* Free htcap ie */
70 	ie = req->scan_req.htcap.ptr;
71 	if (ie) {
72 		req->scan_req.htcap.len = 0;
73 		req->scan_req.htcap.ptr = NULL;
74 		qdf_mem_free(ie);
75 	}
76 
77 	/* Free vhtcap ie */
78 	ie = req->scan_req.vhtcap.ptr;
79 	if (ie) {
80 		req->scan_req.vhtcap.len = 0;
81 		req->scan_req.vhtcap.ptr = NULL;
82 		qdf_mem_free(ie);
83 	}
84 	/* free scan_start_request memory */
85 	qdf_mem_free(req);
86 
87 	return QDF_STATUS_SUCCESS;
88 }
89 
90 static QDF_STATUS
91 scm_scan_get_pdev_global_event_handlers(struct scan_event_listeners *listeners,
92 		struct pdev_scan_ev_handler *pdev_ev_handler)
93 {
94 	uint32_t i;
95 	struct cb_handler *cb_handlers  = &(pdev_ev_handler->cb_handlers[0]);
96 
97 	for (i = 0; i < MAX_SCAN_EVENT_HANDLERS_PER_PDEV; i++, cb_handlers++) {
98 		if ((cb_handlers->func) &&
99 		    (listeners->count < MAX_SCAN_EVENT_LISTENERS)) {
100 			listeners->cb[listeners->count].func =
101 				cb_handlers->func;
102 			listeners->cb[listeners->count].arg =
103 				cb_handlers->arg;
104 			listeners->count++;
105 		}
106 	}
107 
108 	return QDF_STATUS_SUCCESS;
109 }
110 
111 static QDF_STATUS
112 scm_scan_get_requester_event_handler(struct scan_event_listeners *listeners,
113 		struct scan_requester_info *requesters,
114 		wlan_scan_requester requester_id)
115 {
116 	uint32_t idx;
117 	struct cb_handler *ev_handler;
118 
119 	idx = requester_id & WLAN_SCAN_REQUESTER_ID_PREFIX;
120 	if (idx != WLAN_SCAN_REQUESTER_ID_PREFIX)
121 		return QDF_STATUS_SUCCESS;
122 
123 	idx = requester_id & WLAN_SCAN_REQUESTER_ID_MASK;
124 	if (idx < WLAN_MAX_REQUESTORS) {
125 		ev_handler = &(requesters[idx].ev_handler);
126 		if (ev_handler->func) {
127 			if (listeners->count < MAX_SCAN_EVENT_LISTENERS) {
128 				listeners->cb[listeners->count].func =
129 							     ev_handler->func;
130 				listeners->cb[listeners->count].arg =
131 							     ev_handler->arg;
132 				listeners->count++;
133 			}
134 		}
135 		return QDF_STATUS_SUCCESS;
136 	} else {
137 		scm_err("invalid requester id");
138 		return QDF_STATUS_E_INVAL;
139 	}
140 
141 }
142 
143 static void scm_scan_post_event(struct wlan_objmgr_vdev *vdev,
144 		struct scan_event *event)
145 {
146 	uint32_t i = 0;
147 	struct wlan_scan_obj *scan;
148 	struct pdev_scan_ev_handler *pdev_ev_handler;
149 	struct cb_handler *cb_handlers;
150 	struct scan_requester_info *requesters;
151 	struct scan_event_listeners *listeners;
152 
153 	if (!vdev || !event) {
154 		scm_err("vdev: 0x%pK, event: 0x%pK", vdev, event);
155 		return;
156 	}
157 	if (!event->requester) {
158 		scm_err("invalid requester id");
159 		QDF_ASSERT(0);
160 	}
161 	scan = wlan_vdev_get_scan_obj(vdev);
162 	pdev_ev_handler = wlan_vdev_get_pdev_scan_ev_handlers(vdev);
163 	if (!pdev_ev_handler)
164 		return;
165 	cb_handlers = &(pdev_ev_handler->cb_handlers[0]);
166 	requesters = scan->requesters;
167 
168 	listeners = qdf_mem_malloc_atomic(sizeof(*listeners));
169 	if (!listeners) {
170 		scm_warn("couldn't allocate listeners list");
171 		return;
172 	}
173 
174 	/* initialize number of listeners */
175 	listeners->count = 0;
176 
177 	/*
178 	 * Initiator of scan request decides which all scan events
179 	 * he is interested in and FW will send only those scan events
180 	 * to host driver.
181 	 * All the events received by scan module will be notified
182 	 * to all registered handlers.
183 	 */
184 
185 	qdf_spin_lock_bh(&scan->lock);
186 	/* find all global scan event handlers on this pdev */
187 	scm_scan_get_pdev_global_event_handlers(listeners, pdev_ev_handler);
188 	/* find owner who triggered this scan request */
189 	scm_scan_get_requester_event_handler(listeners, requesters,
190 			event->requester);
191 	qdf_spin_unlock_bh(&scan->lock);
192 
193 	/* notify all interested handlers */
194 	for (i = 0; i < listeners->count; i++)
195 		listeners->cb[i].func(vdev, event, listeners->cb[i].arg);
196 	qdf_mem_free(listeners);
197 }
198 
199 static QDF_STATUS
200 scm_release_serialization_command(struct wlan_objmgr_vdev *vdev,
201 		uint32_t scan_id)
202 {
203 	struct wlan_serialization_queued_cmd_info cmd = {0};
204 
205 	cmd.requestor = WLAN_UMAC_COMP_SCAN;
206 	cmd.cmd_type = WLAN_SER_CMD_SCAN;
207 	cmd.cmd_id = scan_id;
208 	cmd.req_type = WLAN_SER_CANCEL_SINGLE_SCAN;
209 	cmd.vdev = vdev;
210 	cmd.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE;
211 
212 	/* Inform serialization for command completion */
213 	wlan_serialization_remove_cmd(&cmd);
214 
215 	return QDF_STATUS_SUCCESS;
216 }
217 
218 static QDF_STATUS
219 scm_post_internal_scan_complete_event(struct scan_start_request *req,
220 		enum scan_completion_reason reason)
221 {
222 	struct scan_event event = {0, };
223 
224 	/* prepare internal scan complete event */
225 	event.type = SCAN_EVENT_TYPE_COMPLETED;
226 	event.reason = reason;
227 	event.chan_freq = 0; /* Invalid frequency */
228 	event.vdev_id =  req->scan_req.vdev_id;
229 	event.requester = req->scan_req.scan_req_id;
230 	event.scan_id = req->scan_req.scan_id;
231 	/* Fill scan_start_request used to trigger this scan */
232 	event.scan_start_req = req;
233 	/* post scan event to registered handlers */
234 	scm_scan_post_event(req->vdev, &event);
235 
236 	return QDF_STATUS_SUCCESS;
237 }
238 
239 static inline struct pdev_scan_info *
240 scm_scan_get_pdev_priv_info(uint8_t pdev_id, struct wlan_scan_obj *scan_obj)
241 {
242 	return &scan_obj->pdev_info[pdev_id];
243 }
244 
245 static QDF_STATUS
246 scm_update_last_scan_time(struct scan_start_request *req)
247 {
248 	uint8_t pdev_id;
249 	struct wlan_scan_obj *scan_obj;
250 	struct pdev_scan_info *pdev_scan_info;
251 
252 	scan_obj = wlan_vdev_get_scan_obj(req->vdev);
253 	pdev_id = wlan_scan_vdev_get_pdev_id(req->vdev);
254 	pdev_scan_info = scm_scan_get_pdev_priv_info(pdev_id, scan_obj);
255 	/* update last scan start time */
256 	pdev_scan_info->last_scan_time = qdf_system_ticks();
257 
258 	return QDF_STATUS_SUCCESS;
259 }
260 
261 static QDF_STATUS
262 scm_activate_scan_request(struct scan_start_request *req)
263 {
264 	QDF_STATUS status;
265 
266 	status = tgt_scan_start(req);
267 	if (status != QDF_STATUS_SUCCESS) {
268 		scm_err("tgt_scan_start failed, status: %d", status);
269 		/* scan could not be started and hence
270 		 * we will not receive any completions.
271 		 * post scan cancelled
272 		 */
273 		scm_post_internal_scan_complete_event(req,
274 				SCAN_REASON_CANCELLED);
275 		return status;
276 	}
277 	/* save last scan start time */
278 	status = scm_update_last_scan_time(req);
279 
280 	return status;
281 }
282 
283 static QDF_STATUS
284 scm_cancel_scan_request(struct scan_start_request *req)
285 {
286 	struct scan_cancel_request cancel_req = {0, };
287 	QDF_STATUS status;
288 
289 	cancel_req.vdev = req->vdev;
290 	cancel_req.cancel_req.scan_id = req->scan_req.scan_id;
291 	cancel_req.cancel_req.requester = req->scan_req.scan_req_id;
292 	cancel_req.cancel_req.req_type = WLAN_SCAN_CANCEL_SINGLE;
293 	cancel_req.cancel_req.vdev_id = req->scan_req.vdev_id;
294 	/* send scan cancel to fw */
295 	status = tgt_scan_cancel(&cancel_req);
296 	if (status != QDF_STATUS_SUCCESS)
297 		scm_err("tgt_scan_cancel failed: status: %d, scanid: %d",
298 			status, req->scan_req.scan_id);
299 	/* notify event handler about scan cancellation */
300 	scm_post_internal_scan_complete_event(req, SCAN_REASON_CANCELLED);
301 
302 	return status;
303 }
304 
305 static QDF_STATUS
306 scm_scan_serialize_callback(struct wlan_serialization_command *cmd,
307 	enum wlan_serialization_cb_reason reason)
308 {
309 	struct scan_start_request *req;
310 	QDF_STATUS status;
311 
312 	if (!cmd) {
313 		scm_err("cmd is NULL, reason: %d", reason);
314 		QDF_ASSERT(0);
315 		return QDF_STATUS_E_NULL_VALUE;
316 	}
317 
318 	if (!cmd->umac_cmd) {
319 		scm_err("cmd->umac_cmd is NULL , reason: %d", reason);
320 		QDF_ASSERT(0);
321 		return QDF_STATUS_E_NULL_VALUE;
322 	}
323 
324 	req = cmd->umac_cmd;
325 	if (!req->vdev) {
326 		scm_err("NULL vdev. req:0x%pK, reason:%d\n", req, reason);
327 		QDF_ASSERT(0);
328 		return QDF_STATUS_E_NULL_VALUE;
329 	}
330 
331 	qdf_mtrace(QDF_MODULE_ID_SERIALIZATION, QDF_MODULE_ID_SCAN, reason,
332 		   req->scan_req.vdev_id, req->scan_req.scan_id);
333 
334 	switch (reason) {
335 	case WLAN_SER_CB_ACTIVATE_CMD:
336 		/* command moved to active list
337 		 * modify the params if required for concurency case.
338 		 */
339 		status = scm_activate_scan_request(req);
340 		break;
341 
342 	case WLAN_SER_CB_CANCEL_CMD:
343 		/* command removed from pending list.
344 		 * notify registered scan event handlers with
345 		 * status completed and reason cancelled.
346 		 */
347 		status = scm_post_internal_scan_complete_event(req,
348 				SCAN_REASON_CANCELLED);
349 		break;
350 
351 	case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT:
352 		/* active command timed out.
353 		 * prepare internal scan cancel request
354 		 */
355 		status = scm_cancel_scan_request(req);
356 		break;
357 
358 	case WLAN_SER_CB_RELEASE_MEM_CMD:
359 		/* command successfully completed.
360 		 * Release vdev reference and free scan_start_request memory
361 		 */
362 		cmd->umac_cmd = NULL;
363 		wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
364 		status = scm_scan_free_scan_request_mem(req);
365 		break;
366 
367 	default:
368 		/* Do nothing but logging */
369 		QDF_ASSERT(0);
370 		status = QDF_STATUS_E_INVAL;
371 		break;
372 	}
373 
374 	return status;
375 }
376 
377 bool scm_is_scan_allowed(struct wlan_objmgr_vdev *vdev)
378 {
379 	struct wlan_scan_obj *scan_psoc_obj;
380 	struct scan_vdev_obj *scan_vdev_obj;
381 
382 	if (!vdev) {
383 		scm_err("vdev is NULL");
384 		return false;
385 	}
386 
387 	scan_psoc_obj = wlan_vdev_get_scan_obj(vdev);
388 	if (!scan_psoc_obj) {
389 		scm_err("Couldn't find scan psoc object");
390 		return false;
391 	}
392 
393 	if (scan_psoc_obj->scan_disabled) {
394 		scm_err_rl("scan disabled %x, for psoc",
395 			   scan_psoc_obj->scan_disabled);
396 		return false;
397 	}
398 
399 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
400 	if (!scan_vdev_obj) {
401 		scm_err("Couldn't find scan vdev object");
402 		return false;
403 	}
404 
405 	if (scan_vdev_obj->scan_disabled) {
406 		scm_err_rl("scan disabled %x on vdev_id:%d",
407 			   scan_vdev_obj->scan_disabled,
408 			   wlan_vdev_get_id(vdev));
409 		return false;
410 	}
411 
412 	return true;
413 }
414 
415 #ifdef WLAN_POLICY_MGR_ENABLE
416 /**
417  * scm_update_dbs_scan_ctrl_ext_flag() - update dbs scan ctrl flags
418  * @req: pointer to scan request
419  *
420  * This function sets scan_ctrl_flags_ext value depending on the type of
421  * scan and the channel lists.
422  *
423  * Non-DBS scan is requested if any of the below case is met:
424  *     1. HW is DBS incapable
425  *     2. A high accuracy scan request is sent by kernel.
426  *
427  * DBS scan is enabled for these conditions:
428  *     1. A low power or low span scan request is sent by kernel.
429  * For remaining cases DBS is enabled by default.
430  * Return: void
431  */
432 static void
433 scm_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req)
434 {
435 	struct wlan_objmgr_psoc *psoc;
436 	uint32_t scan_dbs_policy = SCAN_DBS_POLICY_DEFAULT;
437 	bool ndi_present;
438 
439 	psoc = wlan_vdev_get_psoc(req->vdev);
440 
441 	if (!policy_mgr_is_dbs_scan_allowed(psoc)) {
442 		scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS;
443 		goto end;
444 	}
445 
446 	if (!wlan_scan_cfg_honour_nl_scan_policy_flags(psoc)) {
447 		scm_debug_rl("nl scan policy flags not honoured, goto end");
448 		goto end;
449 	}
450 
451 	ndi_present = policy_mgr_mode_specific_connection_count(psoc,
452 								PM_NDI_MODE,
453 								NULL);
454 
455 	if (ndi_present && !policy_mgr_is_hw_dbs_2x2_capable(psoc)) {
456 		scm_debug("NDP present go for DBS scan");
457 		goto end;
458 	}
459 
460 	if (req->scan_req.scan_policy_high_accuracy) {
461 		scm_debug("high accuracy scan received, going for non-dbs scan");
462 		scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS;
463 		goto end;
464 	}
465 	if ((req->scan_req.scan_policy_low_power) ||
466 	    (req->scan_req.scan_policy_low_span)) {
467 		scm_debug("low power/span scan received, going for dbs scan");
468 		scan_dbs_policy = SCAN_DBS_POLICY_IGNORE_DUTY;
469 		goto end;
470 	}
471 
472 end:
473 	req->scan_req.scan_ctrl_flags_ext |=
474 		((scan_dbs_policy << SCAN_FLAG_EXT_DBS_SCAN_POLICY_BIT)
475 		 & SCAN_FLAG_EXT_DBS_SCAN_POLICY_MASK);
476 }
477 
478 /**
479  * scm_update_passive_dwell_time() - update dwell passive time
480  * @vdev: vdev object
481  * @req: scan request
482  *
483  * Return: None
484  */
485 static void
486 scm_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev,
487 			      struct scan_start_request *req)
488 {
489 	struct wlan_objmgr_psoc *psoc;
490 
491 	psoc = wlan_vdev_get_psoc(vdev);
492 	if (!psoc)
493 		return;
494 
495 	if (policy_mgr_is_sta_connected_2g(psoc) &&
496 	    !policy_mgr_is_hw_dbs_capable(psoc) &&
497 	    ucfg_scan_get_bt_activity(psoc))
498 		req->scan_req.dwell_time_passive =
499 				PASSIVE_DWELL_TIME_BT_A2DP_ENABLED;
500 }
501 
502 static const struct probe_time_dwell_time
503 	scan_probe_time_dwell_time_map[SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE] = {
504 	{28, 11},               /* 0 SSID */
505 	{28, 20},               /* 1 SSID */
506 	{28, 20},               /* 2 SSID */
507 	{28, 20},               /* 3 SSID */
508 	{28, 20},               /* 4 SSID */
509 	{28, 20},               /* 5 SSID */
510 	{28, 20},               /* 6 SSID */
511 	{28, 11},               /* 7 SSID */
512 	{28, 11},               /* 8 SSID */
513 	{28, 11},               /* 9 SSID */
514 	{28, 8}                 /* 10 SSID */
515 };
516 
517 /**
518  * scm_scan_get_burst_duration() - get burst duration depending on max chan
519  * and miracast.
520  * @max_ch_time: max channel time
521  * @miracast_enabled: if miracast is enabled
522  *
523  * Return: burst_duration
524  */
525 static inline
526 int scm_scan_get_burst_duration(int max_ch_time, bool miracast_enabled)
527 {
528 	int burst_duration = 0;
529 
530 	if (miracast_enabled) {
531 		/*
532 		 * When miracast is running, burst
533 		 * duration needs to be minimum to avoid
534 		 * any stutter or glitch in miracast
535 		 * during station scan
536 		 */
537 		if (max_ch_time <= SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION)
538 			burst_duration = max_ch_time;
539 		else
540 			burst_duration = SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION;
541 	} else {
542 		/*
543 		 * If miracast is not running, accommodate max
544 		 * stations to make the scans faster
545 		 */
546 		burst_duration = SCAN_GO_BURST_SCAN_MAX_NUM_OFFCHANNELS *
547 							max_ch_time;
548 
549 		if (burst_duration > SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION) {
550 			uint8_t channels = SCAN_P2P_SCAN_MAX_BURST_DURATION /
551 								 max_ch_time;
552 
553 			if (channels)
554 				burst_duration = channels * max_ch_time;
555 			else
556 				burst_duration =
557 					 SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION;
558 		}
559 	}
560 	return burst_duration;
561 }
562 
563 #define SCM_ACTIVE_DWELL_TIME_NAN      60
564 #define SCM_ACTIVE_DWELL_TIME_SAP      40
565 
566 /**
567  * scm_req_update_concurrency_params() - update scan req params depending on
568  * concurrent mode present.
569  * @vdev: vdev object pointer
570  * @req: scan request
571  * @scan_obj: scan object
572  *
573  * Return: void
574  */
575 static void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev,
576 					      struct scan_start_request *req,
577 					      struct wlan_scan_obj *scan_obj)
578 {
579 	bool ap_present, go_present, sta_active, p2p_cli_present, ndi_present;
580 	struct wlan_objmgr_psoc *psoc;
581 	uint16_t sap_peer_count = 0;
582 	uint16_t go_peer_count = 0;
583 	struct wlan_objmgr_pdev *pdev;
584 
585 	psoc = wlan_vdev_get_psoc(vdev);
586 	pdev = wlan_vdev_get_pdev(vdev);
587 
588 	if (!psoc || !pdev)
589 		return;
590 
591 	ap_present = policy_mgr_mode_specific_connection_count(
592 				psoc, PM_SAP_MODE, NULL);
593 	go_present = policy_mgr_mode_specific_connection_count(
594 				psoc, PM_P2P_GO_MODE, NULL);
595 	p2p_cli_present = policy_mgr_mode_specific_connection_count(
596 				psoc, PM_P2P_CLIENT_MODE, NULL);
597 	sta_active = policy_mgr_mode_specific_connection_count(
598 				psoc, PM_STA_MODE, NULL);
599 	ndi_present = policy_mgr_mode_specific_connection_count(
600 				psoc, PM_NDI_MODE, NULL);
601 	if (ap_present)
602 		sap_peer_count =
603 		wlan_util_get_peer_count_for_mode(pdev, QDF_SAP_MODE);
604 	if (go_present)
605 		go_peer_count =
606 		wlan_util_get_peer_count_for_mode(pdev, QDF_P2P_GO_MODE);
607 
608 	if (!req->scan_req.scan_f_passive)
609 		scm_update_passive_dwell_time(vdev, req);
610 
611 	if (policy_mgr_get_connection_count(psoc)) {
612 		if (req->scan_req.scan_f_passive)
613 			req->scan_req.dwell_time_passive =
614 				scan_obj->scan_def.conc_passive_dwell;
615 		else
616 			req->scan_req.dwell_time_active =
617 				scan_obj->scan_def.conc_active_dwell;
618 		req->scan_req.max_rest_time =
619 				scan_obj->scan_def.conc_max_rest_time;
620 		req->scan_req.min_rest_time =
621 			scan_obj->scan_def.conc_min_rest_time;
622 		req->scan_req.idle_time = scan_obj->scan_def.conc_idle_time;
623 	}
624 
625 	if (wlan_vdev_is_up(req->vdev) != QDF_STATUS_SUCCESS)
626 		req->scan_req.adaptive_dwell_time_mode =
627 			scan_obj->scan_def.adaptive_dwell_time_mode_nc;
628 	/*
629 	 * If AP/GO is active and has connected clients :
630 	 * 1.set min rest time same as max rest time, so that
631 	 * firmware spends more time on home channel which will
632 	 * increase the probability of sending beacon at TBTT
633 	 * 2.if DBS is supported and SAP is not on 2g,
634 	 * do not reset active dwell time for 2g.
635 	 */
636 	if ((ap_present && sap_peer_count) ||
637 	    (go_present && go_peer_count)) {
638 		if (policy_mgr_is_hw_dbs_capable(psoc) &&
639 		    policy_mgr_is_sap_go_on_2g(psoc)) {
640 			req->scan_req.dwell_time_active_2g =
641 				QDF_MIN(req->scan_req.dwell_time_active,
642 					(SCAN_CTS_DURATION_MS_MAX -
643 					SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME));
644 		}
645 		req->scan_req.min_rest_time = req->scan_req.max_rest_time;
646 	}
647 
648 	/*
649 	 * If scan req for SAP (ACS Sacn) use dwell_time_active_def as dwell
650 	 * time for 2g channels instead of dwell_time_active_2g
651 	 */
652 	if (vdev->vdev_mlme.vdev_opmode == QDF_SAP_MODE)
653 		req->scan_req.dwell_time_active_2g = SCM_ACTIVE_DWELL_TIME_SAP;
654 
655 	if (req->scan_req.scan_type == SCAN_TYPE_DEFAULT) {
656 		/*
657 		 * Decide burst_duration and dwell_time_active based on
658 		 * what type of devices are active.
659 		 */
660 		do {
661 			if (ap_present && go_present && sta_active) {
662 				if (req->scan_req.dwell_time_active <=
663 					SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION)
664 					req->scan_req.burst_duration =
665 						req->scan_req.dwell_time_active;
666 				else
667 					req->scan_req.burst_duration =
668 					SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION;
669 
670 				break;
671 			}
672 
673 			if (scan_obj->miracast_enabled &&
674 			    policy_mgr_is_mcc_in_24G(psoc))
675 				req->scan_req.max_rest_time =
676 				  scan_obj->scan_def.sta_miracast_mcc_rest_time;
677 
678 			if (go_present) {
679 				/*
680 				 * Background scan while GO is sending beacons.
681 				 * Every off-channel transition has overhead of
682 				 * 2 beacon intervals for NOA. Maximize number
683 				 * of channels in every transition by using
684 				 * burst scan.
685 				 */
686 				if (scan_obj->scan_def.go_scan_burst_duration)
687 					req->scan_req.burst_duration =
688 						scan_obj->
689 						scan_def.go_scan_burst_duration;
690 				else
691 					req->scan_req.burst_duration =
692 						scm_scan_get_burst_duration(
693 							req->scan_req.
694 							dwell_time_active,
695 							scan_obj->
696 							miracast_enabled);
697 				break;
698 			}
699 			if ((sta_active || p2p_cli_present)) {
700 				if (scan_obj->scan_def.sta_scan_burst_duration)
701 					req->scan_req.burst_duration =
702 						scan_obj->scan_def.
703 						sta_scan_burst_duration;
704 				break;
705 			}
706 
707 			if (ndi_present ||
708 			    ((go_present || p2p_cli_present) && sta_active)) {
709 				req->scan_req.burst_duration = 0;
710 				break;
711 			}
712 		} while (0);
713 
714 		if (ap_present) {
715 			uint8_t ssid_num;
716 
717 			ssid_num = req->scan_req.num_ssids *
718 					req->scan_req.num_bssid;
719 			req->scan_req.repeat_probe_time =
720 				scan_probe_time_dwell_time_map[
721 					QDF_MIN(ssid_num,
722 					SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE
723 					- 1)].probe_time;
724 			req->scan_req.n_probes =
725 				(req->scan_req.repeat_probe_time > 0) ?
726 				req->scan_req.dwell_time_active /
727 				req->scan_req.repeat_probe_time : 0;
728 		}
729 	}
730 
731 	if (ap_present) {
732 		uint16_t ap_chan_freq;
733 		struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
734 
735 		ap_chan_freq = policy_mgr_get_channel(psoc, PM_SAP_MODE, NULL);
736 		/*
737 		 * P2P/STA scan while SoftAP is sending beacons.
738 		 * Max duration of CTS2self is 32 ms, which limits the
739 		 * dwell time.
740 		 * If DBS is supported and:
741 		 * 1.if SAP is on 2G channel then keep passive
742 		 * dwell time default.
743 		 * 2.if SAP is on 5G/6G channel then update dwell time active.
744 		 */
745 		if (sap_peer_count) {
746 			if (policy_mgr_is_hw_dbs_capable(psoc) &&
747 			    (WLAN_REG_IS_5GHZ_CH_FREQ(ap_chan_freq) ||
748 			    WLAN_REG_IS_6GHZ_CHAN_FREQ(ap_chan_freq))) {
749 				req->scan_req.dwell_time_active =
750 					QDF_MIN(req->scan_req.dwell_time_active,
751 						(SCAN_CTS_DURATION_MS_MAX -
752 					SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME));
753 			}
754 			if (!policy_mgr_is_hw_dbs_capable(psoc) ||
755 			    (policy_mgr_is_hw_dbs_capable(psoc) &&
756 			     WLAN_REG_IS_5GHZ_CH_FREQ(ap_chan_freq))) {
757 				req->scan_req.dwell_time_passive =
758 					req->scan_req.dwell_time_active;
759 			}
760 		}
761 
762 		if (scan_obj->scan_def.ap_scan_burst_duration) {
763 			req->scan_req.burst_duration =
764 				scan_obj->scan_def.ap_scan_burst_duration;
765 		} else {
766 			req->scan_req.burst_duration = 0;
767 			if (wlan_reg_is_dfs_for_freq(pdev, ap_chan_freq))
768 				req->scan_req.burst_duration =
769 					SCAN_BURST_SCAN_MAX_NUM_OFFCHANNELS *
770 					req->scan_req.dwell_time_active;
771 		}
772 	}
773 
774 	if (ndi_present) {
775 		req->scan_req.dwell_time_active =
776 						SCM_ACTIVE_DWELL_TIME_NAN;
777 		req->scan_req.dwell_time_active_2g =
778 			QDF_MIN(req->scan_req.dwell_time_active_2g,
779 			SCM_ACTIVE_DWELL_TIME_NAN);
780 		scm_debug("NDP active modify dwell time 2ghz %d",
781 			req->scan_req.dwell_time_active_2g);
782 	}
783 }
784 
785 /**
786  * scm_scan_chlist_concurrency_modify() - modify chan list to skip 5G if
787  *    required
788  * @vdev: vdev object
789  * @req: scan request
790  *
791  * Check and skip 5G chan list based on DFS AP present and current hw mode.
792  *
793  * Return: void
794  */
795 static inline void scm_scan_chlist_concurrency_modify(
796 	struct wlan_objmgr_vdev *vdev, struct scan_start_request *req)
797 {
798 	struct wlan_objmgr_psoc *psoc;
799 	uint32_t i;
800 	uint32_t num_scan_channels;
801 
802 	psoc = wlan_vdev_get_psoc(vdev);
803 	if (!psoc)
804 		return;
805 	/* do this only for STA and P2P-CLI mode */
806 	if (!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) &&
807 	    !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE))
808 		return;
809 	if (!policy_mgr_scan_trim_5g_chnls_for_dfs_ap(psoc))
810 		return;
811 	num_scan_channels = 0;
812 	for (i = 0; i < req->scan_req.chan_list.num_chan; i++) {
813 		if (WLAN_REG_IS_5GHZ_CH_FREQ(
814 			req->scan_req.chan_list.chan[i].freq)) {
815 			continue;
816 		}
817 		req->scan_req.chan_list.chan[num_scan_channels++] =
818 			req->scan_req.chan_list.chan[i];
819 	}
820 	if (num_scan_channels < req->scan_req.chan_list.num_chan)
821 		scm_debug("5g chan skipped (%d, %d)",
822 			  req->scan_req.chan_list.num_chan, num_scan_channels);
823 	req->scan_req.chan_list.num_chan = num_scan_channels;
824 }
825 #else
826 static inline
827 void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev,
828 				       struct scan_start_request *req,
829 				       struct wlan_scan_obj *scan_obj)
830 {
831 }
832 
833 static inline void
834 scm_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req)
835 {
836 }
837 
838 static inline void scm_scan_chlist_concurrency_modify(
839 	struct wlan_objmgr_vdev *vdev, struct scan_start_request *req)
840 {
841 }
842 #endif
843 
844 #ifdef CONFIG_BAND_6GHZ
845 static void
846 scm_update_6ghz_channel_list(struct wlan_objmgr_vdev *vdev,
847 			     struct chan_list *chan_list,
848 			     struct wlan_scan_obj *scan_obj)
849 {
850 	uint8_t i;
851 	struct regulatory_channel *chan_list_6g;
852 	bool psc_channel_found = false;
853 	bool channel_6g_found = false;
854 	uint8_t num_scan_channels = 0, channel_count;
855 	struct wlan_objmgr_pdev *pdev;
856 	uint32_t freq;
857 
858 	pdev = wlan_vdev_get_pdev(vdev);
859 	if (!pdev)
860 		return;
861 
862 	scm_debug("6g scan mode %d", scan_obj->scan_def.scan_mode_6g);
863 	for (i = 0; i < chan_list->num_chan; i++) {
864 		freq = chan_list->chan[i].freq;
865 		if ((scan_obj->scan_def.scan_mode_6g ==
866 		     SCAN_MODE_6G_NO_CHANNEL) &&
867 		    (wlan_reg_is_6ghz_chan_freq(freq))) {
868 			/* Drop the 6Ghz channels */
869 			continue;
870 		} else if ((scan_obj->scan_def.scan_mode_6g ==
871 			SCAN_MODE_6G_PSC_CHANNEL) &&
872 			(wlan_reg_is_6ghz_chan_freq(freq))) {
873 			/* Allow only PSC channels */
874 			if (wlan_reg_is_6ghz_psc_chan_freq(freq))
875 				psc_channel_found = true;
876 			else
877 				continue;
878 		} else if ((scan_obj->scan_def.scan_mode_6g ==
879 			     SCAN_MODE_6G_ALL_CHANNEL) &&
880 			    (wlan_reg_is_6ghz_chan_freq(freq))) {
881 			/* Allow  any 6ghz channel */
882 			channel_6g_found = true;
883 		}
884 		chan_list->chan[num_scan_channels++] =
885 			chan_list->chan[i];
886 	}
887 
888 	scm_debug("psc_channel_found %d channel_6g_found%d",
889 		  psc_channel_found, channel_6g_found);
890 	if ((scan_obj->scan_def.scan_mode_6g == SCAN_MODE_6G_PSC_CHANNEL &&
891 	     !psc_channel_found) ||
892 	    (scan_obj->scan_def.scan_mode_6g == SCAN_MODE_6G_ALL_CHANNEL &&
893 	     !channel_6g_found)) {
894 		chan_list_6g = qdf_mem_malloc(NUM_6GHZ_CHANNELS *
895 				sizeof(struct regulatory_channel));
896 		if (!chan_list_6g)
897 			goto end;
898 
899 		/* Add the 6Ghz channels based on config*/
900 		channel_count = wlan_reg_get_band_channel_list(pdev,
901 							       BIT(REG_BAND_6G),
902 							       chan_list_6g);
903 		scm_debug("Number of 6G channels %d", channel_count);
904 		for (i = 0; i < channel_count; i++) {
905 			if ((scan_obj->scan_def.scan_mode_6g ==
906 			     SCAN_MODE_6G_PSC_CHANNEL) &&
907 			     (!psc_channel_found) &&
908 			     wlan_reg_is_6ghz_psc_chan_freq(chan_list_6g[i].
909 				center_freq)) {
910 				chan_list->chan[num_scan_channels++].freq =
911 					chan_list_6g[i].center_freq;
912 			} else if ((scan_obj->scan_def.scan_mode_6g ==
913 			     SCAN_MODE_6G_ALL_CHANNEL) &&
914 			    (!channel_6g_found)) {
915 				chan_list->chan[num_scan_channels++].freq =
916 					chan_list_6g[i].center_freq;
917 			}
918 		}
919 		qdf_mem_free(chan_list_6g);
920 	}
921 end:
922 	chan_list->num_chan = num_scan_channels;
923 }
924 #else
925 static void
926 scm_update_6ghz_channel_list(struct wlan_objmgr_vdev *vdev,
927 			     struct chan_list *chan_list,
928 			     struct wlan_scan_obj *scan_obj)
929 {
930 }
931 #endif
932 
933 #ifdef FEATURE_6G_SCAN_CHAN_SORT_ALGO
934 static void scm_sort_6ghz_channel_list(struct wlan_objmgr_vdev *vdev,
935 				       struct chan_list *chan_list)
936 {
937 	uint8_t i, j = 0, max, tmp_list_count;
938 	struct meta_rnr_channel *channel;
939 	struct chan_info temp_list[MAX_6GHZ_CHANNEL];
940 	struct rnr_chan_weight *rnr_chan_info, *temp;
941 	uint32_t weight;
942 	struct wlan_objmgr_psoc *psoc;
943 
944 	rnr_chan_info = qdf_mem_malloc(sizeof(rnr_chan_info) * MAX_6GHZ_CHANNEL);
945 	if (!rnr_chan_info)
946 		return;
947 
948 	for (i = 0; i < chan_list->num_chan; i++) {
949 		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_list->chan[i].freq))
950 			temp_list[j++].freq = chan_list->chan[i].freq;
951 	}
952 	tmp_list_count = j;
953 	scm_debug("Total 6ghz channels %d", tmp_list_count);
954 
955 	/* No Need to sort if the 6ghz channels are less than one */
956 	if (tmp_list_count < 1) {
957 		qdf_mem_free(rnr_chan_info);
958 		return;
959 	}
960 
961 	psoc = wlan_vdev_get_psoc(vdev);
962 	if (!psoc) {
963 		scm_err("Psoc is NULL");
964 		qdf_mem_free(rnr_chan_info);
965 		return;
966 	}
967 
968 	/* compute the weightage */
969 	for (i = 0, j = 0; i < tmp_list_count; i++) {
970 		channel = scm_get_chan_meta(psoc, temp_list[i].freq);
971 		if (!channel)
972 			continue;
973 		weight = channel->bss_beacon_probe_count * BCN_PROBE_WEIGHTAGE +
974 			 channel->saved_profile_count * SAVED_PROFILE_WEIGHTAGE;
975 		rnr_chan_info[j].weight = weight;
976 		rnr_chan_info[j].chan_freq = temp_list[i].freq;
977 		j++;
978 		scm_debug("Freq %d weight %d bcn_cnt %d", temp_list[i].freq,
979 			  weight, channel->bss_beacon_probe_count);
980 	}
981 
982 	/* Sort the channel using selection sort - descending order */
983 	for (i = 0; i < tmp_list_count - 1; i++) {
984 		max = i;
985 		for (j = i + 1; j < tmp_list_count; j++) {
986 			if (rnr_chan_info[j].weight >
987 			    rnr_chan_info[max].weight)
988 				max = j;
989 		}
990 		if (max != i) {
991 			qdf_mem_copy(&temp, &rnr_chan_info[max],
992 				     sizeof(*rnr_chan_info));
993 			qdf_mem_copy(&rnr_chan_info[max], &rnr_chan_info[i],
994 				     sizeof(*rnr_chan_info));
995 			qdf_mem_copy(&rnr_chan_info[i], &temp,
996 				     sizeof(*rnr_chan_info));
997 		}
998 	}
999 
1000 	/* update the 6g list based on the weightage */
1001 	for (i = 0, j = 0; (i < NUM_CHANNELS && j < tmp_list_count); i++) {
1002 		if (wlan_reg_is_6ghz_chan_freq(chan_list->chan[i].freq))
1003 			chan_list->chan[i].freq = rnr_chan_info[j++].chan_freq;
1004 	}
1005 	qdf_mem_free(rnr_chan_info);
1006 }
1007 
1008 static void scm_update_rnr_info(struct wlan_objmgr_psoc *psoc,
1009 				struct scan_start_request *req)
1010 {
1011 	uint8_t i, num_bssid = 0, num_ssid = 0;
1012 	uint8_t total_count = MAX_HINTS_PER_SCAN_REQ;
1013 	uint32_t freq;
1014 	struct meta_rnr_channel *chan;
1015 	qdf_list_node_t *cur_node, *next_node = NULL;
1016 	struct scan_rnr_node *rnr_node;
1017 	struct chan_list *chan_list;
1018 	QDF_STATUS status;
1019 
1020 	if (!req)
1021 		return;
1022 
1023 	chan_list = &req->scan_req.chan_list;
1024 	for (i = 0; i < chan_list->num_chan; i++) {
1025 		freq = chan_list->chan[i].freq;
1026 
1027 		chan = scm_get_chan_meta(psoc, freq);
1028 		if (!chan) {
1029 			scm_debug("Failed to get meta, freq %d", freq);
1030 			continue;
1031 		}
1032 		if (qdf_list_empty(&chan->rnr_list))
1033 			continue;
1034 
1035 		qdf_list_peek_front(&chan->rnr_list, &cur_node);
1036 		while (cur_node && total_count) {
1037 			rnr_node = qdf_container_of(cur_node,
1038 						    struct scan_rnr_node,
1039 						    node);
1040 			if (!qdf_is_macaddr_zero(&rnr_node->entry.bssid) &&
1041 			    req->scan_req.num_hint_bssid <
1042 			    WLAN_SCAN_MAX_HINT_BSSID) {
1043 				qdf_mem_copy(&req->scan_req.hint_bssid[num_bssid++].bssid,
1044 					     &rnr_node->entry.bssid,
1045 					     QDF_MAC_ADDR_SIZE);
1046 				req->scan_req.num_hint_bssid++;
1047 				total_count--;
1048 			} else if (rnr_node->entry.short_ssid &&
1049 				   req->scan_req.num_hint_s_ssid <
1050 				   WLAN_SCAN_MAX_HINT_S_SSID) {
1051 				req->scan_req.hint_s_ssid[num_ssid++].short_ssid =
1052 						rnr_node->entry.short_ssid;
1053 				req->scan_req.num_hint_s_ssid++;
1054 				total_count--;
1055 			}
1056 			status = qdf_list_peek_next(&chan->rnr_list, cur_node,
1057 						    &next_node);
1058 			if (QDF_IS_STATUS_ERROR(status))
1059 				break;
1060 			cur_node = next_node;
1061 			next_node = NULL;
1062 		}
1063 	}
1064 }
1065 
1066 static void scm_add_rnr_info(struct wlan_objmgr_pdev *pdev,
1067 			     struct scan_start_request *req)
1068 {
1069 	struct wlan_objmgr_psoc *psoc;
1070 	struct channel_list_db *rnr_db;
1071 
1072 	psoc = wlan_pdev_get_psoc(pdev);
1073 	if (!psoc)
1074 		return;
1075 	rnr_db = scm_get_rnr_channel_db(psoc);
1076 	if (!rnr_db)
1077 		return;
1078 
1079 	rnr_db->scan_count++;
1080 	if (rnr_db->scan_count >= RNR_UPDATE_SCAN_CNT_THRESHOLD) {
1081 		rnr_db->scan_count = 0;
1082 		scm_rnr_db_flush(psoc);
1083 		scm_update_rnr_from_scan_cache(pdev);
1084 	}
1085 
1086 	scm_update_rnr_info(psoc, req);
1087 }
1088 
1089 #else
1090 static void scm_sort_6ghz_channel_list(struct wlan_objmgr_vdev *vdev,
1091 				       struct chan_list *chan_list)
1092 {
1093 }
1094 
1095 static void scm_add_rnr_info(struct wlan_objmgr_pdev *pdev,
1096 			     struct scan_start_request *req)
1097 {
1098 }
1099 #endif
1100 
1101 /**
1102  * scm_update_channel_list() - update scan req params depending on dfs inis
1103  * and initial scan request.
1104  * @req: scan request
1105  * @scan_obj: scan object
1106  *
1107  * Return: void
1108  */
1109 static void
1110 scm_update_channel_list(struct scan_start_request *req,
1111 			struct wlan_scan_obj *scan_obj)
1112 {
1113 	uint8_t i;
1114 	uint8_t num_scan_channels = 0;
1115 	struct scan_vdev_obj *scan_vdev_obj;
1116 	struct wlan_objmgr_pdev *pdev;
1117 	bool first_scan_done = true;
1118 	bool p2p_search = false;
1119 	bool skip_dfs_ch = true;
1120 	uint32_t first_freq;
1121 
1122 	pdev = wlan_vdev_get_pdev(req->vdev);
1123 
1124 	scan_vdev_obj = wlan_get_vdev_scan_obj(req->vdev);
1125 	if (!scan_vdev_obj) {
1126 		scm_err("null scan_vdev_obj");
1127 		return;
1128 	}
1129 
1130 	if (!scan_vdev_obj->first_scan_done) {
1131 		first_scan_done = false;
1132 		scan_vdev_obj->first_scan_done = true;
1133 	}
1134 
1135 	if (req->scan_req.scan_type == SCAN_TYPE_P2P_SEARCH)
1136 		p2p_search = true;
1137 	/*
1138 	 * No need to update channels if req is single channel* ie ROC,
1139 	 * Preauth or a single channel scan etc.
1140 	 * If the single chan in the scan channel list is an NOL channel,it is
1141 	 * removed and it would reduce the number of scan channels to 0.
1142 	 */
1143 	first_freq = req->scan_req.chan_list.chan[0].freq;
1144 	if ((req->scan_req.chan_list.num_chan == 1) &&
1145 	    (!utils_dfs_is_freq_in_nol(pdev, first_freq)))
1146 		return;
1147 
1148 	/* do this only for STA and P2P-CLI mode */
1149 	if ((!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) &&
1150 	    !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE)) &&
1151 	    !p2p_search)
1152 		skip_dfs_ch = false;
1153 
1154 	if ((scan_obj->scan_def.allow_dfs_chan_in_scan &&
1155 	    (scan_obj->scan_def.allow_dfs_chan_in_first_scan ||
1156 	     first_scan_done)) &&
1157 	     !(scan_obj->scan_def.skip_dfs_chan_in_p2p_search && p2p_search) &&
1158 	     !scan_obj->miracast_enabled)
1159 		skip_dfs_ch = false;
1160 
1161 	for (i = 0; i < req->scan_req.chan_list.num_chan; i++) {
1162 		uint32_t freq;
1163 
1164 		freq = req->scan_req.chan_list.chan[i].freq;
1165 		if (skip_dfs_ch &&
1166 		    wlan_reg_chan_has_dfs_attribute_for_freq(pdev, freq)) {
1167 			scm_nofl_debug("Skip DFS freq %d", freq);
1168 			continue;
1169 		}
1170 		if (utils_dfs_is_freq_in_nol(pdev, freq)) {
1171 			scm_nofl_debug("Skip NOL freq %d", freq);
1172 			continue;
1173 		}
1174 
1175 		req->scan_req.chan_list.chan[num_scan_channels++] =
1176 			req->scan_req.chan_list.chan[i];
1177 	}
1178 
1179 	req->scan_req.chan_list.num_chan = num_scan_channels;
1180 	/* Dont upadte the channel list for SAP mode */
1181 	if (wlan_vdev_mlme_get_opmode(req->vdev) != QDF_SAP_MODE) {
1182 		scm_update_6ghz_channel_list(req->vdev,
1183 					     &req->scan_req.chan_list,
1184 					     scan_obj);
1185 		scm_sort_6ghz_channel_list(req->vdev, &req->scan_req.chan_list);
1186 	}
1187 	scm_scan_chlist_concurrency_modify(req->vdev, req);
1188 }
1189 
1190 /**
1191  * scm_scan_req_update_params() - update scan req params depending on modes
1192  * and scan type.
1193  * @vdev: vdev object pointer
1194  * @req: scan request
1195  * @scan_obj: scan object
1196  *
1197  * Return: void
1198  */
1199 static void
1200 scm_scan_req_update_params(struct wlan_objmgr_vdev *vdev,
1201 			   struct scan_start_request *req,
1202 			   struct wlan_scan_obj *scan_obj)
1203 {
1204 	struct chan_list *custom_chan_list;
1205 	struct wlan_objmgr_pdev *pdev;
1206 	uint8_t pdev_id;
1207 
1208 	/* Ensure correct number of probes are sent on active channel */
1209 	if (!req->scan_req.repeat_probe_time)
1210 		req->scan_req.repeat_probe_time =
1211 			req->scan_req.dwell_time_active / SCAN_NPROBES_DEFAULT;
1212 
1213 	if (req->scan_req.scan_f_passive)
1214 		req->scan_req.scan_ctrl_flags_ext |=
1215 			SCAN_FLAG_EXT_FILTER_PUBLIC_ACTION_FRAME;
1216 
1217 	if (!req->scan_req.n_probes)
1218 		req->scan_req.n_probes = (req->scan_req.repeat_probe_time > 0) ?
1219 					  req->scan_req.dwell_time_active /
1220 					  req->scan_req.repeat_probe_time : 0;
1221 
1222 	if (req->scan_req.scan_type == SCAN_TYPE_P2P_SEARCH ||
1223 	    req->scan_req.scan_type == SCAN_TYPE_P2P_LISTEN) {
1224 		req->scan_req.adaptive_dwell_time_mode = SCAN_DWELL_MODE_STATIC;
1225 		req->scan_req.dwell_time_active_2g = 0;
1226 		if (req->scan_req.scan_type == SCAN_TYPE_P2P_LISTEN) {
1227 			req->scan_req.repeat_probe_time = 0;
1228 		} else {
1229 			req->scan_req.scan_f_filter_prb_req = true;
1230 			if (!req->scan_req.num_ssids)
1231 				req->scan_req.scan_f_bcast_probe = true;
1232 
1233 			req->scan_req.dwell_time_active +=
1234 					P2P_SEARCH_DWELL_TIME_INC;
1235 			/*
1236 			 * 3 channels with default max dwell time 40 ms.
1237 			 * Cap limit will be set by
1238 			 * P2P_SCAN_MAX_BURST_DURATION. Burst duration
1239 			 * should be such that no channel is scanned less
1240 			 * than the dwell time in normal scenarios.
1241 			 */
1242 			if (req->scan_req.chan_list.num_chan ==
1243 			    WLAN_P2P_SOCIAL_CHANNELS &&
1244 			    !scan_obj->miracast_enabled)
1245 				req->scan_req.repeat_probe_time =
1246 					req->scan_req.dwell_time_active / 5;
1247 			else
1248 				req->scan_req.repeat_probe_time =
1249 					req->scan_req.dwell_time_active / 3;
1250 			if (scan_obj->scan_def.p2p_scan_burst_duration) {
1251 				req->scan_req.burst_duration =
1252 					scan_obj->scan_def.
1253 					p2p_scan_burst_duration;
1254 			} else {
1255 				req->scan_req.burst_duration =
1256 						BURST_SCAN_MAX_NUM_OFFCHANNELS *
1257 						req->scan_req.dwell_time_active;
1258 				if (req->scan_req.burst_duration >
1259 				    P2P_SCAN_MAX_BURST_DURATION) {
1260 					uint8_t channels =
1261 						P2P_SCAN_MAX_BURST_DURATION /
1262 						req->scan_req.dwell_time_active;
1263 					if (channels)
1264 						req->scan_req.burst_duration =
1265 						channels *
1266 						req->scan_req.dwell_time_active;
1267 					else
1268 						req->scan_req.burst_duration =
1269 						P2P_SCAN_MAX_BURST_DURATION;
1270 				}
1271 			}
1272 			req->scan_req.scan_ev_bss_chan = false;
1273 		}
1274 	} else {
1275 		req->scan_req.scan_f_cck_rates = true;
1276 		if (!req->scan_req.num_ssids)
1277 			req->scan_req.scan_f_bcast_probe = true;
1278 		req->scan_req.scan_f_add_ds_ie_in_probe = true;
1279 		req->scan_req.scan_f_filter_prb_req = true;
1280 		req->scan_req.scan_f_add_tpc_ie_in_probe = true;
1281 	}
1282 
1283 	scm_update_dbs_scan_ctrl_ext_flag(req);
1284 
1285 	/*
1286 	 * No need to update conncurrency parmas if req is passive scan on
1287 	 * single channel ie ROC, Preauth etc
1288 	 */
1289 	if (!(req->scan_req.scan_f_passive &&
1290 	      req->scan_req.chan_list.num_chan == 1) &&
1291 	      req->scan_req.scan_type != SCAN_TYPE_RRM)
1292 		scm_req_update_concurrency_params(vdev, req, scan_obj);
1293 
1294 	/*
1295 	 * Set wide band flag if enabled. This will cause
1296 	 * phymode TLV being sent to FW.
1297 	 */
1298 	pdev = wlan_vdev_get_pdev(vdev);
1299 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
1300 	if (ucfg_scan_get_wide_band_scan(pdev))
1301 		req->scan_req.scan_f_wide_band = true;
1302 	else
1303 		req->scan_req.scan_f_wide_band = false;
1304 
1305 	/*
1306 	 * Overwrite scan channles with custom scan channel
1307 	 * list if configured.
1308 	 */
1309 	custom_chan_list = &scan_obj->pdev_info[pdev_id].custom_chan_list;
1310 	if (custom_chan_list->num_chan)
1311 		qdf_mem_copy(&req->scan_req.chan_list, custom_chan_list,
1312 			     sizeof(struct chan_list));
1313 	else if (!req->scan_req.chan_list.num_chan)
1314 		ucfg_scan_init_chanlist_params(req, 0, NULL, NULL);
1315 
1316 	if (scan_obj->scan_def.scan_mode_6g != SCAN_MODE_6G_NO_CHANNEL)
1317 		scm_add_rnr_info(pdev, req);
1318 	scm_update_channel_list(req, scan_obj);
1319 }
1320 
1321 static inline void scm_print_scan_req_info(struct scan_req_params *req)
1322 {
1323 	uint32_t buff_len;
1324 	char *chan_buff;
1325 	uint32_t len = 0;
1326 	uint8_t idx, count = 0;
1327 	struct chan_list *chan_lst;
1328 #define MAX_SCAN_FREQ_TO_PRINT 60
1329 
1330 	scm_nofl_debug("Scan start: scan id %d vdev %d Dwell time: act %d pass %d act_2G %d act_6G %d pass_6G %d, probe time %d n_probes %d flags %x ext_flag %x events %x policy %d wide_bw %d pri %d",
1331 		       req->scan_id, req->vdev_id, req->dwell_time_active,
1332 		       req->dwell_time_passive, req->dwell_time_active_2g,
1333 		       req->dwell_time_active_6g, req->dwell_time_passive_6g,
1334 		       req->repeat_probe_time, req->n_probes, req->scan_flags,
1335 		       req->scan_ctrl_flags_ext, req->scan_events,
1336 		       req->scan_policy_type, req->scan_f_wide_band,
1337 		       req->scan_priority);
1338 
1339 	for (idx = 0; idx < req->num_ssids; idx++)
1340 		scm_nofl_debug("SSID[%d]: %.*s", idx, req->ssid[idx].length,
1341 			       req->ssid[idx].ssid);
1342 
1343 	chan_lst  = &req->chan_list;
1344 
1345 	if (!chan_lst->num_chan)
1346 		return;
1347 	/*
1348 	 * Buffer of (num channl * 5) + 1  to consider the 4 char freq and
1349 	 * 1 space after it for each channel and 1 to end the string with NULL.
1350 	 */
1351 	buff_len =
1352 		(QDF_MIN(MAX_SCAN_FREQ_TO_PRINT, chan_lst->num_chan) * 5) + 1;
1353 	chan_buff = qdf_mem_malloc(buff_len);
1354 	if (!chan_buff)
1355 		return;
1356 	scm_nofl_debug("Total freq %d", chan_lst->num_chan);
1357 	for (idx = 0; idx < chan_lst->num_chan; idx++) {
1358 		len += qdf_scnprintf(chan_buff + len, buff_len - len, "%d ",
1359 				     chan_lst->chan[idx].freq);
1360 		count++;
1361 		if (count >= MAX_SCAN_FREQ_TO_PRINT) {
1362 			/* Print the MAX_SCAN_FREQ_TO_PRINT channels */
1363 			scm_nofl_debug("Freq list: %s", chan_buff);
1364 			len = 0;
1365 			count = 0;
1366 		}
1367 	}
1368 	if (len)
1369 		scm_nofl_debug("Freq list: %s", chan_buff);
1370 
1371 	qdf_mem_free(chan_buff);
1372 }
1373 QDF_STATUS
1374 scm_scan_start_req(struct scheduler_msg *msg)
1375 {
1376 	struct wlan_serialization_command cmd = {0, };
1377 	enum wlan_serialization_status ser_cmd_status;
1378 	struct scan_start_request *req = NULL;
1379 	struct wlan_scan_obj *scan_obj;
1380 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1381 
1382 
1383 	if (!msg) {
1384 		scm_err("msg received is NULL");
1385 		QDF_ASSERT(0);
1386 		return QDF_STATUS_E_NULL_VALUE;
1387 	}
1388 	if (!msg->bodyptr) {
1389 		scm_err("bodyptr is NULL");
1390 		QDF_ASSERT(0);
1391 		return QDF_STATUS_E_NULL_VALUE;
1392 	}
1393 
1394 	req = msg->bodyptr;
1395 
1396 	if (!scm_is_scan_allowed(req->vdev)) {
1397 		scm_err("scan disabled, rejecting the scan req");
1398 		status = QDF_STATUS_E_NULL_VALUE;
1399 		goto err;
1400 	}
1401 
1402 	scan_obj = wlan_vdev_get_scan_obj(req->vdev);
1403 	if (!scan_obj) {
1404 		scm_debug("Couldn't find scan object");
1405 		status = QDF_STATUS_E_NULL_VALUE;
1406 		goto err;
1407 	}
1408 
1409 	scm_scan_req_update_params(req->vdev, req, scan_obj);
1410 	scm_print_scan_req_info(&req->scan_req);
1411 
1412 	if (!req->scan_req.chan_list.num_chan) {
1413 		scm_info("Reject 0 channel Scan");
1414 		status = QDF_STATUS_E_NULL_VALUE;
1415 		goto err;
1416 	}
1417 
1418 	cmd.cmd_type = WLAN_SER_CMD_SCAN;
1419 	cmd.cmd_id = req->scan_req.scan_id;
1420 	cmd.cmd_cb = scm_scan_serialize_callback;
1421 	cmd.umac_cmd = req;
1422 	cmd.source = WLAN_UMAC_COMP_SCAN;
1423 	cmd.is_high_priority = false;
1424 	cmd.cmd_timeout_duration = req->scan_req.max_scan_time +
1425 		SCAN_TIMEOUT_GRACE_PERIOD;
1426 	cmd.vdev = req->vdev;
1427 
1428 	if (scan_obj->disable_timeout)
1429 		cmd.cmd_timeout_duration = 0;
1430 
1431 	qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_SERIALIZATION,
1432 		   WLAN_SER_CMD_SCAN, req->vdev->vdev_objmgr.vdev_id,
1433 		   req->scan_req.scan_id);
1434 
1435 	ser_cmd_status = wlan_serialization_request(&cmd);
1436 	switch (ser_cmd_status) {
1437 	case WLAN_SER_CMD_PENDING:
1438 		/* command moved to pending list.Do nothing */
1439 		break;
1440 	case WLAN_SER_CMD_ACTIVE:
1441 		/* command moved to active list. Do nothing */
1442 		break;
1443 	default:
1444 		scm_debug("ser cmd status %d", ser_cmd_status);
1445 		goto err;
1446 	}
1447 
1448 	return status;
1449 err:
1450 	/*
1451 	 * notify registered scan event handlers
1452 	 * about internal error
1453 	 */
1454 	scm_post_internal_scan_complete_event(req,
1455 					      SCAN_REASON_INTERNAL_FAILURE);
1456 	/*
1457 	 * cmd can't be serviced.
1458 	 * release vdev reference and free scan_start_request memory
1459 	 */
1460 	if (req) {
1461 		wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
1462 		scm_scan_free_scan_request_mem(req);
1463 	}
1464 
1465 	return status;
1466 }
1467 
1468 static inline enum wlan_serialization_cancel_type
1469 get_serialization_cancel_type(enum scan_cancel_req_type type)
1470 {
1471 	enum wlan_serialization_cancel_type serialization_type;
1472 
1473 	switch (type) {
1474 	case WLAN_SCAN_CANCEL_SINGLE:
1475 		serialization_type = WLAN_SER_CANCEL_SINGLE_SCAN;
1476 		break;
1477 	case WLAN_SCAN_CANCEL_VDEV_ALL:
1478 		serialization_type = WLAN_SER_CANCEL_VDEV_SCANS;
1479 		break;
1480 	case WLAN_SCAN_CANCEL_PDEV_ALL:
1481 		serialization_type = WLAN_SER_CANCEL_PDEV_SCANS;
1482 		break;
1483 	case WLAN_SCAN_CANCEL_HOST_VDEV_ALL:
1484 		serialization_type = WLAN_SER_CANCEL_VDEV_HOST_SCANS;
1485 		break;
1486 	default:
1487 		QDF_ASSERT(0);
1488 		scm_warn("invalid scan_cancel_req_type: %d", type);
1489 		serialization_type = WLAN_SER_CANCEL_PDEV_SCANS;
1490 		break;
1491 	}
1492 
1493 	return serialization_type;
1494 }
1495 
1496 QDF_STATUS
1497 scm_scan_cancel_req(struct scheduler_msg *msg)
1498 {
1499 	struct wlan_serialization_queued_cmd_info cmd = {0,};
1500 	struct wlan_serialization_command ser_cmd = {0,};
1501 	enum wlan_serialization_cmd_status ser_cmd_status;
1502 	struct scan_cancel_request *req;
1503 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1504 
1505 	if (!msg) {
1506 		scm_err("msg received is NULL");
1507 		QDF_ASSERT(0);
1508 		return QDF_STATUS_E_NULL_VALUE;
1509 	}
1510 	if (!msg->bodyptr) {
1511 		scm_err("Bodyptr is NULL");
1512 		QDF_ASSERT(0);
1513 		return QDF_STATUS_E_NULL_VALUE;
1514 	}
1515 
1516 	req = msg->bodyptr;
1517 	/*
1518 	 * If requester wants to wait for target scan cancel event
1519 	 * instead of internally generated cancel event, just check
1520 	 * which queue this scan request belongs to and send scan
1521 	 * cancel request to FW accordingly.
1522 	 * Else generate internal scan cancel event and notify
1523 	 * handlers and free scan request resources.
1524 	 */
1525 	if (req->wait_tgt_cancel &&
1526 			(req->cancel_req.req_type == WLAN_SCAN_CANCEL_SINGLE)) {
1527 		ser_cmd.cmd_type = WLAN_SER_CMD_SCAN;
1528 		ser_cmd.cmd_id = req->cancel_req.scan_id;
1529 		ser_cmd.cmd_cb = NULL;
1530 		ser_cmd.umac_cmd = NULL;
1531 		ser_cmd.source = WLAN_UMAC_COMP_SCAN;
1532 		ser_cmd.is_high_priority = false;
1533 		ser_cmd.vdev = req->vdev;
1534 		if (wlan_serialization_is_cmd_present_in_active_queue(NULL, &ser_cmd))
1535 			ser_cmd_status = WLAN_SER_CMD_IN_ACTIVE_LIST;
1536 		else if (wlan_serialization_is_cmd_present_in_pending_queue(NULL, &ser_cmd))
1537 			ser_cmd_status = WLAN_SER_CMD_IN_PENDING_LIST;
1538 		else
1539 			ser_cmd_status = WLAN_SER_CMD_NOT_FOUND;
1540 	} else {
1541 		cmd.requestor = 0;
1542 		cmd.cmd_type = WLAN_SER_CMD_SCAN;
1543 		cmd.cmd_id = req->cancel_req.scan_id;
1544 		cmd.vdev = req->vdev;
1545 		cmd.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE |
1546 			WLAN_SERIALIZATION_PENDING_QUEUE;
1547 		cmd.req_type = get_serialization_cancel_type(req->cancel_req.req_type);
1548 
1549 		ser_cmd_status = wlan_serialization_cancel_request(&cmd);
1550 	}
1551 
1552 	scm_debug("status: %d, reqid: %d, scanid: %d, vdevid: %d, type: %d",
1553 		ser_cmd_status, req->cancel_req.requester,
1554 		req->cancel_req.scan_id, req->cancel_req.vdev_id,
1555 		req->cancel_req.req_type);
1556 
1557 	switch (ser_cmd_status) {
1558 	case WLAN_SER_CMD_IN_PENDING_LIST:
1559 		/* do nothing */
1560 		break;
1561 	case WLAN_SER_CMD_IN_ACTIVE_LIST:
1562 	case WLAN_SER_CMDS_IN_ALL_LISTS:
1563 		/* send wmi scan cancel to fw */
1564 		status = tgt_scan_cancel(req);
1565 		break;
1566 	case WLAN_SER_CMD_NOT_FOUND:
1567 		/* do nothing */
1568 		break;
1569 	default:
1570 		QDF_ASSERT(0);
1571 		status = QDF_STATUS_E_INVAL;
1572 		break;
1573 	}
1574 
1575 	/* Release vdev reference and scan cancel request
1576 	 * processing is complete
1577 	 */
1578 	wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
1579 	/* Free cancel request memory */
1580 	qdf_mem_free(req);
1581 
1582 	return status;
1583 }
1584 
1585 #ifdef FEATURE_WLAN_SCAN_PNO
1586 static QDF_STATUS
1587 scm_pno_event_handler(struct wlan_objmgr_vdev *vdev,
1588 	struct scan_event *event)
1589 {
1590 	struct scan_vdev_obj *scan_vdev_obj;
1591 	struct wlan_scan_obj *scan_psoc_obj;
1592 	scan_event_handler pno_cb;
1593 	void *cb_arg;
1594 
1595 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
1596 	scan_psoc_obj = wlan_vdev_get_scan_obj(vdev);
1597 	if (!scan_vdev_obj || !scan_psoc_obj) {
1598 		scm_err("null scan_vdev_obj %pK scan_obj %pK",
1599 			scan_vdev_obj, scan_psoc_obj);
1600 		return QDF_STATUS_E_INVAL;
1601 	}
1602 
1603 	switch (event->type) {
1604 	case SCAN_EVENT_TYPE_NLO_COMPLETE:
1605 		if (!scan_vdev_obj->pno_match_evt_received)
1606 			return QDF_STATUS_SUCCESS;
1607 		qdf_wake_lock_release(&scan_psoc_obj->pno_cfg.pno_wake_lock,
1608 			WIFI_POWER_EVENT_WAKELOCK_PNO);
1609 		qdf_wake_lock_timeout_acquire(
1610 			&scan_psoc_obj->pno_cfg.pno_wake_lock,
1611 			SCAN_PNO_SCAN_COMPLETE_WAKE_LOCK_TIMEOUT);
1612 		scan_vdev_obj->pno_match_evt_received = false;
1613 		break;
1614 	case SCAN_EVENT_TYPE_NLO_MATCH:
1615 		scan_vdev_obj->pno_match_evt_received = true;
1616 		qdf_wake_lock_timeout_acquire(
1617 			&scan_psoc_obj->pno_cfg.pno_wake_lock,
1618 			SCAN_PNO_MATCH_WAKE_LOCK_TIMEOUT);
1619 		return QDF_STATUS_SUCCESS;
1620 	default:
1621 		return QDF_STATUS_E_INVAL;
1622 	}
1623 	qdf_spin_lock_bh(&scan_psoc_obj->lock);
1624 	pno_cb = scan_psoc_obj->pno_cfg.pno_cb.func;
1625 	cb_arg = scan_psoc_obj->pno_cfg.pno_cb.arg;
1626 	qdf_spin_unlock_bh(&scan_psoc_obj->lock);
1627 
1628 	if (pno_cb)
1629 		pno_cb(vdev, event, cb_arg);
1630 
1631 	return QDF_STATUS_SUCCESS;
1632 }
1633 #else
1634 
1635 static QDF_STATUS
1636 scm_pno_event_handler(struct wlan_objmgr_vdev *vdev,
1637 	struct scan_event *event)
1638 {
1639 	return QDF_STATUS_SUCCESS;
1640 }
1641 #endif
1642 
1643 /**
1644  * scm_scan_update_scan_event() - update scan event
1645  * @scan: scan object
1646  * @event: scan event
1647  * @scan_start_req: scan_start_req used for triggering scan
1648  *
1649  * update scan params in scan event
1650  *
1651  * Return: QDF_STATUS
1652  */
1653 static QDF_STATUS
1654 scm_scan_update_scan_event(struct wlan_scan_obj *scan,
1655 		struct scan_event *event,
1656 		struct scan_start_request *scan_start_req)
1657 {
1658 	if (!event)
1659 		return QDF_STATUS_E_NULL_VALUE;
1660 
1661 	if (!scan || !scan_start_req) {
1662 		event->scan_start_req = NULL;
1663 		return QDF_STATUS_E_NULL_VALUE;
1664 	}
1665 	/* copy scan start request to pass back buffer */
1666 	qdf_mem_copy(&scan->scan_start_request_buff, scan_start_req,
1667 			sizeof(struct scan_start_request));
1668 	/* reset all pointers */
1669 	scan->scan_start_request_buff.scan_req.extraie.ptr = NULL;
1670 	scan->scan_start_request_buff.scan_req.extraie.len = 0;
1671 	scan->scan_start_request_buff.scan_req.htcap.ptr = NULL;
1672 	scan->scan_start_request_buff.scan_req.htcap.len = 0;
1673 	scan->scan_start_request_buff.scan_req.vhtcap.ptr = NULL;
1674 	scan->scan_start_request_buff.scan_req.vhtcap.len = 0;
1675 
1676 	event->scan_start_req = &scan->scan_start_request_buff;
1677 
1678 	return QDF_STATUS_SUCCESS;
1679 }
1680 
1681 QDF_STATUS
1682 scm_scan_event_handler(struct scheduler_msg *msg)
1683 {
1684 	struct wlan_objmgr_vdev *vdev;
1685 	struct scan_event *event;
1686 	struct scan_event_info *event_info;
1687 	struct wlan_serialization_command cmd = {0,};
1688 	struct wlan_serialization_command *queued_cmd;
1689 	struct scan_start_request *scan_start_req;
1690 	struct wlan_scan_obj *scan;
1691 
1692 	if (!msg) {
1693 		scm_err("NULL msg received ");
1694 		QDF_ASSERT(0);
1695 		return QDF_STATUS_E_NULL_VALUE;
1696 	}
1697 	if (!msg->bodyptr) {
1698 		scm_err("NULL scan event received");
1699 		QDF_ASSERT(0);
1700 		return QDF_STATUS_E_NULL_VALUE;
1701 	}
1702 
1703 	event_info = msg->bodyptr;
1704 	vdev = event_info->vdev;
1705 	event = &(event_info->event);
1706 
1707 	scm_debug("vdevid:%d, type:%d, reason:%d, freq:%d, reqstr:%d, scanid:%d",
1708 		  event->vdev_id, event->type, event->reason, event->chan_freq,
1709 		  event->requester, event->scan_id);
1710 	/*
1711 	 * NLO requests are never queued, so post NLO events
1712 	 * without checking for their presence in active queue.
1713 	 */
1714 	switch (event->type) {
1715 	case SCAN_EVENT_TYPE_NLO_COMPLETE:
1716 	case SCAN_EVENT_TYPE_NLO_MATCH:
1717 		scm_pno_event_handler(vdev, event);
1718 		goto exit;
1719 	default:
1720 		break;
1721 	}
1722 
1723 	cmd.cmd_type = WLAN_SER_CMD_SCAN;
1724 	cmd.cmd_id = event->scan_id;
1725 	cmd.cmd_cb = NULL;
1726 	cmd.umac_cmd = NULL;
1727 	cmd.source = WLAN_UMAC_COMP_SCAN;
1728 	cmd.is_high_priority = false;
1729 	cmd.vdev = vdev;
1730 	if (!wlan_serialization_is_cmd_present_in_active_queue(NULL, &cmd)) {
1731 		/*
1732 		 * We received scan event for an already completed/cancelled
1733 		 * scan request. Drop this event.
1734 		 */
1735 		scm_debug("Received scan event while request not in active queue");
1736 		goto exit;
1737 	}
1738 
1739 	/* Fill scan_start_request used to trigger this scan */
1740 	queued_cmd = wlan_serialization_get_scan_cmd_using_scan_id(
1741 			wlan_vdev_get_psoc(vdev), wlan_vdev_get_id(vdev),
1742 			event->scan_id, true);
1743 
1744 	if (!queued_cmd) {
1745 		scm_err("NULL queued_cmd");
1746 		goto exit;
1747 	}
1748 	if (!queued_cmd->umac_cmd) {
1749 		scm_err("NULL umac_cmd");
1750 		goto exit;
1751 	}
1752 	scan_start_req = queued_cmd->umac_cmd;
1753 
1754 	if (scan_start_req->scan_req.scan_req_id != event->requester) {
1755 		scm_err("req ID mismatch, scan_req_id:%d, event_req_id:%d",
1756 			scan_start_req->scan_req.scan_req_id, event->requester);
1757 		goto exit;
1758 	}
1759 
1760 	scan = wlan_vdev_get_scan_obj(vdev);
1761 	if (scan)
1762 		scm_scan_update_scan_event(scan, event, scan_start_req);
1763 
1764 	switch (event->type) {
1765 	case SCAN_EVENT_TYPE_COMPLETED:
1766 		if (event->reason == SCAN_REASON_COMPLETED)
1767 			scm_11d_decide_country_code(vdev);
1768 		/* fall through to release the command */
1769 	case SCAN_EVENT_TYPE_START_FAILED:
1770 	case SCAN_EVENT_TYPE_DEQUEUED:
1771 		scm_release_serialization_command(vdev, event->scan_id);
1772 		break;
1773 	default:
1774 		break;
1775 	}
1776 
1777 	/* Notify all interested parties */
1778 	scm_scan_post_event(vdev, event);
1779 
1780 exit:
1781 	/* free event info memory */
1782 	qdf_mem_free(event_info);
1783 	wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID);
1784 
1785 	return QDF_STATUS_SUCCESS;
1786 }
1787 
1788 QDF_STATUS scm_scan_event_flush_callback(struct scheduler_msg *msg)
1789 {
1790 	struct wlan_objmgr_vdev *vdev;
1791 	struct scan_event_info *event_info;
1792 	struct scan_event *event;
1793 
1794 	if (!msg || !msg->bodyptr) {
1795 		scm_err("msg or msg->bodyptr is NULL");
1796 		return QDF_STATUS_E_NULL_VALUE;
1797 	}
1798 
1799 	event_info = msg->bodyptr;
1800 	vdev = event_info->vdev;
1801 	event = &event_info->event;
1802 
1803 	scm_debug("Flush scan event vdev %d type %d reason %d freq: %d req %d scanid %d",
1804 		  event->vdev_id, event->type, event->reason, event->chan_freq,
1805 		  event->requester, event->scan_id);
1806 
1807 	/* free event info memory */
1808 	qdf_mem_free(event_info);
1809 	wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID);
1810 
1811 	return QDF_STATUS_SUCCESS;
1812 }
1813 
1814 QDF_STATUS scm_bcn_probe_flush_callback(struct scheduler_msg *msg)
1815 {
1816 	struct scan_bcn_probe_event *bcn;
1817 
1818 	bcn = msg->bodyptr;
1819 
1820 	if (!bcn) {
1821 		scm_err("bcn is NULL");
1822 		return QDF_STATUS_E_NULL_VALUE;
1823 	}
1824 	if (bcn->psoc)
1825 		wlan_objmgr_psoc_release_ref(bcn->psoc, WLAN_SCAN_ID);
1826 	if (bcn->rx_data)
1827 		qdf_mem_free(bcn->rx_data);
1828 	if (bcn->buf)
1829 		qdf_nbuf_free(bcn->buf);
1830 	qdf_mem_free(bcn);
1831 
1832 	return QDF_STATUS_SUCCESS;
1833 }
1834 
1835 QDF_STATUS scm_scan_start_flush_callback(struct scheduler_msg *msg)
1836 {
1837 	struct scan_start_request *req;
1838 
1839 	if (!msg || !msg->bodyptr) {
1840 		scm_err("msg or msg->bodyptr is NULL");
1841 		return QDF_STATUS_E_NULL_VALUE;
1842 	}
1843 
1844 	req = msg->bodyptr;
1845 	scm_post_internal_scan_complete_event(req, SCAN_REASON_CANCELLED);
1846 	wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
1847 	scm_scan_free_scan_request_mem(req);
1848 
1849 	return QDF_STATUS_SUCCESS;
1850 }
1851 
1852 QDF_STATUS scm_scan_cancel_flush_callback(struct scheduler_msg *msg)
1853 {
1854 	struct scan_cancel_request *req;
1855 
1856 	if (!msg || !msg->bodyptr) {
1857 		scm_err("msg or msg->bodyptr is NULL");
1858 		return QDF_STATUS_E_NULL_VALUE;
1859 	}
1860 
1861 	req = msg->bodyptr;
1862 	wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
1863 	/* Free cancel request memory */
1864 	qdf_mem_free(req);
1865 
1866 	return QDF_STATUS_SUCCESS;
1867 }
1868