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