xref: /wlan-dirver/qca-wifi-host-cmn/umac/scan/core/src/wlan_scan_manager.c (revision 8ddef7dd9a290d4a9b1efd5d3efacf51d78a1a0d)
1 /*
2  * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /*
20  * DOC: 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_dfs_utils_api.h>
35 #include <wlan_policy_mgr_api.h>
36 #endif
37 
38 
39 QDF_STATUS
40 scm_scan_free_scan_request_mem(struct scan_start_request *req)
41 {
42 	void *ie;
43 
44 	if (!req) {
45 		scm_err("null request");
46 		QDF_ASSERT(0);
47 		return QDF_STATUS_E_FAILURE;
48 	}
49 	scm_debug("freed scan request: 0x%pK, scan_id: %d, requester: %d",
50 		  req, req->scan_req.scan_id, req->scan_req.scan_req_id);
51 	/* Free vendor(extra) ie */
52 	ie = req->scan_req.extraie.ptr;
53 	if (ie) {
54 		req->scan_req.extraie.ptr = NULL;
55 		req->scan_req.extraie.len = 0;
56 		qdf_mem_free(ie);
57 	}
58 
59 	/* Free htcap ie */
60 	ie = req->scan_req.htcap.ptr;
61 	if (ie) {
62 		req->scan_req.htcap.len = 0;
63 		req->scan_req.htcap.ptr = NULL;
64 		qdf_mem_free(ie);
65 	}
66 
67 	/* Free vhtcap ie */
68 	ie = req->scan_req.vhtcap.ptr;
69 	if (ie) {
70 		req->scan_req.vhtcap.len = 0;
71 		req->scan_req.vhtcap.ptr = NULL;
72 		qdf_mem_free(ie);
73 	}
74 	/* free scan_start_request memory */
75 	qdf_mem_free(req);
76 
77 	return QDF_STATUS_SUCCESS;
78 }
79 
80 static QDF_STATUS
81 scm_scan_get_pdev_global_event_handlers(struct scan_event_listeners *listeners,
82 		struct pdev_scan_ev_handler *pdev_ev_handler)
83 {
84 	uint32_t i;
85 	struct cb_handler *cb_handlers  = &(pdev_ev_handler->cb_handlers[0]);
86 
87 	for (i = 0; i < MAX_SCAN_EVENT_HANDLERS_PER_PDEV; i++, cb_handlers++) {
88 		if ((cb_handlers->func) &&
89 		    (listeners->count < MAX_SCAN_EVENT_LISTENERS)) {
90 			listeners->cb[listeners->count].func =
91 				cb_handlers->func;
92 			listeners->cb[listeners->count].arg =
93 				cb_handlers->arg;
94 			listeners->count++;
95 		}
96 	}
97 
98 	return QDF_STATUS_SUCCESS;
99 }
100 
101 static QDF_STATUS
102 scm_scan_get_requester_event_handler(struct scan_event_listeners *listeners,
103 		struct scan_requester_info *requesters,
104 		wlan_scan_requester requester_id)
105 {
106 	uint32_t idx;
107 	struct cb_handler *ev_handler;
108 
109 	idx = requester_id & WLAN_SCAN_REQUESTER_ID_PREFIX;
110 	if (idx != WLAN_SCAN_REQUESTER_ID_PREFIX)
111 		return QDF_STATUS_SUCCESS;
112 
113 	idx = requester_id & WLAN_SCAN_REQUESTER_ID_MASK;
114 	if (idx < WLAN_MAX_REQUESTORS) {
115 		ev_handler = &(requesters[idx].ev_handler);
116 		if (ev_handler->func) {
117 			if (listeners->count < MAX_SCAN_EVENT_LISTENERS) {
118 				listeners->cb[listeners->count].func =
119 							     ev_handler->func;
120 				listeners->cb[listeners->count].arg =
121 							     ev_handler->arg;
122 				listeners->count++;
123 			}
124 		}
125 		return QDF_STATUS_SUCCESS;
126 	} else {
127 		scm_err("invalid requester id");
128 		return QDF_STATUS_E_INVAL;
129 	}
130 
131 }
132 
133 static void scm_scan_post_event(struct wlan_objmgr_vdev *vdev,
134 		struct scan_event *event)
135 {
136 	uint32_t i = 0;
137 	struct wlan_scan_obj *scan;
138 	struct pdev_scan_ev_handler *pdev_ev_handler;
139 	struct cb_handler *cb_handlers;
140 	struct scan_requester_info *requesters;
141 	struct scan_event_listeners *listeners;
142 
143 	if (!vdev || !event) {
144 		scm_err("vdev: 0x%pK, event: 0x%pK", vdev, event);
145 		return;
146 	}
147 	if (!event->requester) {
148 		scm_err("invalid requester id");
149 		QDF_ASSERT(0);
150 	}
151 	scan = wlan_vdev_get_scan_obj(vdev);
152 	pdev_ev_handler = wlan_vdev_get_pdev_scan_ev_handlers(vdev);
153 	cb_handlers = &(pdev_ev_handler->cb_handlers[0]);
154 	requesters = scan->requesters;
155 
156 	scm_debug("vdev: %d, type: %d, reason: %d, freq: %d, req: %d, scanid: %d",
157 		  event->vdev_id, event->type, event->reason, event->chan_freq,
158 		  event->requester, event->scan_id);
159 
160 	listeners = qdf_mem_malloc_atomic(sizeof(*listeners));
161 	if (!listeners) {
162 		scm_warn("couldn't allocate listeners list");
163 		return;
164 	}
165 
166 	/* initialize number of listeners */
167 	listeners->count = 0;
168 
169 	/*
170 	 * Initiator of scan request decides which all scan events
171 	 * he is interested in and FW will send only those scan events
172 	 * to host driver.
173 	 * All the events received by scan module will be notified
174 	 * to all registered handlers.
175 	 */
176 
177 	qdf_spin_lock_bh(&scan->lock);
178 	/* find all global scan event handlers on this pdev */
179 	scm_scan_get_pdev_global_event_handlers(listeners, pdev_ev_handler);
180 	/* find owner who triggered this scan request */
181 	scm_scan_get_requester_event_handler(listeners, requesters,
182 			event->requester);
183 	qdf_spin_unlock_bh(&scan->lock);
184 
185 	/* notify all interested handlers */
186 	for (i = 0; i < listeners->count; i++) {
187 		scm_debug("func: 0x%pK, arg: 0x%pK",
188 			listeners->cb[i].func, listeners->cb[i].arg);
189 		listeners->cb[i].func(vdev, event, listeners->cb[i].arg);
190 	}
191 	qdf_mem_free(listeners);
192 }
193 
194 static QDF_STATUS
195 scm_release_serialization_command(struct wlan_objmgr_vdev *vdev,
196 		uint32_t scan_id)
197 {
198 	struct wlan_serialization_queued_cmd_info cmd = {0};
199 
200 	cmd.requestor = WLAN_UMAC_COMP_SCAN;
201 	cmd.cmd_type = WLAN_SER_CMD_SCAN;
202 	cmd.cmd_id = scan_id;
203 	cmd.req_type = WLAN_SER_CANCEL_SINGLE_SCAN;
204 	cmd.vdev = vdev;
205 	cmd.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE;
206 
207 	/* Inform serialization for command completion */
208 	wlan_serialization_remove_cmd(&cmd);
209 
210 	return QDF_STATUS_SUCCESS;
211 }
212 
213 static QDF_STATUS
214 scm_post_internal_scan_complete_event(struct scan_start_request *req,
215 		enum scan_completion_reason reason)
216 {
217 	struct scan_event event = {0, };
218 
219 	/* prepare internal scan complete event */
220 	event.type = SCAN_EVENT_TYPE_COMPLETED;
221 	event.reason = reason;
222 	event.chan_freq = 0; /* Invalid frequency */
223 	event.vdev_id =  req->scan_req.vdev_id;
224 	event.requester = req->scan_req.scan_req_id;
225 	event.scan_id = req->scan_req.scan_id;
226 	/* Fill scan_start_request used to trigger this scan */
227 	event.scan_start_req = req;
228 	/* post scan event to registered handlers */
229 	scm_scan_post_event(req->vdev, &event);
230 
231 	return QDF_STATUS_SUCCESS;
232 }
233 
234 static inline struct pdev_scan_info *
235 scm_scan_get_pdev_priv_info(uint8_t pdev_id, struct wlan_scan_obj *scan_obj)
236 {
237 	return &scan_obj->pdev_info[pdev_id];
238 }
239 
240 static QDF_STATUS
241 scm_update_last_scan_time(struct scan_start_request *req)
242 {
243 	uint8_t pdev_id;
244 	struct wlan_scan_obj *scan_obj;
245 	struct pdev_scan_info *pdev_scan_info;
246 
247 	scan_obj = wlan_vdev_get_scan_obj(req->vdev);
248 	pdev_id = wlan_scan_vdev_get_pdev_id(req->vdev);
249 	pdev_scan_info = scm_scan_get_pdev_priv_info(pdev_id, scan_obj);
250 	/* update last scan start time */
251 	pdev_scan_info->last_scan_time = qdf_system_ticks();
252 
253 	return QDF_STATUS_SUCCESS;
254 }
255 
256 static QDF_STATUS
257 scm_activate_scan_request(struct scan_start_request *req)
258 {
259 	QDF_STATUS status;
260 
261 	status = tgt_scan_start(req);
262 	if (status != QDF_STATUS_SUCCESS) {
263 		scm_err("tgt_scan_start failed, status: %d", status);
264 		/* scan could not be started and hence
265 		 * we will not receive any completions.
266 		 * post scan cancelled
267 		 */
268 		scm_post_internal_scan_complete_event(req,
269 				SCAN_REASON_CANCELLED);
270 		return status;
271 	}
272 	/* save last scan start time */
273 	status = scm_update_last_scan_time(req);
274 
275 	return status;
276 }
277 
278 static QDF_STATUS
279 scm_cancel_scan_request(struct scan_start_request *req)
280 {
281 	struct scan_cancel_request cancel_req = {0, };
282 	QDF_STATUS status;
283 
284 	cancel_req.vdev = req->vdev;
285 	cancel_req.cancel_req.scan_id = req->scan_req.scan_id;
286 	cancel_req.cancel_req.requester = req->scan_req.scan_req_id;
287 	cancel_req.cancel_req.req_type = WLAN_SCAN_CANCEL_SINGLE;
288 	cancel_req.cancel_req.vdev_id = req->scan_req.vdev_id;
289 	/* send scan cancel to fw */
290 	status = tgt_scan_cancel(&cancel_req);
291 	if (status != QDF_STATUS_SUCCESS)
292 		scm_err("tgt_scan_cancel failed: status: %d, scanid: %d",
293 			status, req->scan_req.scan_id);
294 	/* notify event handler about scan cancellation */
295 	scm_post_internal_scan_complete_event(req, SCAN_REASON_CANCELLED);
296 
297 	return status;
298 }
299 
300 static QDF_STATUS
301 scm_scan_serialize_callback(struct wlan_serialization_command *cmd,
302 	enum wlan_serialization_cb_reason reason)
303 {
304 	struct scan_start_request *req;
305 	QDF_STATUS status;
306 
307 	if (!cmd) {
308 		scm_err("cmd is NULL, reason: %d", reason);
309 		QDF_ASSERT(0);
310 		return QDF_STATUS_E_NULL_VALUE;
311 	}
312 
313 	if (!cmd->umac_cmd) {
314 		scm_err("cmd->umac_cmd is NULL , reason: %d", reason);
315 		QDF_ASSERT(0);
316 		return QDF_STATUS_E_NULL_VALUE;
317 	}
318 
319 	req = cmd->umac_cmd;
320 	scm_debug("reason:%d, reqid:%d, scanid:%d, vdevid:%d, vdev:0x%pK",
321 		reason, req->scan_req.scan_req_id, req->scan_req.scan_id,
322 		req->scan_req.vdev_id, req->vdev);
323 
324 	if (!req->vdev) {
325 		scm_err("NULL vdev. req:0x%pK, reason:%d\n", req, reason);
326 		QDF_ASSERT(0);
327 		return QDF_STATUS_E_NULL_VALUE;
328 	}
329 
330 	qdf_mtrace(QDF_MODULE_ID_SERIALIZATION, QDF_MODULE_ID_SCAN, reason,
331 		   req->scan_req.vdev_id, req->scan_req.scan_id);
332 
333 	switch (reason) {
334 	case WLAN_SER_CB_ACTIVATE_CMD:
335 		/* command moved to active list
336 		 * modify the params if required for concurency case.
337 		 */
338 		status = scm_activate_scan_request(req);
339 		break;
340 
341 	case WLAN_SER_CB_CANCEL_CMD:
342 		/* command removed from pending list.
343 		 * notify registered scan event handlers with
344 		 * status completed and reason cancelled.
345 		 */
346 		status = scm_post_internal_scan_complete_event(req,
347 				SCAN_REASON_CANCELLED);
348 		break;
349 
350 	case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT:
351 		/* active command timed out.
352 		 * prepare internal scan cancel request
353 		 */
354 		status = scm_cancel_scan_request(req);
355 		break;
356 
357 	case WLAN_SER_CB_RELEASE_MEM_CMD:
358 		/* command successfully completed.
359 		 * Release vdev reference and free scan_start_request memory
360 		 */
361 		cmd->umac_cmd = NULL;
362 		wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
363 		status = scm_scan_free_scan_request_mem(req);
364 		break;
365 
366 	default:
367 		/* Do nothing but logging */
368 		QDF_ASSERT(0);
369 		status = QDF_STATUS_E_INVAL;
370 		break;
371 	}
372 
373 	return status;
374 }
375 
376 bool scm_is_scan_allowed(struct wlan_objmgr_vdev *vdev)
377 {
378 	struct wlan_scan_obj *scan_psoc_obj;
379 	struct scan_vdev_obj *scan_vdev_obj;
380 
381 	if (!vdev) {
382 		scm_err("vdev is NULL");
383 		return false;
384 	}
385 
386 	scan_psoc_obj = wlan_vdev_get_scan_obj(vdev);
387 	if (!scan_psoc_obj) {
388 		scm_err("Couldn't find scan psoc object");
389 		return false;
390 	}
391 
392 	if (scan_psoc_obj->scan_disabled) {
393 		scm_err_rl("scan disabled %x, for psoc",
394 			   scan_psoc_obj->scan_disabled);
395 		return false;
396 	}
397 
398 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
399 	if (!scan_vdev_obj) {
400 		scm_err("Couldn't find scan vdev object");
401 		return false;
402 	}
403 
404 	if (scan_vdev_obj->scan_disabled) {
405 		scm_err_rl("scan disabled %x on vdev_id:%d",
406 			   scan_vdev_obj->scan_disabled,
407 			   wlan_vdev_get_id(vdev));
408 		return false;
409 	}
410 
411 	return true;
412 }
413 
414 #ifdef WLAN_POLICY_MGR_ENABLE
415 /**
416  * scm_update_dbs_scan_ctrl_ext_flag() - update dbs scan ctrl flags
417  * @req: pointer to scan request
418  *
419  * This function sets scan_ctrl_flags_ext value depending on the type of
420  * scan and the channel lists.
421  *
422  * Non-DBS scan is requested if any of the below case is met:
423  *     1. HW is DBS incapable
424  *     2. A high accuracy scan request is sent by kernel.
425  *
426  * DBS scan is enabled for these conditions:
427  *     1. A low power or low span scan request is sent by kernel.
428  * For remaining cases DBS is enabled by default.
429  * Return: void
430  */
431 static void
432 scm_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req)
433 {
434 	struct wlan_objmgr_psoc *psoc;
435 	uint32_t scan_dbs_policy = SCAN_DBS_POLICY_DEFAULT;
436 
437 	psoc = wlan_vdev_get_psoc(req->vdev);
438 
439 	if (!policy_mgr_is_hw_dbs_capable(psoc)) {
440 		scm_debug("dbs disabled, going for non-dbs scan");
441 		scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS;
442 		goto end;
443 	}
444 
445 	if (req->scan_req.scan_policy_high_accuracy) {
446 		scm_debug("high accuracy scan received, going for non-dbs scan");
447 		scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS;
448 		goto end;
449 	}
450 	if ((req->scan_req.scan_policy_low_power) ||
451 	    (req->scan_req.scan_policy_low_span)) {
452 		scm_debug("low power/span scan received, going for dbs scan");
453 		scan_dbs_policy = SCAN_DBS_POLICY_IGNORE_DUTY;
454 		goto end;
455 	}
456 
457 end:
458 	req->scan_req.scan_ctrl_flags_ext |=
459 		((scan_dbs_policy << SCAN_FLAG_EXT_DBS_SCAN_POLICY_BIT)
460 		 & SCAN_FLAG_EXT_DBS_SCAN_POLICY_MASK);
461 	scm_debug("scan_ctrl_flags_ext: 0x%x",
462 		  req->scan_req.scan_ctrl_flags_ext);
463 }
464 
465 /**
466  * scm_update_passive_dwell_time() - update dwell passive time
467  * @vdev: vdev object
468  * @req: scan request
469  *
470  * Return: None
471  */
472 static void
473 scm_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev,
474 			      struct scan_start_request *req)
475 {
476 	struct wlan_objmgr_psoc *psoc;
477 
478 	psoc = wlan_vdev_get_psoc(vdev);
479 	if (!psoc)
480 		return;
481 
482 	if (policy_mgr_is_sta_connected_2g(psoc) &&
483 	    !policy_mgr_is_hw_dbs_capable(psoc) &&
484 	    ucfg_scan_get_bt_activity(psoc))
485 		req->scan_req.dwell_time_passive =
486 				PASSIVE_DWELL_TIME_BT_A2DP_ENABLED;
487 }
488 
489 static const struct probe_time_dwell_time
490 	scan_probe_time_dwell_time_map[SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE] = {
491 	{28, 11},               /* 0 SSID */
492 	{28, 20},               /* 1 SSID */
493 	{28, 20},               /* 2 SSID */
494 	{28, 20},               /* 3 SSID */
495 	{28, 20},               /* 4 SSID */
496 	{28, 20},               /* 5 SSID */
497 	{28, 20},               /* 6 SSID */
498 	{28, 11},               /* 7 SSID */
499 	{28, 11},               /* 8 SSID */
500 	{28, 11},               /* 9 SSID */
501 	{28, 8}                 /* 10 SSID */
502 };
503 
504 /**
505  * scm_scan_get_burst_duration() - get burst duration depending on max chan
506  * and miracast.
507  * @max_ch_time: max channel time
508  * @miracast_enabled: if miracast is enabled
509  *
510  * Return: burst_duration
511  */
512 static inline
513 int scm_scan_get_burst_duration(int max_ch_time, bool miracast_enabled)
514 {
515 	int burst_duration = 0;
516 
517 	if (miracast_enabled) {
518 		/*
519 		 * When miracast is running, burst
520 		 * duration needs to be minimum to avoid
521 		 * any stutter or glitch in miracast
522 		 * during station scan
523 		 */
524 		if (max_ch_time <= SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION)
525 			burst_duration = max_ch_time;
526 		else
527 			burst_duration = SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION;
528 	} else {
529 		/*
530 		 * If miracast is not running, accommodate max
531 		 * stations to make the scans faster
532 		 */
533 		burst_duration = SCAN_GO_BURST_SCAN_MAX_NUM_OFFCHANNELS *
534 							max_ch_time;
535 
536 		if (burst_duration > SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION) {
537 			uint8_t channels = SCAN_P2P_SCAN_MAX_BURST_DURATION /
538 								 max_ch_time;
539 
540 			if (channels)
541 				burst_duration = channels * max_ch_time;
542 			else
543 				burst_duration =
544 					 SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION;
545 		}
546 	}
547 	return burst_duration;
548 }
549 
550 /**
551  * scm_req_update_concurrency_params() - update scan req params depending on
552  * concurrent mode present.
553  * @vdev: vdev object pointer
554  * @req: scan request
555  * @scan_obj: scan object
556  *
557  * Return: void
558  */
559 static void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev,
560 					      struct scan_start_request *req,
561 					      struct wlan_scan_obj *scan_obj)
562 {
563 	bool ap_present, go_present, sta_active, p2p_cli_present, ndi_present;
564 	struct wlan_objmgr_psoc *psoc;
565 
566 	psoc = wlan_vdev_get_psoc(vdev);
567 
568 	if (!psoc)
569 		return;
570 
571 	ap_present = policy_mgr_mode_specific_connection_count(
572 				psoc, PM_SAP_MODE, NULL);
573 	go_present = policy_mgr_mode_specific_connection_count(
574 				psoc, PM_P2P_GO_MODE, NULL);
575 	p2p_cli_present = policy_mgr_mode_specific_connection_count(
576 				psoc, PM_P2P_CLIENT_MODE, NULL);
577 	sta_active = policy_mgr_mode_specific_connection_count(
578 				psoc, PM_STA_MODE, NULL);
579 	ndi_present = policy_mgr_mode_specific_connection_count(
580 				psoc, PM_NDI_MODE, NULL);
581 
582 	if (policy_mgr_get_connection_count(psoc)) {
583 		if (req->scan_req.scan_f_passive)
584 			req->scan_req.dwell_time_passive =
585 				scan_obj->scan_def.conc_passive_dwell;
586 		else
587 			req->scan_req.dwell_time_active =
588 				scan_obj->scan_def.conc_active_dwell;
589 		req->scan_req.max_rest_time =
590 				scan_obj->scan_def.conc_max_rest_time;
591 		req->scan_req.min_rest_time =
592 			scan_obj->scan_def.conc_min_rest_time;
593 		req->scan_req.idle_time = scan_obj->scan_def.conc_idle_time;
594 	}
595 
596 	if (wlan_vdev_is_up(req->vdev) != QDF_STATUS_SUCCESS)
597 		req->scan_req.adaptive_dwell_time_mode =
598 			scan_obj->scan_def.adaptive_dwell_time_mode_nc;
599 	/*
600 	 * If AP is active set min rest time same as max rest time, so that
601 	 * firmware spends more time on home channel which will increase the
602 	 * probability of sending beacon at TBTT
603 	 */
604 	if (ap_present || go_present) {
605 		req->scan_req.dwell_time_active_2g = 0;
606 		req->scan_req.min_rest_time = req->scan_req.max_rest_time;
607 	}
608 
609 	/*
610 	 * If scan req for SAP (ACS Sacn) use dwell_time_active_def as dwell
611 	 * time for 2g channels instead of dwell_time_active_2g
612 	 */
613 	if (vdev->vdev_mlme.vdev_opmode == QDF_SAP_MODE)
614 		req->scan_req.dwell_time_active_2g = 0;
615 
616 	if (req->scan_req.p2p_scan_type == SCAN_NON_P2P_DEFAULT) {
617 		/*
618 		 * Decide burst_duration and dwell_time_active based on
619 		 * what type of devices are active.
620 		 */
621 		do {
622 			if (ap_present && go_present && sta_active) {
623 				if (req->scan_req.dwell_time_active <=
624 					SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION)
625 					req->scan_req.burst_duration =
626 						req->scan_req.dwell_time_active;
627 				else
628 					req->scan_req.burst_duration =
629 					SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION;
630 
631 				break;
632 			}
633 
634 			if (scan_obj->miracast_enabled &&
635 			    policy_mgr_is_mcc_in_24G(psoc))
636 				req->scan_req.max_rest_time =
637 				  scan_obj->scan_def.sta_miracast_mcc_rest_time;
638 
639 			if (go_present) {
640 				/*
641 				 * Background scan while GO is sending beacons.
642 				 * Every off-channel transition has overhead of
643 				 * 2 beacon intervals for NOA. Maximize number
644 				 * of channels in every transition by using
645 				 * burst scan.
646 				 */
647 				if (scan_obj->scan_def.go_scan_burst_duration)
648 					req->scan_req.burst_duration =
649 						scan_obj->
650 						scan_def.go_scan_burst_duration;
651 				else
652 					req->scan_req.burst_duration =
653 						scm_scan_get_burst_duration(
654 							req->scan_req.
655 							dwell_time_active,
656 							scan_obj->
657 							miracast_enabled);
658 				break;
659 			}
660 			if ((sta_active || p2p_cli_present)) {
661 				if (scan_obj->scan_def.sta_scan_burst_duration)
662 					req->scan_req.burst_duration =
663 						scan_obj->scan_def.
664 						sta_scan_burst_duration;
665 				break;
666 			}
667 
668 			if (ndi_present) {
669 				req->scan_req.burst_duration =
670 					scm_scan_get_burst_duration(
671 						req->scan_req.dwell_time_active,
672 						scan_obj->miracast_enabled);
673 				break;
674 			}
675 		} while (0);
676 
677 		if (ap_present) {
678 			uint8_t ssid_num;
679 
680 			ssid_num = req->scan_req.num_ssids *
681 					req->scan_req.num_bssid;
682 			req->scan_req.repeat_probe_time =
683 				scan_probe_time_dwell_time_map[
684 					QDF_MIN(ssid_num,
685 					SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE
686 					- 1)].probe_time;
687 			req->scan_req.n_probes =
688 				(req->scan_req.repeat_probe_time > 0) ?
689 				req->scan_req.dwell_time_active /
690 				req->scan_req.repeat_probe_time : 0;
691 		}
692 	}
693 
694 	if (ap_present) {
695 		uint8_t ap_chan;
696 		struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
697 
698 		ap_chan = policy_mgr_get_channel(psoc, PM_SAP_MODE, NULL);
699 		/*
700 		 * P2P/STA scan while SoftAP is sending beacons.
701 		 * Max duration of CTS2self is 32 ms, which limits the
702 		 * dwell time. If DBS is supported and if SAP is on 2G channel
703 		 * then keep passive dwell time default.
704 		 */
705 		req->scan_req.dwell_time_active =
706 				QDF_MIN(req->scan_req.dwell_time_active,
707 					(SCAN_CTS_DURATION_MS_MAX -
708 					SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME));
709 		if (!policy_mgr_is_hw_dbs_capable(psoc) ||
710 		    (policy_mgr_is_hw_dbs_capable(psoc) &&
711 		     WLAN_CHAN_IS_5GHZ(ap_chan))) {
712 			req->scan_req.dwell_time_passive =
713 				req->scan_req.dwell_time_active;
714 		}
715 
716 		if (scan_obj->scan_def.ap_scan_burst_duration) {
717 			req->scan_req.burst_duration =
718 				scan_obj->scan_def.ap_scan_burst_duration;
719 		} else {
720 			req->scan_req.burst_duration = 0;
721 			if (utils_is_dfs_ch(pdev, ap_chan))
722 				req->scan_req.burst_duration =
723 					SCAN_BURST_SCAN_MAX_NUM_OFFCHANNELS *
724 					req->scan_req.dwell_time_active;
725 		}
726 	}
727 }
728 
729 #else
730 static inline
731 void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev,
732 				       struct scan_start_request *req,
733 				       struct wlan_scan_obj *scan_obj)
734 {
735 }
736 
737 static inline void
738 scm_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev,
739 			      struct scan_start_request *req)
740 {
741 }
742 
743 static inline void
744 scm_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req)
745 {
746 }
747 #endif
748 
749 /**
750  * scm_update_channel_list() - update scan req params depending on dfs inis
751  * and initial scan request.
752  * @req: scan request
753  * @scan_obj: scan object
754  *
755  * Return: void
756  */
757 static void
758 scm_update_channel_list(struct scan_start_request *req,
759 			struct wlan_scan_obj *scan_obj)
760 {
761 	uint8_t i;
762 	uint8_t num_scan_channels = 0;
763 	struct scan_vdev_obj *scan_vdev_obj;
764 	struct wlan_objmgr_pdev *pdev;
765 	bool first_scan_done = true;
766 	bool p2p_search = false;
767 
768 	pdev = wlan_vdev_get_pdev(req->vdev);
769 
770 	scan_vdev_obj = wlan_get_vdev_scan_obj(req->vdev);
771 	if (!scan_vdev_obj) {
772 		scm_err("null scan_vdev_obj");
773 		return;
774 	}
775 
776 	if (!scan_vdev_obj->first_scan_done) {
777 		first_scan_done = false;
778 		scan_vdev_obj->first_scan_done = true;
779 	}
780 
781 	if(req->scan_req.p2p_scan_type == SCAN_P2P_SEARCH)
782 		p2p_search = true;
783 	/*
784 	 * No need to update channels if req is passive scan and single channel
785 	 * ie ROC, Preauth etc
786 	 */
787 	if (req->scan_req.scan_f_passive &&
788 	    req->scan_req.chan_list.num_chan == 1)
789 		return;
790 
791 	/* do this only for STA and P2P-CLI mode */
792 	if ((!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) &&
793 	    !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE)) &&
794 	    !p2p_search)
795 		return;
796 
797 	if ((scan_obj->scan_def.allow_dfs_chan_in_scan &&
798 	    (scan_obj->scan_def.allow_dfs_chan_in_first_scan ||
799 	     first_scan_done)) &&
800 	     !(scan_obj->scan_def.skip_dfs_chan_in_p2p_search && p2p_search))
801 		return;
802 
803 	for (i = 0; i < req->scan_req.chan_list.num_chan; i++) {
804 		if (wlan_reg_is_dfs_ch(pdev, wlan_reg_freq_to_chan(pdev,
805 				       req->scan_req.chan_list.chan[i].freq)))
806 			continue;
807 		req->scan_req.chan_list.chan[num_scan_channels++] =
808 				req->scan_req.chan_list.chan[i];
809 	}
810 	req->scan_req.chan_list.num_chan = num_scan_channels;
811 }
812 
813 /**
814  * scm_scan_req_update_params() - update scan req params depending on modes
815  * and scan type.
816  * @vdev: vdev object pointer
817  * @req: scan request
818  * @scan_obj: scan object
819  *
820  * Return: void
821  */
822 static void
823 scm_scan_req_update_params(struct wlan_objmgr_vdev *vdev,
824 			   struct scan_start_request *req,
825 			   struct wlan_scan_obj *scan_obj)
826 {
827 	struct chan_list *custom_chan_list;
828 	struct wlan_objmgr_pdev *pdev;
829 	uint8_t pdev_id;
830 
831 	/* Ensure correct number of probes are sent on active channel */
832 	if (!req->scan_req.repeat_probe_time)
833 		req->scan_req.repeat_probe_time =
834 			req->scan_req.dwell_time_active / SCAN_NPROBES_DEFAULT;
835 
836 	if (req->scan_req.scan_f_passive)
837 		req->scan_req.scan_ctrl_flags_ext |=
838 			SCAN_FLAG_EXT_FILTER_PUBLIC_ACTION_FRAME;
839 
840 	if (!req->scan_req.n_probes)
841 		req->scan_req.n_probes = (req->scan_req.repeat_probe_time > 0) ?
842 					  req->scan_req.dwell_time_active /
843 					  req->scan_req.repeat_probe_time : 0;
844 
845 	if (req->scan_req.p2p_scan_type == SCAN_NON_P2P_DEFAULT) {
846 		req->scan_req.scan_f_cck_rates = true;
847 		if (!req->scan_req.num_ssids)
848 			req->scan_req.scan_f_bcast_probe = true;
849 		req->scan_req.scan_f_add_ds_ie_in_probe = true;
850 		req->scan_req.scan_f_filter_prb_req = true;
851 		req->scan_req.scan_f_add_tpc_ie_in_probe = true;
852 	} else {
853 		req->scan_req.adaptive_dwell_time_mode = SCAN_DWELL_MODE_STATIC;
854 		req->scan_req.dwell_time_active_2g = 0;
855 		if (req->scan_req.p2p_scan_type == SCAN_P2P_LISTEN) {
856 			req->scan_req.repeat_probe_time = 0;
857 		} else {
858 			req->scan_req.scan_f_filter_prb_req = true;
859 			if (!req->scan_req.num_ssids)
860 				req->scan_req.scan_f_bcast_probe = true;
861 
862 			req->scan_req.dwell_time_active +=
863 					P2P_SEARCH_DWELL_TIME_INC;
864 			/*
865 			 * 3 channels with default max dwell time 40 ms.
866 			 * Cap limit will be set by
867 			 * P2P_SCAN_MAX_BURST_DURATION. Burst duration
868 			 * should be such that no channel is scanned less
869 			 * than the dwell time in normal scenarios.
870 			 */
871 			if (req->scan_req.chan_list.num_chan ==
872 			    WLAN_P2P_SOCIAL_CHANNELS &&
873 			    !scan_obj->miracast_enabled)
874 				req->scan_req.repeat_probe_time =
875 					req->scan_req.dwell_time_active / 5;
876 			else
877 				req->scan_req.repeat_probe_time =
878 					req->scan_req.dwell_time_active / 3;
879 			if (scan_obj->scan_def.p2p_scan_burst_duration) {
880 				req->scan_req.burst_duration =
881 					scan_obj->scan_def.
882 					p2p_scan_burst_duration;
883 			} else {
884 				req->scan_req.burst_duration =
885 						BURST_SCAN_MAX_NUM_OFFCHANNELS *
886 						req->scan_req.dwell_time_active;
887 				if (req->scan_req.burst_duration >
888 				    P2P_SCAN_MAX_BURST_DURATION) {
889 					uint8_t channels =
890 						P2P_SCAN_MAX_BURST_DURATION /
891 						req->scan_req.dwell_time_active;
892 					if (channels)
893 						req->scan_req.burst_duration =
894 						channels *
895 						req->scan_req.dwell_time_active;
896 					else
897 						req->scan_req.burst_duration =
898 						P2P_SCAN_MAX_BURST_DURATION;
899 				}
900 			}
901 			req->scan_req.scan_ev_bss_chan = false;
902 		}
903 	}
904 
905 	if (!req->scan_req.scan_f_passive)
906 		scm_update_passive_dwell_time(vdev, req);
907 	scm_update_dbs_scan_ctrl_ext_flag(req);
908 
909 	/*
910 	 * No need to update conncurrency parmas if req is passive scan on
911 	 * single channel ie ROC, Preauth etc
912 	 */
913 	if (!(req->scan_req.scan_f_passive &&
914 	      req->scan_req.chan_list.num_chan == 1))
915 		scm_req_update_concurrency_params(vdev, req, scan_obj);
916 
917 	/*
918 	 * Set wide band flag if enabled. This will cause
919 	 * phymode TLV being sent to FW.
920 	 */
921 	pdev = wlan_vdev_get_pdev(vdev);
922 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
923 	if (ucfg_scan_get_wide_band_scan(pdev))
924 		req->scan_req.scan_f_wide_band = true;
925 	else
926 		req->scan_req.scan_f_wide_band = false;
927 
928 	/*
929 	 * Overwrite scan channles with custom scan channel
930 	 * list if configured.
931 	 */
932 	custom_chan_list = &scan_obj->pdev_info[pdev_id].custom_chan_list;
933 	if (custom_chan_list->num_chan)
934 		qdf_mem_copy(&req->scan_req.chan_list, custom_chan_list,
935 			     sizeof(struct chan_list));
936 	else if (!req->scan_req.chan_list.num_chan)
937 		ucfg_scan_init_chanlist_params(req, 0, NULL, NULL);
938 
939 	scm_update_channel_list(req, scan_obj);
940 	scm_debug("dwell time: active %d, passive %d, repeat_probe_time %d n_probes %d flags_ext %x, wide_bw_scan: %d",
941 		  req->scan_req.dwell_time_active,
942 		  req->scan_req.dwell_time_passive,
943 		  req->scan_req.repeat_probe_time, req->scan_req.n_probes,
944 		  req->scan_req.scan_ctrl_flags_ext,
945 		  req->scan_req.scan_f_wide_band);
946 }
947 
948 QDF_STATUS
949 scm_scan_start_req(struct scheduler_msg *msg)
950 {
951 	struct wlan_serialization_command cmd = {0, };
952 	enum wlan_serialization_status ser_cmd_status;
953 	struct scan_start_request *req = NULL;
954 	struct wlan_scan_obj *scan_obj;
955 	QDF_STATUS status = QDF_STATUS_SUCCESS;
956 	uint8_t idx;
957 
958 	if (!msg) {
959 		scm_err("msg received is NULL");
960 		QDF_ASSERT(0);
961 		return QDF_STATUS_E_NULL_VALUE;
962 	}
963 	if (!msg->bodyptr) {
964 		scm_err("bodyptr is NULL");
965 		QDF_ASSERT(0);
966 		return QDF_STATUS_E_NULL_VALUE;
967 	}
968 
969 	req = msg->bodyptr;
970 
971 	if (!scm_is_scan_allowed(req->vdev)) {
972 		scm_err("scan disabled, rejecting the scan req");
973 		status = QDF_STATUS_E_NULL_VALUE;
974 		goto err;
975 	}
976 
977 	scan_obj = wlan_vdev_get_scan_obj(req->vdev);
978 	if (!scan_obj) {
979 		scm_debug("Couldn't find scan object");
980 		status = QDF_STATUS_E_NULL_VALUE;
981 		goto err;
982 	}
983 
984 	scm_scan_req_update_params(req->vdev, req, scan_obj);
985 	scm_info("request to scan %d channels",
986 		 req->scan_req.chan_list.num_chan);
987 	for (idx = 0; idx < req->scan_req.chan_list.num_chan; idx++)
988 		scm_debug("chan[%d]: freq:%d, phymode:%d", idx,
989 			  req->scan_req.chan_list.chan[idx].freq,
990 			  req->scan_req.chan_list.chan[idx].phymode);
991 
992 	cmd.cmd_type = WLAN_SER_CMD_SCAN;
993 	cmd.cmd_id = req->scan_req.scan_id;
994 	cmd.cmd_cb = (wlan_serialization_cmd_callback)
995 		scm_scan_serialize_callback;
996 	cmd.umac_cmd = req;
997 	cmd.source = WLAN_UMAC_COMP_SCAN;
998 	cmd.is_high_priority = false;
999 	cmd.cmd_timeout_duration = req->scan_req.max_scan_time +
1000 		SCAN_TIMEOUT_GRACE_PERIOD;
1001 	cmd.vdev = req->vdev;
1002 
1003 	if (scan_obj->disable_timeout)
1004 		cmd.cmd_timeout_duration = 0;
1005 
1006 	scm_debug("req: 0x%pK, reqid: %d, scanid: %d, vdevid: %d",
1007 		  req, req->scan_req.scan_req_id, req->scan_req.scan_id,
1008 		  req->scan_req.vdev_id);
1009 
1010 	qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_SERIALIZATION,
1011 		   WLAN_SER_CMD_SCAN, req->vdev->vdev_objmgr.vdev_id,
1012 		   req->scan_req.scan_id);
1013 
1014 	ser_cmd_status = wlan_serialization_request(&cmd);
1015 	scm_debug("wlan_serialization_request status:%d", ser_cmd_status);
1016 
1017 	switch (ser_cmd_status) {
1018 	case WLAN_SER_CMD_PENDING:
1019 		/* command moved to pending list.Do nothing */
1020 		break;
1021 	case WLAN_SER_CMD_ACTIVE:
1022 		/* command moved to active list. Do nothing */
1023 		break;
1024 	case WLAN_SER_CMD_DENIED_LIST_FULL:
1025 	case WLAN_SER_CMD_DENIED_RULES_FAILED:
1026 	case WLAN_SER_CMD_DENIED_UNSPECIFIED:
1027 		goto err;
1028 	default:
1029 		QDF_ASSERT(0);
1030 		status = QDF_STATUS_E_INVAL;
1031 		goto err;
1032 	}
1033 
1034 	return status;
1035 err:
1036 	/*
1037 	 * notify registered scan event handlers
1038 	 * about internal error
1039 	 */
1040 	scm_post_internal_scan_complete_event(req,
1041 					      SCAN_REASON_INTERNAL_FAILURE);
1042 	/*
1043 	 * cmd can't be serviced.
1044 	 * release vdev reference and free scan_start_request memory
1045 	 */
1046 	if (req) {
1047 		wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
1048 		scm_scan_free_scan_request_mem(req);
1049 	}
1050 
1051 	return status;
1052 }
1053 
1054 static inline enum wlan_serialization_cancel_type
1055 get_serialization_cancel_type(enum scan_cancel_req_type type)
1056 {
1057 	enum wlan_serialization_cancel_type serialization_type;
1058 
1059 	switch (type) {
1060 	case WLAN_SCAN_CANCEL_SINGLE:
1061 		serialization_type = WLAN_SER_CANCEL_SINGLE_SCAN;
1062 		break;
1063 	case WLAN_SCAN_CANCEL_VDEV_ALL:
1064 		serialization_type = WLAN_SER_CANCEL_VDEV_SCANS;
1065 		break;
1066 	case WLAN_SCAN_CANCEL_PDEV_ALL:
1067 		serialization_type = WLAN_SER_CANCEL_PDEV_SCANS;
1068 		break;
1069 	default:
1070 		QDF_ASSERT(0);
1071 		scm_warn("invalid scan_cancel_req_type: %d", type);
1072 		serialization_type = WLAN_SER_CANCEL_PDEV_SCANS;
1073 		break;
1074 	}
1075 
1076 	return serialization_type;
1077 }
1078 
1079 QDF_STATUS
1080 scm_scan_cancel_req(struct scheduler_msg *msg)
1081 {
1082 	struct wlan_serialization_queued_cmd_info cmd = {0,};
1083 	struct wlan_serialization_command ser_cmd = {0,};
1084 	enum wlan_serialization_cmd_status ser_cmd_status;
1085 	struct scan_cancel_request *req;
1086 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1087 
1088 	if (!msg) {
1089 		scm_err("msg received is NULL");
1090 		QDF_ASSERT(0);
1091 		return QDF_STATUS_E_NULL_VALUE;
1092 	}
1093 	if (!msg->bodyptr) {
1094 		scm_err("Bodyptr is NULL");
1095 		QDF_ASSERT(0);
1096 		return QDF_STATUS_E_NULL_VALUE;
1097 	}
1098 
1099 	req = msg->bodyptr;
1100 	/*
1101 	 * If requester wants to wait for target scan cancel event
1102 	 * instead of internally generated cancel event, just check
1103 	 * which queue this scan request belongs to and send scan
1104 	 * cancel request to FW accordingly.
1105 	 * Else generate internal scan cancel event and notify
1106 	 * handlers and free scan request resources.
1107 	 */
1108 	if (req->wait_tgt_cancel &&
1109 			(req->cancel_req.req_type == WLAN_SCAN_CANCEL_SINGLE)) {
1110 		ser_cmd.cmd_type = WLAN_SER_CMD_SCAN;
1111 		ser_cmd.cmd_id = req->cancel_req.scan_id;
1112 		ser_cmd.cmd_cb = NULL;
1113 		ser_cmd.umac_cmd = NULL;
1114 		ser_cmd.source = WLAN_UMAC_COMP_SCAN;
1115 		ser_cmd.is_high_priority = false;
1116 		ser_cmd.vdev = req->vdev;
1117 		if (wlan_serialization_is_cmd_present_in_active_queue(NULL, &ser_cmd))
1118 			ser_cmd_status = WLAN_SER_CMD_IN_ACTIVE_LIST;
1119 		else if (wlan_serialization_is_cmd_present_in_pending_queue(NULL, &ser_cmd))
1120 			ser_cmd_status = WLAN_SER_CMD_IN_PENDING_LIST;
1121 		else
1122 			ser_cmd_status = WLAN_SER_CMD_NOT_FOUND;
1123 	} else {
1124 		cmd.requestor = 0;
1125 		cmd.cmd_type = WLAN_SER_CMD_SCAN;
1126 		cmd.cmd_id = req->cancel_req.scan_id;
1127 		cmd.vdev = req->vdev;
1128 		cmd.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE |
1129 			WLAN_SERIALIZATION_PENDING_QUEUE;
1130 		cmd.req_type = get_serialization_cancel_type(req->cancel_req.req_type);
1131 
1132 		ser_cmd_status = wlan_serialization_cancel_request(&cmd);
1133 	}
1134 
1135 	scm_debug("status: %d, reqid: %d, scanid: %d, vdevid: %d, type: %d",
1136 		ser_cmd_status, req->cancel_req.requester,
1137 		req->cancel_req.scan_id, req->cancel_req.vdev_id,
1138 		req->cancel_req.req_type);
1139 
1140 	switch (ser_cmd_status) {
1141 	case WLAN_SER_CMD_IN_PENDING_LIST:
1142 		/* do nothing */
1143 		break;
1144 	case WLAN_SER_CMD_IN_ACTIVE_LIST:
1145 	case WLAN_SER_CMDS_IN_ALL_LISTS:
1146 		/* send wmi scan cancel to fw */
1147 		status = tgt_scan_cancel(req);
1148 		break;
1149 	case WLAN_SER_CMD_NOT_FOUND:
1150 		/* do nothing */
1151 		break;
1152 	default:
1153 		QDF_ASSERT(0);
1154 		status = QDF_STATUS_E_INVAL;
1155 		break;
1156 	}
1157 
1158 	/* Release vdev reference and scan cancel request
1159 	 * processing is complete
1160 	 */
1161 	wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
1162 	/* Free cancel request memory */
1163 	qdf_mem_free(req);
1164 
1165 	return status;
1166 }
1167 
1168 #ifdef FEATURE_WLAN_SCAN_PNO
1169 static QDF_STATUS
1170 scm_pno_event_handler(struct wlan_objmgr_vdev *vdev,
1171 	struct scan_event *event)
1172 {
1173 	struct scan_vdev_obj *scan_vdev_obj;
1174 	struct wlan_scan_obj *scan_psoc_obj;
1175 	scan_event_handler pno_cb;
1176 	void *cb_arg;
1177 
1178 	scan_vdev_obj = wlan_get_vdev_scan_obj(vdev);
1179 	scan_psoc_obj = wlan_vdev_get_scan_obj(vdev);
1180 	if (!scan_vdev_obj || !scan_psoc_obj) {
1181 		scm_err("null scan_vdev_obj %pK scan_obj %pK",
1182 			scan_vdev_obj, scan_psoc_obj);
1183 		return QDF_STATUS_E_INVAL;
1184 	}
1185 
1186 	switch (event->type) {
1187 	case SCAN_EVENT_TYPE_NLO_COMPLETE:
1188 		if (!scan_vdev_obj->pno_match_evt_received)
1189 			return QDF_STATUS_SUCCESS;
1190 		qdf_wake_lock_release(&scan_psoc_obj->pno_cfg.pno_wake_lock,
1191 			WIFI_POWER_EVENT_WAKELOCK_PNO);
1192 		qdf_wake_lock_timeout_acquire(
1193 			&scan_psoc_obj->pno_cfg.pno_wake_lock,
1194 			SCAN_PNO_SCAN_COMPLETE_WAKE_LOCK_TIMEOUT);
1195 		scan_vdev_obj->pno_match_evt_received = false;
1196 		break;
1197 	case SCAN_EVENT_TYPE_NLO_MATCH:
1198 		scan_vdev_obj->pno_match_evt_received = true;
1199 		qdf_wake_lock_timeout_acquire(
1200 			&scan_psoc_obj->pno_cfg.pno_wake_lock,
1201 			SCAN_PNO_MATCH_WAKE_LOCK_TIMEOUT);
1202 		return QDF_STATUS_SUCCESS;
1203 	default:
1204 		return QDF_STATUS_E_INVAL;
1205 	}
1206 	qdf_spin_lock_bh(&scan_psoc_obj->lock);
1207 	pno_cb = scan_psoc_obj->pno_cfg.pno_cb.func;
1208 	cb_arg = scan_psoc_obj->pno_cfg.pno_cb.arg;
1209 	qdf_spin_unlock_bh(&scan_psoc_obj->lock);
1210 
1211 	if (pno_cb)
1212 		pno_cb(vdev, event, cb_arg);
1213 
1214 	return QDF_STATUS_SUCCESS;
1215 }
1216 #else
1217 
1218 static QDF_STATUS
1219 scm_pno_event_handler(struct wlan_objmgr_vdev *vdev,
1220 	struct scan_event *event)
1221 {
1222 	return QDF_STATUS_SUCCESS;
1223 }
1224 #endif
1225 
1226 /**
1227  * scm_scan_update_scan_event() - update scan event
1228  * @scan: scan object
1229  * @event: scan event
1230  * @scan_start_req: scan_start_req used for triggering scan
1231  *
1232  * update scan params in scan event
1233  *
1234  * Return: QDF_STATUS
1235  */
1236 static QDF_STATUS
1237 scm_scan_update_scan_event(struct wlan_scan_obj *scan,
1238 		struct scan_event *event,
1239 		struct scan_start_request *scan_start_req)
1240 {
1241 	if (!event)
1242 		return QDF_STATUS_E_NULL_VALUE;
1243 
1244 	if (!scan || !scan_start_req) {
1245 		event->scan_start_req = NULL;
1246 		return QDF_STATUS_E_NULL_VALUE;
1247 	}
1248 	/* copy scan start request to pass back buffer */
1249 	qdf_mem_copy(&scan->scan_start_request_buff, scan_start_req,
1250 			sizeof(struct scan_start_request));
1251 	/* reset all pointers */
1252 	scan->scan_start_request_buff.scan_req.extraie.ptr = NULL;
1253 	scan->scan_start_request_buff.scan_req.extraie.len = 0;
1254 	scan->scan_start_request_buff.scan_req.htcap.ptr = NULL;
1255 	scan->scan_start_request_buff.scan_req.htcap.len = 0;
1256 	scan->scan_start_request_buff.scan_req.vhtcap.ptr = NULL;
1257 	scan->scan_start_request_buff.scan_req.vhtcap.len = 0;
1258 
1259 	event->scan_start_req = &scan->scan_start_request_buff;
1260 
1261 	return QDF_STATUS_SUCCESS;
1262 }
1263 
1264 QDF_STATUS
1265 scm_scan_event_handler(struct scheduler_msg *msg)
1266 {
1267 	struct wlan_objmgr_vdev *vdev;
1268 	struct scan_event *event;
1269 	struct scan_event_info *event_info;
1270 	struct wlan_serialization_command cmd = {0,};
1271 	struct wlan_serialization_command *queued_cmd;
1272 	struct scan_start_request *scan_start_req;
1273 	struct wlan_scan_obj *scan;
1274 
1275 	if (!msg) {
1276 		scm_err("NULL msg received ");
1277 		QDF_ASSERT(0);
1278 		return QDF_STATUS_E_NULL_VALUE;
1279 	}
1280 	if (!msg->bodyptr) {
1281 		scm_err("NULL scan event received");
1282 		QDF_ASSERT(0);
1283 		return QDF_STATUS_E_NULL_VALUE;
1284 	}
1285 
1286 	event_info = msg->bodyptr;
1287 	vdev = event_info->vdev;
1288 	event = &(event_info->event);
1289 
1290 	scm_debug("vdevid:%d, type:%d, reason:%d, freq:%d, reqstr:%d, scanid:%d",
1291 		  event->vdev_id, event->type, event->reason, event->chan_freq,
1292 		  event->requester, event->scan_id);
1293 	/*
1294 	 * NLO requests are never queued, so post NLO events
1295 	 * without checking for their presence in active queue.
1296 	 */
1297 	switch (event->type) {
1298 	case SCAN_EVENT_TYPE_NLO_COMPLETE:
1299 	case SCAN_EVENT_TYPE_NLO_MATCH:
1300 		scm_pno_event_handler(vdev, event);
1301 		goto exit;
1302 	default:
1303 		break;
1304 	}
1305 
1306 	cmd.cmd_type = WLAN_SER_CMD_SCAN;
1307 	cmd.cmd_id = event->scan_id;
1308 	cmd.cmd_cb = NULL;
1309 	cmd.umac_cmd = NULL;
1310 	cmd.source = WLAN_UMAC_COMP_SCAN;
1311 	cmd.is_high_priority = false;
1312 	cmd.vdev = vdev;
1313 	if (!wlan_serialization_is_cmd_present_in_active_queue(NULL, &cmd)) {
1314 		/*
1315 		 * We received scan event for an already completed/cancelled
1316 		 * scan request. Drop this event.
1317 		 */
1318 		scm_debug("Received scan event while request not in active queue");
1319 		goto exit;
1320 	}
1321 
1322 	/* Fill scan_start_request used to trigger this scan */
1323 	queued_cmd = wlan_serialization_get_scan_cmd_using_scan_id(
1324 			wlan_vdev_get_psoc(vdev), wlan_vdev_get_id(vdev),
1325 			event->scan_id, true);
1326 
1327 	if (!queued_cmd) {
1328 		scm_err("NULL queued_cmd");
1329 		goto exit;
1330 	}
1331 	if (!queued_cmd->umac_cmd) {
1332 		scm_err("NULL umac_cmd");
1333 		goto exit;
1334 	}
1335 	scan_start_req = queued_cmd->umac_cmd;
1336 
1337 	if (scan_start_req->scan_req.scan_req_id != event->requester) {
1338 		scm_err("req ID mismatch, scan_req_id:%d, event_req_id:%d",
1339 				scan_start_req->scan_req.scan_req_id,
1340 				event->requester);
1341 		goto exit;
1342 	}
1343 
1344 	scan = wlan_vdev_get_scan_obj(vdev);
1345 	if (scan)
1346 		scm_scan_update_scan_event(scan, event, scan_start_req);
1347 
1348 	switch (event->type) {
1349 	case SCAN_EVENT_TYPE_COMPLETED:
1350 		if (event->reason == SCAN_REASON_COMPLETED)
1351 			scm_11d_decide_country_code(vdev);
1352 		/* fall through to release the command */
1353 	case SCAN_EVENT_TYPE_START_FAILED:
1354 	case SCAN_EVENT_TYPE_DEQUEUED:
1355 		scm_release_serialization_command(vdev, event->scan_id);
1356 		break;
1357 	default:
1358 		break;
1359 	}
1360 
1361 	/* Notify all interested parties */
1362 	scm_scan_post_event(vdev, event);
1363 
1364 exit:
1365 	/* free event info memory */
1366 	qdf_mem_free(event_info);
1367 	wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID);
1368 
1369 	return QDF_STATUS_SUCCESS;
1370 }
1371 
1372 QDF_STATUS scm_scan_event_flush_callback(struct scheduler_msg *msg)
1373 {
1374 	struct wlan_objmgr_vdev *vdev;
1375 	struct scan_event_info *event_info;
1376 
1377 	if (!msg || !msg->bodyptr) {
1378 		scm_err("msg or msg->bodyptr is NULL");
1379 		return QDF_STATUS_E_NULL_VALUE;
1380 	}
1381 
1382 	event_info = msg->bodyptr;
1383 	vdev = event_info->vdev;
1384 
1385 	/* free event info memory */
1386 	qdf_mem_free(event_info);
1387 	wlan_objmgr_vdev_release_ref(vdev, WLAN_SCAN_ID);
1388 
1389 	return QDF_STATUS_SUCCESS;
1390 }
1391 
1392 QDF_STATUS scm_bcn_probe_flush_callback(struct scheduler_msg *msg)
1393 {
1394 	struct scan_bcn_probe_event *bcn;
1395 
1396 	bcn = msg->bodyptr;
1397 
1398 	if (!bcn) {
1399 		scm_err("bcn is NULL");
1400 		return QDF_STATUS_E_NULL_VALUE;
1401 	}
1402 	if (bcn->psoc)
1403 		wlan_objmgr_psoc_release_ref(bcn->psoc, WLAN_SCAN_ID);
1404 	if (bcn->rx_data)
1405 		qdf_mem_free(bcn->rx_data);
1406 	if (bcn->buf)
1407 		qdf_nbuf_free(bcn->buf);
1408 	qdf_mem_free(bcn);
1409 
1410 	return QDF_STATUS_SUCCESS;
1411 }
1412 
1413 QDF_STATUS scm_scan_start_flush_callback(struct scheduler_msg *msg)
1414 {
1415 	struct scan_start_request *req;
1416 
1417 	if (!msg || !msg->bodyptr) {
1418 		scm_err("msg or msg->bodyptr is NULL");
1419 		return QDF_STATUS_E_NULL_VALUE;
1420 	}
1421 
1422 	req = msg->bodyptr;
1423 	scm_post_internal_scan_complete_event(req, SCAN_REASON_CANCELLED);
1424 	wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
1425 	scm_scan_free_scan_request_mem(req);
1426 
1427 	return QDF_STATUS_SUCCESS;
1428 }
1429 
1430 QDF_STATUS scm_scan_cancel_flush_callback(struct scheduler_msg *msg)
1431 {
1432 	struct scan_cancel_request *req;
1433 
1434 	if (!msg || !msg->bodyptr) {
1435 		scm_err("msg or msg->bodyptr is NULL");
1436 		return QDF_STATUS_E_NULL_VALUE;
1437 	}
1438 
1439 	req = msg->bodyptr;
1440 	wlan_objmgr_vdev_release_ref(req->vdev, WLAN_SCAN_ID);
1441 	/* Free cancel request memory */
1442 	qdf_mem_free(req);
1443 
1444 	return QDF_STATUS_SUCCESS;
1445 }
1446