xref: /wlan-dirver/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c (revision dc882e4dd9e61bd77cf492e38eb95e049c61d2a7)
1 /*
2  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * DOC: wlan_policy_mgr_action.c
22  *
23  * WLAN Concurrenct Connection Management APIs
24  *
25  */
26 
27 /* Include files */
28 
29 #include "wlan_policy_mgr_api.h"
30 #include "wlan_policy_mgr_i.h"
31 #include "qdf_types.h"
32 #include "qdf_trace.h"
33 #include "wlan_objmgr_global_obj.h"
34 #include "qdf_platform.h"
35 #include "wlan_nan_api.h"
36 #include "nan_ucfg_api.h"
37 #include "wlan_mlme_api.h"
38 #include "sap_api.h"
39 #include "wlan_mlme_api.h"
40 #include "wlan_mlme_ucfg_api.h"
41 #include "target_if.h"
42 #include "wlan_cm_api.h"
43 #include "wlan_mlo_link_force.h"
44 
45 enum policy_mgr_conc_next_action (*policy_mgr_get_current_pref_hw_mode_ptr)
46 	(struct wlan_objmgr_psoc *psoc);
47 
48 void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index,
49 			uint32_t new_hw_mode_index,
50 			uint32_t num_vdev_mac_entries,
51 			struct policy_mgr_vdev_mac_map *vdev_mac_map,
52 			uint32_t num_mac_freq,
53 			struct policy_mgr_pdev_mac_freq_map *mac_freq_range,
54 			struct wlan_objmgr_psoc *context)
55 {
56 	QDF_STATUS status;
57 	struct policy_mgr_hw_mode_params hw_mode;
58 	uint32_t i;
59 	struct policy_mgr_psoc_priv_obj *pm_ctx;
60 
61 	pm_ctx = policy_mgr_get_context(context);
62 	if (!pm_ctx) {
63 		policy_mgr_err("Invalid context");
64 		return;
65 	}
66 
67 	if (!vdev_mac_map) {
68 		policy_mgr_err("vdev_mac_map is NULL");
69 		return;
70 	}
71 
72 	policy_mgr_debug("old_hw_mode_index=%d, new_hw_mode_index=%d",
73 		old_hw_mode_index, new_hw_mode_index);
74 
75 	if (mac_freq_range)
76 		for (i = 0; i < num_mac_freq; i++)
77 			policy_mgr_debug("mac_id:%d start_freq:%d end_freq %d",
78 					 mac_freq_range[i].mac_id,
79 					 mac_freq_range[i].start_freq,
80 					 mac_freq_range[i].end_freq);
81 
82 	for (i = 0; i < num_vdev_mac_entries; i++)
83 		policy_mgr_debug("vdev_id:%d mac_id:%d",
84 			vdev_mac_map[i].vdev_id,
85 			vdev_mac_map[i].mac_id);
86 
87 	status = policy_mgr_get_hw_mode_from_idx(context,
88 				new_hw_mode_index, &hw_mode);
89 	if (status != QDF_STATUS_SUCCESS) {
90 		policy_mgr_err("Get HW mode failed: %d", status);
91 		return;
92 	}
93 
94 	policy_mgr_debug("MAC0: TxSS:%d, RxSS:%d, Bw:%d band_cap:%d",
95 			 hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss,
96 			 hw_mode.mac0_bw, hw_mode.mac0_band_cap);
97 	policy_mgr_debug("MAC1: TxSS:%d, RxSS:%d, Bw:%d",
98 			 hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss,
99 			 hw_mode.mac1_bw);
100 	policy_mgr_debug("DBS:%d, Agile DFS:%d, SBS:%d",
101 			 hw_mode.dbs_cap, hw_mode.agile_dfs_cap,
102 			 hw_mode.sbs_cap);
103 
104 	/* update pm_conc_connection_list */
105 	policy_mgr_update_hw_mode_conn_info(context, num_vdev_mac_entries,
106 					    vdev_mac_map, hw_mode,
107 					    num_mac_freq, mac_freq_range);
108 
109 	if (pm_ctx->mode_change_cb)
110 		pm_ctx->mode_change_cb();
111 
112 	return;
113 }
114 
115 QDF_STATUS policy_mgr_check_n_start_opportunistic_timer(
116 		struct wlan_objmgr_psoc *psoc)
117 {
118 	struct policy_mgr_psoc_priv_obj *pm_ctx;
119 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
120 
121 	pm_ctx = policy_mgr_get_context(psoc);
122 	if (!pm_ctx) {
123 		policy_mgr_err("PM ctx not valid. Oppurtunistic timer cannot start");
124 		return QDF_STATUS_E_FAILURE;
125 	}
126 	if (policy_mgr_need_opportunistic_upgrade(psoc, NULL)) {
127 	/* let's start the timer */
128 	qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
129 	status = qdf_mc_timer_start(
130 				&pm_ctx->dbs_opportunistic_timer,
131 				DBS_OPPORTUNISTIC_TIME * 1000);
132 	if (!QDF_IS_STATUS_SUCCESS(status))
133 		policy_mgr_err("Failed to start dbs opportunistic timer");
134 	}
135 	return status;
136 }
137 
138 QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc,
139 		uint32_t session_id,
140 		enum hw_mode_ss_config mac0_ss,
141 		enum hw_mode_bandwidth mac0_bw,
142 		enum hw_mode_ss_config mac1_ss,
143 		enum hw_mode_bandwidth mac1_bw,
144 		enum hw_mode_mac_band_cap mac0_band_cap,
145 		enum hw_mode_dbs_capab dbs,
146 		enum hw_mode_agile_dfs_capab dfs,
147 		enum hw_mode_sbs_capab sbs,
148 		enum policy_mgr_conn_update_reason reason,
149 		uint8_t next_action, enum policy_mgr_conc_next_action action,
150 		uint32_t request_id)
151 {
152 	int8_t hw_mode_index;
153 	struct policy_mgr_hw_mode msg;
154 	QDF_STATUS status;
155 	struct policy_mgr_psoc_priv_obj *pm_ctx;
156 
157 	pm_ctx = policy_mgr_get_context(psoc);
158 	if (!pm_ctx) {
159 		policy_mgr_err("Invalid context");
160 		return QDF_STATUS_E_FAILURE;
161 	}
162 
163 	if (!pm_ctx->sme_cbacks.sme_pdev_set_hw_mode) {
164 		policy_mgr_debug("NOT supported");
165 		return QDF_STATUS_E_NOSUPPORT;
166 	}
167 
168 	/*
169 	 * if HW is not capable of doing 2x2 or ini config disabled 2x2, don't
170 	 * allow to request FW for 2x2
171 	 */
172 	if ((HW_MODE_SS_2x2 == mac0_ss) && (!pm_ctx->user_cfg.enable2x2)) {
173 		policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac0");
174 		mac0_ss = HW_MODE_SS_1x1;
175 	}
176 	if ((HW_MODE_SS_2x2 == mac1_ss) && (!pm_ctx->user_cfg.enable2x2)) {
177 		policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac1");
178 		mac1_ss = HW_MODE_SS_1x1;
179 	}
180 
181 	hw_mode_index = policy_mgr_get_hw_mode_idx_from_dbs_hw_list(psoc,
182 			mac0_ss, mac0_bw, mac1_ss, mac1_bw, mac0_band_cap,
183 			dbs, dfs, sbs);
184 	if (hw_mode_index < 0) {
185 		policy_mgr_err("Invalid HW mode index obtained");
186 		return QDF_STATUS_E_FAILURE;
187 	}
188 
189 	/* Don't send WMI_PDEV_SET_HW_MODE_CMDID to FW if existing SAP / GO is
190 	 * in CAC-in-progress state. Host is blocking this command as FW is
191 	 * having design limitation and FW don't expect this command when CAC
192 	 * is in progress state.
193 	 */
194 	if (pm_ctx->hdd_cbacks.hdd_is_cac_in_progress &&
195 	    pm_ctx->hdd_cbacks.hdd_is_cac_in_progress() &&
196 	    !policy_mgr_is_hw_dbs_2x2_capable(psoc)) {
197 		policy_mgr_err("SAP CAC_IN_PROGRESS state, drop WMI_PDEV_SET_HW_MODE_CMDID");
198 		return QDF_STATUS_E_FAILURE;
199 	}
200 
201 	msg.hw_mode_index = hw_mode_index;
202 	msg.set_hw_mode_cb = (void *)policy_mgr_pdev_set_hw_mode_cb;
203 	msg.reason = reason;
204 	msg.session_id = session_id;
205 	msg.next_action = next_action;
206 	msg.action = action;
207 	msg.context = psoc;
208 	msg.request_id = request_id;
209 
210 	policy_mgr_debug("set hw mode to sme: hw_mode_index: %d session:%d reason:%d action %d request_id %d",
211 			 msg.hw_mode_index, msg.session_id, msg.reason, action,
212 			 msg.request_id);
213 
214 	status = pm_ctx->sme_cbacks.sme_pdev_set_hw_mode(msg);
215 	if (status != QDF_STATUS_SUCCESS) {
216 		policy_mgr_err("Failed to set hw mode to SME");
217 		return status;
218 	}
219 
220 	return QDF_STATUS_SUCCESS;
221 }
222 
223 enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade(
224 		struct wlan_objmgr_psoc *psoc,
225 		enum policy_mgr_conn_update_reason *reason)
226 {
227 	uint32_t conn_index;
228 	enum policy_mgr_conc_next_action upgrade = PM_NOP;
229 	enum policy_mgr_conc_next_action preferred_dbs_action;
230 	uint8_t mac = 0;
231 	struct policy_mgr_hw_mode_params hw_mode;
232 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
233 	struct policy_mgr_psoc_priv_obj *pm_ctx;
234 
235 	if (policy_mgr_is_hwmode_offload_enabled(psoc)) {
236 		policy_mgr_debug("HW mode selection offload is enabled");
237 		return upgrade;
238 	}
239 
240 	pm_ctx = policy_mgr_get_context(psoc);
241 	if (!pm_ctx) {
242 		policy_mgr_err("Invalid Context");
243 		goto exit;
244 	}
245 
246 	if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
247 		policy_mgr_rl_debug("driver isn't dbs capable, no further action needed");
248 		goto exit;
249 	}
250 
251 	status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
252 	if (!QDF_IS_STATUS_SUCCESS(status)) {
253 		policy_mgr_err("policy_mgr_get_current_hw_mode failed");
254 		goto exit;
255 	}
256 	if (!hw_mode.dbs_cap) {
257 		policy_mgr_debug("current HW mode is non-DBS capable");
258 		goto exit;
259 	}
260 
261 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
262 	/* Are both mac's still in use */
263 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
264 		conn_index++) {
265 		policy_mgr_debug("index:%d mac:%d in_use:%d chan:%d org_nss:%d",
266 			conn_index,
267 			pm_conc_connection_list[conn_index].mac,
268 			pm_conc_connection_list[conn_index].in_use,
269 			pm_conc_connection_list[conn_index].freq,
270 			pm_conc_connection_list[conn_index].original_nss);
271 		if ((pm_conc_connection_list[conn_index].mac == 0) &&
272 			pm_conc_connection_list[conn_index].in_use) {
273 			mac |= POLICY_MGR_MAC0;
274 			if (POLICY_MGR_MAC0_AND_MAC1 == mac) {
275 				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
276 				goto done;
277 			}
278 		} else if ((pm_conc_connection_list[conn_index].mac == 1) &&
279 			pm_conc_connection_list[conn_index].in_use) {
280 			mac |= POLICY_MGR_MAC1;
281 			if (policy_mgr_is_hw_dbs_required_for_band(
282 					psoc, HW_MODE_MAC_BAND_2G) &&
283 			    WLAN_REG_IS_24GHZ_CH_FREQ(
284 				pm_conc_connection_list[conn_index].freq)) {
285 				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
286 				policy_mgr_debug("2X2 DBS capable with 2.4 GHZ connection");
287 				goto done;
288 			}
289 			if (POLICY_MGR_MAC0_AND_MAC1 == mac) {
290 				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
291 				goto done;
292 			}
293 		}
294 	}
295 	/* Let's request for single MAC mode */
296 	upgrade = PM_SINGLE_MAC;
297 	if (reason)
298 		*reason = POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC;
299 	/* Is there any connection had an initial connection with 2x2 */
300 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
301 		conn_index++) {
302 		if ((pm_conc_connection_list[conn_index].original_nss == 2) &&
303 			pm_conc_connection_list[conn_index].in_use) {
304 			upgrade = PM_SINGLE_MAC_UPGRADE;
305 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
306 			goto done;
307 		}
308 	}
309 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
310 
311 done:
312 	if (upgrade == PM_NOP && hw_mode.dbs_cap &&
313 	    policy_mgr_is_2x2_1x1_dbs_capable(psoc)) {
314 		preferred_dbs_action =
315 			policy_mgr_get_preferred_dbs_action_table(
316 					psoc, INVALID_VDEV_ID, 0, 0);
317 		if (hw_mode.action_type == PM_DBS1 &&
318 		    preferred_dbs_action == PM_DBS2) {
319 			upgrade = PM_DBS2_DOWNGRADE;
320 			if (reason)
321 				*reason =
322 				POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE;
323 		} else if (hw_mode.action_type == PM_DBS2 &&
324 		    preferred_dbs_action == PM_DBS1) {
325 			upgrade = PM_DBS1_DOWNGRADE;
326 			if (reason)
327 				*reason =
328 				POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE;
329 		}
330 	}
331 exit:
332 	return upgrade;
333 }
334 
335 QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc,
336 					uint32_t vdev_id)
337 {
338 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
339 	uint32_t conn_index = 0, ch_freq, cur_freq;
340 	bool found = false;
341 	struct policy_mgr_vdev_entry_info conn_table_entry;
342 	enum policy_mgr_chain_mode chain_mask = POLICY_MGR_ONE_ONE;
343 	uint8_t nss_2g, nss_5g;
344 	enum policy_mgr_con_mode mode;
345 	uint32_t nss = 0;
346 	struct policy_mgr_psoc_priv_obj *pm_ctx;
347 
348 	pm_ctx = policy_mgr_get_context(psoc);
349 	if (!pm_ctx) {
350 		policy_mgr_err("Invalid Context");
351 		return status;
352 	}
353 
354 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
355 	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
356 		if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
357 			/* debug msg */
358 			found = true;
359 			break;
360 		}
361 		conn_index++;
362 	}
363 
364 	if (!found) {
365 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
366 		/* err msg */
367 		policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list",
368 			vdev_id);
369 		return QDF_STATUS_NOT_INITIALIZED;
370 	}
371 	if (pm_ctx->wma_cbacks.wma_get_connection_info) {
372 		status = pm_ctx->wma_cbacks.wma_get_connection_info(
373 				vdev_id, &conn_table_entry);
374 		if (QDF_STATUS_SUCCESS != status) {
375 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
376 			policy_mgr_err("can't find vdev_id %d in connection table",
377 			vdev_id);
378 			return status;
379 		}
380 	} else {
381 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
382 		policy_mgr_err("wma_get_connection_info is NULL");
383 		return QDF_STATUS_E_FAILURE;
384 	}
385 
386 	cur_freq = pm_conc_connection_list[conn_index].freq;
387 
388 	mode = policy_mgr_get_mode(conn_table_entry.type,
389 					conn_table_entry.sub_type);
390 	ch_freq = conn_table_entry.mhz;
391 	status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g);
392 	if (QDF_IS_STATUS_SUCCESS(status)) {
393 		if ((WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) && nss_2g > 1) ||
394 		    (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && nss_5g > 1))
395 			chain_mask = POLICY_MGR_TWO_TWO;
396 		else
397 			chain_mask = POLICY_MGR_ONE_ONE;
398 		nss = (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) ? nss_2g : nss_5g;
399 	} else {
400 		policy_mgr_err("Error in getting nss");
401 	}
402 
403 	policy_mgr_debug("update PM connection table for vdev:%d", vdev_id);
404 
405 	/* add the entry */
406 	policy_mgr_update_conc_list(
407 			psoc, conn_index, mode, ch_freq,
408 			policy_mgr_get_bw(conn_table_entry.chan_width),
409 			conn_table_entry.mac_id, chain_mask,
410 			nss, vdev_id, true, true, conn_table_entry.ch_flagext);
411 	policy_mgr_dump_current_concurrency(psoc);
412 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
413 
414 	/* do we need to change the HW mode */
415 	policy_mgr_check_n_start_opportunistic_timer(psoc);
416 
417 	if (policy_mgr_is_conc_sap_present_on_sta_freq(psoc, mode, cur_freq) &&
418 	    policy_mgr_update_indoor_concurrency(psoc, vdev_id, 0,
419 						 SWITCH_WITH_CONCURRENCY))
420 		wlan_reg_recompute_current_chan_list(psoc, pm_ctx->pdev);
421 	else if (policy_mgr_update_indoor_concurrency(psoc, vdev_id, cur_freq,
422 						SWITCH_WITHOUT_CONCURRENCY))
423 		wlan_reg_recompute_current_chan_list(psoc, pm_ctx->pdev);
424 	else if (wlan_reg_get_keep_6ghz_sta_cli_connection(pm_ctx->pdev))
425 		wlan_reg_recompute_current_chan_list(psoc, pm_ctx->pdev);
426 
427 	ml_nlink_conn_change_notify(
428 		psoc, vdev_id, ml_nlink_connection_updated_evt, NULL);
429 
430 	return QDF_STATUS_SUCCESS;
431 }
432 
433 QDF_STATUS policy_mgr_update_and_wait_for_connection_update(
434 		struct wlan_objmgr_psoc *psoc,
435 		uint8_t session_id,
436 		uint32_t ch_freq,
437 		enum policy_mgr_conn_update_reason reason)
438 {
439 	QDF_STATUS status;
440 
441 	policy_mgr_debug("session:%d ch_freq:%d reason:%d",
442 			 session_id, ch_freq, reason);
443 
444 	status = policy_mgr_reset_connection_update(psoc);
445 	if (QDF_IS_STATUS_ERROR(status))
446 		policy_mgr_err("clearing event failed");
447 
448 	status = policy_mgr_current_connections_update(
449 			psoc, session_id, ch_freq, reason,
450 			POLICY_MGR_DEF_REQ_ID);
451 	if (QDF_STATUS_E_FAILURE == status) {
452 		policy_mgr_err("connections update failed");
453 		return QDF_STATUS_E_FAILURE;
454 	}
455 
456 	/* Wait only when status is success */
457 	if (QDF_IS_STATUS_SUCCESS(status)) {
458 		status = policy_mgr_wait_for_connection_update(psoc);
459 		if (QDF_IS_STATUS_ERROR(status)) {
460 			policy_mgr_err("qdf wait for event failed");
461 			return QDF_STATUS_E_FAILURE;
462 		}
463 	}
464 
465 	return QDF_STATUS_SUCCESS;
466 }
467 
468 bool policy_mgr_is_dbs_allowed_for_concurrency(
469 		struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE new_conn_mode)
470 {
471 	struct policy_mgr_psoc_priv_obj *pm_ctx;
472 	uint32_t count, dbs_for_sta_sta, dbs_for_sta_p2p;
473 	bool ret = true;
474 	uint32_t ch_sel_plcy;
475 
476 	pm_ctx = policy_mgr_get_context(psoc);
477 	if (!pm_ctx) {
478 		policy_mgr_err("Invalid context");
479 		return ret;
480 	}
481 
482 	count = policy_mgr_get_connection_count(psoc);
483 
484 	if (count != 1 || new_conn_mode == QDF_MAX_NO_OF_MODE)
485 		return ret;
486 
487 	ch_sel_plcy = pm_ctx->cfg.chnl_select_plcy;
488 	dbs_for_sta_sta = PM_CHANNEL_SELECT_LOGIC_STA_STA_GET(ch_sel_plcy);
489 	dbs_for_sta_p2p = PM_CHANNEL_SELECT_LOGIC_STA_P2P_GET(ch_sel_plcy);
490 
491 	switch (pm_conc_connection_list[0].mode) {
492 	case PM_STA_MODE:
493 		switch (new_conn_mode) {
494 		case QDF_STA_MODE:
495 			if (!dbs_for_sta_sta)
496 				return false;
497 			break;
498 		case QDF_P2P_DEVICE_MODE:
499 		case QDF_P2P_CLIENT_MODE:
500 		case QDF_P2P_GO_MODE:
501 			if (!dbs_for_sta_p2p)
502 				return false;
503 			break;
504 		default:
505 			break;
506 		}
507 		break;
508 	case PM_P2P_CLIENT_MODE:
509 	case PM_P2P_GO_MODE:
510 		switch (new_conn_mode) {
511 		case QDF_STA_MODE:
512 			if (!dbs_for_sta_p2p)
513 				return false;
514 			break;
515 		default:
516 			break;
517 		}
518 		break;
519 	case PM_NAN_DISC_MODE:
520 		switch (new_conn_mode) {
521 		case QDF_STA_MODE:
522 		case QDF_SAP_MODE:
523 		case QDF_NDI_MODE:
524 			return true;
525 		default:
526 			return false;
527 		}
528 		break;
529 	default:
530 		break;
531 	}
532 
533 	return ret;
534 }
535 
536 bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc,
537 				     uint32_t ch_freq)
538 {
539 	uint8_t i;
540 	struct policy_mgr_psoc_priv_obj *pm_ctx;
541 
542 	pm_ctx = policy_mgr_get_context(psoc);
543 	if (!pm_ctx) {
544 		policy_mgr_err("Invalid Context");
545 		return false;
546 	}
547 
548 	/*
549 	 * check given channel freq against already existing connections'
550 	 * channel freqs. if they differ then channels are in different bands
551 	 */
552 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
553 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
554 		if (pm_conc_connection_list[i].in_use)
555 			if (!WLAN_REG_IS_SAME_BAND_FREQS(
556 			    ch_freq, pm_conc_connection_list[i].freq)) {
557 				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
558 				policy_mgr_debug("channel is in diff band");
559 				return true;
560 			}
561 	}
562 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
563 
564 	return false;
565 }
566 
567 bool policy_mgr_is_hwmode_set_for_given_chnl(struct wlan_objmgr_psoc *psoc,
568 					     uint32_t ch_freq)
569 {
570 	enum policy_mgr_band band;
571 	bool is_hwmode_dbs, dbs_required_for_2g;
572 
573 	if (policy_mgr_is_hwmode_offload_enabled(psoc)) {
574 		policy_mgr_debug("HW mode selection offload is enabled");
575 		return true;
576 	}
577 
578 	if (policy_mgr_is_hw_dbs_capable(psoc) == false)
579 		return true;
580 
581 	if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))
582 		band = POLICY_MGR_BAND_24;
583 	else
584 		band = POLICY_MGR_BAND_5;
585 
586 	is_hwmode_dbs = policy_mgr_is_current_hwmode_dbs(psoc);
587 	dbs_required_for_2g = policy_mgr_is_hw_dbs_required_for_band(
588 					psoc, HW_MODE_MAC_BAND_2G);
589 	/*
590 	 * If HW supports 2x2 chains in DBS HW mode and if DBS HW mode is not
591 	 * yet set then this is the right time to block the connection.
592 	 */
593 	if (band == POLICY_MGR_BAND_24 && dbs_required_for_2g &&
594 	    !is_hwmode_dbs) {
595 		policy_mgr_err("HW mode is not yet in DBS!!!!!");
596 		return false;
597 	}
598 
599 	return true;
600 }
601 
602 /**
603  * policy_mgr_pri_id_to_con_mode() - convert policy_mgr_pri_id to
604  * policy_mgr_con_mode
605  * @pri_id: policy_mgr_pri_id
606  *
607  * The help function converts policy_mgr_pri_id type to  policy_mgr_con_mode
608  * type.
609  *
610  * Return: policy_mgr_con_mode type.
611  */
612 static
613 enum policy_mgr_con_mode policy_mgr_pri_id_to_con_mode(
614 	enum policy_mgr_pri_id pri_id)
615 {
616 	switch (pri_id) {
617 	case PM_STA_PRI_ID:
618 		return PM_STA_MODE;
619 	case PM_SAP_PRI_ID:
620 		return PM_SAP_MODE;
621 	case PM_P2P_GO_PRI_ID:
622 		return PM_P2P_GO_MODE;
623 	case PM_P2P_CLI_PRI_ID:
624 		return PM_P2P_CLIENT_MODE;
625 	default:
626 		return PM_MAX_NUM_OF_MODE;
627 	}
628 }
629 
630 enum policy_mgr_conc_next_action
631 policy_mgr_get_preferred_dbs_action_table(
632 	struct wlan_objmgr_psoc *psoc,
633 	uint32_t vdev_id,
634 	uint32_t ch_freq,
635 	enum policy_mgr_conn_update_reason reason)
636 {
637 	struct policy_mgr_psoc_priv_obj *pm_ctx;
638 	enum policy_mgr_con_mode pri_conn_mode = PM_MAX_NUM_OF_MODE;
639 	enum policy_mgr_con_mode new_conn_mode = PM_MAX_NUM_OF_MODE;
640 	enum QDF_OPMODE new_conn_op_mode = QDF_MAX_NO_OF_MODE;
641 	bool band_pref_5g = true;
642 	bool vdev_priority_enabled = false;
643 	bool dbs_2x2_5g_1x1_2g_supported;
644 	bool dbs_2x2_2g_1x1_5g_supported;
645 	uint32_t vdev_pri_list, vdev_pri_id;
646 	uint32_t ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
647 	uint8_t vdev_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
648 	uint32_t vdev_count = 0;
649 	uint32_t i;
650 	bool found;
651 
652 	pm_ctx = policy_mgr_get_context(psoc);
653 	if (!pm_ctx) {
654 		policy_mgr_err("Invalid context");
655 		return PM_NOP;
656 	}
657 	dbs_2x2_5g_1x1_2g_supported =
658 		policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc);
659 	dbs_2x2_2g_1x1_5g_supported =
660 		policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc);
661 	policy_mgr_debug("target support DBS1 %d DBS2 %d",
662 			 dbs_2x2_5g_1x1_2g_supported,
663 			 dbs_2x2_2g_1x1_5g_supported);
664 	/*
665 	 * If both DBS1 and DBS2 not supported, this should be Legacy Single
666 	 * DBS mode HW. The policy_mgr_psoc_enable has setup the correct
667 	 * action tables.
668 	 */
669 	if (!dbs_2x2_5g_1x1_2g_supported && !dbs_2x2_2g_1x1_5g_supported)
670 		return PM_NOP;
671 	if (!dbs_2x2_5g_1x1_2g_supported) {
672 		band_pref_5g = false;
673 		policy_mgr_debug("target only supports DBS2!");
674 		goto DONE;
675 	}
676 	if (!dbs_2x2_2g_1x1_5g_supported) {
677 		policy_mgr_debug("target only supports DBS1!");
678 		goto DONE;
679 	}
680 	if (PM_GET_BAND_PREFERRED(pm_ctx->cfg.dbs_selection_plcy) == 1)
681 		band_pref_5g = false;
682 
683 	if (PM_GET_VDEV_PRIORITY_ENABLED(
684 	    pm_ctx->cfg.dbs_selection_plcy) == 1 &&
685 	    pm_ctx->cfg.vdev_priority_list)
686 		vdev_priority_enabled = true;
687 
688 	if (!vdev_priority_enabled)
689 		goto DONE;
690 
691 	if (vdev_id != INVALID_VDEV_ID && ch_freq) {
692 		if (pm_ctx->hdd_cbacks.hdd_get_device_mode)
693 			new_conn_op_mode = pm_ctx->hdd_cbacks.
694 					hdd_get_device_mode(vdev_id);
695 
696 		new_conn_mode =
697 			policy_mgr_qdf_opmode_to_pm_con_mode(psoc,
698 							     new_conn_op_mode,
699 							     vdev_id);
700 		if (new_conn_mode == PM_MAX_NUM_OF_MODE)
701 			policy_mgr_debug("new vdev %d op_mode %d freq %d reason %d: not prioritized",
702 					 vdev_id, new_conn_op_mode,
703 					 ch_freq, reason);
704 		else
705 			policy_mgr_debug("new vdev %d op_mode %d freq %d : reason %d",
706 					 vdev_id, new_conn_op_mode, ch_freq,
707 					 reason);
708 	}
709 	vdev_pri_list = pm_ctx->cfg.vdev_priority_list;
710 	while (vdev_pri_list) {
711 		vdev_pri_id = vdev_pri_list & 0xF;
712 		pri_conn_mode = policy_mgr_pri_id_to_con_mode(vdev_pri_id);
713 		if (pri_conn_mode == PM_MAX_NUM_OF_MODE) {
714 			policy_mgr_debug("vdev_pri_id %d prioritization not supported",
715 					 vdev_pri_id);
716 			goto NEXT;
717 		}
718 		vdev_count = policy_mgr_get_mode_specific_conn_info(
719 				psoc, ch_freq_list, vdev_list, pri_conn_mode);
720 		/**
721 		 * Take care of duplication case, the vdev id may
722 		 * exist in the conn list already with old chan.
723 		 * Replace with new chan before make decision.
724 		 */
725 		found = false;
726 		for (i = 0; i < vdev_count; i++) {
727 			policy_mgr_debug("[%d] vdev %d chan %d conn_mode %d",
728 					 i, vdev_list[i], ch_freq_list[i],
729 					 pri_conn_mode);
730 
731 			if (new_conn_mode == pri_conn_mode &&
732 			    vdev_list[i] == vdev_id) {
733 				ch_freq_list[i] = ch_freq;
734 				found = true;
735 			}
736 		}
737 		/**
738 		 * The new coming vdev should be added to the list to
739 		 * make decision if it is prioritized.
740 		 */
741 		if (!found && new_conn_mode == pri_conn_mode) {
742 			ch_freq_list[vdev_count] = ch_freq;
743 			vdev_list[vdev_count++] = vdev_id;
744 		}
745 		/**
746 		 * if more than one vdev has same priority, keep "band_pref_5g"
747 		 * value as default band preference setting.
748 		 */
749 		if (vdev_count > 1)
750 			break;
751 		/**
752 		 * select the only active vdev (or new coming vdev) chan as
753 		 * preferred band.
754 		 */
755 		if (vdev_count > 0) {
756 			band_pref_5g =
757 				WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq_list[0]);
758 			break;
759 		}
760 NEXT:
761 		vdev_pri_list >>= 4;
762 	}
763 DONE:
764 	policy_mgr_debug("band_pref_5g %d", band_pref_5g);
765 	if (band_pref_5g)
766 		return PM_DBS1;
767 	else
768 		return PM_DBS2;
769 }
770 
771 /**
772  * policy_mgr_get_second_conn_action_table() - get second conn action table
773  * @psoc: Pointer to psoc
774  * @vdev_id: vdev Id
775  * @ch_freq: channel frequency of vdev.
776  * @reason: reason of request
777  *
778  * Get the action table based on current HW Caps and INI user preference.
779  * This function will be called by policy_mgr_current_connections_update during
780  * DBS action decision.
781  *
782  * return : action table address
783  */
784 static policy_mgr_next_action_two_connection_table_type *
785 policy_mgr_get_second_conn_action_table(
786 	struct wlan_objmgr_psoc *psoc,
787 	uint32_t vdev_id,
788 	uint32_t ch_freq,
789 	enum policy_mgr_conn_update_reason reason)
790 {
791 	enum policy_mgr_conc_next_action preferred_action;
792 
793 	if (!policy_mgr_is_2x2_1x1_dbs_capable(psoc))
794 		return next_action_two_connection_table;
795 
796 	preferred_action = policy_mgr_get_preferred_dbs_action_table(
797 				psoc, vdev_id, ch_freq, reason);
798 	switch (preferred_action) {
799 	case PM_DBS2:
800 		return next_action_two_connection_2x2_2g_1x1_5g_table;
801 	default:
802 		return next_action_two_connection_table;
803 	}
804 }
805 
806 /**
807  * policy_mgr_get_third_conn_action_table() - get third connection action table
808  * @psoc: Pointer to psoc
809  * @vdev_id: vdev Id
810  * @ch_freq: channel frequency of vdev.
811  * @reason: reason of request
812  *
813  * Get the action table based on current HW Caps and INI user preference.
814  * This function will be called by policy_mgr_current_connections_update during
815  * DBS action decision.
816  *
817  * return : action table address
818  */
819 static policy_mgr_next_action_three_connection_table_type *
820 policy_mgr_get_third_conn_action_table(
821 	struct wlan_objmgr_psoc *psoc,
822 	uint32_t vdev_id,
823 	uint32_t ch_freq,
824 	enum policy_mgr_conn_update_reason reason)
825 {
826 	enum policy_mgr_conc_next_action preferred_action;
827 
828 	if (!policy_mgr_is_2x2_1x1_dbs_capable(psoc))
829 		return next_action_three_connection_table;
830 
831 	preferred_action = policy_mgr_get_preferred_dbs_action_table(
832 				psoc, vdev_id, ch_freq, reason);
833 	switch (preferred_action) {
834 	case PM_DBS2:
835 		return next_action_three_connection_2x2_2g_1x1_5g_table;
836 	default:
837 		return next_action_three_connection_table;
838 	}
839 }
840 
841 static QDF_STATUS
842 policy_mgr_get_next_action(struct wlan_objmgr_psoc *psoc,
843 			   uint32_t session_id,
844 			   uint32_t ch_freq,
845 			   enum policy_mgr_conn_update_reason reason,
846 			   enum policy_mgr_conc_next_action *next_action)
847 {
848 	uint32_t num_connections = 0;
849 	enum policy_mgr_one_connection_mode second_index = 0;
850 	enum policy_mgr_two_connection_mode third_index = 0;
851 	policy_mgr_next_action_two_connection_table_type *second_conn_table;
852 	policy_mgr_next_action_three_connection_table_type *third_conn_table;
853 	enum policy_mgr_band band;
854 	struct policy_mgr_psoc_priv_obj *pm_ctx;
855 	enum QDF_OPMODE new_conn_mode = QDF_MAX_NO_OF_MODE;
856 
857 	if (!next_action) {
858 		policy_mgr_err("next_action is NULL");
859 		return QDF_STATUS_E_FAILURE;
860 	}
861 
862 	if (policy_mgr_is_hwmode_offload_enabled(psoc)) {
863 		policy_mgr_debug("HW mode selection offload is enabled");
864 		*next_action = PM_NOP;
865 		return QDF_STATUS_SUCCESS;
866 	}
867 
868 	pm_ctx = policy_mgr_get_context(psoc);
869 	if (!pm_ctx) {
870 		policy_mgr_err("Invalid context");
871 		return QDF_STATUS_E_FAILURE;
872 	}
873 
874 	if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))
875 		band = POLICY_MGR_BAND_24;
876 	else
877 		band = POLICY_MGR_BAND_5;
878 
879 	num_connections = policy_mgr_get_connection_count(psoc);
880 
881 	policy_mgr_debug("num_connections=%d freq=%d",
882 			 num_connections, ch_freq);
883 
884 	switch (num_connections) {
885 	case 0:
886 		if (band == POLICY_MGR_BAND_24)
887 			if (policy_mgr_is_hw_dbs_required_for_band(
888 					psoc, HW_MODE_MAC_BAND_2G))
889 				*next_action = PM_DBS;
890 			else
891 				*next_action = PM_NOP;
892 		else
893 			*next_action = PM_NOP;
894 		break;
895 	case 1:
896 		second_index =
897 			policy_mgr_get_second_connection_pcl_table_index(psoc);
898 		if (PM_MAX_ONE_CONNECTION_MODE == second_index) {
899 			policy_mgr_err(
900 			"couldn't find index for 2nd connection next action table");
901 			return QDF_STATUS_E_FAILURE;
902 		}
903 		second_conn_table = policy_mgr_get_second_conn_action_table(
904 			psoc, session_id, ch_freq, reason);
905 		*next_action = (*second_conn_table)[second_index][band];
906 		break;
907 	case 2:
908 		third_index =
909 			policy_mgr_get_third_connection_pcl_table_index(psoc);
910 		if (PM_MAX_TWO_CONNECTION_MODE == third_index) {
911 			policy_mgr_err(
912 			"couldn't find index for 3rd connection next action table");
913 			return QDF_STATUS_E_FAILURE;
914 		}
915 		third_conn_table = policy_mgr_get_third_conn_action_table(
916 			psoc, session_id, ch_freq, reason);
917 		*next_action = (*third_conn_table)[third_index][band];
918 		break;
919 	default:
920 		policy_mgr_err("unexpected num_connections value %d",
921 			num_connections);
922 		break;
923 	}
924 
925 	/*
926 	 * There is no adapter associated with NAN Discovery, hence skip the
927 	 * HDD callback and fill separately.
928 	 */
929 	if (reason == POLICY_MGR_UPDATE_REASON_NAN_DISCOVERY)
930 		new_conn_mode = QDF_NAN_DISC_MODE;
931 	else if (pm_ctx->hdd_cbacks.hdd_get_device_mode)
932 		new_conn_mode = pm_ctx->hdd_cbacks.
933 					hdd_get_device_mode(session_id);
934 
935 	/*
936 	 * Based on channel_select_logic_conc ini, hw mode is set
937 	 * when second connection is about to come up that results
938 	 * in STA+STA and STA+P2P concurrency.
939 	 * 1) If MCC is set and if current hw mode is dbs, hw mode
940 	 *  should be set to single mac for above concurrency.
941 	 * 2) If MCC is set and if current hw mode is not dbs, hw
942 	 *  mode change is not required.
943 	 */
944 	if (policy_mgr_is_current_hwmode_dbs(psoc) &&
945 		!policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode))
946 		*next_action = PM_SINGLE_MAC;
947 	else if (!policy_mgr_is_current_hwmode_dbs(psoc) &&
948 		!policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode))
949 		*next_action = PM_NOP;
950 
951 	policy_mgr_debug("idx2=%d idx3=%d next_action=%d, band=%d reason=%d session_id=%d",
952 			 second_index, third_index, *next_action, band,
953 			 reason, session_id);
954 
955 	return QDF_STATUS_SUCCESS;
956 }
957 
958 static bool
959 policy_mgr_is_hw_mode_change_required(struct wlan_objmgr_psoc *psoc,
960 				      uint32_t ch_freq, uint8_t vdev_id)
961 {
962 	if (policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G)) {
963 		if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))
964 			return true;
965 	} else {
966 		if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) &&
967 		    policy_mgr_is_any_mode_active_on_band_along_with_session
968 			(psoc, vdev_id, POLICY_MGR_BAND_5))
969 			return true;
970 
971 		if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) &&
972 		    policy_mgr_is_any_mode_active_on_band_along_with_session
973 			(psoc, vdev_id, POLICY_MGR_BAND_24))
974 			return true;
975 	}
976 
977 	return false;
978 }
979 
980 static uint32_t
981 policy_mgr_check_for_hw_mode_change(struct wlan_objmgr_psoc *psoc,
982 				    qdf_list_t *scan_list, uint8_t vdev_id)
983 {
984 
985 	struct scan_cache_node *scan_node = NULL;
986 	qdf_list_node_t *cur_node = NULL, *next_node = NULL;
987 	uint32_t ch_freq = 0;
988 	struct scan_cache_entry *entry;
989 
990 	if (policy_mgr_is_hwmode_offload_enabled(psoc)) {
991 		policy_mgr_debug("HW mode selection offload is enabled");
992 		goto end;
993 	}
994 
995 	if (!scan_list || !qdf_list_size(scan_list)) {
996 		policy_mgr_debug("Scan list is NULL or No BSSIDs present");
997 		goto end;
998 	}
999 
1000 	if (!policy_mgr_is_hw_dbs_capable(psoc)) {
1001 		policy_mgr_debug("Driver isn't DBS capable");
1002 		goto end;
1003 	}
1004 
1005 	if (!policy_mgr_is_dbs_allowed_for_concurrency(psoc, QDF_STA_MODE)) {
1006 		policy_mgr_debug("DBS not allowed for concurrency combo");
1007 		goto end;
1008 	}
1009 
1010 	if (!policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
1011 	    !policy_mgr_is_hw_dbs_required_for_band(psoc,
1012 						    HW_MODE_MAC_BAND_2G) &&
1013 	    !policy_mgr_get_connection_count(psoc)) {
1014 		policy_mgr_debug("1x1 DBS with no existing connection, HW mode change not required");
1015 		goto end;
1016 	}
1017 
1018 	qdf_list_peek_front(scan_list, &cur_node);
1019 
1020 	while (cur_node) {
1021 		qdf_list_peek_next(scan_list, cur_node, &next_node);
1022 
1023 		scan_node = qdf_container_of(cur_node, struct scan_cache_node,
1024 					     node);
1025 		entry = scan_node->entry;
1026 		ch_freq = entry->channel.chan_freq;
1027 
1028 		if (policy_mgr_is_hw_mode_change_required(psoc, ch_freq,
1029 							  vdev_id)) {
1030 			policy_mgr_debug("Scan list has BSS of freq %d hw mode required",
1031 					 ch_freq);
1032 			break;
1033 		}
1034 
1035 		ch_freq = 0;
1036 		cur_node = next_node;
1037 		next_node = NULL;
1038 	}
1039 
1040 end:
1041 	return ch_freq;
1042 }
1043 
1044 QDF_STATUS
1045 policy_mgr_change_hw_mode_sta_connect(struct wlan_objmgr_psoc *psoc,
1046 				      qdf_list_t *scan_list, uint8_t vdev_id,
1047 				      uint32_t connect_id)
1048 {
1049 	QDF_STATUS status;
1050 	uint32_t ch_freq;
1051 
1052 	ch_freq = policy_mgr_check_for_hw_mode_change(psoc, scan_list, vdev_id);
1053 
1054 	if (!ch_freq)
1055 		return QDF_STATUS_E_ALREADY;
1056 
1057 	status = policy_mgr_current_connections_update(psoc, vdev_id, ch_freq,
1058 			POLICY_MGR_UPDATE_REASON_STA_CONNECT, connect_id);
1059 
1060 	/*
1061 	 * If status is success then the callback of policy mgr hw mode change
1062 	 * would be called.
1063 	 * If status is no support then the DUT is already in required HW mode.
1064 	 */
1065 
1066 	if (status == QDF_STATUS_E_FAILURE)
1067 		policy_mgr_err("Hw mode change failed");
1068 	else if (status == QDF_STATUS_E_NOSUPPORT)
1069 		status = QDF_STATUS_E_ALREADY;
1070 
1071 	return status;
1072 }
1073 
1074 QDF_STATUS
1075 policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc,
1076 				      uint32_t session_id, uint32_t ch_freq,
1077 				      enum policy_mgr_conn_update_reason
1078 				      reason, uint32_t request_id)
1079 {
1080 	enum policy_mgr_conc_next_action next_action = PM_NOP;
1081 	QDF_STATUS status;
1082 
1083 	if (!policy_mgr_is_hw_dbs_capable(psoc)) {
1084 		policy_mgr_rl_debug("driver isn't dbs capable, no further action needed");
1085 		return QDF_STATUS_E_NOSUPPORT;
1086 	}
1087 
1088 	status = policy_mgr_get_next_action(psoc, session_id, ch_freq, reason,
1089 					    &next_action);
1090 	if (QDF_IS_STATUS_ERROR(status))
1091 		return status;
1092 
1093 	if (PM_NOP != next_action)
1094 		status = policy_mgr_next_actions(psoc, session_id,
1095 						next_action, reason,
1096 						request_id);
1097 	else
1098 		status = QDF_STATUS_E_NOSUPPORT;
1099 
1100 	policy_mgr_debug("next_action %d reason=%d session_id=%d request_id %x",
1101 			 next_action, reason, session_id, request_id);
1102 
1103 	return status;
1104 }
1105 
1106 /**
1107  * policy_mgr_dbs1_dbs2_need_action() - whether more actions are needed
1108  *                                      in DBS1 and DBS2 hw mode
1109  * @psoc: psoc object
1110  * @action: action type
1111  * @hw_mode: hardware mode
1112  *
1113  * The function checks further action are needed or not for DBS1 and DBS2.
1114  *
1115  * Return: true if more action are needed, otherwise
1116  *         return false
1117  */
1118 static bool
1119 policy_mgr_dbs1_dbs2_need_action(struct wlan_objmgr_psoc *psoc,
1120 				 enum policy_mgr_conc_next_action action,
1121 				 struct policy_mgr_hw_mode_params *hw_mode)
1122 {
1123 	if (policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc) ||
1124 	    policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc)) {
1125 		policy_mgr_debug("curr dbs action %d new action %d",
1126 				 hw_mode->action_type, action);
1127 		if (hw_mode->action_type == PM_DBS1 &&
1128 		    ((action == PM_DBS1 ||
1129 		    action == PM_DBS1_DOWNGRADE))) {
1130 			policy_mgr_debug("driver is already in DBS_5G_2x2_24G_1x1 (%d), no further action %d needed",
1131 					 hw_mode->action_type, action);
1132 			return false;
1133 		} else if (hw_mode->action_type == PM_DBS2 &&
1134 			   ((action == PM_DBS2 ||
1135 			   action == PM_DBS2_DOWNGRADE))) {
1136 			policy_mgr_debug("driver is already in DBS_24G_2x2_5G_1x1 (%d), no further action %d needed",
1137 					 hw_mode->action_type, action);
1138 			return false;
1139 		}
1140 	}
1141 
1142 	return true;
1143 }
1144 
1145 QDF_STATUS
1146 policy_mgr_validate_dbs_switch(struct wlan_objmgr_psoc *psoc,
1147 			       enum policy_mgr_conc_next_action action)
1148 {
1149 	QDF_STATUS status;
1150 	struct policy_mgr_hw_mode_params hw_mode;
1151 
1152 	/* check for the current HW index to see if really need any action */
1153 	status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
1154 	if (!QDF_IS_STATUS_SUCCESS(status)) {
1155 		policy_mgr_err("policy_mgr_get_current_hw_mode failed");
1156 		return status;
1157 	}
1158 
1159 	if ((action == PM_SBS) || (action == PM_SBS_DOWNGRADE)) {
1160 		if (!policy_mgr_is_hw_sbs_capable(psoc)) {
1161 			/* No action */
1162 			policy_mgr_notice("firmware is not sbs capable");
1163 			return QDF_STATUS_E_NOSUPPORT;
1164 		}
1165 		/* current mode is already SBS nothing to be
1166 		 * done
1167 		 */
1168 		if (hw_mode.sbs_cap) {
1169 			policy_mgr_notice("current mode is already SBS");
1170 			return QDF_STATUS_E_ALREADY;
1171 		}
1172 		return QDF_STATUS_SUCCESS;
1173 	}
1174 
1175 	if (!hw_mode.dbs_cap) {
1176 		if (action == PM_SINGLE_MAC ||
1177 		    action == PM_SINGLE_MAC_UPGRADE) {
1178 			policy_mgr_notice("current mode is already single MAC");
1179 			return QDF_STATUS_E_ALREADY;
1180 		} else {
1181 			return QDF_STATUS_SUCCESS;
1182 		}
1183 	}
1184 	/**
1185 	 * If already in DBS, no need to request DBS again (HL, Napier).
1186 	 * For dual DBS HW, in case DBS1 -> DBS2 or DBS2 -> DBS1
1187 	 * switching, we need to check the current DBS mode is same as
1188 	 * requested or not.
1189 	 */
1190 	if (policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc) ||
1191 	    policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc)) {
1192 		if (!policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode))
1193 			return QDF_STATUS_E_ALREADY;
1194 	} else if ((action == PM_DBS_DOWNGRADE) || (action == PM_DBS) ||
1195 		   (action == PM_DBS_UPGRADE)) {
1196 		policy_mgr_debug("driver is already in %s mode, no further action needed",
1197 				 (hw_mode.dbs_cap) ? "dbs" : "non dbs");
1198 		return QDF_STATUS_E_ALREADY;
1199 	}
1200 	return QDF_STATUS_SUCCESS;
1201 }
1202 
1203 /**
1204  * policy_mgr_validate_unsupported_action() - unsupported action validation
1205  * @psoc: psoc object
1206  * @action: action type
1207  *
1208  * The help function checks the Action supported by HW or not.
1209  *
1210  * Return: QDF_STATUS_SUCCESS if supported by HW, otherwise
1211  *         return QDF_STATUS_E_NOSUPPORT
1212  */
1213 static QDF_STATUS policy_mgr_validate_unsupported_action
1214 		(struct wlan_objmgr_psoc *psoc,
1215 		 enum policy_mgr_conc_next_action action)
1216 {
1217 	if (action == PM_SBS || action == PM_SBS_DOWNGRADE) {
1218 		if (!policy_mgr_is_hw_sbs_capable(psoc)) {
1219 			/* No action */
1220 			policy_mgr_notice("firmware is not sbs capable");
1221 			return QDF_STATUS_E_NOSUPPORT;
1222 		}
1223 	}
1224 
1225 	return QDF_STATUS_SUCCESS;
1226 }
1227 
1228 QDF_STATUS policy_mgr_next_actions(
1229 		struct wlan_objmgr_psoc *psoc,
1230 		uint32_t session_id,
1231 		enum policy_mgr_conc_next_action action,
1232 		enum policy_mgr_conn_update_reason reason,
1233 		uint32_t request_id)
1234 {
1235 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1236 	struct dbs_nss nss_dbs = {0};
1237 	struct dbs_bw bw_dbs = {0};
1238 	struct policy_mgr_hw_mode_params hw_mode;
1239 	enum policy_mgr_conc_next_action next_action;
1240 	bool is_sbs_supported;
1241 	enum hw_mode_sbs_capab sbs_capab;
1242 
1243 	if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
1244 		policy_mgr_rl_debug("driver isn't dbs capable, no further action needed");
1245 		return QDF_STATUS_E_NOSUPPORT;
1246 	}
1247 	status = policy_mgr_validate_unsupported_action(psoc, action);
1248 	if (!QDF_IS_STATUS_SUCCESS(status))
1249 		return status;
1250 	/* check for the current HW index to see if really need any action */
1251 	status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
1252 	if (!QDF_IS_STATUS_SUCCESS(status)) {
1253 		policy_mgr_err("policy_mgr_get_current_hw_mode failed");
1254 		return status;
1255 	}
1256 
1257 	switch (action) {
1258 	case PM_DBS_DOWNGRADE:
1259 		/*
1260 		* check if we have a beaconing entity that is using 2x2. If yes,
1261 		* update the beacon template & notify FW. Once FW confirms
1262 		*  beacon updated, send down the HW mode change req
1263 		*/
1264 		status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
1265 					PM_DBS, reason, session_id, request_id);
1266 		break;
1267 	case PM_DBS:
1268 		(void)policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs);
1269 		policy_mgr_get_hw_dbs_max_bw(psoc, &bw_dbs);
1270 		is_sbs_supported = policy_mgr_is_hw_sbs_capable(psoc);
1271 		sbs_capab = is_sbs_supported ? HW_MODE_SBS : HW_MODE_SBS_NONE;
1272 		status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1273 						     nss_dbs.mac0_ss,
1274 						     bw_dbs.mac0_bw,
1275 						     nss_dbs.mac1_ss,
1276 						     bw_dbs.mac1_bw,
1277 						     HW_MODE_MAC_BAND_NONE,
1278 						     HW_MODE_DBS,
1279 						     HW_MODE_AGILE_DFS_NONE,
1280 						     sbs_capab,
1281 						     reason, PM_NOP, PM_DBS,
1282 						     request_id);
1283 		break;
1284 	case PM_SINGLE_MAC_UPGRADE:
1285 		/*
1286 		 * change the HW mode first before the NSS upgrade
1287 		 */
1288 		status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1289 						HW_MODE_SS_2x2,
1290 						HW_MODE_80_MHZ,
1291 						HW_MODE_SS_0x0, HW_MODE_BW_NONE,
1292 						HW_MODE_MAC_BAND_NONE,
1293 						HW_MODE_DBS_NONE,
1294 						HW_MODE_AGILE_DFS_NONE,
1295 						HW_MODE_SBS_NONE,
1296 						reason, PM_UPGRADE,
1297 						PM_SINGLE_MAC_UPGRADE,
1298 						request_id);
1299 		break;
1300 	case PM_SINGLE_MAC:
1301 		status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1302 						HW_MODE_SS_2x2,
1303 						HW_MODE_80_MHZ,
1304 						HW_MODE_SS_0x0, HW_MODE_BW_NONE,
1305 						HW_MODE_MAC_BAND_NONE,
1306 						HW_MODE_DBS_NONE,
1307 						HW_MODE_AGILE_DFS_NONE,
1308 						HW_MODE_SBS_NONE,
1309 						reason, PM_NOP, PM_SINGLE_MAC,
1310 						request_id);
1311 		break;
1312 	case PM_DBS_UPGRADE:
1313 		status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1314 						HW_MODE_SS_2x2,
1315 						HW_MODE_80_MHZ,
1316 						HW_MODE_SS_2x2, HW_MODE_80_MHZ,
1317 						HW_MODE_MAC_BAND_NONE,
1318 						HW_MODE_DBS,
1319 						HW_MODE_AGILE_DFS_NONE,
1320 						HW_MODE_SBS_NONE,
1321 						reason, PM_UPGRADE,
1322 						PM_DBS_UPGRADE, request_id);
1323 		break;
1324 	case PM_SBS_DOWNGRADE:
1325 		status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
1326 					PM_SBS, reason, session_id, request_id);
1327 		break;
1328 	case PM_SBS:
1329 		status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1330 						HW_MODE_SS_1x1,
1331 						HW_MODE_80_MHZ,
1332 						HW_MODE_SS_1x1, HW_MODE_80_MHZ,
1333 						HW_MODE_MAC_BAND_NONE,
1334 						HW_MODE_DBS,
1335 						HW_MODE_AGILE_DFS_NONE,
1336 						HW_MODE_SBS,
1337 						reason, PM_NOP, PM_SBS,
1338 						request_id);
1339 		break;
1340 	case PM_DOWNGRADE:
1341 		/*
1342 		 * check if we have a beaconing entity that advertised 2x2
1343 		 * initially. If yes, update the beacon template & notify FW.
1344 		 */
1345 		status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_1,
1346 					PM_NOP, POLICY_MGR_ANY, reason,
1347 					session_id, request_id);
1348 		break;
1349 	case PM_UPGRADE:
1350 		/*
1351 		 * check if we have a beaconing entity that advertised 2x2
1352 		 * initially. If yes, update the beacon template & notify FW.
1353 		 */
1354 		status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_2,
1355 					PM_NOP, POLICY_MGR_ANY, reason,
1356 					session_id, request_id);
1357 		break;
1358 	case PM_DBS1_DOWNGRADE:
1359 		if (policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode))
1360 			status = policy_mgr_complete_action(psoc,
1361 							    POLICY_MGR_RX_NSS_1,
1362 							    PM_DBS1, reason,
1363 							    session_id,
1364 							    request_id);
1365 		else
1366 			status = QDF_STATUS_E_ALREADY;
1367 		break;
1368 	case PM_DBS2_DOWNGRADE:
1369 		if (policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode))
1370 			status = policy_mgr_complete_action(psoc,
1371 							    POLICY_MGR_RX_NSS_1,
1372 							    PM_DBS2, reason,
1373 							    session_id,
1374 							    request_id);
1375 		else
1376 			status = QDF_STATUS_E_ALREADY;
1377 		break;
1378 	case PM_DBS1:
1379 		/*
1380 		 * PM_DBS1 (2x2 5G + 1x1 2G) will support 5G 2x2. If previous
1381 		 * mode is DBS, that should be 2x2 2G + 1x1 5G mode and
1382 		 * the 5G band was downgraded to 1x1. So, we need to
1383 		 * upgrade 5G vdevs after hw mode change.
1384 		 */
1385 		if (policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode)) {
1386 			if (hw_mode.dbs_cap)
1387 				next_action = PM_UPGRADE_5G;
1388 			else
1389 				next_action = PM_NOP;
1390 			status = policy_mgr_pdev_set_hw_mode(
1391 					psoc, session_id,
1392 					HW_MODE_SS_2x2,
1393 					HW_MODE_80_MHZ,
1394 					HW_MODE_SS_1x1, HW_MODE_40_MHZ,
1395 					HW_MODE_MAC_BAND_5G,
1396 					HW_MODE_DBS,
1397 					HW_MODE_AGILE_DFS_NONE,
1398 					HW_MODE_SBS_NONE,
1399 					reason, next_action, PM_DBS1,
1400 					request_id);
1401 		} else {
1402 			status = QDF_STATUS_E_ALREADY;
1403 		}
1404 		break;
1405 	case PM_DBS2:
1406 		/*
1407 		 * PM_DBS2 (2x2 2G + 1x1 5G) will support 2G 2x2. If previous
1408 		 * mode is DBS, that should be 2x2 5G + 1x1 2G mode and
1409 		 * the 2G band was downgraded to 1x1. So, we need to
1410 		 * upgrade 5G vdevs after hw mode change.
1411 		 */
1412 		if (policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode)) {
1413 			if (hw_mode.dbs_cap)
1414 				next_action = PM_UPGRADE_2G;
1415 			else
1416 				next_action = PM_NOP;
1417 			status = policy_mgr_pdev_set_hw_mode(
1418 						psoc, session_id,
1419 						HW_MODE_SS_2x2,
1420 						HW_MODE_40_MHZ,
1421 						HW_MODE_SS_1x1, HW_MODE_40_MHZ,
1422 						HW_MODE_MAC_BAND_2G,
1423 						HW_MODE_DBS,
1424 						HW_MODE_AGILE_DFS_NONE,
1425 						HW_MODE_SBS_NONE,
1426 						reason, next_action, PM_DBS2,
1427 						request_id);
1428 		} else {
1429 			status = QDF_STATUS_E_ALREADY;
1430 		}
1431 		break;
1432 	case PM_UPGRADE_5G:
1433 		status = policy_mgr_nss_update(
1434 					psoc, POLICY_MGR_RX_NSS_2,
1435 					PM_NOP, POLICY_MGR_BAND_5, reason,
1436 					session_id, request_id);
1437 		break;
1438 	case PM_UPGRADE_2G:
1439 		status = policy_mgr_nss_update(
1440 					psoc, POLICY_MGR_RX_NSS_2,
1441 					PM_NOP, POLICY_MGR_BAND_24, reason,
1442 					session_id, request_id);
1443 		break;
1444 	default:
1445 		policy_mgr_err("unexpected action value %d", action);
1446 		status = QDF_STATUS_E_FAILURE;
1447 		break;
1448 	}
1449 
1450 	return status;
1451 }
1452 
1453 QDF_STATUS
1454 policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc,
1455 				 uint8_t vdev_id, uint32_t ch_freq,
1456 				 enum policy_mgr_conn_update_reason reason,
1457 				 uint32_t request_id)
1458 {
1459 	QDF_STATUS status;
1460 	uint8_t num_cxn_del = 0;
1461 	struct policy_mgr_conc_connection_info info = {0};
1462 
1463 	policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id,
1464 						      &info, &num_cxn_del);
1465 
1466 	if (!policy_mgr_check_for_session_conc(psoc, vdev_id, ch_freq)) {
1467 		policy_mgr_err("Conc not allowed for the vdev %d", vdev_id);
1468 		return QDF_STATUS_E_FAILURE;
1469 	}
1470 
1471 	status = policy_mgr_reset_connection_update(psoc);
1472 	if (!QDF_IS_STATUS_SUCCESS(status))
1473 		policy_mgr_err("clearing event failed");
1474 
1475 	status = policy_mgr_current_connections_update(psoc, vdev_id,
1476 						       ch_freq, reason,
1477 						       request_id);
1478 	if (QDF_STATUS_E_FAILURE == status)
1479 		policy_mgr_err("connections update failed");
1480 
1481 	if (num_cxn_del > 0)
1482 		policy_mgr_restore_deleted_conn_info(psoc, &info,
1483 						     num_cxn_del);
1484 
1485 	return status;
1486 }
1487 
1488 enum policy_mgr_con_mode
1489 policy_mgr_con_mode_by_vdev_id(struct wlan_objmgr_psoc *psoc,
1490 			       uint8_t vdev_id)
1491 {
1492 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1493 	enum policy_mgr_con_mode mode = PM_MAX_NUM_OF_MODE;
1494 	enum QDF_OPMODE op_mode;
1495 
1496 	pm_ctx = policy_mgr_get_context(psoc);
1497 	if (!pm_ctx) {
1498 		policy_mgr_err("Invalid Context");
1499 		return mode;
1500 	}
1501 
1502 	op_mode = wlan_get_opmode_vdev_id(pm_ctx->pdev, vdev_id);
1503 	return policy_mgr_qdf_opmode_to_pm_con_mode(psoc, op_mode, vdev_id);
1504 }
1505 
1506 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
1507 qdf_freq_t
1508 policy_mgr_get_user_config_sap_freq(struct wlan_objmgr_psoc *psoc,
1509 				    uint8_t vdev_id)
1510 {
1511 	struct wlan_objmgr_vdev *vdev;
1512 	qdf_freq_t freq;
1513 
1514 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
1515 						    WLAN_POLICY_MGR_ID);
1516 	if (!vdev) {
1517 		policy_mgr_err("vdev is NULL");
1518 		return 0;
1519 	}
1520 	freq = wlan_get_sap_user_config_freq(vdev);
1521 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
1522 
1523 	return freq;
1524 }
1525 
1526 /**
1527  * policy_mgr_is_sap_go_existed() - Check if restart SAP/Go exist
1528  * @psoc: PSOC object data
1529  *
1530  * To simplify, if SAP/P2P Go exist, they may need switch channel for
1531  * forcing scc with sta or band capability change.
1532  * Restart: true or false
1533  */
1534 static bool policy_mgr_is_sap_go_existed(struct wlan_objmgr_psoc *psoc)
1535 {
1536 	uint32_t ap_present, go_present;
1537 
1538 	ap_present = policy_mgr_mode_specific_connection_count(
1539 				psoc, PM_SAP_MODE, NULL);
1540 	if (ap_present)
1541 		return true;
1542 
1543 	go_present = policy_mgr_mode_specific_connection_count(
1544 				psoc, PM_P2P_GO_MODE, NULL);
1545 	if (go_present)
1546 		return true;
1547 
1548 	return false;
1549 }
1550 
1551 #ifdef FEATURE_WLAN_CH_AVOID_EXT
1552 bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc,
1553 				uint32_t ch_freq)
1554 {
1555 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1556 	bool is_safe = true;
1557 	uint8_t j;
1558 	unsigned long restriction_mask;
1559 
1560 	pm_ctx = policy_mgr_get_context(psoc);
1561 	if (!pm_ctx) {
1562 		policy_mgr_err("Invalid context");
1563 		return is_safe;
1564 	}
1565 
1566 	if (pm_ctx->unsafe_channel_count == 0)
1567 		return is_safe;
1568 
1569 	restriction_mask =
1570 		(unsigned long)policy_mgr_get_freq_restriction_mask(pm_ctx);
1571 	for (j = 0; j < pm_ctx->unsafe_channel_count; j++) {
1572 		if ((ch_freq == pm_ctx->unsafe_channel_list[j]) &&
1573 		    (qdf_test_bit(QDF_SAP_MODE, &restriction_mask) ||
1574 		     !wlan_mlme_get_coex_unsafe_chan_nb_user_prefer(psoc))) {
1575 			is_safe = false;
1576 			policy_mgr_warn("Freq %d is not safe, restriction mask %lu", ch_freq, restriction_mask);
1577 			break;
1578 		}
1579 	}
1580 
1581 	return is_safe;
1582 }
1583 
1584 bool policy_mgr_restrict_sap_on_unsafe_chan(struct wlan_objmgr_psoc *psoc)
1585 {
1586 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1587 	unsigned long restriction_mask;
1588 
1589 	pm_ctx = policy_mgr_get_context(psoc);
1590 	if (!pm_ctx) {
1591 		policy_mgr_err("Invalid context");
1592 		return false;
1593 	}
1594 
1595 	restriction_mask =
1596 		(unsigned long)policy_mgr_get_freq_restriction_mask(pm_ctx);
1597 	return qdf_test_bit(QDF_SAP_MODE, &restriction_mask);
1598 }
1599 #else
1600 bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc,
1601 				uint32_t ch_freq)
1602 {
1603 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1604 	bool is_safe = true;
1605 	uint8_t j;
1606 
1607 	pm_ctx = policy_mgr_get_context(psoc);
1608 	if (!pm_ctx) {
1609 		policy_mgr_err("Invalid context");
1610 		return is_safe;
1611 	}
1612 
1613 	if (pm_ctx->unsafe_channel_count == 0)
1614 		return is_safe;
1615 
1616 	for (j = 0; j < pm_ctx->unsafe_channel_count; j++) {
1617 		if (ch_freq == pm_ctx->unsafe_channel_list[j]) {
1618 			is_safe = false;
1619 			policy_mgr_warn("Freq %d is not safe", ch_freq);
1620 			break;
1621 		}
1622 	}
1623 
1624 	return is_safe;
1625 }
1626 #endif
1627 
1628 bool policy_mgr_is_sap_freq_allowed(struct wlan_objmgr_psoc *psoc,
1629 				    uint32_t sap_freq)
1630 {
1631 	uint32_t nan_2g_freq, nan_5g_freq;
1632 
1633 	if (policy_mgr_is_safe_channel(psoc, sap_freq))
1634 		return true;
1635 
1636 	/*
1637 	 * Return true if it's STA+SAP SCC and
1638 	 * STA+SAP SCC on LTE coex channel is allowed.
1639 	 */
1640 	if (policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) &&
1641 	    policy_mgr_is_sta_sap_scc(psoc, sap_freq)) {
1642 		policy_mgr_debug("unsafe freq %d for sap is allowed", sap_freq);
1643 		return true;
1644 	}
1645 
1646 	nan_2g_freq =
1647 		policy_mgr_mode_specific_get_channel(psoc, PM_NAN_DISC_MODE);
1648 	nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(psoc);
1649 
1650 	if ((WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, sap_freq) ||
1651 	     WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, sap_freq)) &&
1652 	    policy_mgr_is_force_scc(psoc) &&
1653 	    policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(psoc)) {
1654 		policy_mgr_debug("NAN+SAP SCC on unsafe freq %d is allowed",
1655 				  sap_freq);
1656 		return true;
1657 	}
1658 
1659 	return false;
1660 }
1661 
1662 bool policy_mgr_is_sap_restart_required_after_sta_disconnect(
1663 			struct wlan_objmgr_psoc *psoc,
1664 			uint32_t sap_vdev_id, uint32_t *intf_ch_freq,
1665 			bool is_acs_mode)
1666 {
1667 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1668 	uint32_t curr_sap_freq = 0, new_sap_freq = 0;
1669 	bool sta_sap_scc_on_dfs_chan =
1670 		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
1671 	bool sta_sap_scc_on_lte_coex_chan =
1672 		policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc);
1673 	uint8_t sta_sap_scc_on_dfs_chnl_config_value = 0;
1674 	uint32_t cc_count, i, go_index_start, pcl_len = 0;
1675 	uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS * 2];
1676 	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS * 2];
1677 	enum policy_mgr_con_mode mode;
1678 	uint32_t pcl_channels[NUM_CHANNELS + 1];
1679 	uint8_t pcl_weight[NUM_CHANNELS + 1];
1680 	struct policy_mgr_conc_connection_info info = {0};
1681 	uint8_t num_cxn_del = 0;
1682 	QDF_STATUS status;
1683 	uint32_t sta_gc_present = 0;
1684 	qdf_freq_t user_config_freq = 0;
1685 	tQDF_MCC_TO_SCC_SWITCH_MODE cc_mode =
1686 				policy_mgr_get_mcc_to_scc_switch_mode(psoc);
1687 
1688 	if (intf_ch_freq)
1689 		*intf_ch_freq = 0;
1690 
1691 	pm_ctx = policy_mgr_get_context(psoc);
1692 	if (!pm_ctx) {
1693 		policy_mgr_err("Invalid pm context");
1694 		return false;
1695 	}
1696 
1697 	policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc, &sta_sap_scc_on_dfs_chnl_config_value);
1698 
1699 	if (!policy_mgr_is_hw_dbs_capable(psoc))
1700 		if (policy_mgr_get_connection_count(psoc) > 1)
1701 			return false;
1702 
1703 	cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
1704 							  &op_ch_freq_list[0],
1705 							  &vdev_id[0],
1706 							  PM_SAP_MODE);
1707 	go_index_start = cc_count;
1708 	if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS)
1709 		cc_count += policy_mgr_get_mode_specific_conn_info(
1710 					psoc, &op_ch_freq_list[cc_count],
1711 					&vdev_id[cc_count], PM_P2P_GO_MODE);
1712 
1713 	sta_gc_present =
1714 		policy_mgr_mode_specific_connection_count(psoc,
1715 							  PM_STA_MODE, NULL) +
1716 		policy_mgr_mode_specific_connection_count(psoc,
1717 							  PM_P2P_CLIENT_MODE,
1718 							  NULL);
1719 
1720 	for (i = 0 ; i < cc_count; i++) {
1721 		if (sap_vdev_id != INVALID_VDEV_ID &&
1722 		    sap_vdev_id != vdev_id[i])
1723 			continue;
1724 
1725 		sap_vdev_id = vdev_id[i];
1726 		user_config_freq =
1727 			policy_mgr_get_user_config_sap_freq(psoc, sap_vdev_id);
1728 
1729 		if (policy_mgr_is_any_mode_active_on_band_along_with_session(
1730 				psoc,  vdev_id[i],
1731 				WLAN_REG_IS_24GHZ_CH_FREQ(op_ch_freq_list[i]) ?
1732 				POLICY_MGR_BAND_24 : POLICY_MGR_BAND_5))
1733 			continue;
1734 
1735 		if (sta_sap_scc_on_dfs_chan &&
1736 		    (sta_sap_scc_on_dfs_chnl_config_value != 2) &&
1737 		     wlan_reg_is_dfs_for_freq(pm_ctx->pdev,
1738 					      op_ch_freq_list[i]) &&
1739 		     pm_ctx->last_disconn_sta_freq == op_ch_freq_list[i]) {
1740 			curr_sap_freq = op_ch_freq_list[i];
1741 			policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sta_sap_scc_on_dfs_chnl_config_value %u, dfs sap_ch_freq %u",
1742 					 sta_sap_scc_on_dfs_chan,
1743 					 sta_sap_scc_on_dfs_chnl_config_value,
1744 					 curr_sap_freq);
1745 			break;
1746 		}
1747 
1748 		if ((is_acs_mode ||
1749 		     policy_mgr_restrict_sap_on_unsafe_chan(psoc)) &&
1750 		    sta_sap_scc_on_lte_coex_chan &&
1751 		    !policy_mgr_is_safe_channel(psoc, op_ch_freq_list[i]) &&
1752 		    pm_ctx->last_disconn_sta_freq == op_ch_freq_list[i]) {
1753 			curr_sap_freq = op_ch_freq_list[i];
1754 			policy_mgr_debug("sta_sap_scc_on_lte_coex_chan %u unsafe sap_ch_freq %u",
1755 					 sta_sap_scc_on_lte_coex_chan,
1756 					 curr_sap_freq);
1757 			break;
1758 		}
1759 		/* When STA+SAP SCC is allowed on indoor channel,
1760 		 * Restart the SAP when :
1761 		 * 1. The user configured SAP frequency is not
1762 		 * the same as current freq. (or)
1763 		 * 2. The frequency is not allowed in the indoor
1764 		 * channel.
1765 		 */
1766 		if (pm_ctx->last_disconn_sta_freq == op_ch_freq_list[i] &&
1767 		    !policy_mgr_is_sap_go_interface_allowed_on_indoor(
1768 							pm_ctx->pdev,
1769 							sap_vdev_id,
1770 							op_ch_freq_list[i])) {
1771 			curr_sap_freq = op_ch_freq_list[i];
1772 			policy_mgr_debug("indoor sap_ch_freq %u",
1773 					 curr_sap_freq);
1774 			break;
1775 		}
1776 
1777 		/*
1778 		 * STA got disconnected & SAP has previously moved to 2.4 GHz
1779 		 * due to concurrency, then move SAP back to user configured
1780 		 * frequency.
1781 		 * if SCC to MCC switch mode is
1782 		 * QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL, the move SAP to
1783 		 * user configured frequency whenever standalone SAP is
1784 		 * currently not on the user configured frequency.
1785 		 * else move the SAP only when SAP is on 2.4 GHz band and user
1786 		 * configured frequency is on any other bands.
1787 		 */
1788 		if (!sta_gc_present && user_config_freq &&
1789 		    cc_mode == QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL &&
1790 		    op_ch_freq_list[i] != user_config_freq) {
1791 			curr_sap_freq = op_ch_freq_list[i];
1792 			policy_mgr_debug("Move sap to user configured freq: %d",
1793 					 user_config_freq);
1794 		} else if (!sta_gc_present && user_config_freq &&
1795 			   WLAN_REG_IS_24GHZ_CH_FREQ(op_ch_freq_list[i]) &&
1796 			   !WLAN_REG_IS_24GHZ_CH_FREQ(user_config_freq)) {
1797 			curr_sap_freq = op_ch_freq_list[i];
1798 			policy_mgr_debug("Move sap to user configured freq: %d",
1799 					 user_config_freq);
1800 			break;
1801 		}
1802 	}
1803 
1804 	if (!curr_sap_freq) {
1805 		policy_mgr_debug("SAP restart is not required");
1806 		return false;
1807 	}
1808 
1809 	mode = i >= go_index_start ? PM_P2P_GO_MODE : PM_SAP_MODE;
1810 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1811 	policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, sap_vdev_id,
1812 						      &info, &num_cxn_del);
1813 
1814 	/* Add the user config ch as first condidate */
1815 	pcl_channels[0] = user_config_freq;
1816 	pcl_weight[0] = 0;
1817 	status = policy_mgr_get_pcl(psoc, mode, &pcl_channels[1], &pcl_len,
1818 				    &pcl_weight[1],
1819 				    QDF_ARRAY_SIZE(pcl_weight) - 1,
1820 				    sap_vdev_id);
1821 	if (status == QDF_STATUS_SUCCESS)
1822 		pcl_len++;
1823 	else
1824 		pcl_len = 1;
1825 
1826 
1827 	for (i = 0; i < pcl_len; i++) {
1828 		if (pcl_channels[i] == curr_sap_freq)
1829 			continue;
1830 
1831 		if (!policy_mgr_is_safe_channel(psoc, pcl_channels[i]) ||
1832 		    wlan_reg_is_dfs_for_freq(pm_ctx->pdev, pcl_channels[i]))
1833 			continue;
1834 
1835 		/* SAP moved to 2.4 GHz, due to STA on DFS or Indoor where
1836 		 * concurrency is not allowed, now that there is no
1837 		 * STA/GC in 5 GHz band, move 2.4 GHz SAP to 5 GHz band if SAP
1838 		 * was initially started on 5 GHz band.
1839 		 * Checking again here as pcl_channels[0] could be
1840 		 * on indoor which is not removed in policy_mgr_get_pcl
1841 		 */
1842 		if (!sta_gc_present &&
1843 		    !policy_mgr_is_sap_go_interface_allowed_on_indoor(
1844 							pm_ctx->pdev,
1845 							sap_vdev_id,
1846 							pcl_channels[i])) {
1847 			policy_mgr_debug("Do not allow SAP on indoor frequency, STA is absent");
1848 			continue;
1849 		}
1850 
1851 		new_sap_freq = pcl_channels[i];
1852 		break;
1853 	}
1854 
1855 	/* Restore the connection entry */
1856 	if (num_cxn_del > 0)
1857 		policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del);
1858 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1859 
1860 	if (new_sap_freq == 0 || curr_sap_freq == new_sap_freq)
1861 		return false;
1862 	if (!intf_ch_freq)
1863 		return true;
1864 
1865 	*intf_ch_freq = new_sap_freq;
1866 	policy_mgr_debug("Standalone SAP(vdev_id %d) is not allowed on DFS/Unsafe channel, Move it to channel %u",
1867 			 sap_vdev_id, *intf_ch_freq);
1868 
1869 	return true;
1870 }
1871 
1872 /**
1873  * policy_mgr_is_nan_sap_unsafe_ch_scc_allowed() - Check if NAN+SAP SCC is
1874  *                                               allowed in LTE COEX unsafe ch
1875  * @pm_ctx: policy_mgr_psoc_priv_obj policy mgr context
1876  * @ch_freq: Channel frequency to check
1877  *
1878  * Return: True if allowed else false
1879  */
1880 static bool
1881 policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(struct policy_mgr_psoc_priv_obj
1882 					    *pm_ctx, uint32_t ch_freq)
1883 {
1884 	if (policy_mgr_is_safe_channel(pm_ctx->psoc, ch_freq) ||
1885 	    pm_ctx->cfg.nan_sap_scc_on_lte_coex_chnl)
1886 		return true;
1887 
1888 	return false;
1889 }
1890 
1891 /**
1892  * policy_mgr_nan_disable_work() - qdf defer function wrapper for NAN disable
1893  * @data: qdf_work data
1894  *
1895  * Return: None
1896  */
1897 static void policy_mgr_nan_disable_work(void *data)
1898 {
1899 	struct wlan_objmgr_psoc *psoc = data;
1900 
1901 	ucfg_nan_disable_concurrency(psoc);
1902 }
1903 
1904 bool policy_mgr_nan_sap_scc_on_unsafe_ch_chk(struct wlan_objmgr_psoc *psoc,
1905 					     uint32_t sap_freq)
1906 {
1907 	uint32_t nan_2g_freq, nan_5g_freq;
1908 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1909 
1910 	pm_ctx = policy_mgr_get_context(psoc);
1911 	if (!pm_ctx) {
1912 		policy_mgr_err("Invalid Context");
1913 		return false;
1914 	}
1915 
1916 	nan_2g_freq = policy_mgr_mode_specific_get_channel(psoc,
1917 							   PM_NAN_DISC_MODE);
1918 	if (nan_2g_freq == 0) {
1919 		policy_mgr_debug("No NAN+SAP SCC");
1920 		return false;
1921 	}
1922 	nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(psoc);
1923 
1924 	policy_mgr_debug("Freq SAP: %d NAN: %d %d", sap_freq,
1925 			 nan_2g_freq, nan_5g_freq);
1926 	if (WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, sap_freq)) {
1927 		if (policy_mgr_is_force_scc(pm_ctx->psoc) &&
1928 		    policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(pm_ctx,
1929 								nan_2g_freq))
1930 			return true;
1931 	} else if (WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, sap_freq)) {
1932 		if (policy_mgr_is_force_scc(pm_ctx->psoc) &&
1933 		    policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(pm_ctx,
1934 								nan_5g_freq))
1935 			return true;
1936 	} else {
1937 		/*
1938 		 * NAN + SAP in different bands. Continue to check for
1939 		 * SAP in unsafe channel
1940 		 */
1941 		return false;
1942 	}
1943 	policy_mgr_info("NAN+SAP unsafe ch SCC not allowed. Disabling NAN");
1944 	/* change context to worker since this is executed in sched thread ctx*/
1945 	qdf_create_work(0, &pm_ctx->nan_sap_conc_work,
1946 			policy_mgr_nan_disable_work, psoc);
1947 	qdf_sched_work(0, &pm_ctx->nan_sap_conc_work);
1948 
1949 	return false;
1950 }
1951 
1952 bool
1953 policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc,
1954 					 enum policy_mgr_con_mode mode,
1955 					 uint32_t ch_freq)
1956 {
1957 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1958 	uint32_t sap_freq, nan_2g_freq, nan_5g_freq;
1959 
1960 	pm_ctx = policy_mgr_get_context(psoc);
1961 	if (!pm_ctx) {
1962 		policy_mgr_err("Invalid Context");
1963 		return false;
1964 	}
1965 
1966 	if (!(mode == PM_SAP_MODE || mode == PM_NAN_DISC_MODE)) {
1967 		policy_mgr_debug("Not NAN or SAP mode");
1968 		return true;
1969 	}
1970 
1971 	if (!ch_freq) {
1972 		policy_mgr_err("Invalid channel");
1973 		return false;
1974 	}
1975 
1976 	if (!wlan_nan_get_sap_conc_support(pm_ctx->psoc)) {
1977 		policy_mgr_debug("NAN+SAP not supported in fw");
1978 		/* Reject NAN as SAP is of high priority */
1979 		if (mode == PM_NAN_DISC_MODE)
1980 			return false;
1981 		/* Before SAP start disable NAN */
1982 		ucfg_nan_disable_concurrency(pm_ctx->psoc);
1983 		return true;
1984 	}
1985 
1986 	if (mode == PM_NAN_DISC_MODE) {
1987 		sap_freq = policy_mgr_mode_specific_get_channel(pm_ctx->psoc,
1988 								PM_SAP_MODE);
1989 		policy_mgr_debug("FREQ SAP: %d NAN: %d", sap_freq, ch_freq);
1990 		if (ucfg_is_nan_dbs_supported(pm_ctx->psoc) &&
1991 		    !WLAN_REG_IS_SAME_BAND_FREQS(sap_freq, ch_freq))
1992 			return true;
1993 
1994 		if (sap_freq == ch_freq) {
1995 			policy_mgr_debug("NAN+SAP SCC");
1996 			return true;
1997 		}
1998 
1999 		if (!policy_mgr_is_force_scc(pm_ctx->psoc)) {
2000 			policy_mgr_debug("SAP force SCC disabled");
2001 			return false;
2002 		}
2003 		if (!policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(
2004 						pm_ctx, ch_freq)) {
2005 			policy_mgr_debug("NAN+SAP unsafe ch SCC disabled");
2006 			return false;
2007 		}
2008 	} else if (mode == PM_SAP_MODE) {
2009 		nan_2g_freq =
2010 			policy_mgr_mode_specific_get_channel(pm_ctx->psoc,
2011 							     PM_NAN_DISC_MODE);
2012 		nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(pm_ctx->psoc);
2013 		policy_mgr_debug("SAP CH: %d NAN Ch: %d %d", ch_freq,
2014 				 nan_2g_freq, nan_5g_freq);
2015 		if (ucfg_is_nan_conc_control_supported(pm_ctx->psoc) &&
2016 		    !ucfg_is_nan_dbs_supported(pm_ctx->psoc) &&
2017 		    !WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, ch_freq)) {
2018 			if (!policy_mgr_is_force_scc(pm_ctx->psoc)) {
2019 				policy_mgr_debug("NAN and SAP are in different bands but SAP force SCC disabled");
2020 				ucfg_nan_disable_concurrency(pm_ctx->psoc);
2021 				return true;
2022 			}
2023 		} else if (WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, ch_freq) ||
2024 			   WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, ch_freq)) {
2025 			if (ch_freq == nan_2g_freq || ch_freq == nan_5g_freq) {
2026 				policy_mgr_debug("NAN+SAP SCC");
2027 				return true;
2028 			}
2029 			if (!policy_mgr_is_force_scc(pm_ctx->psoc)) {
2030 				policy_mgr_debug("SAP force SCC disabled");
2031 				ucfg_nan_disable_concurrency(pm_ctx->psoc);
2032 				return true;
2033 			}
2034 			if ((WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) &&
2035 			     !policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(
2036 			     pm_ctx, nan_5g_freq)) ||
2037 			    (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) &&
2038 			     !policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(
2039 			     pm_ctx, nan_2g_freq))) {
2040 				policy_mgr_debug("NAN+SAP unsafe ch SCC disabled");
2041 				ucfg_nan_disable_concurrency(pm_ctx->psoc);
2042 				return true;
2043 			}
2044 		}
2045 	}
2046 	return true;
2047 }
2048 
2049 QDF_STATUS
2050 policy_mgr_nan_sap_post_enable_conc_check(struct wlan_objmgr_psoc *psoc)
2051 {
2052 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2053 	struct policy_mgr_conc_connection_info *sap_info = NULL;
2054 	uint8_t i;
2055 	qdf_freq_t nan_freq_2g, nan_freq_5g;
2056 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2057 
2058 	pm_ctx = policy_mgr_get_context(psoc);
2059 	if (!pm_ctx) {
2060 		policy_mgr_err("Invalid pm context");
2061 		return QDF_STATUS_E_INVAL;
2062 	}
2063 
2064 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2065 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
2066 		if (pm_conc_connection_list[i].mode == PM_SAP_MODE &&
2067 		    pm_conc_connection_list[i].in_use) {
2068 			sap_info = &pm_conc_connection_list[i];
2069 			break;
2070 		}
2071 	}
2072 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2073 
2074 	if (!sap_info)
2075 		goto end;
2076 	if (sap_info->freq == 0)
2077 		goto end;
2078 	nan_freq_2g = policy_mgr_mode_specific_get_channel(psoc,
2079 							   PM_NAN_DISC_MODE);
2080 	nan_freq_5g = wlan_nan_get_disc_5g_ch_freq(psoc);
2081 	if (sap_info->freq == nan_freq_2g || sap_info->freq == nan_freq_5g) {
2082 		policy_mgr_debug("NAN and SAP already in SCC");
2083 		goto end;
2084 	}
2085 	if (nan_freq_2g == 0)
2086 		goto end;
2087 
2088 	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
2089 	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
2090 		policy_mgr_debug("channel switch is already in progress");
2091 		return status;
2092 	}
2093 
2094 	if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason)
2095 		pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(psoc,
2096 					sap_info->vdev_id,
2097 					CSA_REASON_CONCURRENT_NAN_EVENT);
2098 
2099 	/* SAP should be moved to 2g NAN channel on non-DBS platforms */
2100 	if (!ucfg_is_nan_dbs_supported(pm_ctx->psoc) ||
2101 	    WLAN_REG_IS_24GHZ_CH_FREQ(sap_info->freq)) {
2102 		policy_mgr_debug("Force SCC for NAN+SAP Ch freq: %d",
2103 				 nan_freq_2g);
2104 		status =
2105 		policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id,
2106 						       nan_freq_2g,
2107 						       policy_mgr_get_ch_width(
2108 						       sap_info->bw),
2109 						       true);
2110 		if (status == QDF_STATUS_SUCCESS)
2111 			status = QDF_STATUS_E_PENDING;
2112 	} else if (nan_freq_5g && WLAN_REG_IS_5GHZ_CH_FREQ(sap_info->freq)) {
2113 		policy_mgr_debug("Force SCC for NAN+SAP Ch freq: %d",
2114 				 nan_freq_5g);
2115 		status =
2116 		policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id,
2117 						       nan_freq_5g,
2118 						       policy_mgr_get_ch_width(
2119 						       sap_info->bw),
2120 						       true);
2121 		if (status == QDF_STATUS_SUCCESS)
2122 			status = QDF_STATUS_E_PENDING;
2123 	}
2124 
2125 end:
2126 	pm_ctx->sta_ap_intf_check_work_info->nan_force_scc_in_progress = false;
2127 
2128 	return status;
2129 }
2130 
2131 void policy_mgr_nan_sap_post_disable_conc_check(struct wlan_objmgr_psoc *psoc)
2132 {
2133 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2134 	struct policy_mgr_conc_connection_info *sap_info = NULL;
2135 	uint32_t sap_freq = 0, i;
2136 	QDF_STATUS status;
2137 	uint32_t user_config_freq;
2138 	uint8_t band_mask = 0;
2139 	uint8_t chn_idx, num_chan;
2140 	struct regulatory_channel *channel_list;
2141 
2142 	pm_ctx = policy_mgr_get_context(psoc);
2143 	if (!pm_ctx) {
2144 		policy_mgr_err("Invalid pm context");
2145 		return;
2146 	}
2147 
2148 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
2149 		if (pm_conc_connection_list[i].mode == PM_SAP_MODE &&
2150 		    pm_conc_connection_list[i].in_use) {
2151 			sap_info = &pm_conc_connection_list[i];
2152 			sap_freq = sap_info->freq;
2153 			break;
2154 		}
2155 	}
2156 	if (sap_freq == 0 || policy_mgr_is_safe_channel(psoc, sap_freq))
2157 		return;
2158 
2159 	user_config_freq = policy_mgr_get_user_config_sap_freq(
2160 						psoc, sap_info->vdev_id);
2161 
2162 	sap_freq = policy_mgr_get_nondfs_preferred_channel(psoc, PM_SAP_MODE,
2163 							   false,
2164 							   sap_info->vdev_id);
2165 	policy_mgr_debug("User/ACS orig Freq: %d New SAP Freq: %d",
2166 			 user_config_freq, sap_freq);
2167 
2168 	if (wlan_reg_is_enable_in_secondary_list_for_freq(pm_ctx->pdev,
2169 							  user_config_freq) &&
2170 	    policy_mgr_is_safe_channel(psoc, user_config_freq)) {
2171 		policy_mgr_debug("Give preference to user config freq");
2172 		sap_freq = user_config_freq;
2173 	} else {
2174 		channel_list = qdf_mem_malloc(
2175 					sizeof(struct regulatory_channel) *
2176 					       NUM_CHANNELS);
2177 		if (!channel_list)
2178 			return;
2179 
2180 		band_mask |= BIT(wlan_reg_freq_to_band(user_config_freq));
2181 		num_chan = wlan_reg_get_band_channel_list_for_pwrmode(
2182 						pm_ctx->pdev,
2183 						band_mask,
2184 						channel_list,
2185 						REG_CURRENT_PWR_MODE);
2186 		for (chn_idx = 0; chn_idx < num_chan; chn_idx++) {
2187 			if (wlan_reg_is_enable_in_secondary_list_for_freq(
2188 					pm_ctx->pdev,
2189 					channel_list[chn_idx].center_freq) &&
2190 			    policy_mgr_is_safe_channel(
2191 					psoc,
2192 					channel_list[chn_idx].center_freq)) {
2193 				policy_mgr_debug("Prefer user config band freq %d",
2194 						 channel_list[chn_idx].center_freq);
2195 				sap_freq = channel_list[chn_idx].center_freq;
2196 			}
2197 		}
2198 		qdf_mem_free(channel_list);
2199 	}
2200 
2201 	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
2202 	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
2203 		policy_mgr_debug("wait as channel switch is already in progress");
2204 		status = qdf_wait_single_event(
2205 					&pm_ctx->channel_switch_complete_evt,
2206 					CHANNEL_SWITCH_COMPLETE_TIMEOUT);
2207 		if (QDF_IS_STATUS_ERROR(status))
2208 			policy_mgr_err("wait for event failed, still continue with channel switch");
2209 	}
2210 
2211 	if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason)
2212 		pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(
2213 				psoc, sap_info->vdev_id,
2214 				CSA_REASON_CONCURRENT_NAN_EVENT);
2215 
2216 	policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id,
2217 					       sap_freq,
2218 					       policy_mgr_get_ch_width(
2219 					       sap_info->bw), true);
2220 }
2221 
2222 void policy_mgr_check_sap_restart(struct wlan_objmgr_psoc *psoc,
2223 				  uint8_t vdev_id)
2224 {
2225 	QDF_STATUS status;
2226 	uint32_t ch_freq;
2227 	struct policy_mgr_psoc_priv_obj *pm_ctx = NULL;
2228 
2229 	if (!psoc) {
2230 		policy_mgr_err("Invalid psoc");
2231 		return;
2232 	}
2233 	pm_ctx = policy_mgr_get_context(psoc);
2234 	if (!pm_ctx) {
2235 		policy_mgr_err("Invalid context");
2236 		return;
2237 	}
2238 
2239 	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
2240 	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
2241 		policy_mgr_debug("channel switch is already in progress");
2242 		return;
2243 	}
2244 
2245 	/*
2246 	 * Restart should be handled by sap_fsm_validate_and_change_channel(),
2247 	 * after SAP starts.
2248 	 */
2249 	if (pm_ctx->hdd_cbacks.hdd_is_cac_in_progress &&
2250 	    pm_ctx->hdd_cbacks.hdd_is_cac_in_progress()) {
2251 		policy_mgr_debug("DFS CAC in progress, do not restart SAP");
2252 		return;
2253 	}
2254 
2255 	if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) {
2256 		policy_mgr_err("SAP restart get channel callback in NULL");
2257 		goto end;
2258 	}
2259 	status =
2260 		pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart(psoc,
2261 								      vdev_id,
2262 								      &ch_freq);
2263 	if (status == QDF_STATUS_SUCCESS)
2264 		policy_mgr_debug("SAP vdev id %d switch to new ch freq: %d",
2265 				 vdev_id, ch_freq);
2266 
2267 end:
2268 	pm_ctx->last_disconn_sta_freq = 0;
2269 }
2270 
2271 /**
2272  * policy_mgr_handle_sap_plus_go_force_scc() - Do SAP/GO force SCC
2273  * @psoc: soc object
2274  *
2275  * This function will check SAP/GO channel state and select channel
2276  * to avoid MCC, then do channel change on the second interface.
2277  *
2278  * Return: QDF_STATUS_SUCCESS if successfully handle the SAP/GO
2279  * force SCC.
2280  */
2281 static QDF_STATUS
2282 policy_mgr_handle_sap_plus_go_force_scc(struct wlan_objmgr_psoc *psoc)
2283 {
2284 	QDF_STATUS status = QDF_STATUS_E_INVAL;
2285 	uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
2286 	enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE;
2287 	enum policy_mgr_con_mode vdev_con_mode;
2288 	uint32_t existing_ch_freq, chan_freq, intf_ch_freq;
2289 	enum phy_ch_width existing_ch_width;
2290 	uint8_t vdev_id;
2291 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2292 	struct sta_ap_intf_check_work_ctx *work_info;
2293 	struct ch_params ch_params = {0};
2294 	enum QDF_OPMODE opmode;
2295 
2296 	pm_ctx = policy_mgr_get_context(psoc);
2297 	if (!pm_ctx) {
2298 		policy_mgr_err("Invalid Context");
2299 		return status;
2300 	}
2301 
2302 	work_info = pm_ctx->sta_ap_intf_check_work_info;
2303 	if (!work_info) {
2304 		policy_mgr_err("invalid work info");
2305 		return status;
2306 	}
2307 	if (work_info->sap_plus_go_force_scc.reason == CSA_REASON_UNKNOWN)
2308 		return status;
2309 
2310 	vdev_id = work_info->sap_plus_go_force_scc.initiator_vdev_id;
2311 	chan_freq = wlan_get_operation_chan_freq_vdev_id(pm_ctx->pdev, vdev_id);
2312 	opmode = wlan_get_opmode_vdev_id(pm_ctx->pdev, vdev_id);
2313 	vdev_con_mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, opmode,
2314 							     vdev_id);
2315 
2316 	existing_vdev_id =
2317 		policy_mgr_fetch_existing_con_info(
2318 				psoc,
2319 				vdev_id,
2320 				chan_freq,
2321 				&existing_vdev_mode,
2322 				&existing_ch_freq, &existing_ch_width);
2323 	policy_mgr_debug("initiator vdev %d mode %d freq %d, existing vdev %d mode %d freq %d reason %d",
2324 			 vdev_id, vdev_con_mode, chan_freq, existing_vdev_id,
2325 			 existing_vdev_mode, existing_ch_freq,
2326 			 work_info->sap_plus_go_force_scc.reason);
2327 
2328 	if (existing_vdev_id == WLAN_UMAC_VDEV_ID_MAX)
2329 		goto force_scc_done;
2330 
2331 	if (!((vdev_con_mode == PM_P2P_GO_MODE &&
2332 	       existing_vdev_mode == PM_SAP_MODE) ||
2333 	      (vdev_con_mode == PM_SAP_MODE &&
2334 	       existing_vdev_mode == PM_P2P_GO_MODE)))
2335 		goto force_scc_done;
2336 
2337 	if (!pm_ctx->hdd_cbacks.wlan_check_cc_intf_cb)
2338 		goto force_scc_done;
2339 
2340 	intf_ch_freq = 0;
2341 	status = pm_ctx->hdd_cbacks.wlan_check_cc_intf_cb(psoc,
2342 							  existing_vdev_id,
2343 							  &intf_ch_freq);
2344 	policy_mgr_debug("vdev %d freq %d intf %d status %d",
2345 			 existing_vdev_id, existing_ch_freq,
2346 			 intf_ch_freq, status);
2347 	if (QDF_IS_STATUS_ERROR(status))
2348 		goto force_scc_done;
2349 	if (!intf_ch_freq || intf_ch_freq == existing_ch_freq)
2350 		goto force_scc_done;
2351 
2352 	ch_params.ch_width = existing_ch_width;
2353 	if (pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params) {
2354 		status = pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params(
2355 			psoc, existing_vdev_id, intf_ch_freq, &ch_params);
2356 		if (QDF_IS_STATUS_ERROR(status))
2357 			policy_mgr_debug("no candidate valid bw for vdev %d intf %d",
2358 					 existing_vdev_id, intf_ch_freq);
2359 	}
2360 
2361 	status = policy_mgr_valid_sap_conc_channel_check(
2362 		    psoc, &intf_ch_freq, existing_ch_freq, existing_vdev_id,
2363 		    &ch_params);
2364 	if (QDF_IS_STATUS_ERROR(status)) {
2365 		policy_mgr_err("warning no candidate freq for vdev %d freq %d intf %d",
2366 			       existing_vdev_id, existing_ch_freq,
2367 			       intf_ch_freq);
2368 		goto force_scc_done;
2369 	}
2370 
2371 	if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason)
2372 		pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(
2373 				psoc, existing_vdev_id,
2374 				work_info->sap_plus_go_force_scc.reason);
2375 
2376 	status = policy_mgr_change_sap_channel_with_csa(
2377 			psoc, existing_vdev_id, intf_ch_freq,
2378 			ch_params.ch_width, true);
2379 	if (QDF_IS_STATUS_ERROR(status)) {
2380 		policy_mgr_err("warning sap/go vdev %d freq %d intf %d csa failed",
2381 			       existing_vdev_id, existing_ch_freq,
2382 			       intf_ch_freq);
2383 	}
2384 
2385 force_scc_done:
2386 	work_info->sap_plus_go_force_scc.reason = CSA_REASON_UNKNOWN;
2387 	work_info->sap_plus_go_force_scc.initiator_vdev_id =
2388 					WLAN_UMAC_VDEV_ID_MAX;
2389 	work_info->sap_plus_go_force_scc.responder_vdev_id =
2390 					WLAN_UMAC_VDEV_ID_MAX;
2391 
2392 	return status;
2393 }
2394 
2395 QDF_STATUS
2396 policy_mgr_check_sap_go_force_scc(struct wlan_objmgr_psoc *psoc,
2397 				  struct wlan_objmgr_vdev *vdev,
2398 				  enum sap_csa_reason_code reason_code)
2399 {
2400 	uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
2401 	enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE;
2402 	enum policy_mgr_con_mode vdev_con_mode;
2403 	uint32_t con_freq, chan_freq;
2404 	enum phy_ch_width ch_width;
2405 	uint8_t vdev_id;
2406 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2407 	struct sta_ap_intf_check_work_ctx *work_info;
2408 	enum QDF_OPMODE opmode;
2409 
2410 	if (reason_code != CSA_REASON_GO_BSS_STARTED &&
2411 	    reason_code != CSA_REASON_USER_INITIATED)
2412 		return QDF_STATUS_SUCCESS;
2413 
2414 	pm_ctx = policy_mgr_get_context(psoc);
2415 	if (!pm_ctx) {
2416 		policy_mgr_err("Invalid Context");
2417 		return QDF_STATUS_E_INVAL;
2418 	}
2419 	if (!vdev) {
2420 		policy_mgr_err("vdev is null");
2421 		return QDF_STATUS_E_INVAL;
2422 	}
2423 	vdev_id = wlan_vdev_get_id(vdev);
2424 	opmode = wlan_vdev_mlme_get_opmode(vdev);
2425 	work_info = pm_ctx->sta_ap_intf_check_work_info;
2426 	if (!work_info) {
2427 		policy_mgr_err("invalid work info");
2428 		return QDF_STATUS_E_INVAL;
2429 	}
2430 
2431 	chan_freq = wlan_get_operation_chan_freq(vdev);
2432 	vdev_con_mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, opmode,
2433 							     vdev_id);
2434 
2435 	existing_vdev_id =
2436 		policy_mgr_fetch_existing_con_info(psoc,
2437 						   vdev_id,
2438 						   chan_freq,
2439 						   &existing_vdev_mode,
2440 						   &con_freq, &ch_width);
2441 	if (existing_vdev_id == WLAN_UMAC_VDEV_ID_MAX)
2442 		return QDF_STATUS_SUCCESS;
2443 
2444 	if (!((vdev_con_mode == PM_P2P_GO_MODE &&
2445 	       existing_vdev_mode == PM_SAP_MODE) ||
2446 	      (vdev_con_mode == PM_SAP_MODE &&
2447 	       existing_vdev_mode == PM_P2P_GO_MODE)))
2448 		return QDF_STATUS_SUCCESS;
2449 
2450 	work_info->sap_plus_go_force_scc.reason = reason_code;
2451 	work_info->sap_plus_go_force_scc.initiator_vdev_id = vdev_id;
2452 	work_info->sap_plus_go_force_scc.responder_vdev_id = existing_vdev_id;
2453 
2454 	policy_mgr_debug("initiator vdev %d freq %d, existing vdev %d freq %d reason %d",
2455 			 vdev_id, chan_freq, existing_vdev_id,
2456 			 con_freq, reason_code);
2457 
2458 	if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
2459 				    WAIT_BEFORE_GO_FORCESCC_RESTART))
2460 		policy_mgr_debug("change interface request already queued");
2461 
2462 	return QDF_STATUS_E_PENDING;
2463 }
2464 
2465 /**
2466  * policy_mgr_is_any_conn_in_transition() - Check if any STA/CLI
2467  * connection is disconnecting or roaming state
2468  * @psoc: PSOC object information
2469  *
2470  * This function will check connection table and find any STA/CLI
2471  * in transition state such as disconnecting, or roaming.
2472  *
2473  * Return: true if there is one STA/CLI in transition state.
2474  */
2475 static bool
2476 policy_mgr_is_any_conn_in_transition(struct wlan_objmgr_psoc *psoc)
2477 {
2478 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2479 	uint32_t i;
2480 	struct policy_mgr_conc_connection_info *conn_info;
2481 	struct wlan_objmgr_vdev *vdev;
2482 	bool non_connected = false;
2483 	uint8_t vdev_id;
2484 
2485 	pm_ctx = policy_mgr_get_context(psoc);
2486 	if (!pm_ctx) {
2487 		policy_mgr_err("Invalid pm context");
2488 		return false;
2489 	}
2490 
2491 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2492 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
2493 		conn_info = &pm_conc_connection_list[i];
2494 		if (!(conn_info->in_use &&
2495 		      (conn_info->mode == PM_STA_MODE ||
2496 		       conn_info->mode == PM_P2P_CLIENT_MODE)))
2497 			continue;
2498 		vdev_id = conn_info->vdev_id;
2499 		vdev = wlan_objmgr_get_vdev_by_id_from_pdev(
2500 				pm_ctx->pdev, vdev_id, WLAN_POLICY_MGR_ID);
2501 		if (!vdev) {
2502 			policy_mgr_err("vdev %d: not found", vdev_id);
2503 			continue;
2504 		}
2505 
2506 		non_connected = !wlan_cm_is_vdev_connected(vdev);
2507 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
2508 		if (non_connected) {
2509 			policy_mgr_debug("vdev %d: is in transition state",
2510 					 vdev_id);
2511 			break;
2512 		}
2513 	}
2514 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2515 
2516 	return non_connected;
2517 }
2518 
2519 static void __policy_mgr_check_sta_ap_concurrent_ch_intf(
2520 				struct policy_mgr_psoc_priv_obj *pm_ctx)
2521 {
2522 	uint32_t mcc_to_scc_switch, cc_count = 0, i;
2523 	QDF_STATUS status;
2524 	uint32_t ch_freq;
2525 	uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
2526 	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS];
2527 	struct sta_ap_intf_check_work_ctx *work_info;
2528 
2529 	if (!pm_ctx) {
2530 		policy_mgr_err("Invalid context");
2531 		return;
2532 	}
2533 	work_info = pm_ctx->sta_ap_intf_check_work_info;
2534 
2535 	if (work_info->nan_force_scc_in_progress) {
2536 		policy_mgr_nan_sap_post_enable_conc_check(pm_ctx->psoc);
2537 		return;
2538 	}
2539 	/*
2540 	 * Check if force scc is required for GO + GO case. vdev id will be
2541 	 * valid in case of GO+GO force scc only. So, for valid vdev id move
2542 	 * first GO to newly formed GO channel.
2543 	 */
2544 	policy_mgr_debug("p2p go vdev id: %d csa reason: %d",
2545 			 work_info->go_plus_go_force_scc.vdev_id,
2546 			 work_info->sap_plus_go_force_scc.reason);
2547 	if (pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id <
2548 	    WLAN_UMAC_VDEV_ID_MAX) {
2549 		policy_mgr_do_go_plus_go_force_scc(
2550 			pm_ctx->psoc, work_info->go_plus_go_force_scc.vdev_id,
2551 			work_info->go_plus_go_force_scc.ch_freq,
2552 			work_info->go_plus_go_force_scc.ch_width);
2553 		work_info->go_plus_go_force_scc.vdev_id = WLAN_UMAC_VDEV_ID_MAX;
2554 		goto end;
2555 	}
2556 	/*
2557 	 * Check if force scc is required for GO + SAP case.
2558 	 */
2559 	if (pm_ctx->sta_ap_intf_check_work_info->sap_plus_go_force_scc.reason !=
2560 	    CSA_REASON_UNKNOWN) {
2561 		status = policy_mgr_handle_sap_plus_go_force_scc(pm_ctx->psoc);
2562 		goto end;
2563 	}
2564 
2565 	mcc_to_scc_switch =
2566 		policy_mgr_get_mcc_to_scc_switch_mode(pm_ctx->psoc);
2567 
2568 	policy_mgr_debug("Concurrent open sessions running: %d",
2569 			 policy_mgr_concurrent_open_sessions_running(pm_ctx->psoc));
2570 
2571 	if (!policy_mgr_is_sap_go_existed(pm_ctx->psoc))
2572 		goto end;
2573 
2574 	cc_count = policy_mgr_get_mode_specific_conn_info(
2575 				pm_ctx->psoc, &op_ch_freq_list[cc_count],
2576 				&vdev_id[cc_count], PM_SAP_MODE);
2577 	policy_mgr_debug("Number of concurrent SAP: %d", cc_count);
2578 	if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS)
2579 		cc_count = cc_count +
2580 				policy_mgr_get_mode_specific_conn_info(
2581 					pm_ctx->psoc, &op_ch_freq_list[cc_count],
2582 					&vdev_id[cc_count], PM_P2P_GO_MODE);
2583 	policy_mgr_debug("Number of beaconing entities (SAP + GO):%d",
2584 							cc_count);
2585 	if (!cc_count) {
2586 		policy_mgr_err("Could not retrieve SAP/GO operating channel&vdevid");
2587 		goto end;
2588 	}
2589 
2590 	/* When any STA/CLI is transition state, such as roaming or
2591 	 * disconnecting, skip force scc for this time.
2592 	 */
2593 	if (policy_mgr_is_any_conn_in_transition(pm_ctx->psoc)) {
2594 		policy_mgr_debug("defer sap conc check to a later time due to another sta/cli dicon/roam pending");
2595 		goto end;
2596 	}
2597 
2598 	if (policy_mgr_is_ap_start_in_progress(pm_ctx->psoc)) {
2599 		policy_mgr_debug("defer sap conc check to a later time due to another sap/go start pending");
2600 		qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
2601 				       SAP_CONC_CHECK_DEFER_TIMEOUT_MS);
2602 		goto end;
2603 	}
2604 	if (policy_mgr_is_set_link_in_progress(pm_ctx->psoc)) {
2605 		policy_mgr_debug("defer sap conc check to a later time due to ml sta set link in progress");
2606 		qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
2607 				       SAP_CONC_CHECK_DEFER_TIMEOUT_MS);
2608 		goto end;
2609 	}
2610 
2611 	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
2612 	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
2613 		policy_mgr_debug("wait as channel switch is already in progress");
2614 		status = qdf_wait_single_event(
2615 					&pm_ctx->channel_switch_complete_evt,
2616 					CHANNEL_SWITCH_COMPLETE_TIMEOUT);
2617 		if (QDF_IS_STATUS_ERROR(status))
2618 			policy_mgr_err("wait for event failed, still continue with channel switch");
2619 	}
2620 
2621 	if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) {
2622 		policy_mgr_err("SAP restart get channel callback in NULL");
2623 		goto end;
2624 	}
2625 	if (cc_count <= MAX_NUMBER_OF_CONC_CONNECTIONS)
2626 		for (i = 0; i < cc_count; i++) {
2627 			status = pm_ctx->hdd_cbacks.
2628 				wlan_hdd_get_channel_for_sap_restart
2629 					(pm_ctx->psoc, vdev_id[i], &ch_freq);
2630 			if (status == QDF_STATUS_SUCCESS) {
2631 				policy_mgr_debug("SAP vdev id %d restarts due to MCC->SCC switch, old ch freq :%d new ch freq: %d",
2632 						 vdev_id[i],
2633 						 op_ch_freq_list[i], ch_freq);
2634 				break;
2635 			}
2636 		}
2637 
2638 end:
2639 	pm_ctx->last_disconn_sta_freq = 0;
2640 }
2641 
2642 void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data)
2643 {
2644 	struct qdf_op_sync *op_sync;
2645 
2646 	if (qdf_op_protect(&op_sync))
2647 		return;
2648 
2649 	__policy_mgr_check_sta_ap_concurrent_ch_intf(data);
2650 
2651 	qdf_op_unprotect(op_sync);
2652 }
2653 
2654 static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc,
2655 						uint32_t sta_ch_freq)
2656 {
2657 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2658 	bool sta_sap_scc_on_dfs_chan, sta_sap_scc_on_indoor_channel;
2659 
2660 	pm_ctx = policy_mgr_get_context(psoc);
2661 	if (!pm_ctx) {
2662 		policy_mgr_err("Invalid context");
2663 		return false;
2664 	}
2665 
2666 	sta_sap_scc_on_dfs_chan =
2667 		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
2668 	if (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, sta_ch_freq) &&
2669 	    sta_sap_scc_on_dfs_chan) {
2670 		policy_mgr_debug("STA, SAP SCC is allowed on DFS chan %u",
2671 				 sta_ch_freq);
2672 		return true;
2673 	}
2674 
2675 	sta_sap_scc_on_indoor_channel =
2676 		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
2677 	if (wlan_reg_is_freq_indoor(pm_ctx->pdev, sta_ch_freq) &&
2678 	    sta_sap_scc_on_indoor_channel) {
2679 		policy_mgr_debug("STA, SAP SCC is allowed on indoor chan %u",
2680 				 sta_ch_freq);
2681 		return true;
2682 	}
2683 
2684 	if ((wlan_reg_is_dfs_for_freq(pm_ctx->pdev, sta_ch_freq) &&
2685 	     !sta_sap_scc_on_dfs_chan) ||
2686 	    wlan_reg_is_passive_or_disable_for_pwrmode(
2687 	    pm_ctx->pdev, sta_ch_freq, REG_CURRENT_PWR_MODE) ||
2688 	    (wlan_reg_is_freq_indoor(pm_ctx->pdev, sta_ch_freq) &&
2689 	    !sta_sap_scc_on_indoor_channel) ||
2690 	    !policy_mgr_is_safe_channel(psoc, sta_ch_freq)) {
2691 		if (policy_mgr_is_hw_dbs_capable(psoc))
2692 			return true;
2693 		else
2694 			return false;
2695 	}
2696 	else
2697 		return true;
2698 }
2699 
2700 static bool policy_mgr_get_srd_enable_for_vdev(
2701 				struct wlan_objmgr_psoc *psoc,
2702 				uint8_t vdev_id)
2703 {
2704 	struct wlan_objmgr_vdev *vdev;
2705 	enum QDF_OPMODE vdev_opmode;
2706 	bool enable_srd_channel = false;
2707 
2708 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
2709 						    WLAN_POLICY_MGR_ID);
2710 	if (!vdev) {
2711 		policy_mgr_err("vdev is NULL");
2712 		return false;
2713 	}
2714 
2715 	vdev_opmode = wlan_vdev_mlme_get_opmode(vdev);
2716 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
2717 
2718 	wlan_mlme_get_srd_master_mode_for_vdev(psoc, vdev_opmode,
2719 					       &enable_srd_channel);
2720 	return enable_srd_channel;
2721 }
2722 
2723 QDF_STATUS
2724 policy_mgr_valid_sap_conc_channel_check(struct wlan_objmgr_psoc *psoc,
2725 					uint32_t *con_ch_freq,
2726 					uint32_t sap_ch_freq,
2727 					uint8_t sap_vdev_id,
2728 					struct ch_params *ch_params)
2729 {
2730 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2731 	uint32_t ch_freq = *con_ch_freq;
2732 	bool find_alternate = false;
2733 	enum phy_ch_width old_ch_width;
2734 	bool sta_sap_scc_on_dfs_chan, sta_sap_scc_on_indoor_channel;
2735 	bool is_dfs;
2736 	bool is_6ghz_cap;
2737 	bool is_sta_sap_scc;
2738 	enum policy_mgr_con_mode con_mode;
2739 	uint32_t nan_2g_freq, nan_5g_freq;
2740 
2741 	pm_ctx = policy_mgr_get_context(psoc);
2742 	if (!pm_ctx) {
2743 		policy_mgr_err("Invalid context");
2744 		return QDF_STATUS_E_FAILURE;
2745 	}
2746 	/*
2747 	 * If force SCC is set, Check if conc channel is DFS
2748 	 * or passive or part of LTE avoided channel list.
2749 	 * In that case move SAP to other band if DBS is supported,
2750 	 * return otherwise
2751 	 */
2752 	if (!policy_mgr_is_force_scc(psoc))
2753 		return QDF_STATUS_SUCCESS;
2754 
2755 	/*
2756 	 * If interference is 0, it could be STA/SAP SCC,
2757 	 * check further if SAP can start on STA home channel or
2758 	 * select other band channel if not.
2759 	 */
2760 	if (!ch_freq) {
2761 		if (!policy_mgr_any_other_vdev_on_same_mac_as_freq(psoc,
2762 								   sap_ch_freq,
2763 								   sap_vdev_id))
2764 			return QDF_STATUS_SUCCESS;
2765 
2766 		ch_freq = sap_ch_freq;
2767 	}
2768 
2769 	if (!ch_freq)
2770 		return QDF_STATUS_SUCCESS;
2771 
2772 	con_mode = policy_mgr_con_mode_by_vdev_id(psoc, sap_vdev_id);
2773 
2774 	is_sta_sap_scc = policy_mgr_is_sta_sap_scc(psoc, ch_freq);
2775 
2776 	nan_2g_freq =
2777 		policy_mgr_mode_specific_get_channel(psoc, PM_NAN_DISC_MODE);
2778 	nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(psoc);
2779 
2780 	sta_sap_scc_on_dfs_chan =
2781 		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
2782 
2783 	sta_sap_scc_on_indoor_channel =
2784 		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
2785 	old_ch_width = ch_params->ch_width;
2786 	if (pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params)
2787 		pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params(
2788 			psoc, sap_vdev_id, ch_freq, ch_params);
2789 
2790 	is_dfs = wlan_mlme_check_chan_param_has_dfs(
2791 			pm_ctx->pdev, ch_params, ch_freq);
2792 	is_6ghz_cap = policy_mgr_get_ap_6ghz_capable(psoc, sap_vdev_id, NULL);
2793 
2794 	if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && is_dfs &&
2795 	    !sta_sap_scc_on_dfs_chan && is_sta_sap_scc) {
2796 		find_alternate = true;
2797 		policymgr_nofl_debug("sap not capable of DFS SCC on con ch_freq %d",
2798 				     ch_freq);
2799 	} else if (wlan_reg_is_disable_for_pwrmode(pm_ctx->pdev, ch_freq,
2800 						   REG_CURRENT_PWR_MODE)) {
2801 		find_alternate = true;
2802 		policymgr_nofl_debug("sap not capable on disabled con ch_freq %d",
2803 				     ch_freq);
2804 	} else if (con_mode == PM_P2P_GO_MODE &&
2805 		   wlan_reg_is_passive_or_disable_for_pwrmode(
2806 						pm_ctx->pdev,
2807 						ch_freq,
2808 						REG_CURRENT_PWR_MODE) &&
2809 		   !(policy_mgr_is_go_scc_strict(psoc) &&
2810 		     (!is_sta_sap_scc || sta_sap_scc_on_dfs_chan))) {
2811 		find_alternate = true;
2812 		policymgr_nofl_debug("Go not capable on dfs/disabled con ch_freq %d",
2813 				     ch_freq);
2814 	} else if (!policy_mgr_is_safe_channel(psoc, ch_freq) &&
2815 		   !(policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) &&
2816 		     is_sta_sap_scc) &&
2817 		   !(policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(psoc) &&
2818 		    (WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, ch_freq) ||
2819 		     WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, ch_freq)))) {
2820 		find_alternate = true;
2821 		policymgr_nofl_debug("sap not capable unsafe con ch_freq %d",
2822 				     ch_freq);
2823 	} else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq) &&
2824 		   !WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ch_freq) &&
2825 		   !is_6ghz_cap) {
2826 		policymgr_nofl_debug("sap not capable on 6GHZ con ch_freq %d",
2827 				     ch_freq);
2828 		find_alternate = true;
2829 	} else if (wlan_reg_is_etsi13_srd_chan_for_freq(pm_ctx->pdev,
2830 							ch_freq) &&
2831 		   !policy_mgr_get_srd_enable_for_vdev(psoc, sap_vdev_id)) {
2832 		find_alternate = true;
2833 		policymgr_nofl_debug("sap not capable on SRD con ch_freq %d",
2834 				     ch_freq);
2835 	} else if (!policy_mgr_is_sap_go_interface_allowed_on_indoor(
2836 							pm_ctx->pdev,
2837 							sap_vdev_id, ch_freq)) {
2838 		policymgr_nofl_debug("sap not capable on indoor con ch_freq %d is_sta_sap_scc:%d",
2839 				     ch_freq, is_sta_sap_scc);
2840 		find_alternate = true;
2841 	}
2842 
2843 	if (find_alternate) {
2844 		if (policy_mgr_is_hw_dbs_capable(psoc)) {
2845 			ch_freq = policy_mgr_get_alternate_channel_for_sap(
2846 						psoc, sap_vdev_id, sap_ch_freq,
2847 						REG_BAND_UNKNOWN);
2848 			policymgr_nofl_debug("selected alternate ch %d",
2849 					     ch_freq);
2850 			if (!ch_freq) {
2851 				policymgr_nofl_debug("Sap can't have concurrency on %d in dbs hw",
2852 						     *con_ch_freq);
2853 				return QDF_STATUS_E_FAILURE;
2854 			}
2855 		} else {
2856 			/* MCC not supported for non-DBS chip*/
2857 			ch_freq = 0;
2858 			if (con_mode == PM_SAP_MODE) {
2859 				policymgr_nofl_debug("MCC situation in non-dbs hw STA freq %d SAP freq %d not supported",
2860 						     *con_ch_freq, sap_ch_freq);
2861 				return QDF_STATUS_E_FAILURE;
2862 			} else {
2863 				policymgr_nofl_debug("MCC situation in non-dbs hw STA freq %d GO freq %d SCC not supported",
2864 						     *con_ch_freq, sap_ch_freq);
2865 			}
2866 		}
2867 	}
2868 
2869 	if (ch_freq != sap_ch_freq || old_ch_width != ch_params->ch_width) {
2870 		*con_ch_freq = ch_freq;
2871 		policymgr_nofl_debug("sap conc result con freq %d bw %d org freq %d bw %d",
2872 				     ch_freq, ch_params->ch_width, sap_ch_freq,
2873 				     old_ch_width);
2874 	}
2875 
2876 	if (*con_ch_freq &&
2877 	    pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params)
2878 		pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params(
2879 			psoc, sap_vdev_id, ch_freq, ch_params);
2880 
2881 	return QDF_STATUS_SUCCESS;
2882 }
2883 
2884 void policy_mgr_check_concurrent_intf_and_restart_sap(
2885 		struct wlan_objmgr_psoc *psoc, bool is_acs_mode)
2886 {
2887 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2888 	uint32_t mcc_to_scc_switch;
2889 	uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
2890 	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
2891 	uint32_t cc_count = 0;
2892 	uint32_t timeout_ms = 0;
2893 	bool restart_sap = false;
2894 	uint32_t sap_freq;
2895 	/*
2896 	 * if no sta, sap/p2p go may need switch channel for band
2897 	 * capability change.
2898 	 * If sta exist, sap/p2p go may need switch channel to force scc
2899 	 */
2900 	bool sta_check = false, gc_check = false;
2901 
2902 	pm_ctx = policy_mgr_get_context(psoc);
2903 	if (!pm_ctx) {
2904 		policy_mgr_err("Invalid context");
2905 		return;
2906 	}
2907 	if (!pm_ctx->sta_ap_intf_check_work_info) {
2908 		policy_mgr_err("Invalid sta_ap_intf_check_work_info");
2909 		return;
2910 	}
2911 	if (!policy_mgr_is_sap_go_existed(psoc)) {
2912 		policy_mgr_debug(
2913 			"No action taken at check_concurrent_intf_and_restart_sap");
2914 		return;
2915 	}
2916 	/*
2917 	 * If STA+SAP sessions are on DFS channel and STA+SAP SCC is
2918 	 * enabled on DFS channel then move the SAP out of DFS channel
2919 	 * as soon as STA gets disconnect.
2920 	 * If STA+SAP sessions are on unsafe channel and STA+SAP SCC is
2921 	 * enabled on unsafe channel then move the SAP to safe channel
2922 	 * as soon as STA disconnected.
2923 	 */
2924 	if (policy_mgr_is_sap_restart_required_after_sta_disconnect(
2925 			psoc, INVALID_VDEV_ID, &sap_freq, is_acs_mode)) {
2926 		policy_mgr_debug("move the SAP to configured channel %u",
2927 				 sap_freq);
2928 		restart_sap = true;
2929 		goto sap_restart;
2930 	}
2931 
2932 	/*
2933 	 * force SCC with STA+STA+SAP will need some additional logic
2934 	 */
2935 	cc_count = policy_mgr_get_mode_specific_conn_info(
2936 				psoc, &op_ch_freq_list[cc_count],
2937 				&vdev_id[cc_count], PM_STA_MODE);
2938 	if (!cc_count) {
2939 		policy_mgr_debug("Could not get STA operating channel&vdevid");
2940 	}
2941 
2942 	sta_check = !cc_count ||
2943 		    policy_mgr_valid_sta_channel_check(psoc, op_ch_freq_list[0]);
2944 
2945 	cc_count = 0;
2946 	cc_count = policy_mgr_get_mode_specific_conn_info(
2947 				psoc, &op_ch_freq_list[cc_count],
2948 				&vdev_id[cc_count], PM_P2P_CLIENT_MODE);
2949 	if (!cc_count)
2950 		policy_mgr_debug("Could not get GC operating channel&vdevid");
2951 
2952 	gc_check = !!cc_count;
2953 	policy_mgr_debug("gc_check: %d", gc_check);
2954 
2955 	mcc_to_scc_switch =
2956 		policy_mgr_get_mcc_to_scc_switch_mode(psoc);
2957 	policy_mgr_debug("MCC to SCC switch: %d chan: %d",
2958 			 mcc_to_scc_switch, op_ch_freq_list[0]);
2959 sap_restart:
2960 	/*
2961 	 * If sta_sap_scc_on_dfs_chan is true then standalone SAP is not
2962 	 * allowed on DFS channel. SAP is allowed on DFS channel only when STA
2963 	 * is already connected on that channel.
2964 	 * In following condition restart_sap will be true if
2965 	 * sta_sap_scc_on_dfs_chan is true and SAP is on DFS channel.
2966 	 * This scenario can come if STA+SAP are operating on DFS channel and
2967 	 * STA gets disconnected.
2968 	 */
2969 	if (restart_sap ||
2970 	    ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) &&
2971 	    (sta_check || gc_check))) {
2972 		if (!pm_ctx->sta_ap_intf_check_work_info) {
2973 			policy_mgr_err("invalid sta_ap_intf_check_work_info");
2974 			return;
2975 		}
2976 
2977 		policy_mgr_debug("Checking for Concurrent Change interference");
2978 
2979 		if (policy_mgr_mode_specific_connection_count(
2980 					psoc, PM_P2P_GO_MODE, NULL))
2981 			timeout_ms = MAX_NOA_TIME;
2982 
2983 		if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
2984 					    timeout_ms)) {
2985 			policy_mgr_debug("change interface request already queued");
2986 			return;
2987 		}
2988 	}
2989 }
2990 
2991 bool policy_mgr_check_bw_with_unsafe_chan_freq(struct wlan_objmgr_psoc *psoc,
2992 					       qdf_freq_t center_freq,
2993 					       enum phy_ch_width ch_width)
2994 {
2995 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2996 	uint32_t freq_start, freq_end, bw, i, unsafe_chan_freq;
2997 
2998 	pm_ctx = policy_mgr_get_context(psoc);
2999 	if (!pm_ctx) {
3000 		policy_mgr_err("Invalid Context");
3001 		return true;
3002 	}
3003 
3004 	if (ch_width <= CH_WIDTH_20MHZ || !center_freq)
3005 		return true;
3006 
3007 	if (!pm_ctx->unsafe_channel_count)
3008 		return true;
3009 
3010 	bw = wlan_reg_get_bw_value(ch_width);
3011 	freq_start = center_freq - bw / 2;
3012 	freq_end = center_freq + bw / 2;
3013 
3014 	for (i = 0; i < pm_ctx->unsafe_channel_count; i++) {
3015 		unsafe_chan_freq = pm_ctx->unsafe_channel_list[i];
3016 		if (unsafe_chan_freq > freq_start &&
3017 		    unsafe_chan_freq < freq_end) {
3018 			policy_mgr_debug("unsafe ch freq %d is in range %d-%d",
3019 					 unsafe_chan_freq,
3020 					 freq_start,
3021 					 freq_end);
3022 			return false;
3023 		}
3024 	}
3025 	return true;
3026 }
3027 
3028 /**
3029  * policy_mgr_change_sap_channel_with_csa() - Move SAP channel using (E)CSA
3030  * @psoc: PSOC object information
3031  * @vdev_id: Vdev id
3032  * @ch_freq: Channel to change
3033  * @ch_width: channel width to change
3034  * @forced: Force to switch channel, ignore SCC/MCC check
3035  *
3036  * Invoke the callback function to change SAP channel using (E)CSA
3037  *
3038  * Return: QDF_STATUS_SUCCESS for success
3039  */
3040 QDF_STATUS
3041 policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc,
3042 				       uint8_t vdev_id, uint32_t ch_freq,
3043 				       uint32_t ch_width, bool forced)
3044 {
3045 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3046 	struct ch_params ch_params = {0};
3047 	qdf_freq_t center_freq;
3048 	QDF_STATUS status;
3049 
3050 	pm_ctx = policy_mgr_get_context(psoc);
3051 	if (!pm_ctx) {
3052 		policy_mgr_err("Invalid context");
3053 		return QDF_STATUS_E_INVAL;
3054 	}
3055 	if (pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params) {
3056 		ch_params.ch_width = ch_width;
3057 		status = pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params(
3058 			psoc, vdev_id, ch_freq, &ch_params);
3059 		if (QDF_IS_STATUS_SUCCESS(status) &&
3060 		    ch_width > ch_params.ch_width)
3061 			ch_width = ch_params.ch_width;
3062 	}
3063 
3064 	if (ch_params.mhz_freq_seg1)
3065 		center_freq = ch_params.mhz_freq_seg1;
3066 	else
3067 		center_freq = ch_params.mhz_freq_seg0;
3068 
3069 	if (!policy_mgr_check_bw_with_unsafe_chan_freq(psoc,
3070 						       center_freq,
3071 						       ch_width)) {
3072 		policy_mgr_info("SAP bw shrink to 20M for unsafe");
3073 		ch_width = CH_WIDTH_20MHZ;
3074 	}
3075 
3076 	if (pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb) {
3077 		policy_mgr_info("SAP change change without restart");
3078 		status = pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb(psoc,
3079 								       vdev_id,
3080 								       ch_freq,
3081 								       ch_width,
3082 								       forced);
3083 	} else {
3084 		status = QDF_STATUS_E_INVAL;
3085 	}
3086 
3087 	return status;
3088 }
3089 #endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */
3090 
3091 QDF_STATUS
3092 policy_mgr_sta_sap_dfs_scc_conc_check(struct wlan_objmgr_psoc *psoc,
3093 				      uint8_t vdev_id,
3094 				      struct csa_offload_params *csa_event)
3095 {
3096 	uint8_t concur_vdev_id, i;
3097 	bool move_sap_go_first;
3098 	enum hw_mode_bandwidth bw;
3099 	qdf_freq_t cur_freq, new_freq;
3100 	struct wlan_objmgr_vdev *vdev, *conc_vdev;
3101 	struct wlan_objmgr_pdev *pdev;
3102 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3103 	enum policy_mgr_con_mode cur_mode;
3104 	enum policy_mgr_con_mode concur_mode = PM_MAX_NUM_OF_MODE;
3105 
3106 	pm_ctx = policy_mgr_get_context(psoc);
3107 	if (!pm_ctx) {
3108 		policy_mgr_err("Invalid context");
3109 		return QDF_STATUS_E_INVAL;
3110 	}
3111 	if (!csa_event) {
3112 		policy_mgr_err("CSA IE Received event is NULL");
3113 		return QDF_STATUS_E_INVAL;
3114 	}
3115 
3116 	policy_mgr_get_dfs_sta_sap_go_scc_movement(psoc, &move_sap_go_first);
3117 	if (!move_sap_go_first) {
3118 		policy_mgr_err("g_move_sap_go_1st_on_dfs_sta_csa is disabled");
3119 		return QDF_STATUS_E_NOSUPPORT;
3120 	}
3121 
3122 	cur_mode = policy_mgr_get_mode_by_vdev_id(psoc, vdev_id);
3123 	if (cur_mode != PM_STA_MODE) {
3124 		policy_mgr_err("CSA received on non-STA connection");
3125 		return QDF_STATUS_E_INVAL;
3126 	}
3127 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
3128 						    WLAN_POLICY_MGR_ID);
3129 	if (!vdev) {
3130 		policy_mgr_err("vdev is NULL");
3131 		return QDF_STATUS_E_INVAL;
3132 	}
3133 	pdev = wlan_vdev_get_pdev(vdev);
3134 	cur_freq = wlan_get_operation_chan_freq_vdev_id(pdev, vdev_id);
3135 
3136 	if (!wlan_reg_is_dfs_for_freq(pdev, cur_freq) &&
3137 	    !wlan_reg_is_freq_indoor(pdev, cur_freq)) {
3138 		policy_mgr_err("SAP / GO operating channel is non-DFS");
3139 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
3140 		return QDF_STATUS_E_INVAL;
3141 	}
3142 
3143 	/* Check if there is any SAP / GO operating on the same channel or not
3144 	 * If yes, then get the current bandwidth and vdev_id of concurrent SAP
3145 	 * or GO and trigger channel switch to new channel received in CSA on
3146 	 * STA interface. If this new channel is DFS then trigger channel
3147 	 * switch to non-DFS channel. Once STA moves to this new channel and
3148 	 * when it receives very first beacon, it will then enforce SCC again
3149 	 */
3150 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
3151 		if (pm_conc_connection_list[i].in_use &&
3152 		    pm_conc_connection_list[i].freq == cur_freq &&
3153 		    pm_conc_connection_list[i].vdev_id != vdev_id &&
3154 		    (pm_conc_connection_list[i].mode == PM_P2P_GO_MODE ||
3155 		     pm_conc_connection_list[i].mode == PM_SAP_MODE)) {
3156 			concur_mode = pm_conc_connection_list[i].mode;
3157 			bw = pm_conc_connection_list[i].bw;
3158 			concur_vdev_id = pm_conc_connection_list[i].vdev_id;
3159 			break;
3160 		}
3161 	}
3162 
3163 	/* If there is no concurrent SAP / GO, then return */
3164 	if (concur_mode == PM_MAX_NUM_OF_MODE) {
3165 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
3166 		return QDF_STATUS_E_INVAL;
3167 	}
3168 
3169 	conc_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, concur_vdev_id,
3170 							 WLAN_POLICY_MGR_ID);
3171 	if (!conc_vdev) {
3172 		policy_mgr_err("conc_vdev is NULL");
3173 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
3174 		return QDF_STATUS_E_INVAL;
3175 	}
3176 	wlan_vdev_mlme_set_sap_go_move_before_sta(conc_vdev, true);
3177 	wlan_vdev_mlme_set_sap_go_move_before_sta(vdev, true);
3178 	wlan_objmgr_vdev_release_ref(conc_vdev, WLAN_POLICY_MGR_ID);
3179 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
3180 
3181 	/*Change the CSA count*/
3182 	if (pm_ctx->sme_cbacks.sme_change_sap_csa_count)
3183 		/* Total 4 CSA frames are allowed so that GO / SAP
3184 		 * will move to new channel within 500ms
3185 		 */
3186 		pm_ctx->sme_cbacks.sme_change_sap_csa_count(4);
3187 	new_freq = csa_event->csa_chan_freq;
3188 
3189 	/* If the new channel is DFS or indoor, then select another channel
3190 	 * and switch the SAP / GO to avoid CAC. This will resume traffic on
3191 	 * SAP / GO interface immediately. Once STA moves to this new channel
3192 	 * and receives the very first beacon, then it will enforece SCC
3193 	 */
3194 	if (wlan_reg_is_dfs_for_freq(pdev, new_freq) ||
3195 	    wlan_reg_is_freq_indoor(pdev, new_freq)) {
3196 		if (wlan_reg_is_24ghz_ch_freq(new_freq)) {
3197 			new_freq = wlan_reg_min_24ghz_chan_freq();
3198 		} else if (wlan_reg_is_5ghz_ch_freq(new_freq)) {
3199 			new_freq = wlan_reg_min_5ghz_chan_freq();
3200 			/* if none of the 5G channel is non-DFS */
3201 			if (wlan_reg_is_dfs_for_freq(pdev, new_freq) ||
3202 			    wlan_reg_is_freq_indoor(pdev, new_freq))
3203 				new_freq = policy_mgr_get_nondfs_preferred_channel(psoc,
3204 										   concur_mode,
3205 										   true,
3206 										   concur_vdev_id);
3207 		} else {
3208 			new_freq = wlan_reg_min_6ghz_chan_freq();
3209 		}
3210 	}
3211 	policy_mgr_debug("Restart vdev: %u on freq: %u",
3212 			 concur_vdev_id, new_freq);
3213 
3214 	return policy_mgr_change_sap_channel_with_csa(psoc, concur_vdev_id,
3215 						      new_freq, bw, true);
3216 }
3217 
3218 void policy_mgr_sta_sap_dfs_enforce_scc(struct wlan_objmgr_psoc *psoc,
3219 					uint8_t vdev_id)
3220 {
3221 	bool is_sap_go_moved_before_sta, move_sap_go_first;
3222 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3223 	struct wlan_objmgr_vdev *vdev;
3224 	struct wlan_objmgr_pdev *pdev;
3225 	enum policy_mgr_con_mode cur_mode;
3226 
3227 	pm_ctx = policy_mgr_get_context(psoc);
3228 	if (!pm_ctx) {
3229 		policy_mgr_err("Invalid context");
3230 		return;
3231 	}
3232 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
3233 						    WLAN_POLICY_MGR_ID);
3234 	if (!vdev) {
3235 		policy_mgr_err("vdev is NULL");
3236 		return;
3237 	}
3238 	is_sap_go_moved_before_sta =
3239 			wlan_vdev_mlme_is_sap_go_move_before_sta(vdev);
3240 	pdev = wlan_vdev_get_pdev(vdev);
3241 	wlan_vdev_mlme_set_sap_go_move_before_sta(vdev, false);
3242 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
3243 
3244 	policy_mgr_get_dfs_sta_sap_go_scc_movement(psoc, &move_sap_go_first);
3245 	if (!is_sap_go_moved_before_sta || !move_sap_go_first) {
3246 		policy_mgr_debug("SAP / GO moved before STA: %u INI g_move_sap_go_1st_on_dfs_sta_csa: %u",
3247 				 is_sap_go_moved_before_sta, move_sap_go_first);
3248 		return;
3249 	}
3250 
3251 	cur_mode = policy_mgr_get_mode_by_vdev_id(psoc, vdev_id);
3252 	if (cur_mode != PM_STA_MODE) {
3253 		policy_mgr_err("CSA received on non-STA connection");
3254 		return;
3255 	}
3256 
3257 	policy_mgr_debug("Enforce SCC");
3258 	policy_mgr_check_concurrent_intf_and_restart_sap(psoc, false);
3259 }
3260 
3261 #ifdef WLAN_FEATURE_P2P_P2P_STA
3262 void policy_mgr_do_go_plus_go_force_scc(struct wlan_objmgr_psoc *psoc,
3263 					uint8_t vdev_id, uint32_t ch_freq,
3264 					uint32_t ch_width)
3265 {
3266 	uint8_t total_connection;
3267 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3268 
3269 	pm_ctx = policy_mgr_get_context(psoc);
3270 	if (!pm_ctx) {
3271 		policy_mgr_err("Invalid Context");
3272 		return;
3273 	}
3274 
3275 	total_connection = policy_mgr_mode_specific_connection_count(
3276 						psoc, PM_P2P_GO_MODE, NULL);
3277 
3278 	policy_mgr_debug("Total p2p go connection %d", total_connection);
3279 
3280 	/* If any p2p disconnected, don't do csa */
3281 	if (total_connection > 1) {
3282 		if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason)
3283 			pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(
3284 				psoc, vdev_id,
3285 				CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL);
3286 
3287 		policy_mgr_change_sap_channel_with_csa(psoc, vdev_id,
3288 						       ch_freq, ch_width, true);
3289 	}
3290 }
3291 
3292 void policy_mgr_process_forcescc_for_go(struct wlan_objmgr_psoc *psoc,
3293 					uint8_t vdev_id, uint32_t ch_freq,
3294 					uint32_t ch_width,
3295 					enum policy_mgr_con_mode mode)
3296 {
3297 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3298 	struct sta_ap_intf_check_work_ctx *work_info;
3299 
3300 	pm_ctx = policy_mgr_get_context(psoc);
3301 	if (!pm_ctx) {
3302 		policy_mgr_err("Invalid Context");
3303 		return;
3304 	}
3305 	if (!pm_ctx->sta_ap_intf_check_work_info) {
3306 		policy_mgr_err("invalid work info");
3307 		return;
3308 	}
3309 	work_info = pm_ctx->sta_ap_intf_check_work_info;
3310 	if (mode == PM_P2P_GO_MODE) {
3311 		work_info->go_plus_go_force_scc.vdev_id = vdev_id;
3312 		work_info->go_plus_go_force_scc.ch_freq = ch_freq;
3313 		work_info->go_plus_go_force_scc.ch_width = ch_width;
3314 	}
3315 
3316 	if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
3317 				    WAIT_BEFORE_GO_FORCESCC_RESTART))
3318 		policy_mgr_debug("change interface request already queued");
3319 }
3320 #endif
3321 
3322 bool policy_mgr_is_chan_switch_in_progress(struct wlan_objmgr_psoc *psoc)
3323 {
3324 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3325 
3326 	pm_ctx = policy_mgr_get_context(psoc);
3327 	if (!pm_ctx) {
3328 		policy_mgr_err("Invalid pm context");
3329 		return false;
3330 	}
3331 	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
3332 	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
3333 		policy_mgr_debug("channel switch is in progress");
3334 		return true;
3335 	}
3336 
3337 	return false;
3338 }
3339 
3340 QDF_STATUS policy_mgr_wait_chan_switch_complete_evt(
3341 		struct wlan_objmgr_psoc *psoc)
3342 {
3343 	QDF_STATUS status;
3344 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3345 
3346 	pm_ctx = policy_mgr_get_context(psoc);
3347 
3348 	if (!pm_ctx) {
3349 		policy_mgr_err("Invalid context");
3350 		return QDF_STATUS_E_FAILURE;
3351 	}
3352 
3353 	status = qdf_wait_single_event(
3354 				&pm_ctx->channel_switch_complete_evt,
3355 				CHANNEL_SWITCH_COMPLETE_TIMEOUT);
3356 	if (QDF_IS_STATUS_ERROR(status))
3357 		policy_mgr_err("wait for event failed, still continue with channel switch");
3358 
3359 	return status;
3360 }
3361 
3362 static void __policy_mgr_is_ap_start_in_progress(struct wlan_objmgr_pdev *pdev,
3363 						 void *object, void *arg)
3364 {
3365 	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
3366 	uint32_t *ap_starting_vdev_id = (uint32_t *)arg;
3367 	enum wlan_serialization_cmd_type cmd_type;
3368 	enum QDF_OPMODE op_mode;
3369 
3370 	if (!vdev || !ap_starting_vdev_id)
3371 		return;
3372 	if (*ap_starting_vdev_id != WLAN_INVALID_VDEV_ID)
3373 		return;
3374 	op_mode = wlan_vdev_mlme_get_opmode(vdev);
3375 	if (op_mode != QDF_SAP_MODE && op_mode != QDF_P2P_GO_MODE &&
3376 	    op_mode != QDF_NDI_MODE)
3377 		return;
3378 	/* Check AP start is present in active and pending queue or not */
3379 	cmd_type = wlan_serialization_get_vdev_active_cmd_type(vdev);
3380 	if (cmd_type == WLAN_SER_CMD_VDEV_START_BSS ||
3381 	    wlan_ser_is_non_scan_cmd_type_in_vdev_queue(
3382 			vdev, WLAN_SER_CMD_VDEV_START_BSS)) {
3383 		*ap_starting_vdev_id = wlan_vdev_get_id(vdev);
3384 		policy_mgr_debug("vdev %d op mode %d start bss is pending",
3385 				 *ap_starting_vdev_id, op_mode);
3386 	}
3387 }
3388 
3389 bool policy_mgr_is_ap_start_in_progress(struct wlan_objmgr_psoc *psoc)
3390 {
3391 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3392 	uint32_t ap_starting_vdev_id = WLAN_INVALID_VDEV_ID;
3393 
3394 	pm_ctx = policy_mgr_get_context(psoc);
3395 	if (!pm_ctx) {
3396 		policy_mgr_err("Invalid pm context");
3397 		return false;
3398 	}
3399 
3400 	wlan_objmgr_pdev_iterate_obj_list(pm_ctx->pdev, WLAN_VDEV_OP,
3401 					  __policy_mgr_is_ap_start_in_progress,
3402 					  &ap_starting_vdev_id, 0,
3403 					  WLAN_POLICY_MGR_ID);
3404 
3405 	return ap_starting_vdev_id != WLAN_INVALID_VDEV_ID;
3406 }
3407 
3408 void policy_mgr_process_force_scc_for_nan(struct wlan_objmgr_psoc *psoc)
3409 {
3410 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3411 
3412 	pm_ctx = policy_mgr_get_context(psoc);
3413 	if (!pm_ctx) {
3414 		policy_mgr_err("Invalid Context");
3415 		return;
3416 	}
3417 	if (!pm_ctx->sta_ap_intf_check_work_info) {
3418 		policy_mgr_err("invalid work info");
3419 		return;
3420 	}
3421 
3422 	pm_ctx->sta_ap_intf_check_work_info->nan_force_scc_in_progress = true;
3423 
3424 	if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 0))
3425 		policy_mgr_debug("change interface request already queued");
3426 }
3427 
3428 QDF_STATUS policy_mgr_wait_for_connection_update(struct wlan_objmgr_psoc *psoc)
3429 {
3430 	QDF_STATUS status;
3431 	struct policy_mgr_psoc_priv_obj *policy_mgr_context;
3432 
3433 	policy_mgr_context = policy_mgr_get_context(psoc);
3434 	if (!policy_mgr_context) {
3435 		policy_mgr_err("Invalid context");
3436 		return QDF_STATUS_E_FAILURE;
3437 	}
3438 
3439 	status = qdf_wait_single_event(
3440 			&policy_mgr_context->connection_update_done_evt,
3441 			CONNECTION_UPDATE_TIMEOUT);
3442 
3443 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3444 		policy_mgr_err("wait for event failed");
3445 		return QDF_STATUS_E_FAILURE;
3446 	}
3447 
3448 	return QDF_STATUS_SUCCESS;
3449 }
3450 
3451 QDF_STATUS policy_mgr_reset_connection_update(struct wlan_objmgr_psoc *psoc)
3452 {
3453 	QDF_STATUS status;
3454 	struct policy_mgr_psoc_priv_obj *policy_mgr_context;
3455 
3456 	policy_mgr_context = policy_mgr_get_context(psoc);
3457 	if (!policy_mgr_context) {
3458 		policy_mgr_err("Invalid context");
3459 		return QDF_STATUS_E_FAILURE;
3460 	}
3461 
3462 	status = qdf_event_reset(
3463 		&policy_mgr_context->connection_update_done_evt);
3464 
3465 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3466 		policy_mgr_err("clear event failed");
3467 		return QDF_STATUS_E_FAILURE;
3468 	}
3469 
3470 	return QDF_STATUS_SUCCESS;
3471 }
3472 
3473 void policy_mgr_reset_hw_mode_change(struct wlan_objmgr_psoc *psoc)
3474 {
3475 	policy_mgr_err("Clear hw mode change and connection update evt");
3476 	policy_mgr_set_hw_mode_change_in_progress(
3477 			psoc, POLICY_MGR_HW_MODE_NOT_IN_PROGRESS);
3478 	policy_mgr_reset_connection_update(psoc);
3479 }
3480 
3481 QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc)
3482 {
3483 	QDF_STATUS status;
3484 	struct policy_mgr_psoc_priv_obj *policy_mgr_context;
3485 
3486 	policy_mgr_context = policy_mgr_get_context(psoc);
3487 	if (!policy_mgr_context) {
3488 		policy_mgr_err("Invalid context");
3489 		return QDF_STATUS_E_FAILURE;
3490 	}
3491 
3492 	status = qdf_event_set(&policy_mgr_context->connection_update_done_evt);
3493 
3494 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3495 		policy_mgr_err("set event failed");
3496 		return QDF_STATUS_E_FAILURE;
3497 	}
3498 
3499 	return QDF_STATUS_SUCCESS;
3500 }
3501 
3502 QDF_STATUS policy_mgr_set_chan_switch_complete_evt(
3503 		struct wlan_objmgr_psoc *psoc)
3504 {
3505 	QDF_STATUS status;
3506 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3507 
3508 	pm_ctx = policy_mgr_get_context(psoc);
3509 
3510 	if (!pm_ctx) {
3511 		policy_mgr_err("Invalid context");
3512 		return QDF_STATUS_E_FAILURE;
3513 	}
3514 
3515 	/*
3516 	 * Set channel_switch_complete_evt only if no vdev has channel switch
3517 	 * in progress.
3518 	 */
3519 	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
3520 	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
3521 		policy_mgr_info("Not all channel switch completed");
3522 		return QDF_STATUS_SUCCESS;
3523 	}
3524 
3525 	status = qdf_event_set_all(&pm_ctx->channel_switch_complete_evt);
3526 
3527 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3528 		policy_mgr_err("set event failed");
3529 		return QDF_STATUS_E_FAILURE;
3530 	}
3531 
3532 	return QDF_STATUS_SUCCESS;
3533 }
3534 
3535 QDF_STATUS policy_mgr_reset_chan_switch_complete_evt(
3536 		struct wlan_objmgr_psoc *psoc)
3537 {
3538 	QDF_STATUS status;
3539 	struct policy_mgr_psoc_priv_obj *policy_mgr_context;
3540 
3541 	policy_mgr_context = policy_mgr_get_context(psoc);
3542 
3543 	if (!policy_mgr_context) {
3544 		policy_mgr_err("Invalid context");
3545 		return QDF_STATUS_E_FAILURE;
3546 	}
3547 	status = qdf_event_reset(
3548 			&policy_mgr_context->channel_switch_complete_evt);
3549 
3550 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3551 		policy_mgr_err("reset event failed");
3552 		return QDF_STATUS_E_FAILURE;
3553 	}
3554 
3555 	return QDF_STATUS_SUCCESS;
3556 }
3557 
3558 QDF_STATUS policy_mgr_set_opportunistic_update(struct wlan_objmgr_psoc *psoc)
3559 {
3560 	QDF_STATUS status;
3561 	struct policy_mgr_psoc_priv_obj *policy_mgr_context;
3562 
3563 	policy_mgr_context = policy_mgr_get_context(psoc);
3564 	if (!policy_mgr_context) {
3565 		policy_mgr_err("Invalid context");
3566 		return QDF_STATUS_E_FAILURE;
3567 	}
3568 
3569 	status = qdf_event_set(
3570 			&policy_mgr_context->opportunistic_update_done_evt);
3571 
3572 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3573 		policy_mgr_err("set event failed");
3574 		return QDF_STATUS_E_FAILURE;
3575 	}
3576 
3577 	return QDF_STATUS_SUCCESS;
3578 }
3579 
3580 QDF_STATUS policy_mgr_stop_opportunistic_timer(struct wlan_objmgr_psoc *psoc)
3581 {
3582 	struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
3583 
3584 	policy_mgr_ctx = policy_mgr_get_context(psoc);
3585 	if (!policy_mgr_ctx) {
3586 		policy_mgr_err("Invalid context");
3587 		return QDF_STATUS_E_FAILURE;
3588 	}
3589 
3590 	if (policy_mgr_ctx->dbs_opportunistic_timer.state !=
3591 	    QDF_TIMER_STATE_RUNNING)
3592 		return QDF_STATUS_SUCCESS;
3593 
3594 	qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer);
3595 	return QDF_STATUS_SUCCESS;
3596 }
3597 
3598 QDF_STATUS policy_mgr_restart_opportunistic_timer(
3599 		struct wlan_objmgr_psoc *psoc, bool check_state)
3600 {
3601 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3602 	struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
3603 
3604 	if (policy_mgr_is_hwmode_offload_enabled(psoc)) {
3605 		policy_mgr_debug("HW mode selection offload is enabled");
3606 		return QDF_STATUS_E_NOSUPPORT;
3607 	}
3608 
3609 	policy_mgr_ctx = policy_mgr_get_context(psoc);
3610 	if (!policy_mgr_ctx) {
3611 		policy_mgr_err("Invalid context");
3612 		return status;
3613 	}
3614 
3615 	if (check_state &&
3616 			QDF_TIMER_STATE_RUNNING !=
3617 			policy_mgr_ctx->dbs_opportunistic_timer.state)
3618 		return status;
3619 
3620 	qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer);
3621 
3622 	status = qdf_mc_timer_start(
3623 			&policy_mgr_ctx->dbs_opportunistic_timer,
3624 			DBS_OPPORTUNISTIC_TIME * 1000);
3625 
3626 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3627 		policy_mgr_err("failed to start opportunistic timer");
3628 		return status;
3629 	}
3630 
3631 	return status;
3632 }
3633 
3634 QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch(
3635 			struct wlan_objmgr_psoc *psoc, uint8_t session_id)
3636 {
3637 	QDF_STATUS status = QDF_STATUS_E_FAILURE, qdf_status;
3638 	enum policy_mgr_conc_next_action action;
3639 
3640 	if (policy_mgr_is_hwmode_offload_enabled(psoc)) {
3641 		policy_mgr_debug("HW mode selection offload is enabled");
3642 		return QDF_STATUS_E_NOSUPPORT;
3643 	}
3644 
3645 	if (!policy_mgr_is_hw_dbs_capable(psoc)) {
3646 		policy_mgr_rl_debug("PM/DBS is disabled");
3647 		return status;
3648 	}
3649 
3650 	action = (*policy_mgr_get_current_pref_hw_mode_ptr)(psoc);
3651 	if ((action != PM_DBS_DOWNGRADE) &&
3652 	    (action != PM_SINGLE_MAC_UPGRADE) &&
3653 	    (action != PM_DBS1_DOWNGRADE) &&
3654 	    (action != PM_DBS2_DOWNGRADE)) {
3655 		policy_mgr_err("Invalid action: %d", action);
3656 		status = QDF_STATUS_SUCCESS;
3657 		goto done;
3658 	}
3659 
3660 	policy_mgr_debug("action:%d session id:%d", action, session_id);
3661 
3662 	/* Opportunistic timer is started, PM will check if MCC upgrade can be
3663 	 * done on timer expiry. This avoids any possible ping pong effect
3664 	 * as well.
3665 	 */
3666 	if (action == PM_SINGLE_MAC_UPGRADE) {
3667 		qdf_status = policy_mgr_restart_opportunistic_timer(
3668 			psoc, false);
3669 		if (QDF_IS_STATUS_SUCCESS(qdf_status))
3670 			policy_mgr_debug("opportunistic timer for MCC upgrade");
3671 		goto done;
3672 	}
3673 
3674 	/* For DBS, we want to move right away to DBS mode */
3675 	status = policy_mgr_next_actions(psoc, session_id, action,
3676 			POLICY_MGR_UPDATE_REASON_AFTER_CHANNEL_SWITCH,
3677 			POLICY_MGR_DEF_REQ_ID);
3678 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3679 		policy_mgr_err("no set hw mode command was issued");
3680 		goto done;
3681 	}
3682 done:
3683 	/* success must be returned only when a set hw mode was done */
3684 	return status;
3685 }
3686 
3687 QDF_STATUS policy_mgr_check_and_set_hw_mode_for_channel_switch(
3688 		struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
3689 		uint32_t ch_freq, enum policy_mgr_conn_update_reason reason)
3690 {
3691 	QDF_STATUS status;
3692 	struct policy_mgr_conc_connection_info info;
3693 	uint8_t num_cxn_del = 0;
3694 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3695 	enum policy_mgr_conc_next_action next_action = PM_NOP;
3696 
3697 	pm_ctx = policy_mgr_get_context(psoc);
3698 	if (!pm_ctx) {
3699 		policy_mgr_err("Invalid context");
3700 		return QDF_STATUS_E_FAILURE;
3701 	}
3702 
3703 	if (!policy_mgr_is_hw_dbs_capable(psoc) ||
3704 	    (!policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
3705 	    !policy_mgr_is_hw_dbs_required_for_band(
3706 					psoc, HW_MODE_MAC_BAND_2G)))
3707 		return QDF_STATUS_E_NOSUPPORT;
3708 
3709 	/*
3710 	 * Stop opportunistic timer as current connection info will change once
3711 	 * channel is switched and thus if required it will be started once
3712 	 * channel switch is completed. With new connection info.
3713 	 */
3714 	policy_mgr_stop_opportunistic_timer(psoc);
3715 
3716 	if (wlan_reg_freq_to_band(ch_freq) != REG_BAND_2G)
3717 		return QDF_STATUS_E_NOSUPPORT;
3718 
3719 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3720 	/*
3721 	 * Store the connection's parameter and temporarily delete it
3722 	 * from the concurrency table. This way the allow concurrency
3723 	 * check can be used as though a new connection is coming up,
3724 	 * after check, restore the connection to concurrency table.
3725 	 */
3726 	policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id,
3727 						      &info, &num_cxn_del);
3728 
3729 	status = policy_mgr_get_next_action(psoc, vdev_id, ch_freq,
3730 					    reason, &next_action);
3731 	/* Restore the connection entry */
3732 	if (num_cxn_del)
3733 		policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del);
3734 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3735 
3736 	if (QDF_IS_STATUS_ERROR(status))
3737 		goto chk_opportunistic_timer;
3738 
3739 	if (PM_NOP != next_action)
3740 		status = policy_mgr_next_actions(psoc, vdev_id,
3741 						 next_action, reason,
3742 						 POLICY_MGR_DEF_REQ_ID);
3743 	else
3744 		status = QDF_STATUS_E_NOSUPPORT;
3745 
3746 chk_opportunistic_timer:
3747 	/*
3748 	 * If hw mode change failed restart the opportunistic timer to
3749 	 * Switch to single mac if required.
3750 	 */
3751 	if (status == QDF_STATUS_E_FAILURE) {
3752 		policy_mgr_err("Failed to update HW modeStatus %d", status);
3753 		policy_mgr_check_n_start_opportunistic_timer(psoc);
3754 	}
3755 
3756 	return status;
3757 }
3758 
3759 void policy_mgr_checkn_update_hw_mode_single_mac_mode(
3760 		struct wlan_objmgr_psoc *psoc, uint32_t ch_freq)
3761 {
3762 	uint8_t i;
3763 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3764 	bool dbs_required_2g;
3765 	pm_ctx = policy_mgr_get_context(psoc);
3766 	if (!pm_ctx) {
3767 		policy_mgr_err("Invalid Context");
3768 		return;
3769 	}
3770 
3771 	if (!policy_mgr_is_hw_dbs_capable(psoc))
3772 		return;
3773 
3774 	if (QDF_TIMER_STATE_RUNNING == pm_ctx->dbs_opportunistic_timer.state)
3775 		qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
3776 
3777 	dbs_required_2g =
3778 	    policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G);
3779 
3780 	if (dbs_required_2g && WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) {
3781 		policy_mgr_debug("DBS required for new connection");
3782 		return;
3783 	}
3784 
3785 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3786 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
3787 		if (pm_conc_connection_list[i].in_use) {
3788 			if (!WLAN_REG_IS_SAME_BAND_FREQS(
3789 			    ch_freq, pm_conc_connection_list[i].freq) &&
3790 			    (WLAN_REG_IS_24GHZ_CH_FREQ(
3791 			    pm_conc_connection_list[i].freq) ||
3792 			    WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))) {
3793 				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3794 				policy_mgr_debug("DBS required");
3795 				return;
3796 			}
3797 			if (dbs_required_2g && WLAN_REG_IS_24GHZ_CH_FREQ(
3798 			    pm_conc_connection_list[i].freq)) {
3799 				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3800 				policy_mgr_debug("DBS required");
3801 				return;
3802 			}
3803 		}
3804 	}
3805 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3806 	pm_dbs_opportunistic_timer_handler((void *)psoc);
3807 }
3808 
3809 void policy_mgr_check_and_stop_opportunistic_timer(
3810 	struct wlan_objmgr_psoc *psoc, uint8_t id)
3811 {
3812 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3813 	enum policy_mgr_conc_next_action action = PM_NOP;
3814 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3815 	enum policy_mgr_conn_update_reason reason;
3816 
3817 	pm_ctx = policy_mgr_get_context(psoc);
3818 	if (!pm_ctx) {
3819 		policy_mgr_err("Invalid Context");
3820 		return;
3821 	}
3822 	if (QDF_TIMER_STATE_RUNNING ==
3823 		pm_ctx->dbs_opportunistic_timer.state) {
3824 		qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
3825 		action = policy_mgr_need_opportunistic_upgrade(psoc, &reason);
3826 		if (action) {
3827 			qdf_event_reset(&pm_ctx->opportunistic_update_done_evt);
3828 			status = policy_mgr_next_actions(psoc, id, action,
3829 							 reason,
3830 							 POLICY_MGR_DEF_REQ_ID);
3831 			if (status != QDF_STATUS_SUCCESS) {
3832 				policy_mgr_err("Failed in policy_mgr_next_actions");
3833 				return;
3834 			}
3835 			status = qdf_wait_single_event(
3836 					&pm_ctx->opportunistic_update_done_evt,
3837 					CONNECTION_UPDATE_TIMEOUT);
3838 
3839 			if (!QDF_IS_STATUS_SUCCESS(status)) {
3840 				policy_mgr_err("wait for event failed");
3841 				return;
3842 			}
3843 		}
3844 	}
3845 }
3846 
3847 void policy_mgr_set_hw_mode_change_in_progress(
3848 	struct wlan_objmgr_psoc *psoc, enum policy_mgr_hw_mode_change value)
3849 {
3850 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3851 
3852 	pm_ctx = policy_mgr_get_context(psoc);
3853 	if (!pm_ctx) {
3854 		policy_mgr_err("Invalid Context");
3855 		return;
3856 	}
3857 
3858 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3859 	pm_ctx->hw_mode_change_in_progress = value;
3860 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3861 
3862 	policy_mgr_debug("hw_mode_change_in_progress:%d", value);
3863 }
3864 
3865 enum policy_mgr_hw_mode_change policy_mgr_is_hw_mode_change_in_progress(
3866 	struct wlan_objmgr_psoc *psoc)
3867 {
3868 	enum policy_mgr_hw_mode_change value;
3869 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3870 
3871 	value = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
3872 
3873 	pm_ctx = policy_mgr_get_context(psoc);
3874 	if (!pm_ctx) {
3875 		policy_mgr_err("Invalid Context");
3876 		return value;
3877 	}
3878 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3879 	value = pm_ctx->hw_mode_change_in_progress;
3880 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3881 
3882 	return value;
3883 }
3884 
3885 enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index(
3886 	struct wlan_objmgr_psoc *psoc, uint32_t hw_mode_index)
3887 {
3888 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3889 	struct policy_mgr_hw_mode_params hw_mode;
3890 	enum policy_mgr_hw_mode_change value
3891 		= POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
3892 	QDF_STATUS status;
3893 
3894 	pm_ctx = policy_mgr_get_context(psoc);
3895 	if (!pm_ctx) {
3896 		policy_mgr_err("Invalid Context");
3897 		return value;
3898 	}
3899 
3900 	status = policy_mgr_get_hw_mode_from_idx(psoc, hw_mode_index, &hw_mode);
3901 	if (status != QDF_STATUS_SUCCESS) {
3902 		policy_mgr_err("Failed to get HW mode index");
3903 		return value;
3904 	}
3905 
3906 	if (hw_mode.dbs_cap) {
3907 		policy_mgr_debug("DBS is requested with HW (%d)",
3908 				 hw_mode_index);
3909 		value = POLICY_MGR_DBS_IN_PROGRESS;
3910 		goto ret_value;
3911 	}
3912 
3913 	if (hw_mode.sbs_cap) {
3914 		policy_mgr_debug("SBS is requested with HW (%d)",
3915 				 hw_mode_index);
3916 		value = POLICY_MGR_SBS_IN_PROGRESS;
3917 		goto ret_value;
3918 	}
3919 
3920 	value = POLICY_MGR_SMM_IN_PROGRESS;
3921 	policy_mgr_debug("SMM is requested with HW (%d)", hw_mode_index);
3922 
3923 ret_value:
3924 	return value;
3925 }
3926 
3927 #ifdef WLAN_FEATURE_TDLS_CONCURRENCIES
3928 bool
3929 policy_mgr_get_allowed_tdls_offchannel_freq(struct wlan_objmgr_psoc *psoc,
3930 					    struct wlan_objmgr_vdev *vdev,
3931 					    qdf_freq_t *ch_freq)
3932 {
3933 	struct connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
3934 	uint8_t connection_count, i, j, sta_vdev_id;
3935 
3936 	*ch_freq = 0;
3937 	/*
3938 	 * TDLS off channel is not allowed in any MCC scenario
3939 	 */
3940 	if (policy_mgr_current_concurrency_is_mcc(psoc)) {
3941 		policy_mgr_dump_current_concurrency(psoc);
3942 		policy_mgr_debug("TDLS off channel not allowed in MCC");
3943 		return false;
3944 	}
3945 
3946 	/*
3947 	 * TDLS offchannel is done only when STA is connected on 2G channel and
3948 	 * the current concurrency is not MCC
3949 	 */
3950 	if (!policy_mgr_is_sta_connected_2g(psoc)) {
3951 		policy_mgr_debug("STA not-connected on 2.4 Ghz");
3952 		return false;
3953 	}
3954 
3955 	/*
3956 	 * 2 Port DBS scenario - Allow non-STA vdev channel for
3957 	 * TDLS off-channel operation
3958 	 *
3959 	 * 3 Port Scenario - If STA Vdev is on SCC, allow TDLS off-channel on
3960 	 * the channel of vdev on the other MAC
3961 	 * If STA vdev is standalone on one mac, and scc on another mac, then
3962 	 * allow TDLS off channel on other mac scc channel
3963 	 */
3964 	sta_vdev_id = wlan_vdev_get_id(vdev);
3965 	connection_count = policy_mgr_get_connection_info(psoc, info);
3966 	switch (connection_count) {
3967 	case 1:
3968 		return true;
3969 	case 2:
3970 		/*
3971 		 * Allow all the 5GHz/6GHz channels when STA is in SCC
3972 		 */
3973 		if (policy_mgr_current_concurrency_is_scc(psoc)) {
3974 			*ch_freq = 0;
3975 			return true;
3976 		} else if (policy_mgr_is_current_hwmode_dbs(psoc)) {
3977 			/*
3978 			 * In DBS case, allow off-channel operation on the
3979 			 * other mac 5GHz/6GHz channel where the STA is not
3980 			 * present
3981 			 * Don't consider SBS case since STA should be
3982 			 * connected in 2.4GHz channel for TDLS
3983 			 * off-channel and MCC on SBS ex. 3 PORT
3984 			 * 2.4GHz STA + 5GHz Lower MCC + 5GHz Upper will
3985 			 * not be allowed
3986 			 */
3987 			if (sta_vdev_id == info[0].vdev_id)
3988 				*ch_freq = info[1].ch_freq;
3989 			else
3990 				*ch_freq = info[0].ch_freq;
3991 
3992 			return true;
3993 		}
3994 
3995 		break;
3996 	case 3:
3997 
3998 		/*
3999 		 * 3 Vdev SCC on 2.4GHz band. Allow TDLS off-channel operation
4000 		 * on all the 5GHz & 6GHz channels
4001 		 */
4002 		if (info[0].ch_freq == info[1].ch_freq &&
4003 		    info[0].ch_freq == info[2].ch_freq) {
4004 			*ch_freq = 0;
4005 			return true;
4006 		}
4007 
4008 		/*
4009 		 * DBS with SCC on one vdev scenario. Allow TDLS off-channel
4010 		 * on other mac frequency where STA is not present
4011 		 * SBS case is not considered since STA should be connected
4012 		 * on 2.4GHz and TDLS off-channel on SBS MCC is not allowed
4013 		 */
4014 		for (i = 0; i < connection_count; i++) {
4015 			for (j = i + 1; j < connection_count; j++) {
4016 				/*
4017 				 * Find 2 vdevs such that STA is one of the vdev
4018 				 * and STA + other vdev are not on same mac.
4019 				 * Return the foreign vdev frequency which is
4020 				 * not on same mac along with STA
4021 				 */
4022 				if (!policy_mgr_2_freq_always_on_same_mac(
4023 							psoc, info[i].ch_freq,
4024 							info[j].ch_freq)) {
4025 					if (sta_vdev_id == info[i].vdev_id) {
4026 						*ch_freq = info[j].ch_freq;
4027 						return true;
4028 					} else if (sta_vdev_id ==
4029 						   info[j].vdev_id) {
4030 						*ch_freq = info[i].ch_freq;
4031 						return true;
4032 					}
4033 				}
4034 			}
4035 		}
4036 
4037 		return false;
4038 	default:
4039 		policy_mgr_debug("TDLS off channel not allowed on > 3 port conc");
4040 		break;
4041 	}
4042 
4043 	return false;
4044 }
4045 #endif
4046