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