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