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