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