xref: /wlan-driver/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1 /*
2  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2024 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_core.c
22  *
23  * WLAN Concurrenct Connection Management functions
24  *
25  */
26 
27 /* Include files */
28 
29 #include "wlan_policy_mgr_i.h"
30 #include "qdf_types.h"
31 #include "qdf_trace.h"
32 #include "wlan_objmgr_global_obj.h"
33 #include "wlan_mlme_api.h"
34 #include "wlan_cm_roam_api.h"
35 #include "wlan_mlme_ucfg_api.h"
36 #include "wlan_cm_api.h"
37 #include "wlan_reg_ucfg_api.h"
38 #ifdef WLAN_FEATURE_11BE_MLO
39 #include "wlan_mlo_mgr_cmn.h"
40 #include "wlan_mlo_mgr_public_structs.h"
41 #endif
42 #include "wlan_cm_ucfg_api.h"
43 #include "target_if.h"
44 
45 #define POLICY_MGR_MAX_CON_STRING_LEN   230
46 #define LOWER_END_FREQ_5GHZ 4900
47 
48 static const uint16_t sap_mand_5g_freq_list[] = {5745, 5765, 5785, 5805};
49 
50 struct policy_mgr_conc_connection_info
51 	pm_conc_connection_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
52 
53 #ifdef WLAN_FEATURE_11BE_MLO
54 struct policy_mgr_disabled_ml_link_info
55 	pm_disabled_ml_links[MAX_NUMBER_OF_DISABLE_LINK];
56 #endif
57 
policy_mgr_get_context(struct wlan_objmgr_psoc * psoc)58 struct policy_mgr_psoc_priv_obj *policy_mgr_get_context(
59 		struct wlan_objmgr_psoc *psoc)
60 {
61 	struct policy_mgr_psoc_priv_obj *pm_ctx;
62 	pm_ctx = (struct policy_mgr_psoc_priv_obj *)
63 			wlan_objmgr_psoc_get_comp_private_obj(psoc,
64 				WLAN_UMAC_COMP_POLICY_MGR);
65 	return pm_ctx;
66 }
67 
policy_mgr_get_updated_scan_config(struct wlan_objmgr_psoc * psoc,uint32_t * scan_config,bool dbs_scan,bool dbs_plus_agile_scan,bool single_mac_scan_with_dfs)68 QDF_STATUS policy_mgr_get_updated_scan_config(
69 		struct wlan_objmgr_psoc *psoc,
70 		uint32_t *scan_config,
71 		bool dbs_scan,
72 		bool dbs_plus_agile_scan,
73 		bool single_mac_scan_with_dfs)
74 {
75 	struct policy_mgr_psoc_priv_obj *pm_ctx;
76 	uint32_t conc_scan_config_bits = 0;
77 	struct target_psoc_info *tgt_hdl;
78 
79 	pm_ctx = policy_mgr_get_context(psoc);
80 	if (!pm_ctx) {
81 		policy_mgr_err("Invalid Context");
82 		return QDF_STATUS_E_FAILURE;
83 	}
84 	*scan_config = pm_ctx->dual_mac_cfg.cur_scan_config;
85 
86 	tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc);
87 	if (!tgt_hdl) {
88 		policy_mgr_err("tgt_hdl NULL");
89 		return QDF_STATUS_E_FAILURE;
90 	}
91 	conc_scan_config_bits = target_if_get_conc_scan_config_bits(tgt_hdl);
92 
93 	WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_SET(*scan_config, dbs_scan &
94 					   WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_GET(conc_scan_config_bits));
95 	WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_SET(*scan_config,
96 					     dbs_plus_agile_scan &
97 					     WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_GET(conc_scan_config_bits));
98 	WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_SET(*scan_config,
99 						 single_mac_scan_with_dfs &
100 						 WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_GET(conc_scan_config_bits));
101 
102 	policy_mgr_debug("scan_config:%x ", *scan_config);
103 	return QDF_STATUS_SUCCESS;
104 }
105 
policy_mgr_get_updated_fw_mode_config(struct wlan_objmgr_psoc * psoc,uint32_t * fw_mode_config,bool dbs,bool agile_dfs)106 QDF_STATUS policy_mgr_get_updated_fw_mode_config(
107 		struct wlan_objmgr_psoc *psoc,
108 		uint32_t *fw_mode_config,
109 		bool dbs,
110 		bool agile_dfs)
111 {
112 	struct policy_mgr_psoc_priv_obj *pm_ctx;
113 
114 	pm_ctx = policy_mgr_get_context(psoc);
115 	if (!pm_ctx) {
116 		policy_mgr_err("Invalid Context");
117 		return QDF_STATUS_E_FAILURE;
118 	}
119 	*fw_mode_config = pm_ctx->dual_mac_cfg.cur_fw_mode_config;
120 
121 	WMI_DBS_FW_MODE_CFG_DBS_SET(*fw_mode_config, dbs);
122 	WMI_DBS_FW_MODE_CFG_AGILE_DFS_SET(*fw_mode_config, agile_dfs);
123 
124 	policy_mgr_debug("fw_mode_config:%x ", *fw_mode_config);
125 	return QDF_STATUS_SUCCESS;
126 }
127 
policy_mgr_is_dual_mac_disabled_in_ini(struct wlan_objmgr_psoc * psoc)128 bool policy_mgr_is_dual_mac_disabled_in_ini(
129 		struct wlan_objmgr_psoc *psoc)
130 {
131 	bool is_disabled = false;
132 	uint8_t dbs_type = DISABLE_DBS_CXN_AND_SCAN;
133 
134 	policy_mgr_get_dual_mac_feature(psoc, &dbs_type);
135 	/*
136 	 * If DBS support for connection is disabled through INI then assume
137 	 * that DBS is not supported, so that policy manager takes
138 	 * the decision considering non-dbs cases only.
139 	 *
140 	 * For DBS scan check the INI value explicitly
141 	 */
142 	switch (dbs_type) {
143 	case DISABLE_DBS_CXN_AND_SCAN:
144 	case DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN:
145 	case DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN_WITH_ASYNC_SCAN_OFF:
146 		is_disabled = true;
147 		break;
148 	default:
149 		break;
150 	}
151 
152 	return is_disabled;
153 }
154 
policy_mgr_get_mcc_to_scc_switch_mode(struct wlan_objmgr_psoc * psoc)155 uint32_t policy_mgr_get_mcc_to_scc_switch_mode(
156 	struct wlan_objmgr_psoc *psoc)
157 {
158 	struct policy_mgr_psoc_priv_obj *pm_ctx;
159 
160 	pm_ctx = policy_mgr_get_context(psoc);
161 	if (!pm_ctx) {
162 		policy_mgr_err("Invalid Context");
163 		return 0;
164 	}
165 
166 	return pm_ctx->cfg.mcc_to_scc_switch;
167 }
168 
169 #ifdef WLAN_FEATURE_SR
policy_mgr_get_same_mac_conc_sr_status(struct wlan_objmgr_psoc * psoc)170 bool policy_mgr_get_same_mac_conc_sr_status(struct wlan_objmgr_psoc *psoc)
171 {
172 	struct policy_mgr_psoc_priv_obj *pm_ctx;
173 
174 	pm_ctx = policy_mgr_get_context(psoc);
175 	if (!pm_ctx) {
176 		policy_mgr_err("Invalid Context");
177 		return 0;
178 	}
179 
180 	return pm_ctx->cfg.sr_in_same_mac_conc;
181 }
182 #endif
183 
policy_mgr_get_dbs_config(struct wlan_objmgr_psoc * psoc)184 bool policy_mgr_get_dbs_config(struct wlan_objmgr_psoc *psoc)
185 {
186 	struct policy_mgr_psoc_priv_obj *pm_ctx;
187 	uint32_t fw_mode_config;
188 
189 	if (policy_mgr_is_dual_mac_disabled_in_ini(psoc))
190 		return false;
191 
192 
193 	pm_ctx = policy_mgr_get_context(psoc);
194 	if (!pm_ctx) {
195 		policy_mgr_err("Invalid Context");
196 		/* We take that it is disabled and proceed */
197 		return false;
198 	}
199 	fw_mode_config = pm_ctx->dual_mac_cfg.cur_fw_mode_config;
200 
201 	return WMI_DBS_FW_MODE_CFG_DBS_GET(fw_mode_config);
202 }
203 
policy_mgr_get_agile_dfs_config(struct wlan_objmgr_psoc * psoc)204 bool policy_mgr_get_agile_dfs_config(struct wlan_objmgr_psoc *psoc)
205 {
206 	struct policy_mgr_psoc_priv_obj *pm_ctx;
207 	uint32_t fw_mode_config;
208 
209 	if (policy_mgr_is_dual_mac_disabled_in_ini(psoc))
210 		return false;
211 
212 
213 	pm_ctx = policy_mgr_get_context(psoc);
214 	if (!pm_ctx) {
215 		policy_mgr_err("Invalid Context");
216 		/* We take that it is disabled and proceed */
217 		return false;
218 	}
219 	fw_mode_config = pm_ctx->dual_mac_cfg.cur_fw_mode_config;
220 
221 	return WMI_DBS_FW_MODE_CFG_AGILE_DFS_GET(fw_mode_config);
222 }
223 
policy_mgr_get_dbs_scan_config(struct wlan_objmgr_psoc * psoc)224 bool policy_mgr_get_dbs_scan_config(struct wlan_objmgr_psoc *psoc)
225 {
226 	uint32_t scan_config;
227 	struct policy_mgr_psoc_priv_obj *pm_ctx;
228 
229 	if (policy_mgr_is_dual_mac_disabled_in_ini(psoc))
230 		return false;
231 
232 
233 	pm_ctx = policy_mgr_get_context(psoc);
234 	if (!pm_ctx) {
235 		policy_mgr_err("Invalid Context");
236 		/* We take that it is disabled and proceed */
237 		return false;
238 	}
239 	scan_config = pm_ctx->dual_mac_cfg.cur_scan_config;
240 
241 	return WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_GET(scan_config);
242 }
243 
policy_mgr_get_tx_rx_ss_from_config(enum hw_mode_ss_config mac_ss,uint32_t * tx_ss,uint32_t * rx_ss)244 void policy_mgr_get_tx_rx_ss_from_config(enum hw_mode_ss_config mac_ss,
245 		uint32_t *tx_ss, uint32_t *rx_ss)
246 {
247 	switch (mac_ss) {
248 	case HW_MODE_SS_0x0:
249 		*tx_ss = 0;
250 		*rx_ss = 0;
251 		break;
252 	case HW_MODE_SS_1x1:
253 		*tx_ss = 1;
254 		*rx_ss = 1;
255 		break;
256 	case HW_MODE_SS_2x2:
257 		*tx_ss = 2;
258 		*rx_ss = 2;
259 		break;
260 	case HW_MODE_SS_3x3:
261 		*tx_ss = 3;
262 		*rx_ss = 3;
263 		break;
264 	case HW_MODE_SS_4x4:
265 		*tx_ss = 4;
266 		*rx_ss = 4;
267 		break;
268 	default:
269 		*tx_ss = 0;
270 		*rx_ss = 0;
271 	}
272 }
273 
policy_mgr_get_matching_hw_mode_index(struct wlan_objmgr_psoc * psoc,uint32_t mac0_tx_ss,uint32_t mac0_rx_ss,enum hw_mode_bandwidth mac0_bw,uint32_t mac1_tx_ss,uint32_t mac1_rx_ss,enum hw_mode_bandwidth mac1_bw,enum hw_mode_mac_band_cap mac0_band_cap,enum hw_mode_dbs_capab dbs,enum hw_mode_agile_dfs_capab dfs,enum hw_mode_sbs_capab sbs)274 int8_t policy_mgr_get_matching_hw_mode_index(
275 		struct wlan_objmgr_psoc *psoc,
276 		uint32_t mac0_tx_ss, uint32_t mac0_rx_ss,
277 		enum hw_mode_bandwidth mac0_bw,
278 		uint32_t mac1_tx_ss, uint32_t mac1_rx_ss,
279 		enum hw_mode_bandwidth mac1_bw,
280 		enum hw_mode_mac_band_cap mac0_band_cap,
281 		enum hw_mode_dbs_capab dbs,
282 		enum hw_mode_agile_dfs_capab dfs,
283 		enum hw_mode_sbs_capab sbs)
284 {
285 	uint32_t i;
286 	uint32_t t_mac0_tx_ss, t_mac0_rx_ss, t_mac0_bw;
287 	uint32_t t_mac1_tx_ss, t_mac1_rx_ss, t_mac1_bw;
288 	uint32_t dbs_mode, agile_dfs_mode, sbs_mode;
289 	uint32_t t_mac0_band_cap;
290 	int8_t found = -EINVAL;
291 	struct policy_mgr_psoc_priv_obj *pm_ctx;
292 
293 	pm_ctx = policy_mgr_get_context(psoc);
294 	if (!pm_ctx) {
295 		policy_mgr_err("Invalid Context");
296 		return found;
297 	}
298 
299 	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
300 		t_mac0_tx_ss = POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(
301 				pm_ctx->hw_mode.hw_mode_list[i]);
302 		if (t_mac0_tx_ss < mac0_tx_ss)
303 			continue;
304 
305 		t_mac0_rx_ss = POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(
306 				pm_ctx->hw_mode.hw_mode_list[i]);
307 		if (t_mac0_rx_ss < mac0_rx_ss)
308 			continue;
309 
310 		t_mac0_bw = POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(
311 				pm_ctx->hw_mode.hw_mode_list[i]);
312 		/*
313 		 * Firmware advertises max bw capability as CBW 80+80
314 		 * for single MAC. Thus CBW 20/40/80 should also be
315 		 * supported, if CBW 80+80 is supported.
316 		 */
317 		if (t_mac0_bw < mac0_bw)
318 			continue;
319 
320 		t_mac1_tx_ss = POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(
321 				pm_ctx->hw_mode.hw_mode_list[i]);
322 		if (t_mac1_tx_ss < mac1_tx_ss)
323 			continue;
324 
325 		t_mac1_rx_ss = POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(
326 				pm_ctx->hw_mode.hw_mode_list[i]);
327 		if (t_mac1_rx_ss < mac1_rx_ss)
328 			continue;
329 
330 		t_mac1_bw = POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(
331 				pm_ctx->hw_mode.hw_mode_list[i]);
332 		if (t_mac1_bw < mac1_bw)
333 			continue;
334 
335 		dbs_mode = POLICY_MGR_HW_MODE_DBS_MODE_GET(
336 				pm_ctx->hw_mode.hw_mode_list[i]);
337 		if (dbs_mode != dbs)
338 			continue;
339 
340 		agile_dfs_mode = POLICY_MGR_HW_MODE_AGILE_DFS_GET(
341 				pm_ctx->hw_mode.hw_mode_list[i]);
342 		if (agile_dfs_mode != dfs)
343 			continue;
344 
345 		sbs_mode = POLICY_MGR_HW_MODE_SBS_MODE_GET(
346 				pm_ctx->hw_mode.hw_mode_list[i]);
347 		if (sbs_mode != sbs)
348 			continue;
349 
350 		t_mac0_band_cap = POLICY_MGR_HW_MODE_MAC0_BAND_GET(
351 				pm_ctx->hw_mode.hw_mode_list[i]);
352 		if (mac0_band_cap && t_mac0_band_cap != mac0_band_cap)
353 			continue;
354 
355 		found = POLICY_MGR_HW_MODE_ID_GET(
356 				pm_ctx->hw_mode.hw_mode_list[i]);
357 
358 		policy_mgr_debug("hw_mode id %d found at %d", found, i);
359 
360 		break;
361 	}
362 	return found;
363 }
364 
policy_mgr_get_hw_mode_idx_from_dbs_hw_list(struct wlan_objmgr_psoc * psoc,enum hw_mode_ss_config mac0_ss,enum hw_mode_bandwidth mac0_bw,enum hw_mode_ss_config mac1_ss,enum hw_mode_bandwidth mac1_bw,enum hw_mode_mac_band_cap mac0_band_cap,enum hw_mode_dbs_capab dbs,enum hw_mode_agile_dfs_capab dfs,enum hw_mode_sbs_capab sbs)365 int8_t policy_mgr_get_hw_mode_idx_from_dbs_hw_list(
366 		struct wlan_objmgr_psoc *psoc,
367 		enum hw_mode_ss_config mac0_ss,
368 		enum hw_mode_bandwidth mac0_bw,
369 		enum hw_mode_ss_config mac1_ss,
370 		enum hw_mode_bandwidth mac1_bw,
371 		enum hw_mode_mac_band_cap mac0_band_cap,
372 		enum hw_mode_dbs_capab dbs,
373 		enum hw_mode_agile_dfs_capab dfs,
374 		enum hw_mode_sbs_capab sbs)
375 {
376 	uint32_t mac0_tx_ss, mac0_rx_ss;
377 	uint32_t mac1_tx_ss, mac1_rx_ss;
378 
379 	policy_mgr_get_tx_rx_ss_from_config(mac0_ss, &mac0_tx_ss, &mac0_rx_ss);
380 	policy_mgr_get_tx_rx_ss_from_config(mac1_ss, &mac1_tx_ss, &mac1_rx_ss);
381 
382 	policy_mgr_debug("MAC0: TxSS=%d, RxSS=%d, BW=%d band=%d",
383 			 mac0_tx_ss, mac0_rx_ss, mac0_bw, mac0_band_cap);
384 	policy_mgr_debug("MAC1: TxSS=%d, RxSS=%d, BW=%d",
385 			 mac1_tx_ss, mac1_rx_ss, mac1_bw);
386 	policy_mgr_debug("DBS=%d, Agile DFS=%d, SBS=%d",
387 			 dbs, dfs, sbs);
388 
389 	return policy_mgr_get_matching_hw_mode_index(psoc, mac0_tx_ss,
390 						mac0_rx_ss,
391 						mac0_bw,
392 						mac1_tx_ss, mac1_rx_ss,
393 						mac1_bw,
394 						mac0_band_cap,
395 						dbs, dfs, sbs);
396 }
397 
policy_mgr_get_hw_mode_from_idx(struct wlan_objmgr_psoc * psoc,uint32_t idx,struct policy_mgr_hw_mode_params * hw_mode)398 QDF_STATUS policy_mgr_get_hw_mode_from_idx(
399 		struct wlan_objmgr_psoc *psoc,
400 		uint32_t idx,
401 		struct policy_mgr_hw_mode_params *hw_mode)
402 {
403 	uint64_t param;
404 	struct policy_mgr_psoc_priv_obj *pm_ctx;
405 	uint8_t mac0_min_ss;
406 	uint8_t mac1_min_ss;
407 	uint32_t i, hw_mode_id;
408 
409 	pm_ctx = policy_mgr_get_context(psoc);
410 	if (!pm_ctx) {
411 		policy_mgr_err("Invalid Context");
412 		return QDF_STATUS_E_FAILURE;
413 	}
414 	if (!pm_ctx->num_dbs_hw_modes) {
415 		policy_mgr_err("No dbs hw modes available");
416 		return QDF_STATUS_E_FAILURE;
417 	}
418 	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
419 		param = pm_ctx->hw_mode.hw_mode_list[i];
420 		hw_mode_id = POLICY_MGR_HW_MODE_ID_GET(param);
421 		hw_mode->emlsr_cap = POLICY_MGR_HW_MODE_EMLSR_MODE_GET(param);
422 
423 		if (hw_mode_id == idx || hw_mode->emlsr_cap)
424 			break;
425 	}
426 	if (i >= pm_ctx->num_dbs_hw_modes) {
427 		policy_mgr_err("hw mode id %d not found", idx);
428 		return QDF_STATUS_E_FAILURE;
429 	}
430 
431 	param = pm_ctx->hw_mode.hw_mode_list[i];
432 
433 	hw_mode->mac0_tx_ss = POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param);
434 	hw_mode->mac0_rx_ss = POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param);
435 	hw_mode->mac0_bw = POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(param);
436 	hw_mode->mac1_tx_ss = POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param);
437 	hw_mode->mac1_rx_ss = POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param);
438 	hw_mode->mac1_bw = POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(param);
439 	hw_mode->mac0_band_cap = POLICY_MGR_HW_MODE_MAC0_BAND_GET(param);
440 	hw_mode->dbs_cap = POLICY_MGR_HW_MODE_DBS_MODE_GET(param);
441 	hw_mode->agile_dfs_cap = POLICY_MGR_HW_MODE_AGILE_DFS_GET(param);
442 	hw_mode->sbs_cap = POLICY_MGR_HW_MODE_SBS_MODE_GET(param);
443 	if (hw_mode->dbs_cap) {
444 		mac0_min_ss = QDF_MIN(hw_mode->mac0_tx_ss, hw_mode->mac0_rx_ss);
445 		mac1_min_ss = QDF_MIN(hw_mode->mac1_tx_ss, hw_mode->mac1_rx_ss);
446 		if (hw_mode->mac0_band_cap == WLAN_5G_CAPABILITY &&
447 		    mac0_min_ss && mac1_min_ss &&
448 		    mac0_min_ss > mac1_min_ss)
449 			hw_mode->action_type = PM_DBS1;
450 		else if (hw_mode->mac0_band_cap == WLAN_2G_CAPABILITY &&
451 			 mac0_min_ss && mac1_min_ss &&
452 			 mac0_min_ss > mac1_min_ss)
453 			hw_mode->action_type = PM_DBS2;
454 		else
455 			hw_mode->action_type = PM_DBS;
456 	}
457 	return QDF_STATUS_SUCCESS;
458 }
459 
policy_mgr_get_old_and_new_hw_index(struct wlan_objmgr_psoc * psoc,uint32_t * old_hw_mode_index,uint32_t * new_hw_mode_index)460 QDF_STATUS policy_mgr_get_old_and_new_hw_index(
461 		struct wlan_objmgr_psoc *psoc,
462 		uint32_t *old_hw_mode_index,
463 		uint32_t *new_hw_mode_index)
464 {
465 	struct policy_mgr_psoc_priv_obj *pm_ctx;
466 
467 	pm_ctx = policy_mgr_get_context(psoc);
468 	if (!pm_ctx) {
469 		policy_mgr_err("Invalid Context");
470 		return QDF_STATUS_E_INVAL;
471 	}
472 
473 	*old_hw_mode_index = pm_ctx->old_hw_mode_index;
474 	*new_hw_mode_index = pm_ctx->new_hw_mode_index;
475 
476 	return QDF_STATUS_SUCCESS;
477 }
478 
policy_mgr_update_conc_list(struct wlan_objmgr_psoc * psoc,uint32_t conn_index,enum policy_mgr_con_mode mode,uint32_t ch_freq,enum hw_mode_bandwidth bw,uint8_t mac,enum policy_mgr_chain_mode chain_mask,uint32_t original_nss,uint32_t vdev_id,bool in_use,bool update_conn,uint16_t ch_flagext)479 void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc,
480 		uint32_t conn_index,
481 		enum policy_mgr_con_mode mode,
482 		uint32_t ch_freq,
483 		enum hw_mode_bandwidth bw,
484 		uint8_t mac,
485 		enum policy_mgr_chain_mode chain_mask,
486 		uint32_t original_nss,
487 		uint32_t vdev_id,
488 		bool in_use,
489 		bool update_conn,
490 		uint16_t ch_flagext)
491 {
492 	struct policy_mgr_psoc_priv_obj *pm_ctx;
493 	bool mcc_mode;
494 	enum hw_mode_bandwidth max_bw;
495 
496 	pm_ctx = policy_mgr_get_context(psoc);
497 	if (!pm_ctx) {
498 		policy_mgr_err("Invalid Context");
499 		return;
500 	}
501 
502 	if (conn_index >= MAX_NUMBER_OF_CONC_CONNECTIONS) {
503 		policy_mgr_err("Number of connections exceeded conn_index: %d",
504 			conn_index);
505 		return;
506 	}
507 
508 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
509 	pm_conc_connection_list[conn_index].mode = mode;
510 	pm_conc_connection_list[conn_index].freq = ch_freq;
511 	pm_conc_connection_list[conn_index].bw = bw;
512 	pm_conc_connection_list[conn_index].mac = mac;
513 	pm_conc_connection_list[conn_index].chain_mask = chain_mask;
514 	pm_conc_connection_list[conn_index].original_nss = original_nss;
515 	pm_conc_connection_list[conn_index].vdev_id = vdev_id;
516 	pm_conc_connection_list[conn_index].in_use = in_use;
517 	pm_conc_connection_list[conn_index].ch_flagext = ch_flagext;
518 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
519 
520 	/*
521 	 * For STA and P2P client mode, the mode change event sent as part
522 	 * of the callback causes delay in processing M1 frame at supplicant
523 	 * resulting in cert test case failure. The mode change event is sent
524 	 * as part of add key for STA and P2P client mode.
525 	 */
526 	if (pm_ctx->mode_change_cb && update_conn)
527 		pm_ctx->mode_change_cb();
528 
529 	if (pm_ctx->cdp_cbacks.cdp_update_mac_id)
530 		pm_ctx->cdp_cbacks.cdp_update_mac_id(psoc, vdev_id, mac);
531 
532 	/* IPA only cares about STA or SAP mode */
533 	if (mode == PM_STA_MODE || policy_mgr_is_sap_mode(mode)) {
534 		mcc_mode = policy_mgr_current_concurrency_is_mcc(psoc);
535 
536 		if (pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb)
537 			pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb(mcc_mode);
538 
539 		if (pm_ctx->dp_cbacks.hdd_ipa_set_perf_level_bw) {
540 			max_bw = policy_mgr_get_connection_max_channel_width(
541 					psoc);
542 			policy_mgr_debug("max channel width %d", max_bw);
543 			pm_ctx->dp_cbacks.hdd_ipa_set_perf_level_bw(max_bw);
544 		}
545 	}
546 
547 	if (pm_ctx->conc_cbacks.connection_info_update)
548 		pm_ctx->conc_cbacks.connection_info_update();
549 }
550 
551 /**
552  * policy_mgr_store_and_del_conn_info() - Store and del a connection info
553  * @psoc: psoc handle
554  * @mode: Mode whose entry has to be deleted
555  * @all_matching_cxn_to_del: All the specified mode entries should be deleted
556  * @info: Structure array pointer where the connection info will be saved
557  * @num_cxn_del: Number of connection which are going to be deleted
558  *
559  * Saves the connection info corresponding to the provided mode
560  * and deleted that corresponding entry based on vdev from the
561  * connection info structure
562  *
563  * Return: None
564  */
policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,bool all_matching_cxn_to_del,struct policy_mgr_conc_connection_info * info,uint8_t * num_cxn_del)565 void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc,
566 	enum policy_mgr_con_mode mode, bool all_matching_cxn_to_del,
567 	struct policy_mgr_conc_connection_info *info, uint8_t *num_cxn_del)
568 {
569 	int32_t conn_index = 0;
570 	uint32_t found_index = 0;
571 	struct policy_mgr_psoc_priv_obj *pm_ctx;
572 
573 	if (!num_cxn_del) {
574 		policy_mgr_err("num_cxn_del is NULL");
575 		return;
576 	}
577 	*num_cxn_del = 0;
578 	if (!info) {
579 		policy_mgr_err("Invalid connection info");
580 		return;
581 	}
582 	pm_ctx = policy_mgr_get_context(psoc);
583 	if (!pm_ctx) {
584 		policy_mgr_err("Invalid Context");
585 		return;
586 	}
587 
588 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
589 	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
590 		if (mode == pm_conc_connection_list[conn_index].mode) {
591 			/*
592 			 * Storing the connection entry which will be
593 			 * temporarily deleted.
594 			 */
595 			info[found_index] = pm_conc_connection_list[conn_index];
596 			/* Deleting the connection entry */
597 			policy_mgr_decr_connection_count(psoc,
598 					info[found_index].vdev_id);
599 			policy_mgr_debug("Stored %d (%d), deleted STA entry with vdev id %d, index %d",
600 					 info[found_index].vdev_id,
601 					 info[found_index].mode,
602 					 info[found_index].vdev_id, conn_index);
603 			pm_ctx->no_of_active_sessions[info->mode]--;
604 			found_index++;
605 			if (all_matching_cxn_to_del)
606 				continue;
607 			else
608 				break;
609 		}
610 		conn_index++;
611 	}
612 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
613 
614 	if (!found_index) {
615 		*num_cxn_del = 0;
616 		policy_mgr_debug("Mode:%d not available in the conn info",
617 				 mode);
618 	} else {
619 		*num_cxn_del = found_index;
620 		policy_mgr_debug("Mode:%d number of conn %d temp del",
621 				 mode, *num_cxn_del);
622 	}
623 
624 	/*
625 	 * Caller should set the PCL and restore the connection entry
626 	 * in conn info.
627 	 */
628 }
629 
policy_mgr_store_and_del_conn_info_by_vdev_id(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id,struct policy_mgr_conc_connection_info * info,uint8_t * num_cxn_del)630 void policy_mgr_store_and_del_conn_info_by_vdev_id(
631 			struct wlan_objmgr_psoc *psoc,
632 			uint32_t vdev_id,
633 			struct policy_mgr_conc_connection_info *info,
634 			uint8_t *num_cxn_del)
635 {
636 	uint32_t conn_index = 0;
637 	struct policy_mgr_psoc_priv_obj *pm_ctx;
638 
639 	if (!info || !num_cxn_del) {
640 		policy_mgr_err("Invalid parameters");
641 		return;
642 	}
643 
644 	*num_cxn_del = 0;
645 	pm_ctx = policy_mgr_get_context(psoc);
646 	if (!pm_ctx) {
647 		policy_mgr_err("Invalid Context");
648 		return;
649 	}
650 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
651 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
652 	     conn_index++) {
653 		if ((pm_conc_connection_list[conn_index].vdev_id == vdev_id) &&
654 		    pm_conc_connection_list[conn_index].in_use) {
655 			*num_cxn_del = 1;
656 			break;
657 		}
658 	}
659 	/*
660 	 * Storing the connection entry which will be
661 	 * temporarily deleted.
662 	 */
663 	if (*num_cxn_del == 1) {
664 		*info = pm_conc_connection_list[conn_index];
665 		pm_ctx->no_of_active_sessions[info->mode]--;
666 		/* Deleting the connection entry */
667 		policy_mgr_decr_connection_count(
668 			psoc,
669 			pm_conc_connection_list[conn_index].vdev_id);
670 	}
671 
672 	policy_mgr_debug("vdev id %d, num_cxn_del %d", vdev_id, *num_cxn_del);
673 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
674 }
675 
policy_mgr_store_and_del_conn_info_by_chan_and_mode(struct wlan_objmgr_psoc * psoc,uint32_t ch_freq,enum policy_mgr_con_mode mode,struct policy_mgr_conc_connection_info * info,uint8_t * num_cxn_del)676 void policy_mgr_store_and_del_conn_info_by_chan_and_mode(
677 			struct wlan_objmgr_psoc *psoc,
678 			uint32_t ch_freq,
679 			enum policy_mgr_con_mode mode,
680 			struct policy_mgr_conc_connection_info *info,
681 			uint8_t *num_cxn_del)
682 {
683 	uint32_t conn_index = 0;
684 	uint8_t found_index = 0;
685 
686 	struct policy_mgr_psoc_priv_obj *pm_ctx;
687 
688 	if (!info || !num_cxn_del) {
689 		policy_mgr_err("Invalid parameters");
690 		return;
691 	}
692 	*num_cxn_del = 0;
693 	pm_ctx = policy_mgr_get_context(psoc);
694 	if (!pm_ctx) {
695 		policy_mgr_err("Invalid Context");
696 		return;
697 	}
698 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
699 	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
700 		if (ch_freq != pm_conc_connection_list[conn_index].freq ||
701 		    mode != pm_conc_connection_list[conn_index].mode) {
702 			conn_index++;
703 			continue;
704 		}
705 		info[found_index] = pm_conc_connection_list[conn_index];
706 		policy_mgr_debug("Stored %d (%d), deleted STA entry with vdev id %d, index %d ch %d",
707 				 info[found_index].vdev_id,
708 				 info[found_index].mode,
709 				 info[found_index].vdev_id, conn_index,
710 				 ch_freq);
711 		found_index++;
712 		conn_index++;
713 	}
714 	conn_index = 0;
715 	while (conn_index < found_index) {
716 		policy_mgr_decr_connection_count(
717 			psoc, info[conn_index].vdev_id);
718 
719 		pm_ctx->no_of_active_sessions[info[conn_index].mode]--;
720 		conn_index++;
721 	}
722 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
723 	*num_cxn_del = found_index;
724 }
725 
726 /**
727  * policy_mgr_restore_deleted_conn_info() - Restore connection info
728  * @psoc: psoc handle
729  * @info: An array saving connection info that is to be restored
730  * @num_cxn_del: Number of connection temporary deleted
731  *
732  * Restores the connection info of STA that was saved before
733  * updating the PCL to the FW
734  *
735  * Return: None
736  */
policy_mgr_restore_deleted_conn_info(struct wlan_objmgr_psoc * psoc,struct policy_mgr_conc_connection_info * info,uint8_t num_cxn_del)737 void policy_mgr_restore_deleted_conn_info(struct wlan_objmgr_psoc *psoc,
738 		struct policy_mgr_conc_connection_info *info,
739 		uint8_t num_cxn_del)
740 {
741 	uint32_t conn_index;
742 	struct policy_mgr_psoc_priv_obj *pm_ctx;
743 	int i;
744 
745 	if (MAX_NUMBER_OF_CONC_CONNECTIONS < num_cxn_del || 0 == num_cxn_del) {
746 		policy_mgr_err("Failed to restore %d/%d deleted information",
747 				num_cxn_del, MAX_NUMBER_OF_CONC_CONNECTIONS);
748 		return;
749 	}
750 	pm_ctx = policy_mgr_get_context(psoc);
751 	if (!pm_ctx) {
752 		policy_mgr_err("Invalid Context");
753 		return;
754 	}
755 
756 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
757 	conn_index = policy_mgr_get_connection_count(psoc);
758 	if (conn_index + num_cxn_del > MAX_NUMBER_OF_CONC_CONNECTIONS) {
759 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
760 		policy_mgr_err("Failed to restore the deleted information %d/%d, as it exceed max %d",
761 			       conn_index, num_cxn_del,
762 			       MAX_NUMBER_OF_CONC_CONNECTIONS);
763 		return;
764 	}
765 
766 	qdf_mem_copy(&pm_conc_connection_list[conn_index], info,
767 		     num_cxn_del * sizeof(*info));
768 	pm_ctx->no_of_active_sessions[info->mode] += num_cxn_del;
769 	for (i = 0; i < num_cxn_del; i++)
770 		policy_mgr_debug("Restored the deleleted conn info, vdev:%d, index:%d",
771 				 info[i].vdev_id, conn_index++);
772 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
773 }
774 
775 static bool
policy_mgr_is_freq_range_5_6ghz(qdf_freq_t start_freq,qdf_freq_t end_freq)776 policy_mgr_is_freq_range_5_6ghz(qdf_freq_t start_freq, qdf_freq_t end_freq)
777 {
778 	/*
779 	 * As Fw is sending the whole hardware range which include 4.9Ghz as
780 	 * well. Use LOWER_END_FREQ_5GHZ to differentiate 2.4Ghz and 5Ghz
781 	 */
782 	if (start_freq >= LOWER_END_FREQ_5GHZ &&
783 	    end_freq >= LOWER_END_FREQ_5GHZ)
784 		return true;
785 
786 	return false;
787 }
788 
789 static bool
policy_mgr_is_freq_range_2ghz(qdf_freq_t start_freq,qdf_freq_t end_freq)790 policy_mgr_is_freq_range_2ghz(qdf_freq_t start_freq, qdf_freq_t end_freq)
791 {
792 	/*
793 	 * As Fw is sending the whole hardware range which include 4.9Ghz as
794 	 * well. Use LOWER_END_FREQ_5GHZ to differentiate 2.4Ghz and 5Ghz
795 	 */
796 	if (start_freq < LOWER_END_FREQ_5GHZ && end_freq < LOWER_END_FREQ_5GHZ)
797 		return true;
798 
799 	return false;
800 }
801 
802 static void
policy_mgr_fill_curr_mac_2ghz_freq(uint32_t mac_id,struct policy_mgr_pdev_mac_freq_map * freq,struct policy_mgr_psoc_priv_obj * pm_ctx)803 policy_mgr_fill_curr_mac_2ghz_freq(uint32_t mac_id,
804 				   struct policy_mgr_pdev_mac_freq_map *freq,
805 				   struct policy_mgr_psoc_priv_obj *pm_ctx)
806 {
807 	pm_ctx->hw_mode.cur_mac_freq_range[mac_id].low_2ghz_freq =
808 					QDF_MAX(freq->start_freq,
809 						wlan_reg_min_24ghz_chan_freq());
810 	pm_ctx->hw_mode.cur_mac_freq_range[mac_id].high_2ghz_freq =
811 					QDF_MIN(freq->end_freq,
812 						wlan_reg_max_24ghz_chan_freq());
813 }
814 
815 static void
policy_mgr_fill_curr_mac_5ghz_freq(uint32_t mac_id,struct policy_mgr_pdev_mac_freq_map * freq,struct policy_mgr_psoc_priv_obj * pm_ctx)816 policy_mgr_fill_curr_mac_5ghz_freq(uint32_t mac_id,
817 				   struct policy_mgr_pdev_mac_freq_map *freq,
818 				   struct policy_mgr_psoc_priv_obj *pm_ctx)
819 {
820 	qdf_freq_t max_5g_freq;
821 
822 	max_5g_freq = wlan_reg_max_6ghz_chan_freq() ?
823 			wlan_reg_max_6ghz_chan_freq() :
824 			wlan_reg_max_5ghz_chan_freq();
825 
826 	pm_ctx->hw_mode.cur_mac_freq_range[mac_id].low_5ghz_freq =
827 					QDF_MAX(freq->start_freq,
828 						wlan_reg_min_5ghz_chan_freq());
829 	pm_ctx->hw_mode.cur_mac_freq_range[mac_id].high_5ghz_freq =
830 					QDF_MIN(freq->end_freq, max_5g_freq);
831 }
832 
833 void
policy_mgr_fill_curr_mac_freq_by_hwmode(struct policy_mgr_psoc_priv_obj * pm_ctx,enum policy_mgr_mode mode_hw)834 policy_mgr_fill_curr_mac_freq_by_hwmode(struct policy_mgr_psoc_priv_obj *pm_ctx,
835 					enum policy_mgr_mode mode_hw)
836 {
837 	uint8_t i;
838 	struct policy_mgr_freq_range *cur_mac_freq, *hwmode_freq;
839 
840 	cur_mac_freq = pm_ctx->hw_mode.cur_mac_freq_range;
841 	hwmode_freq = pm_ctx->hw_mode.freq_range_caps[mode_hw];
842 
843 	for (i = 0; i < MAX_MAC; i++) {
844 		cur_mac_freq[i].low_2ghz_freq = hwmode_freq[i].low_2ghz_freq;
845 		cur_mac_freq[i].high_2ghz_freq = hwmode_freq[i].high_2ghz_freq;
846 		cur_mac_freq[i].low_5ghz_freq = hwmode_freq[i].low_5ghz_freq;
847 		cur_mac_freq[i].high_5ghz_freq = hwmode_freq[i].high_5ghz_freq;
848 	}
849 }
850 
851 static void
policy_mgr_fill_legacy_freq_range(struct policy_mgr_psoc_priv_obj * pm_ctx,struct policy_mgr_hw_mode_params hw_mode)852 policy_mgr_fill_legacy_freq_range(struct policy_mgr_psoc_priv_obj *pm_ctx,
853 				  struct policy_mgr_hw_mode_params hw_mode)
854 {
855 	enum policy_mgr_mode mode;
856 
857 	mode = hw_mode.dbs_cap ? MODE_DBS : MODE_SMM;
858 	policy_mgr_fill_curr_mac_freq_by_hwmode(pm_ctx, mode);
859 }
860 
861 static QDF_STATUS
policy_mgr_fill_curr_freq_by_pdev_freq(int32_t num_mac_freq,struct policy_mgr_pdev_mac_freq_map * freq,struct policy_mgr_psoc_priv_obj * pm_ctx,struct policy_mgr_hw_mode_params hw_mode)862 policy_mgr_fill_curr_freq_by_pdev_freq(int32_t num_mac_freq,
863 				struct policy_mgr_pdev_mac_freq_map *freq,
864 				struct policy_mgr_psoc_priv_obj *pm_ctx,
865 				struct policy_mgr_hw_mode_params hw_mode)
866 {
867 	uint32_t mac_id, i;
868 
869 	/* memzero before filling it */
870 	qdf_mem_zero(pm_ctx->hw_mode.cur_mac_freq_range,
871 		     sizeof(pm_ctx->hw_mode.cur_mac_freq_range));
872 	for (i = 0; i < num_mac_freq; i++) {
873 		mac_id = freq[i].mac_id;
874 
875 		if (mac_id >= MAX_MAC) {
876 			policy_mgr_debug("Invalid pdev id %d", mac_id);
877 			return QDF_STATUS_E_INVAL;
878 		}
879 
880 		if (policy_mgr_is_freq_range_2ghz(freq[i].start_freq,
881 						  freq[i].end_freq)) {
882 			policy_mgr_fill_curr_mac_2ghz_freq(mac_id,
883 							   &freq[i],
884 							   pm_ctx);
885 		} else if (policy_mgr_is_freq_range_5_6ghz(freq[i].start_freq,
886 							 freq[i].end_freq)) {
887 			policy_mgr_fill_curr_mac_5ghz_freq(mac_id, &freq[i],
888 							   pm_ctx);
889 		} else  {
890 			policy_mgr_err("Invalid different band freq range: mac_id %d start freq %d end_freq %d",
891 				       mac_id, freq[i].start_freq,
892 				       freq[i].end_freq);
893 			return QDF_STATUS_E_INVAL;
894 		}
895 	}
896 
897 	return QDF_STATUS_SUCCESS;
898 }
899 
900 static void
policy_mgr_update_curr_mac_freq(uint32_t num_mac_freq,struct policy_mgr_pdev_mac_freq_map * freq,struct policy_mgr_psoc_priv_obj * pm_ctx,struct policy_mgr_hw_mode_params hw_mode)901 policy_mgr_update_curr_mac_freq(uint32_t num_mac_freq,
902 				struct policy_mgr_pdev_mac_freq_map *freq,
903 				struct policy_mgr_psoc_priv_obj *pm_ctx,
904 				struct policy_mgr_hw_mode_params hw_mode)
905 {
906 	QDF_STATUS status;
907 
908 	if (num_mac_freq && freq) {
909 		status = policy_mgr_fill_curr_freq_by_pdev_freq(num_mac_freq,
910 								freq, pm_ctx,
911 								hw_mode);
912 		if (QDF_IS_STATUS_SUCCESS(status))
913 			return;
914 	}
915 
916 	policy_mgr_fill_legacy_freq_range(pm_ctx, hw_mode);
917 }
918 
919 /**
920  * policy_mgr_update_hw_mode_conn_info() - Update connection
921  * info based on HW mode
922  * @psoc: psoc handle
923  * @num_vdev_mac_entries: Number of vdev-mac id entries that follow
924  * @vdev_mac_map: Mapping of vdev-mac id
925  * @hw_mode: HW mode
926  * @num_mac_freq: number of Frequency Range
927  * @freq_info: Pointer to Frequency Range
928  *
929  * Updates the connection info parameters based on the new HW mode
930  *
931  * Return: None
932  */
policy_mgr_update_hw_mode_conn_info(struct wlan_objmgr_psoc * psoc,uint32_t num_vdev_mac_entries,struct policy_mgr_vdev_mac_map * vdev_mac_map,struct policy_mgr_hw_mode_params hw_mode,uint32_t num_mac_freq,struct policy_mgr_pdev_mac_freq_map * freq_info)933 void policy_mgr_update_hw_mode_conn_info(struct wlan_objmgr_psoc *psoc,
934 				uint32_t num_vdev_mac_entries,
935 				struct policy_mgr_vdev_mac_map *vdev_mac_map,
936 				struct policy_mgr_hw_mode_params hw_mode,
937 				uint32_t num_mac_freq,
938 				struct policy_mgr_pdev_mac_freq_map *freq_info)
939 {
940 	uint32_t i, conn_index, found;
941 	struct policy_mgr_psoc_priv_obj *pm_ctx;
942 
943 	pm_ctx = policy_mgr_get_context(psoc);
944 	if (!pm_ctx) {
945 		policy_mgr_err("Invalid Context");
946 		return;
947 	}
948 
949 	policy_mgr_update_curr_mac_freq(num_mac_freq, freq_info, pm_ctx,
950 					hw_mode);
951 
952 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
953 	for (i = 0; i < num_vdev_mac_entries; i++) {
954 		conn_index = 0;
955 		found = 0;
956 		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
957 			if (vdev_mac_map[i].vdev_id ==
958 				pm_conc_connection_list[conn_index].vdev_id) {
959 				found = 1;
960 				break;
961 			}
962 			conn_index++;
963 		}
964 		if (found) {
965 			pm_conc_connection_list[conn_index].mac =
966 				vdev_mac_map[i].mac_id;
967 			policy_mgr_debug("vdev:%d, mac:%d",
968 			  pm_conc_connection_list[conn_index].vdev_id,
969 			  pm_conc_connection_list[conn_index].mac);
970 			if (pm_ctx->cdp_cbacks.cdp_update_mac_id)
971 				pm_ctx->cdp_cbacks.cdp_update_mac_id(
972 					psoc,
973 					vdev_mac_map[i].vdev_id,
974 					vdev_mac_map[i].mac_id);
975 		}
976 	}
977 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
978 
979 	policy_mgr_dump_connection_status_info(psoc);
980 }
981 
policy_mgr_pdev_set_hw_mode_cb(uint32_t status,uint32_t cfgd_hw_mode_index,uint32_t num_vdev_mac_entries,struct policy_mgr_vdev_mac_map * vdev_mac_map,uint8_t next_action,enum policy_mgr_conn_update_reason reason,uint32_t session_id,void * context,uint32_t request_id)982 void policy_mgr_pdev_set_hw_mode_cb(uint32_t status,
983 				uint32_t cfgd_hw_mode_index,
984 				uint32_t num_vdev_mac_entries,
985 				struct policy_mgr_vdev_mac_map *vdev_mac_map,
986 				uint8_t next_action,
987 				enum policy_mgr_conn_update_reason reason,
988 				uint32_t session_id, void *context,
989 				uint32_t request_id)
990 {
991 	QDF_STATUS ret;
992 	struct policy_mgr_hw_mode_params hw_mode;
993 	struct policy_mgr_psoc_priv_obj *pm_ctx;
994 
995 	pm_ctx = policy_mgr_get_context(context);
996 	if (!pm_ctx) {
997 		policy_mgr_err("Invalid Context");
998 		goto set_done_event;
999 	}
1000 
1001 	policy_mgr_set_hw_mode_change_in_progress(context,
1002 		POLICY_MGR_HW_MODE_NOT_IN_PROGRESS);
1003 
1004 	if (status == SET_HW_MODE_STATUS_OK ||
1005 	    status == SET_HW_MODE_STATUS_ALREADY) {
1006 		policy_mgr_set_connection_update(context);
1007 	}
1008 
1009 	if (status != SET_HW_MODE_STATUS_OK) {
1010 		policy_mgr_debug("Set HW mode failed with status %d", status);
1011 		goto next_action;
1012 	}
1013 
1014 	/* vdev mac map for NAN Discovery is expected in NAN Enable resp */
1015 	if (reason != POLICY_MGR_UPDATE_REASON_NAN_DISCOVERY &&
1016 	    !vdev_mac_map) {
1017 		policy_mgr_err("vdev_mac_map is NULL");
1018 		goto set_done_event;
1019 	}
1020 
1021 	ret = policy_mgr_get_hw_mode_from_idx(context, cfgd_hw_mode_index,
1022 					      &hw_mode);
1023 	if (QDF_IS_STATUS_ERROR(ret)) {
1024 		policy_mgr_err("Get HW mode for index %d reason: %d",
1025 			       cfgd_hw_mode_index, ret);
1026 		goto set_done_event;
1027 	}
1028 	policy_mgr_debug("HW mode idx %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",
1029 			 cfgd_hw_mode_index, hw_mode.dbs_cap,
1030 			 hw_mode.agile_dfs_cap, hw_mode.sbs_cap,
1031 			 hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss,
1032 			 hw_mode.mac0_bw, hw_mode.mac0_band_cap,
1033 			 hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss,
1034 			 hw_mode.mac1_bw);
1035 	policy_mgr_dump_freq_range_n_vdev_map(num_vdev_mac_entries,
1036 					      vdev_mac_map, 0, NULL);
1037 
1038 	/* update pm_conc_connection_list */
1039 	policy_mgr_update_hw_mode_conn_info(context,
1040 					    num_vdev_mac_entries,
1041 					    vdev_mac_map,
1042 					    hw_mode, 0, NULL);
1043 	if (pm_ctx->mode_change_cb)
1044 		pm_ctx->mode_change_cb();
1045 
1046 	/* Notify tdls */
1047 	if (pm_ctx->tdls_cbacks.tdls_notify_decrement_session)
1048 		pm_ctx->tdls_cbacks.tdls_notify_decrement_session(pm_ctx->psoc);
1049 
1050 next_action:
1051 	if (PM_NOP != next_action && (status == SET_HW_MODE_STATUS_ALREADY ||
1052 	    status == SET_HW_MODE_STATUS_OK))
1053 		policy_mgr_next_actions(context, session_id,
1054 			next_action, reason, request_id);
1055 	else
1056 		policy_mgr_debug("No action needed right now");
1057 
1058 set_done_event:
1059 	ret = policy_mgr_set_opportunistic_update(context);
1060 	if (!QDF_IS_STATUS_SUCCESS(ret))
1061 		policy_mgr_err("ERROR: set opportunistic_update event failed");
1062 }
1063 
1064 static char *
ml_sta_prefix(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id)1065 ml_sta_prefix(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id)
1066 {
1067 	struct wlan_objmgr_vdev *vdev;
1068 
1069 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
1070 						    vdev_id,
1071 						    WLAN_POLICY_MGR_ID);
1072 	if (!vdev) {
1073 		policy_mgr_err("invalid vdev for id %d",
1074 			       vdev_id);
1075 		return "STA";
1076 	}
1077 
1078 	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
1079 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
1080 		return "ML STA";
1081 	}
1082 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
1083 
1084 	return "STA";
1085 }
1086 
1087 static void
policy_mgr_dump_ml_sta_conc(struct wlan_objmgr_psoc * psoc,uint8_t * num_mlo_sta)1088 policy_mgr_dump_ml_sta_conc(struct wlan_objmgr_psoc *psoc,
1089 			    uint8_t *num_mlo_sta)
1090 {
1091 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1092 
1093 	if (!num_mlo_sta)
1094 		return;
1095 
1096 	pm_ctx = policy_mgr_get_context(psoc);
1097 	if (!pm_ctx) {
1098 		policy_mgr_err("Invalid Context");
1099 		return;
1100 	}
1101 
1102 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1103 
1104 	if (policy_mgr_is_mlo_in_mode_dbs(psoc, PM_STA_MODE, NULL,
1105 					  num_mlo_sta))
1106 		policy_mgr_debug("ML STA %d links in DBS band", *num_mlo_sta);
1107 	else if (policy_mgr_is_mlo_in_mode_sbs(psoc, PM_STA_MODE, NULL,
1108 					       num_mlo_sta))
1109 		policy_mgr_debug("ML STA %d links in SBS band", *num_mlo_sta);
1110 	else if (*num_mlo_sta > 1)
1111 		policy_mgr_debug("ML STA %d links in same mac MLSR",
1112 				 *num_mlo_sta);
1113 
1114 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1115 }
1116 
1117 /**
1118  * policy_mgr_dump_current_concurrency_one_connection() - To dump the
1119  * current concurrency info with one connection
1120  * @psoc: psoc object
1121  * @cc_mode: connection string
1122  * @length: Maximum size of the string
1123  *
1124  * This routine is called to dump the concurrency info
1125  *
1126  * Return: length of the string
1127  */
policy_mgr_dump_current_concurrency_one_connection(struct wlan_objmgr_psoc * psoc,char * cc_mode,uint32_t length)1128 static uint32_t policy_mgr_dump_current_concurrency_one_connection(
1129 		struct wlan_objmgr_psoc *psoc,
1130 		char *cc_mode, uint32_t length)
1131 {
1132 	uint32_t count = 0;
1133 	enum policy_mgr_con_mode mode;
1134 	char buf[9] = {0};
1135 
1136 	mode = pm_conc_connection_list[0].mode;
1137 	qdf_scnprintf(buf, sizeof(buf), "(vdev %d)",
1138 		      pm_conc_connection_list[0].vdev_id);
1139 
1140 	switch (mode) {
1141 	case PM_STA_MODE:
1142 		count = strlcat(cc_mode,
1143 				ml_sta_prefix(
1144 				psoc, pm_conc_connection_list[0].vdev_id),
1145 				length);
1146 		break;
1147 	case PM_SAP_MODE:
1148 		count = strlcat(cc_mode, "SAP",
1149 					length);
1150 		break;
1151 	case PM_P2P_CLIENT_MODE:
1152 		count = strlcat(cc_mode, "P2P CLI",
1153 					length);
1154 		break;
1155 	case PM_P2P_GO_MODE:
1156 		count = strlcat(cc_mode, "P2P GO",
1157 					length);
1158 		break;
1159 	case PM_NAN_DISC_MODE:
1160 		count = strlcat(cc_mode, "NAN DISC", length);
1161 		break;
1162 	case PM_NDI_MODE:
1163 		count = strlcat(cc_mode, "NDI", length);
1164 		break;
1165 	case PM_LL_LT_SAP_MODE:
1166 		count = strlcat(cc_mode, "LT_SAP", length);
1167 		break;
1168 	default:
1169 		policy_mgr_err("unexpected mode %d", mode);
1170 		break;
1171 	}
1172 	count += strlcat(cc_mode, buf, length);
1173 
1174 	return count;
1175 }
1176 
1177 /**
1178  * policy_mgr_dump_current_concurrency_two_connection() - To dump the
1179  * current concurrency info with two connections
1180  * @psoc: psoc object
1181  * @cc_mode: connection string
1182  * @length: Maximum size of the string
1183  *
1184  * This routine is called to dump the concurrency info
1185  *
1186  * Return: length of the string
1187  */
policy_mgr_dump_current_concurrency_two_connection(struct wlan_objmgr_psoc * psoc,char * cc_mode,uint32_t length)1188 static uint32_t policy_mgr_dump_current_concurrency_two_connection(
1189 		struct wlan_objmgr_psoc *psoc,
1190 		char *cc_mode, uint32_t length)
1191 {
1192 	uint32_t count = 0;
1193 	enum policy_mgr_con_mode mode;
1194 	char buf[9] = {0};
1195 
1196 	mode = pm_conc_connection_list[1].mode;
1197 	qdf_scnprintf(buf, sizeof(buf), "(vdev %d)",
1198 		      pm_conc_connection_list[1].vdev_id);
1199 
1200 	switch (mode) {
1201 	case PM_STA_MODE:
1202 		count = policy_mgr_dump_current_concurrency_one_connection(
1203 				psoc, cc_mode, length);
1204 		count += strlcat(cc_mode, "+", length);
1205 		count += strlcat(cc_mode,
1206 				 ml_sta_prefix(
1207 				 psoc, pm_conc_connection_list[1].vdev_id),
1208 				 length);
1209 		break;
1210 	case PM_SAP_MODE:
1211 		count = policy_mgr_dump_current_concurrency_one_connection(
1212 				psoc, cc_mode, length);
1213 		count += strlcat(cc_mode, "+SAP",
1214 					length);
1215 		break;
1216 	case PM_P2P_CLIENT_MODE:
1217 		count = policy_mgr_dump_current_concurrency_one_connection(
1218 				psoc, cc_mode, length);
1219 		count += strlcat(cc_mode, "+P2P CLI",
1220 					length);
1221 		break;
1222 	case PM_P2P_GO_MODE:
1223 		count = policy_mgr_dump_current_concurrency_one_connection(
1224 				psoc, cc_mode, length);
1225 		count += strlcat(cc_mode, "+P2P GO",
1226 					length);
1227 		break;
1228 	case PM_NDI_MODE:
1229 		count = policy_mgr_dump_current_concurrency_one_connection(
1230 				psoc, cc_mode, length);
1231 		count += strlcat(cc_mode, "+NDI",
1232 					length);
1233 		break;
1234 	case PM_NAN_DISC_MODE:
1235 		count = policy_mgr_dump_current_concurrency_one_connection(
1236 				psoc, cc_mode, length);
1237 		count += strlcat(cc_mode, "+NAN Disc", length);
1238 		break;
1239 	case PM_LL_LT_SAP_MODE:
1240 		count = policy_mgr_dump_current_concurrency_one_connection(
1241 				psoc, cc_mode, length);
1242 		count += strlcat(cc_mode, "+LT_SAP",
1243 					length);
1244 		break;
1245 	default:
1246 		policy_mgr_err("unexpected mode %d", mode);
1247 		break;
1248 	}
1249 	count += strlcat(cc_mode, buf, length);
1250 
1251 	return count;
1252 }
1253 
1254 /**
1255  * policy_mgr_dump_current_concurrency_three_connection() - To dump the
1256  * current concurrency info with three connections
1257  * @psoc: psoc object
1258  * @cc_mode: connection string
1259  * @length: Maximum size of the string
1260  *
1261  * This routine is called to dump the concurrency info
1262  *
1263  * Return: length of the string
1264  */
policy_mgr_dump_current_concurrency_three_connection(struct wlan_objmgr_psoc * psoc,char * cc_mode,uint32_t length)1265 static uint32_t policy_mgr_dump_current_concurrency_three_connection(
1266 		struct wlan_objmgr_psoc *psoc,
1267 		char *cc_mode, uint32_t length)
1268 {
1269 	uint32_t count = 0;
1270 	enum policy_mgr_con_mode mode;
1271 	char buf[9] = {0};
1272 
1273 	mode = pm_conc_connection_list[2].mode;
1274 	qdf_scnprintf(buf, sizeof(buf), "(vdev %d)",
1275 		      pm_conc_connection_list[2].vdev_id);
1276 
1277 	switch (mode) {
1278 	case PM_STA_MODE:
1279 		count = policy_mgr_dump_current_concurrency_two_connection(
1280 				psoc, cc_mode, length);
1281 		count += strlcat(cc_mode, "+", length);
1282 		count += strlcat(cc_mode,
1283 				 ml_sta_prefix(
1284 				 psoc, pm_conc_connection_list[2].vdev_id),
1285 				 length);
1286 		break;
1287 	case PM_SAP_MODE:
1288 		count = policy_mgr_dump_current_concurrency_two_connection(
1289 				psoc, cc_mode, length);
1290 		count += strlcat(cc_mode, "+SAP",
1291 					length);
1292 		break;
1293 	case PM_P2P_CLIENT_MODE:
1294 		count = policy_mgr_dump_current_concurrency_two_connection(
1295 				psoc, cc_mode, length);
1296 		count += strlcat(cc_mode, "+P2P CLI",
1297 					length);
1298 		break;
1299 	case PM_P2P_GO_MODE:
1300 		count = policy_mgr_dump_current_concurrency_two_connection(
1301 				psoc, cc_mode, length);
1302 		count += strlcat(cc_mode, "+P2P GO",
1303 					length);
1304 		break;
1305 	case PM_NAN_DISC_MODE:
1306 		count = policy_mgr_dump_current_concurrency_two_connection(
1307 				psoc, cc_mode, length);
1308 		count += strlcat(cc_mode, "+NAN Disc",
1309 					length);
1310 		break;
1311 	case PM_NDI_MODE:
1312 		count = policy_mgr_dump_current_concurrency_two_connection(
1313 				psoc, cc_mode, length);
1314 		count += strlcat(cc_mode, "+NDI",
1315 					length);
1316 		break;
1317 	case PM_LL_LT_SAP_MODE:
1318 		count = policy_mgr_dump_current_concurrency_two_connection(
1319 				psoc, cc_mode, length);
1320 		count += strlcat(cc_mode, "+LT_SAP",
1321 					length);
1322 
1323 		break;
1324 	default:
1325 		policy_mgr_err("unexpected mode %d", mode);
1326 		break;
1327 	}
1328 	count += strlcat(cc_mode, buf, length);
1329 
1330 	return count;
1331 }
1332 
1333 static void
policy_mgr_dump_dual_mac_concurrency(struct policy_mgr_psoc_priv_obj * pm_ctx,char * cc_mode,uint32_t length)1334 policy_mgr_dump_dual_mac_concurrency(struct policy_mgr_psoc_priv_obj *pm_ctx,
1335 				     char *cc_mode, uint32_t length)
1336 {
1337 	char buf[26] = {0};
1338 	uint8_t i;
1339 	uint8_t j;
1340 	uint32_t vdev_bit_mask = 0;
1341 
1342 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1343 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
1344 		if (!pm_conc_connection_list[i].in_use)
1345 			continue;
1346 		for (j = i + 1; j < MAX_NUMBER_OF_CONC_CONNECTIONS; j++) {
1347 			if (!pm_conc_connection_list[j].in_use)
1348 				continue;
1349 			if (policy_mgr_are_2_freq_on_same_mac(
1350 					pm_ctx->psoc,
1351 					pm_conc_connection_list[i].freq,
1352 					pm_conc_connection_list[j].freq)) {
1353 				qdf_mem_zero(buf, sizeof(buf));
1354 				qdf_scnprintf(
1355 					buf, sizeof(buf),
1356 					": vdev %d & %d %s on mac %d",
1357 					pm_conc_connection_list[i].vdev_id,
1358 					pm_conc_connection_list[j].vdev_id,
1359 					pm_conc_connection_list[i].freq ==
1360 					pm_conc_connection_list[j].freq ? "SCC"
1361 					: "MCC",
1362 					pm_conc_connection_list[i].mac);
1363 				QDF_SET_PARAM(
1364 					vdev_bit_mask,
1365 					pm_conc_connection_list[i].vdev_id);
1366 				QDF_SET_PARAM(
1367 					vdev_bit_mask,
1368 					pm_conc_connection_list[j].vdev_id);
1369 				strlcat(cc_mode, buf, length);
1370 			}
1371 		}
1372 	}
1373 
1374 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
1375 		/* in_use flag is required to be checked because vdev bit
1376 		 * mask will be 0 for 4th bit if only 3 port concurrency is
1377 		 * present on a hardware that can support 4 port concurrency
1378 		 */
1379 		if (!pm_conc_connection_list[i].in_use ||
1380 		    QDF_HAS_PARAM(
1381 		    vdev_bit_mask, pm_conc_connection_list[i].vdev_id))
1382 			continue;
1383 
1384 		qdf_mem_zero(buf, sizeof(buf));
1385 		qdf_scnprintf(buf, sizeof(buf), ": vdev %d alone on mac %d",
1386 			      pm_conc_connection_list[i].vdev_id,
1387 			      pm_conc_connection_list[i].mac);
1388 		strlcat(cc_mode, buf, length);
1389 	}
1390 
1391 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1392 }
1393 
1394 /**
1395  * policy_mgr_dump_dbs_concurrency() - To dump the dbs concurrency
1396  * combination
1397  * @psoc: psoc handle
1398  * @cc_mode: connection string
1399  * @length: Maximum size of the string
1400  *
1401  * This routine is called to dump the concurrency info
1402  *
1403  * Return: None
1404  */
policy_mgr_dump_dbs_concurrency(struct wlan_objmgr_psoc * psoc,char * cc_mode,uint32_t length)1405 static void policy_mgr_dump_dbs_concurrency(struct wlan_objmgr_psoc *psoc,
1406 					char *cc_mode, uint32_t length)
1407 {
1408 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1409 
1410 	pm_ctx = policy_mgr_get_context(psoc);
1411 	if (!pm_ctx) {
1412 		policy_mgr_err("Invalid Context");
1413 		return;
1414 	}
1415 
1416 	strlcat(cc_mode, " DBS", length);
1417 	policy_mgr_dump_dual_mac_concurrency(pm_ctx, cc_mode, length);
1418 }
1419 
1420 /**
1421  * policy_mgr_dump_sbs_concurrency() - To dump the sbs concurrency
1422  * combination
1423  * @psoc: psoc handle
1424  * @cc_mode: connection string
1425  * @length: Maximum size of the string
1426  *
1427  * This routine is called to dump the concurrency info
1428  *
1429  * Return: None
1430  */
policy_mgr_dump_sbs_concurrency(struct wlan_objmgr_psoc * psoc,char * cc_mode,uint32_t length)1431 static void policy_mgr_dump_sbs_concurrency(struct wlan_objmgr_psoc *psoc,
1432 					    char *cc_mode, uint32_t length)
1433 {
1434 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1435 
1436 	pm_ctx = policy_mgr_get_context(psoc);
1437 	if (!pm_ctx) {
1438 		policy_mgr_err("Invalid Context");
1439 		return;
1440 	}
1441 
1442 	strlcat(cc_mode, " SBS", length);
1443 	policy_mgr_dump_dual_mac_concurrency(pm_ctx, cc_mode, length);
1444 }
1445 
1446 #ifdef WLAN_FEATURE_11BE_MLO
1447 void
policy_mgr_dump_disabled_ml_links(struct policy_mgr_psoc_priv_obj * pm_ctx)1448 policy_mgr_dump_disabled_ml_links(struct policy_mgr_psoc_priv_obj *pm_ctx)
1449 {
1450 	uint8_t buf[POLICY_MGR_MAX_CON_STRING_LEN] = {0};
1451 	uint32_t len = 0, count = 0, i;
1452 
1453 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1454 	for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) {
1455 		if (pm_disabled_ml_links[i].in_use) {
1456 			len += qdf_scnprintf(buf + len,
1457 					    POLICY_MGR_MAX_CON_STRING_LEN - len,
1458 					    "vdev %d :Mode %d freq %d, ",
1459 					    pm_disabled_ml_links[i].vdev_id,
1460 					    pm_disabled_ml_links[i].mode,
1461 					    pm_disabled_ml_links[i].freq);
1462 			count++;
1463 		}
1464 	}
1465 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1466 	if (count)
1467 		policy_mgr_debug("Disabled links(%d): %s", count, buf);
1468 }
1469 #endif
1470 
1471 #ifdef FEATURE_FOURTH_CONNECTION
1472 /**
1473  * policy_mgr_dump_current_concurrency_4_connection() - To dump the
1474  * current concurrency info with 4 connections
1475  * @psoc: psoc object
1476  * @cc_mode: connection string
1477  * @length: Maximum size of the string
1478  *
1479  * This routine is called to dump the concurrency info
1480  *
1481  * Return: length of the string
1482  */
policy_mgr_dump_current_concurrency_4_connection(struct wlan_objmgr_psoc * psoc,char * cc_mode,uint32_t length)1483 static uint32_t policy_mgr_dump_current_concurrency_4_connection(
1484 		struct wlan_objmgr_psoc *psoc, char *cc_mode, uint32_t length)
1485 {
1486 	uint32_t count = 0;
1487 	enum policy_mgr_con_mode mode;
1488 	char buf[9] = {0};
1489 
1490 	mode = pm_conc_connection_list[3].mode;
1491 	qdf_scnprintf(buf, sizeof(buf), "(vdev %d)",
1492 		      pm_conc_connection_list[3].vdev_id);
1493 
1494 	switch (mode) {
1495 	case PM_STA_MODE:
1496 		count = policy_mgr_dump_current_concurrency_three_connection(
1497 				psoc, cc_mode, length);
1498 		count += strlcat(cc_mode, "+", length);
1499 		count += strlcat(cc_mode,
1500 				 ml_sta_prefix(
1501 				 psoc, pm_conc_connection_list[3].vdev_id),
1502 				 length);
1503 		break;
1504 	case PM_SAP_MODE:
1505 		count = policy_mgr_dump_current_concurrency_three_connection(
1506 				psoc, cc_mode, length);
1507 		count += strlcat(cc_mode, "+SAP",
1508 					length);
1509 		break;
1510 	case PM_P2P_CLIENT_MODE:
1511 		count = policy_mgr_dump_current_concurrency_three_connection(
1512 				psoc, cc_mode, length);
1513 		count += strlcat(cc_mode, "+P2P CLI",
1514 					length);
1515 		break;
1516 	case PM_P2P_GO_MODE:
1517 		count = policy_mgr_dump_current_concurrency_three_connection(
1518 				psoc, cc_mode, length);
1519 		count += strlcat(cc_mode, "+P2P GO",
1520 					length);
1521 		break;
1522 	case PM_NAN_DISC_MODE:
1523 		count = policy_mgr_dump_current_concurrency_three_connection(
1524 				psoc, cc_mode, length);
1525 		count += strlcat(cc_mode, "+NAN Disc",
1526 					length);
1527 		break;
1528 	case PM_NDI_MODE:
1529 		count = policy_mgr_dump_current_concurrency_three_connection(
1530 				psoc, cc_mode, length);
1531 		count += strlcat(cc_mode, "+NDI",
1532 					length);
1533 		break;
1534 	case PM_LL_LT_SAP_MODE:
1535 		count = policy_mgr_dump_current_concurrency_three_connection(
1536 				psoc, cc_mode, length);
1537 		count += strlcat(cc_mode, "+LT_SAP",
1538 					length);
1539 		break;
1540 
1541 	default:
1542 		policy_mgr_err("unexpected mode %d", mode);
1543 		break;
1544 	}
1545 	count += strlcat(cc_mode, buf, length);
1546 
1547 	return count;
1548 }
1549 
1550 static bool
policy_mgr_handle_dump_4th_connection(struct policy_mgr_psoc_priv_obj * pm_ctx,uint32_t num_connections,char * cc_mode,uint32_t len)1551 policy_mgr_handle_dump_4th_connection(struct policy_mgr_psoc_priv_obj *pm_ctx,
1552 				      uint32_t num_connections,
1553 				      char *cc_mode, uint32_t len)
1554 {
1555 	uint32_t count = 0;
1556 
1557 	if (num_connections != 4)
1558 		return false;
1559 
1560 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1561 
1562 	count = policy_mgr_dump_current_concurrency_4_connection(
1563 		pm_ctx->psoc, cc_mode, len);
1564 
1565 	if (policy_mgr_is_current_hwmode_dbs(pm_ctx->psoc))
1566 		policy_mgr_dump_dbs_concurrency(pm_ctx->psoc, cc_mode, len);
1567 	else if (policy_mgr_is_current_hwmode_sbs(pm_ctx->psoc))
1568 		policy_mgr_dump_sbs_concurrency(pm_ctx->psoc, cc_mode, len);
1569 	else
1570 		strlcat(cc_mode, " MCC", len);
1571 
1572 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1573 
1574 	return true;
1575 }
1576 #else
1577 static inline bool
policy_mgr_handle_dump_4th_connection(struct policy_mgr_psoc_priv_obj * pm_ctx,uint32_t num_connections,char * cc_mode,uint32_t len)1578 policy_mgr_handle_dump_4th_connection(struct policy_mgr_psoc_priv_obj *pm_ctx,
1579 				      uint32_t num_connections,
1580 				      char *cc_mode, uint32_t len)
1581 {
1582 	return false;
1583 }
1584 #endif
1585 
policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc * psoc)1586 void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc)
1587 {
1588 	uint32_t num_connections = 0;
1589 	char *cc_mode;
1590 	uint32_t count = 0;
1591 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1592 	uint32_t len = POLICY_MGR_MAX_CON_STRING_LEN;
1593 	uint8_t num_mlo_sta = 0;
1594 
1595 	pm_ctx = policy_mgr_get_context(psoc);
1596 	if (!pm_ctx) {
1597 		policy_mgr_err("Invalid Context");
1598 		return;
1599 	}
1600 
1601 	num_connections = policy_mgr_get_connection_count(psoc);
1602 	if (!num_connections)
1603 		return;
1604 
1605 	cc_mode = qdf_mem_malloc(len);
1606 	if (!cc_mode)
1607 		return;
1608 
1609 	policy_mgr_dump_connection_status_info(psoc);
1610 	policy_mgr_dump_ml_sta_conc(psoc, &num_mlo_sta);
1611 	switch (num_connections) {
1612 	case 1:
1613 		policy_mgr_dump_current_concurrency_one_connection(psoc,
1614 								   cc_mode,
1615 								   len);
1616 		policy_mgr_debug("%s Standalone", cc_mode);
1617 		break;
1618 	case 2:
1619 		count = policy_mgr_dump_current_concurrency_two_connection(
1620 			psoc, cc_mode, len);
1621 		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1622 		if (pm_conc_connection_list[0].freq ==
1623 		    pm_conc_connection_list[1].freq) {
1624 			strlcat(cc_mode, " SCC", len);
1625 			/* In some platform 2.4 Ghz can lead to DBS,
1626 			 * so check for DBS for SCC/MCC case
1627 			 */
1628 			if (policy_mgr_is_current_hwmode_dbs(psoc))
1629 				strlcat(cc_mode, " (DBS)", len);
1630 		} else if (policy_mgr_2_freq_always_on_same_mac(psoc,
1631 			   pm_conc_connection_list[0].freq,
1632 			   pm_conc_connection_list[1].freq)) {
1633 			strlcat(cc_mode, " MCC", len);
1634 			if (policy_mgr_is_current_hwmode_dbs(psoc))
1635 				strlcat(cc_mode, " (DBS)", len);
1636 		} else if (policy_mgr_is_current_hwmode_dbs(psoc)) {
1637 			strlcat(cc_mode, " DBS", len);
1638 		} else if (policy_mgr_is_current_hwmode_sbs(psoc)) {
1639 			strlcat(cc_mode, " SBS", len);
1640 		} else {
1641 			if (num_mlo_sta < 2)
1642 				strlcat(cc_mode, " MCC", len);
1643 			else
1644 				strlcat(cc_mode, " SMM", len);
1645 		}
1646 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1647 		policy_mgr_debug("%s", cc_mode);
1648 		break;
1649 	case 3:
1650 		count = policy_mgr_dump_current_concurrency_three_connection(
1651 			psoc, cc_mode, len);
1652 		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1653 		if (pm_conc_connection_list[0].freq ==
1654 		    pm_conc_connection_list[1].freq &&
1655 		    pm_conc_connection_list[0].freq ==
1656 		    pm_conc_connection_list[2].freq){
1657 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1658 			strlcat(cc_mode, " SCC", len);
1659 		} else if (policy_mgr_are_3_freq_on_same_mac(psoc,
1660 				pm_conc_connection_list[0].freq,
1661 				pm_conc_connection_list[1].freq,
1662 				pm_conc_connection_list[2].freq)) {
1663 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1664 			if (num_mlo_sta < 2)
1665 				strlcat(cc_mode, " MCC on single MAC", len);
1666 			else
1667 				strlcat(cc_mode, " on single MAC", len);
1668 		} else {
1669 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1670 			if (policy_mgr_is_current_hwmode_dbs(psoc))
1671 				policy_mgr_dump_dbs_concurrency(psoc, cc_mode,
1672 								len);
1673 			else if (policy_mgr_is_current_hwmode_sbs(psoc))
1674 				policy_mgr_dump_sbs_concurrency(psoc, cc_mode,
1675 								len);
1676 			else if (num_mlo_sta < 2)
1677 				strlcat(cc_mode, " MCC", len);
1678 			else
1679 				strlcat(cc_mode, " SMM", len);
1680 		}
1681 		policy_mgr_debug("%s", cc_mode);
1682 		break;
1683 	case 4:
1684 		if (policy_mgr_handle_dump_4th_connection(pm_ctx,
1685 							  num_connections,
1686 							  cc_mode, len)) {
1687 			policy_mgr_debug("%s", cc_mode);
1688 			break;
1689 		}
1690 	fallthrough;
1691 	default:
1692 		policy_mgr_debug("unexpected num_connections value %d",
1693 				 num_connections);
1694 		break;
1695 	}
1696 	qdf_mem_free(cc_mode);
1697 
1698 	policy_mgr_dump_disabled_ml_links(pm_ctx);
1699 
1700 	return;
1701 }
1702 
1703 /**
1704  * policy_mgr_set_pcl_for_existing_combo() - Set PCL for existing connection
1705  * @psoc: psoc handle
1706  * @mode: Connection mode of type 'policy_mgr_con_mode'
1707  * @vdev_id: Vdev Id
1708  *
1709  * Set the PCL for an existing connection
1710  *
1711  * Return: None
1712  */
policy_mgr_set_pcl_for_existing_combo(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint8_t vdev_id)1713 void policy_mgr_set_pcl_for_existing_combo(struct wlan_objmgr_psoc *psoc,
1714 					   enum policy_mgr_con_mode mode,
1715 					   uint8_t vdev_id)
1716 {
1717 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1718 	struct policy_mgr_pcl_list pcl;
1719 
1720 	status = policy_mgr_get_pcl_for_vdev_id(psoc, mode, pcl.pcl_list,
1721 						&pcl.pcl_len,
1722 						pcl.weight_list,
1723 						QDF_ARRAY_SIZE(pcl.weight_list),
1724 						vdev_id);
1725 	/* Send PCL only if policy_mgr_pdev_get_pcl returned success */
1726 	if (QDF_IS_STATUS_SUCCESS(status)) {
1727 		status = policy_mgr_set_pcl(psoc, &pcl, vdev_id, false);
1728 		if (QDF_IS_STATUS_ERROR(status))
1729 			policy_mgr_err("Send set PCL to policy mgr failed");
1730 	}
1731 }
1732 
policy_mgr_set_pcl_for_connected_vdev(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,bool clear_pcl)1733 void policy_mgr_set_pcl_for_connected_vdev(struct wlan_objmgr_psoc *psoc,
1734 					   uint8_t vdev_id, bool clear_pcl)
1735 {
1736 	struct policy_mgr_pcl_list msg = { {0} };
1737 	struct wlan_objmgr_vdev *vdev;
1738 	uint8_t roam_enabled_vdev_id;
1739 	bool sta_concurrency_is_with_different_mac, dual_sta_roam_enabled;
1740 
1741 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
1742 						    WLAN_POLICY_MGR_ID);
1743 	if (!vdev) {
1744 		policy_mgr_err("vdev is NULL");
1745 		return;
1746 	}
1747 
1748 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) {
1749 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
1750 		return;
1751 	}
1752 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
1753 
1754 	/*
1755 	 * Get the vdev id of the STA on which roaming is already
1756 	 * initialized and set the vdev PCL for that STA vdev if dual
1757 	 * STA roaming feature is enabled and concurrency is STA + STA.
1758 	 */
1759 	roam_enabled_vdev_id = policy_mgr_get_roam_enabled_sta_session_id(psoc,
1760 								       vdev_id);
1761 	if (roam_enabled_vdev_id == WLAN_UMAC_VDEV_ID_MAX)
1762 		return;
1763 
1764 	sta_concurrency_is_with_different_mac =
1765 		policy_mgr_concurrent_sta_on_different_mac(psoc);
1766 	dual_sta_roam_enabled = wlan_mlme_get_dual_sta_roaming_enabled(psoc);
1767 	policy_mgr_debug("dual_sta_roam:%d, sta concurrency on different mac:%d, clear_pcl:%d",
1768 			 dual_sta_roam_enabled,
1769 			 sta_concurrency_is_with_different_mac,
1770 			 clear_pcl);
1771 
1772 	if (dual_sta_roam_enabled) {
1773 		if (clear_pcl) {
1774 			/*
1775 			 * Here the PCL level should be at vdev level already
1776 			 * as this is invoked from disconnect handler. Clear the
1777 			 * vdev pcl for the existing connected STA vdev and this
1778 			 * is followed by set PDEV pcl.
1779 			 */
1780 			policy_mgr_set_pcl(psoc, &msg,
1781 					   roam_enabled_vdev_id, true);
1782 			wlan_cm_roam_activate_pcl_per_vdev(psoc,
1783 							   roam_enabled_vdev_id,
1784 							   false);
1785 		} else if (sta_concurrency_is_with_different_mac) {
1786 			wlan_cm_roam_activate_pcl_per_vdev(psoc,
1787 							   roam_enabled_vdev_id,
1788 							   true);
1789 		}
1790 		policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE,
1791 						      roam_enabled_vdev_id);
1792 	}
1793 }
1794 
1795 #ifdef WLAN_FEATURE_11BE_MLO
1796 uint32_t
policy_mgr_get_connected_vdev_band_mask(struct wlan_objmgr_vdev * vdev)1797 policy_mgr_get_connected_vdev_band_mask(struct wlan_objmgr_vdev *vdev)
1798 {
1799 	struct wlan_channel *chan;
1800 	uint32_t band_mask = 0;
1801 	struct wlan_objmgr_vdev *ml_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS] = {0};
1802 	uint16_t ml_vdev_cnt = 0;
1803 	struct wlan_objmgr_vdev *t_vdev;
1804 	int i;
1805 
1806 	if (!vdev) {
1807 		policy_mgr_err("vdev is NULL");
1808 		return band_mask;
1809 	}
1810 
1811 	if (wlan_vdev_mlme_is_link_sta_vdev(vdev)) {
1812 		policy_mgr_debug("skip mlo link sta");
1813 		return band_mask;
1814 	}
1815 
1816 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE ||
1817 	    !wlan_vdev_mlme_is_mlo_vdev(vdev)) {
1818 		chan = wlan_vdev_get_active_channel(vdev);
1819 		if (!chan) {
1820 			policy_mgr_err("no active channel");
1821 			return band_mask;
1822 		}
1823 
1824 		band_mask |= BIT(wlan_reg_freq_to_band(chan->ch_freq));
1825 		return band_mask;
1826 	}
1827 
1828 	mlo_get_ml_vdev_list(vdev, &ml_vdev_cnt, ml_vdev_list);
1829 	for (i = 0; i < ml_vdev_cnt; i++) {
1830 		t_vdev = ml_vdev_list[i];
1831 		if (!ucfg_cm_is_vdev_connected(t_vdev))
1832 			goto next;
1833 
1834 		chan = wlan_vdev_get_active_channel(t_vdev);
1835 		if (!chan)
1836 			goto next;
1837 
1838 		band_mask |= BIT(wlan_reg_freq_to_band(chan->ch_freq));
1839 next:
1840 		mlo_release_vdev_ref(t_vdev);
1841 	}
1842 
1843 	return band_mask;
1844 }
1845 #else
1846 uint32_t
policy_mgr_get_connected_vdev_band_mask(struct wlan_objmgr_vdev * vdev)1847 policy_mgr_get_connected_vdev_band_mask(struct wlan_objmgr_vdev *vdev)
1848 {
1849 	struct wlan_channel *chan;
1850 	uint32_t band_mask = 0;
1851 
1852 	if (!vdev) {
1853 		policy_mgr_err("vdev is NULL");
1854 		return band_mask;
1855 	}
1856 
1857 	chan = wlan_vdev_get_active_channel(vdev);
1858 	if (!chan) {
1859 		policy_mgr_err("no active channel");
1860 		return band_mask;
1861 	}
1862 
1863 	band_mask |= BIT(wlan_reg_freq_to_band(chan->ch_freq));
1864 	return band_mask;
1865 }
1866 #endif
1867 
1868 /**
1869  * policy_mgr_get_connected_roaming_vdev_band_mask() - get connected vdev
1870  * band mask
1871  * @psoc: PSOC object
1872  * @vdev_id: Vdev id
1873  *
1874  * Return: reg wifi band mask
1875  */
1876 uint32_t
policy_mgr_get_connected_roaming_vdev_band_mask(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)1877 policy_mgr_get_connected_roaming_vdev_band_mask(struct wlan_objmgr_psoc *psoc,
1878 						uint8_t vdev_id)
1879 {
1880 	uint32_t band_mask = 0, roam_band_mask, band_mask_for_vdev;
1881 	struct wlan_objmgr_vdev *vdev;
1882 	bool dual_sta_roam_active, is_pcl_per_vdev;
1883 	bool is_sbs_capable = false;
1884 
1885 	is_sbs_capable =
1886 		policy_mgr_is_hw_sbs_capable(psoc);
1887 
1888 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
1889 						    WLAN_POLICY_MGR_ID);
1890 	if (!vdev) {
1891 		policy_mgr_err("vdev is NULL");
1892 		return 0;
1893 	}
1894 
1895 	roam_band_mask = wlan_cm_get_roam_band_value(psoc, vdev);
1896 
1897 	/*
1898 	 * If sbs is enabled, just send PCL to F/W directly,  allow SBS<->DBS
1899 	 * roaming,  not just limit intra band.
1900 	 */
1901 	if (is_sbs_capable) {
1902 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
1903 		return roam_band_mask;
1904 	}
1905 	band_mask_for_vdev = policy_mgr_get_connected_vdev_band_mask(vdev);
1906 
1907 	is_pcl_per_vdev = wlan_cm_roam_is_pcl_per_vdev_active(psoc, vdev_id);
1908 	dual_sta_roam_active = wlan_mlme_get_dual_sta_roaming_enabled(psoc);
1909 
1910 	policy_mgr_debug("connected STA vdev_id:%d, pcl_per_vdev:%d, dual_sta_roam_active:%d",
1911 			 vdev_id, is_pcl_per_vdev,
1912 			 dual_sta_roam_active);
1913 
1914 	if (dual_sta_roam_active && is_pcl_per_vdev) {
1915 		policy_mgr_debug("connected vdev band mask:%d",
1916 				 band_mask_for_vdev);
1917 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
1918 		return band_mask_for_vdev;
1919 	}
1920 
1921 	/*
1922 	 * if vendor command to configure roam band is set , we will
1923 	 * take this as priority instead of drv cmd "SETROAMINTRABAND" or
1924 	 * active connection band.
1925 	 */
1926 	ucfg_reg_get_band(wlan_vdev_get_pdev(vdev), &band_mask);
1927 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
1928 
1929 	if (roam_band_mask != band_mask) {
1930 		policy_mgr_debug("roam_band_mask:%d", roam_band_mask);
1931 		return roam_band_mask;
1932 	}
1933 
1934 	/*
1935 	 * If PCL command is PDEV level, only one sta is active.
1936 	 * So fill the band mask if intra band roaming is enabled
1937 	 */
1938 	if ((!is_pcl_per_vdev) && ucfg_mlme_is_roam_intra_band(psoc)) {
1939 		policy_mgr_debug("connected STA band mask:%d",
1940 				 band_mask_for_vdev);
1941 		return band_mask_for_vdev;
1942 	}
1943 
1944 	policy_mgr_debug("band_mask:%d", band_mask);
1945 	return band_mask;
1946 }
1947 
policy_mgr_set_pcl(struct wlan_objmgr_psoc * psoc,struct policy_mgr_pcl_list * msg,uint8_t vdev_id,bool clear_vdev_pcl)1948 QDF_STATUS policy_mgr_set_pcl(struct wlan_objmgr_psoc *psoc,
1949 			      struct policy_mgr_pcl_list *msg,
1950 			      uint8_t vdev_id,
1951 			      bool clear_vdev_pcl)
1952 {
1953 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1954 	struct scheduler_msg message = {0};
1955 	struct set_pcl_req *req_msg;
1956 	uint32_t i;
1957 
1958 	if (!msg) {
1959 		policy_mgr_err("msg is NULL");
1960 		return QDF_STATUS_E_FAILURE;
1961 	}
1962 
1963 	if (!MLME_IS_ROAM_INITIALIZED(psoc, vdev_id)) {
1964 		policy_mgr_debug("Roam is not initialized on vdev:%d", vdev_id);
1965 		return QDF_STATUS_E_FAILURE;
1966 	}
1967 
1968 	req_msg = qdf_mem_malloc(sizeof(*req_msg));
1969 	if (!req_msg)
1970 		return QDF_STATUS_E_NOMEM;
1971 
1972 	req_msg->band_mask =
1973 		policy_mgr_get_connected_roaming_vdev_band_mask(psoc, vdev_id);
1974 	for (i = 0; i < msg->pcl_len; i++) {
1975 		req_msg->chan_weights.pcl_list[i] =  msg->pcl_list[i];
1976 		req_msg->chan_weights.weight_list[i] =  msg->weight_list[i];
1977 	}
1978 
1979 	req_msg->chan_weights.pcl_len = msg->pcl_len;
1980 	req_msg->clear_vdev_pcl = clear_vdev_pcl;
1981 
1982 	/*
1983 	 * Set vdev value as WLAN_UMAC_VDEV_ID_MAX, if PDEV level
1984 	 * PCL command needs to be sent.
1985 	 */
1986 	if (!wlan_cm_roam_is_pcl_per_vdev_active(psoc, vdev_id))
1987 		vdev_id = WLAN_UMAC_VDEV_ID_MAX;
1988 
1989 	req_msg->vdev_id = vdev_id;
1990 
1991 	/* Serialize the req through MC thread */
1992 	message.bodyptr = req_msg;
1993 	message.type    = SIR_HAL_SET_PCL_TO_FW;
1994 	status = scheduler_post_message(QDF_MODULE_ID_POLICY_MGR,
1995 					QDF_MODULE_ID_WMA,
1996 					QDF_MODULE_ID_WMA, &message);
1997 	if (QDF_IS_STATUS_ERROR(status)) {
1998 		policy_mgr_err("scheduler_post_msg failed!(err=%d)", status);
1999 		qdf_mem_free(req_msg);
2000 		status = QDF_STATUS_E_FAILURE;
2001 	}
2002 
2003 	return status;
2004 }
2005 
pm_get_vdev_id_of_first_conn_idx(struct wlan_objmgr_psoc * psoc)2006 static uint32_t pm_get_vdev_id_of_first_conn_idx(struct wlan_objmgr_psoc *psoc)
2007 {
2008 	uint32_t conn_index = 0, vdev_id = 0;
2009 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2010 	struct wlan_objmgr_vdev *vdev;
2011 
2012 	pm_ctx = policy_mgr_get_context(psoc);
2013 	if (!pm_ctx) {
2014 		policy_mgr_err("Invalid Context");
2015 		return conn_index;
2016 	}
2017 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2018 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
2019 	     conn_index++)  {
2020 		if (pm_conc_connection_list[conn_index].in_use) {
2021 			vdev_id = pm_conc_connection_list[conn_index].vdev_id;
2022 			policy_mgr_debug("Use vdev_id:%d for opportunistic upgrade",
2023 					 vdev_id);
2024 			break;
2025 		}
2026 	}
2027 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2028 	if (conn_index == MAX_NUMBER_OF_CONC_CONNECTIONS) {
2029 		vdev = wlan_objmgr_pdev_get_first_vdev(pm_ctx->pdev,
2030 						       WLAN_POLICY_MGR_ID);
2031 		if (vdev) {
2032 			vdev_id = wlan_vdev_get_id(vdev);
2033 			wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
2034 		}
2035 		policy_mgr_debug("Use default vdev_id:%d for opportunistic upgrade",
2036 				 vdev_id);
2037 	}
2038 
2039 	return vdev_id;
2040 }
2041 
2042 /**
2043  * pm_dbs_opportunistic_timer_handler() - handler of
2044  * dbs_opportunistic_timer
2045  * @data:  context
2046  *
2047  * handler for dbs_opportunistic_timer
2048  *
2049  * Return: None
2050  */
pm_dbs_opportunistic_timer_handler(void * data)2051 void pm_dbs_opportunistic_timer_handler(void *data)
2052 {
2053 	enum policy_mgr_conc_next_action action = PM_NOP;
2054 	uint32_t session_id;
2055 	struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)data;
2056 	enum policy_mgr_conn_update_reason reason =
2057 				POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC;
2058 	struct policy_mgr_psoc_priv_obj *pm_ctx = policy_mgr_get_context(psoc);
2059 
2060 	if (!psoc) {
2061 		policy_mgr_err("Invalid Context");
2062 		return;
2063 	}
2064 
2065 	/* if we still need it */
2066 	action = policy_mgr_need_opportunistic_upgrade(psoc, &reason);
2067 	policy_mgr_debug("action:%d", action);
2068 	if (!action) {
2069 		return;
2070 	} else if (pm_ctx->hdd_cbacks.hdd_is_cac_in_progress &&
2071 		   pm_ctx->hdd_cbacks.hdd_is_cac_in_progress()) {
2072 		policy_mgr_debug("SAP is in CAC_IN_PROGRESS state, restarting");
2073 		policy_mgr_restart_opportunistic_timer(psoc, false);
2074 		return;
2075 	}
2076 	session_id = pm_get_vdev_id_of_first_conn_idx(psoc);
2077 	policy_mgr_next_actions(psoc, session_id, action,
2078 				reason, POLICY_MGR_DEF_REQ_ID);
2079 }
2080 
policy_mgr_get_connection_for_vdev_id(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id)2081 uint32_t policy_mgr_get_connection_for_vdev_id(struct wlan_objmgr_psoc *psoc,
2082 					       uint32_t vdev_id)
2083 {
2084 	uint32_t conn_index = 0;
2085 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2086 
2087 	pm_ctx = policy_mgr_get_context(psoc);
2088 	if (!pm_ctx) {
2089 		policy_mgr_err("Invalid Context");
2090 		return conn_index;
2091 	}
2092 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2093 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
2094 		 conn_index++) {
2095 		if ((pm_conc_connection_list[conn_index].vdev_id == vdev_id) &&
2096 			pm_conc_connection_list[conn_index].in_use) {
2097 			break;
2098 		}
2099 	}
2100 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2101 
2102 	return conn_index;
2103 }
2104 
2105 /**
2106  * policy_mgr_get_bw() - Get channel bandwidth type used by WMI
2107  * @chan_width: channel bandwidth type defined by host
2108  *
2109  * Get the channel bandwidth type used by WMI
2110  *
2111  * Return: hw_mode_bandwidth
2112  */
policy_mgr_get_bw(enum phy_ch_width chan_width)2113 enum hw_mode_bandwidth policy_mgr_get_bw(enum phy_ch_width chan_width)
2114 {
2115 	enum hw_mode_bandwidth bw = HW_MODE_BW_NONE;
2116 
2117 	switch (chan_width) {
2118 	case CH_WIDTH_20MHZ:
2119 		bw = HW_MODE_20_MHZ;
2120 		break;
2121 	case CH_WIDTH_40MHZ:
2122 		bw = HW_MODE_40_MHZ;
2123 		break;
2124 	case CH_WIDTH_80MHZ:
2125 		bw = HW_MODE_80_MHZ;
2126 		break;
2127 	case CH_WIDTH_160MHZ:
2128 		bw = HW_MODE_160_MHZ;
2129 		break;
2130 	case CH_WIDTH_80P80MHZ:
2131 		bw = HW_MODE_80_PLUS_80_MHZ;
2132 		break;
2133 	case CH_WIDTH_5MHZ:
2134 		bw = HW_MODE_5_MHZ;
2135 		break;
2136 	case CH_WIDTH_10MHZ:
2137 		bw = HW_MODE_10_MHZ;
2138 		break;
2139 	case CH_WIDTH_320MHZ:
2140 		bw = HW_MODE_320_MHZ;
2141 		break;
2142 	default:
2143 		policy_mgr_err("Unknown channel BW type %d", chan_width);
2144 		break;
2145 	}
2146 
2147 	return bw;
2148 }
2149 
policy_mgr_get_ch_width(enum hw_mode_bandwidth bw)2150 enum phy_ch_width policy_mgr_get_ch_width(enum hw_mode_bandwidth bw)
2151 {
2152 	enum phy_ch_width ch_width = CH_WIDTH_INVALID;
2153 
2154 	switch (bw) {
2155 	case HW_MODE_20_MHZ:
2156 		ch_width = CH_WIDTH_20MHZ;
2157 		break;
2158 	case HW_MODE_40_MHZ:
2159 		ch_width = CH_WIDTH_40MHZ;
2160 		break;
2161 	case HW_MODE_80_MHZ:
2162 		ch_width = CH_WIDTH_80MHZ;
2163 		break;
2164 	case HW_MODE_160_MHZ:
2165 		ch_width = CH_WIDTH_160MHZ;
2166 		break;
2167 	case HW_MODE_80_PLUS_80_MHZ:
2168 		ch_width = CH_WIDTH_80P80MHZ;
2169 		break;
2170 	case HW_MODE_5_MHZ:
2171 		ch_width = CH_WIDTH_5MHZ;
2172 		break;
2173 	case HW_MODE_10_MHZ:
2174 		ch_width = CH_WIDTH_10MHZ;
2175 		break;
2176 	case HW_MODE_320_MHZ:
2177 		ch_width = CH_WIDTH_320MHZ;
2178 		break;
2179 	default:
2180 		policy_mgr_err("Invalid phy_ch_width type %d", ch_width);
2181 		break;
2182 	}
2183 
2184 	return ch_width;
2185 }
2186 
2187 static bool
is_preset_in_chlist(uint32_t chan_freq,const uint32_t * chlist,uint32_t chlist_len)2188 is_preset_in_chlist(uint32_t chan_freq, const uint32_t *chlist,
2189 		    uint32_t chlist_len)
2190 {
2191 	uint32_t i;
2192 
2193 	for (i = 0; i < chlist_len; i++)
2194 		if (chlist[i] == chan_freq)
2195 			return true;
2196 
2197 	return false;
2198 }
2199 
2200 static void
get_sbs_chlist(struct wlan_objmgr_psoc * psoc,uint32_t * sbs_freqs,uint32_t * sbs_num,uint32_t chan_freq,const uint32_t * chlist1,uint32_t chlist1_len,const uint32_t * chlist2,uint32_t chlist2_len)2201 get_sbs_chlist(struct wlan_objmgr_psoc *psoc,
2202 	       uint32_t *sbs_freqs, uint32_t *sbs_num, uint32_t chan_freq,
2203 	       const uint32_t *chlist1, uint32_t chlist1_len,
2204 	       const uint32_t *chlist2, uint32_t chlist2_len)
2205 {
2206 	uint32_t size_of_sbs = *sbs_num;
2207 	uint32_t i;
2208 
2209 	*sbs_num = 0;
2210 	for (i = 0; i < chlist1_len; i++) {
2211 		if (*sbs_num >= size_of_sbs)
2212 			return;
2213 		if (policy_mgr_are_sbs_chan(psoc, chan_freq, chlist1[i]))
2214 			sbs_freqs[(*sbs_num)++] = chlist1[i];
2215 	}
2216 	for (i = 0; i < chlist2_len; i++) {
2217 		if (*sbs_num >= size_of_sbs)
2218 			return;
2219 		if (policy_mgr_are_sbs_chan(psoc, chan_freq, chlist2[i]))
2220 			sbs_freqs[(*sbs_num)++] = chlist2[i];
2221 	}
2222 }
2223 
2224 static void
get_rest_chlist(uint32_t * rest_freqs,uint32_t * rest_num,uint32_t * scc_freqs,uint32_t scc_num,uint32_t * sbs_freqs,uint32_t sbs_num,const uint32_t * chlist1,uint32_t chlist1_len,const uint32_t * chlist2,uint32_t chlist2_len)2225 get_rest_chlist(uint32_t *rest_freqs, uint32_t *rest_num,
2226 		uint32_t *scc_freqs, uint32_t scc_num,
2227 		uint32_t *sbs_freqs, uint32_t sbs_num,
2228 		const uint32_t *chlist1, uint32_t chlist1_len,
2229 		const uint32_t *chlist2, uint32_t chlist2_len)
2230 {
2231 	uint32_t size_of_rest = *rest_num;
2232 	uint32_t i;
2233 
2234 	*rest_num = 0;
2235 	for (i = 0; i < chlist1_len; i++) {
2236 		if (*rest_num >= size_of_rest)
2237 			return;
2238 		if (is_preset_in_chlist(chlist1[i], scc_freqs, scc_num) ||
2239 		    is_preset_in_chlist(chlist1[i], sbs_freqs, sbs_num))
2240 			continue;
2241 		rest_freqs[(*rest_num)++] = chlist1[i];
2242 	}
2243 	for (i = 0; i < chlist2_len; i++) {
2244 		if (*rest_num >= size_of_rest)
2245 			return;
2246 		if (is_preset_in_chlist(chlist2[i], scc_freqs, scc_num) ||
2247 		    is_preset_in_chlist(chlist2[i], sbs_freqs, sbs_num))
2248 			continue;
2249 		rest_freqs[(*rest_num)++] = chlist2[i];
2250 	}
2251 }
2252 
2253 static void
get_sub_channels(struct wlan_objmgr_psoc * psoc,uint32_t * sbs_freqs,uint32_t * sbs_num,uint32_t * scc_freqs,uint32_t * scc_num,uint32_t * rest_freqs,uint32_t * rest_num,const uint32_t * chlist_5g,uint32_t chlist_5g_len,const uint32_t * chlist_6g,uint32_t chlist_6g_len)2254 get_sub_channels(struct wlan_objmgr_psoc *psoc,
2255 		 uint32_t *sbs_freqs, uint32_t *sbs_num,
2256 		 uint32_t *scc_freqs, uint32_t *scc_num,
2257 		 uint32_t *rest_freqs, uint32_t *rest_num,
2258 		 const uint32_t *chlist_5g, uint32_t chlist_5g_len,
2259 		 const uint32_t *chlist_6g, uint32_t chlist_6g_len)
2260 {
2261 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2262 	uint32_t i = 0;
2263 	const uint32_t *chlist1;
2264 	uint8_t chlist1_len;
2265 	const uint32_t *chlist2;
2266 	uint8_t chlist2_len;
2267 	uint32_t size_of_scc = *scc_num;
2268 
2269 	pm_ctx = policy_mgr_get_context(psoc);
2270 	if (!pm_ctx) {
2271 		policy_mgr_err("Invalid Context");
2272 		*scc_num = 0;
2273 		*sbs_num = 0;
2274 		*rest_num = 0;
2275 		return;
2276 	}
2277 
2278 	if (pm_ctx->cfg.pcl_band_priority == POLICY_MGR_PCL_BAND_6G_THEN_5G) {
2279 		chlist1 = chlist_6g;
2280 		chlist1_len = chlist_6g_len;
2281 		chlist2 = chlist_5g;
2282 		chlist2_len = chlist_5g_len;
2283 	} else {
2284 		chlist1 = chlist_5g;
2285 		chlist1_len = chlist_5g_len;
2286 		chlist2 = chlist_6g;
2287 		chlist2_len = chlist_6g_len;
2288 	}
2289 	*scc_num = 0;
2290 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2291 	/* For SCC channels, 6G first then 5G */
2292 	i = 0;
2293 	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(i)) {
2294 		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(
2295 		    pm_conc_connection_list[i].freq)) {
2296 			if (*scc_num < size_of_scc &&
2297 			    !is_preset_in_chlist(
2298 					pm_conc_connection_list[i].freq,
2299 					scc_freqs, *scc_num))
2300 				scc_freqs[(*scc_num)++] =
2301 					pm_conc_connection_list[i].freq;
2302 		}
2303 		i++;
2304 	}
2305 	i = 0;
2306 	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(i)) {
2307 		if (WLAN_REG_IS_5GHZ_CH_FREQ(
2308 		    pm_conc_connection_list[i].freq)) {
2309 			if (*scc_num < size_of_scc &&
2310 			    !is_preset_in_chlist(
2311 					pm_conc_connection_list[i].freq,
2312 					scc_freqs, *scc_num))
2313 				scc_freqs[(*scc_num)++] =
2314 					pm_conc_connection_list[i].freq;
2315 		}
2316 		i++;
2317 	}
2318 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2319 
2320 	/*
2321 	 * scc_num is number of existing 5Ghz or 6Ghz connection freqs.
2322 	 * So check if they are all on same mac in SBS, to get SBS
2323 	 * freq list.
2324 	 *
2325 	 * For scc_num > 2, it will always be with freq across
2326 	 * both mac, as all 3 cannot be on same mac.
2327 	 *
2328 	 * For scc_num == 0, i.e no freq on 5/6Ghz there is no need to
2329 	 * check for SBS freq.
2330 	 *
2331 	 * So check only if scc_num == 1 or 2, with both freq
2332 	 * on same mac in SBS mode (non-SBS) in case of 2.
2333 	 *
2334 	 * sbs_num contains the max number of freq element can be saved in
2335 	 * sbs_freqs array when this function is called.
2336 	 * It will contain actual freq element number in the array on return.
2337 	 * Clear it to 0 if no sbs freq is populated by get_sbs_chlist.
2338 	 */
2339 	if (policy_mgr_is_hw_sbs_capable(psoc) &&
2340 	    (*scc_num == 1 ||
2341 	     (*scc_num == 2 &&
2342 	      !policy_mgr_are_sbs_chan(psoc, scc_freqs[0],
2343 				       scc_freqs[1]))))
2344 		get_sbs_chlist(psoc, sbs_freqs, sbs_num, scc_freqs[0],
2345 			       chlist1, chlist1_len, chlist2, chlist2_len);
2346 	else
2347 		*sbs_num = 0;
2348 
2349 	get_rest_chlist(rest_freqs, rest_num, scc_freqs, *scc_num,
2350 			sbs_freqs, *sbs_num, chlist1, chlist1_len,
2351 			chlist2, chlist2_len);
2352 }
2353 
2354 /**
2355  * add_sbs_chlist_to_pcl() - add sbs channel list in pcl
2356  *
2357  * @psoc: psoc object
2358  * @pcl_freqs: pcl frequencies
2359  * @pcl_weights: pcl weight
2360  * @pcl_sz: pcl size
2361  * @index: pcl index
2362  * @skip_6gh_channel: to skip 6g channels or not
2363  * @chlist_5: 5g channel list
2364  * @chlist_len_5: 5g channel list length
2365  * @chlist_6: 6g channel list
2366  * @chlist_len_6: 6g channel list length
2367  * @order: pcl order
2368  * @high_5_band_scc_present: 5 GHz high band connection present
2369  * @low_5_band_scc_present: 5 GHz low band connection present
2370  *
2371  * Get the pcl list based on current sbs concurrency
2372  *
2373  * Return: None
2374  */
2375 static void
add_sbs_chlist_to_pcl(struct wlan_objmgr_psoc * psoc,uint32_t * pcl_freqs,uint8_t * pcl_weights,uint32_t pcl_sz,uint32_t * index,bool skip_6gh_channel,const uint32_t * chlist_5,uint8_t chlist_len_5,const uint32_t * chlist_6,uint8_t chlist_len_6,enum policy_mgr_pcl_channel_order order,bool * high_5_band_scc_present,bool * low_5_band_scc_present)2376 add_sbs_chlist_to_pcl(struct wlan_objmgr_psoc *psoc,
2377 		      uint32_t *pcl_freqs, uint8_t *pcl_weights,
2378 		      uint32_t pcl_sz, uint32_t *index,
2379 		      bool skip_6gh_channel,
2380 		      const uint32_t *chlist_5, uint8_t chlist_len_5,
2381 		      const uint32_t *chlist_6, uint8_t chlist_len_6,
2382 		      enum policy_mgr_pcl_channel_order order,
2383 		      bool *high_5_band_scc_present,
2384 		      bool *low_5_band_scc_present)
2385 {
2386 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2387 	qdf_freq_t sbs_cut_off_freq;
2388 	qdf_freq_t scc_freq = 0;
2389 	uint32_t i, conn_index = 0;
2390 	struct policy_mgr_conc_connection_info *cl;
2391 
2392 	if (!policy_mgr_is_hw_sbs_capable(psoc))
2393 		return;
2394 
2395 	sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(psoc);
2396 	if (!sbs_cut_off_freq) {
2397 		policy_mgr_err("Invalid cut off freq");
2398 		return;
2399 	}
2400 
2401 	pm_ctx = policy_mgr_get_context(psoc);
2402 	if (!pm_ctx) {
2403 		policy_mgr_err("Invalid Context");
2404 		return;
2405 	}
2406 
2407 	if (order == POLICY_MGR_PCL_ORDER_SCC_5G_LOW_5G_LOW) {
2408 		/* Add 5G low SCC channel*/
2409 		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2410 		cl = pm_conc_connection_list;
2411 		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2412 			if (!WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
2413 			    cl[conn_index].freq < sbs_cut_off_freq) {
2414 				pcl_freqs[*index] = cl[conn_index].freq;
2415 				scc_freq = cl[conn_index].freq;
2416 				pcl_weights[*index] =
2417 						WEIGHT_OF_GROUP1_PCL_CHANNELS;
2418 				(*index)++;
2419 				*low_5_band_scc_present = true;
2420 				break;
2421 			}
2422 
2423 			conn_index++;
2424 		}
2425 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2426 		/* Add rest 5G low channels*/
2427 		for (i = 0; i < chlist_len_5 && *index < pcl_sz; i++) {
2428 			if (chlist_5[i] > sbs_cut_off_freq)
2429 				return;
2430 
2431 			/* SCC channel is already added in pcl freq*/
2432 			if (scc_freq == chlist_5[i])
2433 				continue;
2434 
2435 			pcl_freqs[*index] = chlist_5[i];
2436 			pcl_weights[*index] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
2437 			(*index)++;
2438 		}
2439 		for (i = 0; i < chlist_len_6 && *index < pcl_sz &&
2440 		     !skip_6gh_channel; i++) {
2441 			if (chlist_6[i] > sbs_cut_off_freq)
2442 				return;
2443 
2444 			/* SCC channel is already added in pcl freq*/
2445 			if (scc_freq == chlist_6[i])
2446 				continue;
2447 
2448 			pcl_freqs[*index] = chlist_6[i];
2449 			pcl_weights[*index] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
2450 			(*index)++;
2451 		}
2452 	} else if (order == POLICY_MGR_PCL_ORDER_SCC_5G_HIGH_5G_HIGH ||
2453 		   order ==
2454 		   POLICY_MGR_PCL_ORDER_SCC_5G_HIGH_5G_HIGH_SCC_5G_LOW) {
2455 		/* Add 5G high SCC channel*/
2456 		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2457 		cl = pm_conc_connection_list;
2458 		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2459 			if (!WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
2460 			    cl[conn_index].freq > sbs_cut_off_freq) {
2461 				pcl_freqs[*index] = cl[conn_index].freq;
2462 				scc_freq = cl[conn_index].freq;
2463 				pcl_weights[*index] =
2464 					WEIGHT_OF_GROUP1_PCL_CHANNELS;
2465 				(*index)++;
2466 				*high_5_band_scc_present = true;
2467 				break;
2468 			}
2469 
2470 			conn_index++;
2471 		}
2472 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2473 		/* Add rest 5G high channels*/
2474 		for (i = 0; i < chlist_len_5 && *index < pcl_sz; i++) {
2475 			if (chlist_5[i] < sbs_cut_off_freq)
2476 				continue;
2477 			/* SCC channel is already added in pcl freq*/
2478 			if (scc_freq == chlist_5[i])
2479 				continue;
2480 
2481 			pcl_freqs[*index] = chlist_5[i];
2482 			pcl_weights[*index] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
2483 			(*index)++;
2484 		}
2485 		for (i = 0; i < chlist_len_6 && *index < pcl_sz &&
2486 		     !skip_6gh_channel; i++) {
2487 			if (chlist_6[i] < sbs_cut_off_freq)
2488 				return;
2489 
2490 			/* SCC channel is already added in pcl freq*/
2491 			if (scc_freq == chlist_6[i])
2492 				continue;
2493 
2494 			pcl_freqs[*index] = chlist_6[i];
2495 			pcl_weights[*index] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
2496 			(*index)++;
2497 		}
2498 		if (order ==
2499 		    POLICY_MGR_PCL_ORDER_SCC_5G_HIGH_5G_HIGH_SCC_5G_LOW) {
2500 			conn_index = 0;
2501 			/* Add 5G low SCC channel*/
2502 			qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2503 			cl = pm_conc_connection_list;
2504 			while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2505 				if (!WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
2506 				    cl[conn_index].freq < sbs_cut_off_freq) {
2507 					pcl_freqs[*index] = cl[conn_index].freq;
2508 					pcl_weights[*index] =
2509 						WEIGHT_OF_GROUP3_PCL_CHANNELS;
2510 					(*index)++;
2511 					break;
2512 				}
2513 				conn_index++;
2514 			}
2515 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2516 		}
2517 	} else if (order == POLICY_MGR_PCL_ORDER_SCC_5G_LOW) {
2518 		/* Add 5 GHz low SCC channel*/
2519 		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2520 		cl = pm_conc_connection_list;
2521 		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2522 			if (!WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
2523 			    cl[conn_index].freq < sbs_cut_off_freq) {
2524 				pcl_freqs[*index] = cl[conn_index].freq;
2525 				pcl_weights[*index] =
2526 						WEIGHT_OF_GROUP1_PCL_CHANNELS;
2527 				(*index)++;
2528 				*low_5_band_scc_present = true;
2529 				break;
2530 			}
2531 
2532 			conn_index++;
2533 		}
2534 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2535 	} else if (order == POLICY_MGR_PCL_ORDER_SCC_5G_HIGH) {
2536 		/* Add 5 GHz high SCC channel*/
2537 		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2538 		cl = pm_conc_connection_list;
2539 		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2540 			if (!WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
2541 			    cl[conn_index].freq > sbs_cut_off_freq) {
2542 				pcl_freqs[*index] = cl[conn_index].freq;
2543 				pcl_weights[*index] =
2544 					WEIGHT_OF_GROUP1_PCL_CHANNELS;
2545 				(*index)++;
2546 				*high_5_band_scc_present = true;
2547 				break;
2548 			}
2549 			conn_index++;
2550 		}
2551 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2552 
2553 	} else if (order == POLICY_MGR_PCL_ORDER_SCC_5G_LOW_MCC_5G_HIGH) {
2554 		/* Add 5 GHz low SCC channel*/
2555 		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2556 		cl = pm_conc_connection_list;
2557 		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2558 			if (!WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
2559 			    cl[conn_index].freq < sbs_cut_off_freq) {
2560 				pcl_freqs[*index] = cl[conn_index].freq;
2561 				pcl_weights[*index] =
2562 						WEIGHT_OF_GROUP1_PCL_CHANNELS;
2563 				(*index)++;
2564 				*low_5_band_scc_present = true;
2565 				break;
2566 			}
2567 
2568 			conn_index++;
2569 		}
2570 
2571 		/* Add 5 GHz high MCC channels*/
2572 		for (i = 0; i < chlist_len_5 && *index < pcl_sz; i++) {
2573 			/* Skip 5 GHz low frequencies */
2574 			if (chlist_5[i] < sbs_cut_off_freq)
2575 				continue;
2576 
2577 			conn_index = 0;
2578 			/* Skip SCC channels */
2579 			while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2580 				if (cl[conn_index].freq == chlist_5[i])
2581 					break;
2582 				conn_index++;
2583 			}
2584 
2585 			if (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index))
2586 				continue;
2587 			pcl_freqs[*index] = chlist_5[i];
2588 			pcl_weights[*index] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
2589 			(*index)++;
2590 		}
2591 		for (i = 0; i < chlist_len_6 && *index < pcl_sz &&
2592 		     !skip_6gh_channel; i++) {
2593 			if (chlist_6[i] < sbs_cut_off_freq)
2594 				return;
2595 
2596 			conn_index = 0;
2597 			/* Skip SCC channels */
2598 			while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2599 				if (cl[conn_index].freq == chlist_6[i])
2600 					break;
2601 				conn_index++;
2602 			}
2603 
2604 			if (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index))
2605 				continue;
2606 
2607 			pcl_freqs[*index] = chlist_6[i];
2608 			pcl_weights[*index] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
2609 			(*index)++;
2610 		}
2611 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2612 	} else if (order == POLICY_MGR_PCL_ORDER_SCC_5G_HIGH_MCC_5G_LOW) {
2613 		/* Add 5 GHz high SCC channel*/
2614 		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2615 		cl = pm_conc_connection_list;
2616 		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2617 			if (!WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
2618 			    cl[conn_index].freq > sbs_cut_off_freq) {
2619 				pcl_freqs[*index] = cl[conn_index].freq;
2620 				pcl_weights[*index] =
2621 						WEIGHT_OF_GROUP1_PCL_CHANNELS;
2622 				(*index)++;
2623 				*high_5_band_scc_present = true;
2624 				break;
2625 			}
2626 
2627 			conn_index++;
2628 		}
2629 
2630 		/* Add 5 GHz low MCC channels */
2631 		for (i = 0; i < chlist_len_5 && *index < pcl_sz; i++) {
2632 			/* Skip 5 GHz high frequencies */
2633 			if (chlist_5[i] > sbs_cut_off_freq)
2634 				continue;
2635 
2636 			conn_index = 0;
2637 			/* Skip SCC channels */
2638 			while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2639 				if (cl[conn_index].freq == chlist_5[i])
2640 					break;
2641 				conn_index++;
2642 			}
2643 
2644 			if (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index))
2645 				continue;
2646 			pcl_freqs[*index] = chlist_5[i];
2647 			pcl_weights[*index] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
2648 			(*index)++;
2649 		}
2650 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2651 	}   else {
2652 		policy_mgr_debug("invalid order %d", order);
2653 		return;
2654 	}
2655 
2656 	policy_mgr_debug("new pcl index %d", *index);
2657 
2658 }
2659 
2660 static void
add_chlist_to_pcl(struct wlan_objmgr_pdev * pdev,uint32_t * pcl_freqs,uint8_t * pcl_weights,uint32_t pcl_sz,uint32_t * index,uint32_t weight,const uint32_t * chlist,uint8_t chlist_len,bool skip_6gh_channel)2661 add_chlist_to_pcl(struct wlan_objmgr_pdev *pdev,
2662 		  uint32_t *pcl_freqs, uint8_t *pcl_weights,
2663 		  uint32_t pcl_sz, uint32_t *index, uint32_t weight,
2664 		  const uint32_t *chlist, uint8_t chlist_len,
2665 		  bool skip_6gh_channel)
2666 {
2667 	uint32_t i;
2668 
2669 	for (i = 0; i < chlist_len && *index < pcl_sz; i++) {
2670 		if (skip_6gh_channel &&
2671 		    WLAN_REG_IS_6GHZ_CHAN_FREQ(chlist[i]))
2672 			continue;
2673 		pcl_freqs[*index] = chlist[i];
2674 		pcl_weights[*index] = weight;
2675 		(*index)++;
2676 	}
2677 	policy_mgr_debug("Add chlist len %d index %d",
2678 			 chlist_len, *index);
2679 }
2680 
2681 /**
2682  * policy_mgr_get_connection_channels() - provides the channel(s)
2683  * on which current connection(s) is
2684  * @psoc: psoc object
2685  * @mode: conn mode
2686  * @order: no order OR 2.4 Ghz channel followed by 5 Ghz channel OR
2687  *  5 Ghz channel followed by 2.4 Ghz channel
2688  * @skip_dfs_channel: if this flag is true then skip the dfs channel
2689  * @group_id: Next available groups for weight assignment
2690  * @pcl_freqs: Pointer to the frequencies of PCL
2691  * @pcl_weights: Pointer to the weights of PCL
2692  * @pcl_sz: Max length of the PCL list
2693  * @index: Index from which the PCL list needs to be populated,
2694  *  will increase accordingly if any channel is obtained
2695  *
2696  * This function provides the channel(s) on which current
2697  * connection(s) is/are
2698  *
2699  * Return: QDF_STATUS
2700  */
2701 static QDF_STATUS
policy_mgr_get_connection_channels(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,enum policy_mgr_pcl_channel_order order,bool skip_dfs_channel,enum policy_mgr_pcl_group_id group_id,uint32_t * pcl_freqs,uint8_t * pcl_weights,uint32_t pcl_sz,uint32_t * index)2702 policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc,
2703 				   enum policy_mgr_con_mode mode,
2704 				   enum policy_mgr_pcl_channel_order order,
2705 				   bool skip_dfs_channel,
2706 				   enum policy_mgr_pcl_group_id group_id,
2707 				   uint32_t *pcl_freqs, uint8_t *pcl_weights,
2708 				   uint32_t pcl_sz, uint32_t *index)
2709 {
2710 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2711 	uint32_t conn_index = 0;
2712 	uint32_t weight1, weight2;
2713 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2714 	struct policy_mgr_conc_connection_info *cl;
2715 	bool add_6ghz = true;
2716 	uint32_t idx;
2717 
2718 	pm_ctx = policy_mgr_get_context(psoc);
2719 	if (!pm_ctx) {
2720 		policy_mgr_err("Invalid Context");
2721 		return status;
2722 	}
2723 
2724 	if (!pcl_freqs || !pcl_weights || !index || !pcl_sz) {
2725 		policy_mgr_err("list or index is NULL");
2726 		status = QDF_STATUS_E_INVAL;
2727 		return status;
2728 	}
2729 
2730 	idx = *index;
2731 
2732 	/* POLICY_MGR_PCL_GROUP_ID1_ID2 indicates that all three weights are
2733 	 * available for assignment. i.e., WEIGHT_OF_GROUP1_PCL_CHANNELS,
2734 	 * WEIGHT_OF_GROUP2_PCL_CHANNELS and WEIGHT_OF_GROUP3_PCL_CHANNELS
2735 	 * are all available. Since in this function only two weights are
2736 	 * assigned at max, only group1 and group2 weights are considered.
2737 	 *
2738 	 * The other possible group id POLICY_MGR_PCL_GROUP_ID2_ID3 indicates
2739 	 * group1 was assigned the weight WEIGHT_OF_GROUP1_PCL_CHANNELS and
2740 	 * only weights WEIGHT_OF_GROUP2_PCL_CHANNELS and
2741 	 * WEIGHT_OF_GROUP3_PCL_CHANNELS are available for further weight
2742 	 * assignments.
2743 	 *
2744 	 * e.g., when order is POLICY_MGR_PCL_ORDER_24G_THEN_5G and group id is
2745 	 * POLICY_MGR_PCL_GROUP_ID2_ID3, WEIGHT_OF_GROUP2_PCL_CHANNELS is
2746 	 * assigned to 2.4GHz channels and the weight
2747 	 * WEIGHT_OF_GROUP3_PCL_CHANNELS is assigned to the 5GHz channels.
2748 	 */
2749 	if (group_id == POLICY_MGR_PCL_GROUP_ID1_ID2) {
2750 		weight1 = WEIGHT_OF_GROUP1_PCL_CHANNELS;
2751 		weight2 = WEIGHT_OF_GROUP2_PCL_CHANNELS;
2752 	} else if (group_id == POLICY_MGR_PCL_GROUP_ID2_ID3) {
2753 		weight1 = WEIGHT_OF_GROUP2_PCL_CHANNELS;
2754 		weight2 = WEIGHT_OF_GROUP3_PCL_CHANNELS;
2755 	} else {
2756 		weight1 = WEIGHT_OF_GROUP3_PCL_CHANNELS;
2757 		weight2 = WEIGHT_OF_GROUP4_PCL_CHANNELS;
2758 	}
2759 	if (!policy_mgr_is_6ghz_conc_mode_supported(psoc, mode))
2760 		add_6ghz = false;
2761 
2762 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2763 	cl = pm_conc_connection_list;
2764 	if (POLICY_MGR_PCL_ORDER_NONE == order) {
2765 		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2766 			bool is_6ghz_ch = WLAN_REG_IS_6GHZ_CHAN_FREQ(
2767 				cl[conn_index].freq);
2768 			if (skip_dfs_channel && wlan_reg_is_dfs_for_freq(
2769 			    pm_ctx->pdev, cl[conn_index].freq)) {
2770 				conn_index++;
2771 			} else if ((idx < pcl_sz) &&
2772 				   (!is_6ghz_ch || add_6ghz)) {
2773 				pcl_freqs[idx] = cl[conn_index++].freq;
2774 				pcl_weights[idx] = weight1;
2775 				idx++;
2776 			} else {
2777 				conn_index++;
2778 			}
2779 		}
2780 	} else if (POLICY_MGR_PCL_ORDER_24G_THEN_5G == order) {
2781 		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2782 			if (WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
2783 			    idx < pcl_sz) {
2784 				pcl_freqs[idx] = cl[conn_index++].freq;
2785 				pcl_weights[idx] = weight1;
2786 				idx++;
2787 			} else {
2788 				conn_index++;
2789 			}
2790 		}
2791 
2792 		conn_index = 0;
2793 		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2794 			if (skip_dfs_channel &&
2795 			    wlan_reg_is_dfs_for_freq(pm_ctx->pdev,
2796 						     cl[conn_index].freq)) {
2797 				conn_index++;
2798 			} else if (WLAN_REG_IS_5GHZ_CH_FREQ(
2799 					cl[conn_index].freq) &&
2800 				   (idx < pcl_sz)) {
2801 				pcl_freqs[idx] = cl[conn_index++].freq;
2802 				pcl_weights[idx] = weight2;
2803 				idx++;
2804 			} else {
2805 				conn_index++;
2806 			}
2807 		}
2808 		conn_index = 0;
2809 		while (add_6ghz &&
2810 		       PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2811 			bool is_6ghz_ch = WLAN_REG_IS_6GHZ_CHAN_FREQ(
2812 				cl[conn_index].freq);
2813 			if (is_6ghz_ch && idx < pcl_sz) {
2814 				pcl_freqs[idx] = cl[conn_index++].freq;
2815 				pcl_weights[idx] = weight2;
2816 				idx++;
2817 			} else {
2818 				conn_index++;
2819 			}
2820 		}
2821 	} else if (POLICY_MGR_PCL_ORDER_5G_THEN_2G == order) {
2822 		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2823 			if (skip_dfs_channel &&
2824 			    wlan_reg_is_dfs_for_freq(
2825 			    pm_ctx->pdev, cl[conn_index].freq)) {
2826 				conn_index++;
2827 			} else if (WLAN_REG_IS_5GHZ_CH_FREQ(
2828 					cl[conn_index].freq) &&
2829 				   (idx < pcl_sz)) {
2830 				pcl_freqs[idx] = cl[conn_index++].freq;
2831 				pcl_weights[idx] = weight1;
2832 				idx++;
2833 			} else {
2834 				conn_index++;
2835 			}
2836 		}
2837 		conn_index = 0;
2838 		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2839 			if (WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
2840 			    idx < pcl_sz) {
2841 				pcl_freqs[idx] = cl[conn_index++].freq;
2842 				pcl_weights[idx] = weight2;
2843 				idx++;
2844 
2845 			} else {
2846 				conn_index++;
2847 			}
2848 		}
2849 		conn_index = 0;
2850 		while (add_6ghz &&
2851 		       PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2852 			bool is_6ghz_ch = WLAN_REG_IS_6GHZ_CHAN_FREQ(
2853 				cl[conn_index].freq);
2854 			if (is_6ghz_ch && idx < pcl_sz) {
2855 				pcl_freqs[idx] = cl[conn_index++].freq;
2856 				pcl_weights[idx] = weight2;
2857 				idx++;
2858 			} else {
2859 				conn_index++;
2860 			}
2861 		}
2862 	} else if (order == POLICY_MGR_PCL_ORDER_2G) {
2863 		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2864 			if (WLAN_REG_IS_24GHZ_CH_FREQ(cl[conn_index].freq) &&
2865 			    idx < pcl_sz) {
2866 				pcl_freqs[idx] = cl[conn_index++].freq;
2867 				pcl_weights[idx] = weight1;
2868 				idx++;
2869 
2870 			} else {
2871 				conn_index++;
2872 			}
2873 		}
2874 	} else if (order == POLICY_MGR_PCL_ORDER_5G) {
2875 		while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2876 			if (skip_dfs_channel &&
2877 			    wlan_reg_is_dfs_for_freq(pm_ctx->pdev,
2878 						     cl[conn_index].freq)) {
2879 				conn_index++;
2880 			} else if (WLAN_REG_IS_5GHZ_CH_FREQ(
2881 					cl[conn_index].freq) &&
2882 				   (idx < pcl_sz)) {
2883 				pcl_freqs[idx] = cl[conn_index++].freq;
2884 				pcl_weights[idx] = weight1;
2885 				idx++;
2886 			} else {
2887 				conn_index++;
2888 			}
2889 		}
2890 		conn_index = 0;
2891 		while (add_6ghz &&
2892 		       PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2893 			bool is_6ghz_ch = WLAN_REG_IS_6GHZ_CHAN_FREQ(
2894 				cl[conn_index].freq);
2895 			if (is_6ghz_ch && idx < pcl_sz) {
2896 				pcl_freqs[idx] = cl[conn_index++].freq;
2897 				pcl_weights[idx] = weight1;
2898 				idx++;
2899 			} else {
2900 				conn_index++;
2901 			}
2902 		}
2903 	} else {
2904 		policy_mgr_err("unknown order %d", order);
2905 		status = QDF_STATUS_E_FAILURE;
2906 	}
2907 
2908 	*index = idx;
2909 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2910 
2911 	return status;
2912 }
2913 
2914 /**
2915  * policy_mgr_set_weight_of_disabled_inactive_channels_to_zero() - set weight
2916  * of disabled and inactive channels to 0
2917  * @psoc: pointer to soc
2918  * @pcl_channels: preferred channel freq list
2919  * @len: length of preferred channel list
2920  * @weight_list: preferred channel weight list
2921  * @weight_len: length of weight list
2922  * This function set the weight of disabled and inactive channels to 0
2923  *
2924  * Return: None
2925  */
policy_mgr_set_weight_of_disabled_inactive_channels_to_zero(struct wlan_objmgr_psoc * psoc,uint32_t * pcl_channels,uint32_t * len,uint8_t * weight_list,uint32_t weight_len)2926 void policy_mgr_set_weight_of_disabled_inactive_channels_to_zero(
2927 		struct wlan_objmgr_psoc *psoc, uint32_t *pcl_channels,
2928 		uint32_t *len, uint8_t *weight_list, uint32_t weight_len)
2929 {
2930 	uint8_t i;
2931 	uint32_t orig_channel_count = 0;
2932 	enum channel_state channel_state;
2933 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2934 
2935 	pm_ctx = policy_mgr_get_context(psoc);
2936 	if (!pm_ctx) {
2937 		policy_mgr_err("Invalid Context");
2938 		return;
2939 	}
2940 
2941 	if (len)
2942 		orig_channel_count = QDF_MIN(*len, NUM_CHANNELS);
2943 	else {
2944 		policy_mgr_err("invalid number of channel length");
2945 		return;
2946 	}
2947 
2948 	policy_mgr_debug("Set weight of disabled, inactive channels to 0");
2949 
2950 	for (i = 0; i < orig_channel_count; i++) {
2951 		if (wlan_reg_is_6ghz_chan_freq(pcl_channels[i]) &&
2952 		    !wlan_reg_is_6ghz_band_set(pm_ctx->pdev)) {
2953 			weight_list[i] = 0;
2954 		} else {
2955 			channel_state = wlan_reg_get_channel_state_for_pwrmode(
2956 						pm_ctx->pdev, pcl_channels[i],
2957 						REG_CURRENT_PWR_MODE);
2958 			if (channel_state == CHANNEL_STATE_DISABLE ||
2959 			    channel_state == CHANNEL_STATE_INVALID)
2960 				weight_list[i] = 0;
2961 		}
2962 	}
2963 
2964 	return;
2965 }
2966 
is_freq_present_in_pcl(uint32_t idx,uint32_t * pcl_freqs,uint32_t chanlist_freq)2967 static bool is_freq_present_in_pcl(uint32_t idx, uint32_t *pcl_freqs,
2968 				   uint32_t chanlist_freq)
2969 {
2970 	uint32_t i;
2971 
2972 	for (i = 0; i < idx; i++) {
2973 		if (pcl_freqs[i] == chanlist_freq)
2974 			return true;
2975 	}
2976 
2977 	return false;
2978 }
2979 
2980 /**
2981  * policy_mgr_add_5g_to_pcl() - add the 5G/6G channels into PCL
2982  * @psoc: psoc object
2983  * @pcl_freqs: Pointer to the frequencies of PCL
2984  * @pcl_weights: Pointer to the weights of PCL
2985  * @pcl_sz: Max length of the PCL list
2986  * @index: Index from which the PCL list needs to be populated,
2987  *  will increase accordingly if any channel is obtained
2988  * @group_id: Next available groups for weight assignment
2989  * @chlist_5g: Pointer to the 5G channel list
2990  * @chlist_5g_len: Length of the 5G channel list
2991  * @chlist_6g: Pointer to the 6G channel list
2992  * @chlist_6g_len: Length of the 6G channel list
2993  *
2994  * Return: None
2995  */
2996 static void
policy_mgr_add_5g_to_pcl(struct wlan_objmgr_psoc * psoc,uint32_t * pcl_freqs,uint8_t * pcl_weights,uint32_t pcl_sz,uint32_t * index,enum policy_mgr_pcl_group_id group_id,const uint32_t * chlist_5g,uint8_t chlist_5g_len,const uint32_t * chlist_6g,uint8_t chlist_6g_len)2997 policy_mgr_add_5g_to_pcl(struct wlan_objmgr_psoc *psoc, uint32_t *pcl_freqs,
2998 			 uint8_t *pcl_weights, uint32_t pcl_sz, uint32_t *index,
2999 			 enum policy_mgr_pcl_group_id group_id,
3000 			 const uint32_t *chlist_5g, uint8_t chlist_5g_len,
3001 			 const uint32_t *chlist_6g, uint8_t chlist_6g_len)
3002 {
3003 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3004 	uint32_t weight1, weight2;
3005 	const uint32_t *chlist1;
3006 	uint8_t chlist1_len;
3007 	uint8_t list_len = 0;
3008 	const uint32_t *chlist2;
3009 	uint8_t chlist2_len;
3010 	uint32_t i;
3011 	uint32_t len = 0, idx;
3012 
3013 	pm_ctx = policy_mgr_get_context(psoc);
3014 	if (!pm_ctx) {
3015 		policy_mgr_err("Invalid Context");
3016 		return;
3017 	}
3018 
3019 	idx = *index;
3020 
3021 	if (group_id == POLICY_MGR_PCL_GROUP_ID1_ID2) {
3022 		weight1 = WEIGHT_OF_GROUP1_PCL_CHANNELS;
3023 		weight2 = WEIGHT_OF_GROUP2_PCL_CHANNELS;
3024 	} else if (group_id == POLICY_MGR_PCL_GROUP_ID2_ID3) {
3025 		weight1 = WEIGHT_OF_GROUP2_PCL_CHANNELS;
3026 		weight2 = WEIGHT_OF_GROUP3_PCL_CHANNELS;
3027 	} else {
3028 		weight1 = WEIGHT_OF_GROUP3_PCL_CHANNELS;
3029 		weight2 = WEIGHT_OF_GROUP4_PCL_CHANNELS;
3030 	}
3031 	if (pm_ctx->cfg.pcl_band_priority == POLICY_MGR_PCL_BAND_6G_THEN_5G) {
3032 		chlist1 = chlist_6g;
3033 		chlist1_len = chlist_6g_len;
3034 		chlist2 = chlist_5g;
3035 		chlist2_len = chlist_5g_len;
3036 	} else {
3037 		chlist1 = chlist_5g;
3038 		chlist1_len = chlist_5g_len;
3039 		chlist2 = chlist_6g;
3040 		chlist2_len = chlist_6g_len;
3041 	}
3042 	if ((chlist1_len + idx) > pcl_sz) {
3043 		policy_mgr_err("no enough weight len %d chlist1_len %d %d",
3044 			       pcl_sz, chlist1_len, idx);
3045 		return;
3046 	}
3047 	for (i = 0; i < chlist1_len; i++) {
3048 		if (is_freq_present_in_pcl(idx, pcl_freqs, chlist1[i]))
3049 			continue;
3050 		pcl_freqs[idx] = chlist1[i];
3051 		pcl_weights[idx] = weight1;
3052 		idx++;
3053 		list_len++;
3054 	}
3055 
3056 	len += list_len;
3057 
3058 	if ((chlist2_len + idx) > pcl_sz) {
3059 		policy_mgr_err("no enough weight len chlist2_len %d %d %d",
3060 			       pcl_sz, chlist2_len, idx);
3061 		return;
3062 	}
3063 	list_len = 0;
3064 	for (i = 0; i < chlist2_len; i++) {
3065 		if (is_freq_present_in_pcl(idx, pcl_freqs, chlist2[i]))
3066 			continue;
3067 		pcl_freqs[idx] = chlist2[i];
3068 		pcl_weights[idx] = weight2;
3069 		idx++;
3070 		list_len++;
3071 	}
3072 	len += list_len;
3073 
3074 	*index = idx;
3075 	policy_mgr_debug("Add 5g chlist len %d 6g chlist len %d len %d index %d order %d",
3076 			 chlist_5g_len, chlist_6g_len, len, idx,
3077 			 pm_ctx->cfg.pcl_band_priority);
3078 }
3079 
3080 /**
3081  * policy_mgr_add_24g_to_pcl() - add the 2.4G channels into PCL
3082  * @pcl_freqs: Pointer to the frequencies of PCL
3083  * @pcl_weights: Pointer to the weights of PCL
3084  * @pcl_sz: Max length of the PCL list
3085  * @index: Index from which the PCL list needs to be populated,
3086  *  will increase accordingly if any channel is obtained
3087  * @weight: group for weight assignment
3088  * @chlist_24g: Pointer to the 2.4G channel list
3089  * @chlist_24g_len: Length of the 2.4G channel list
3090  *
3091  * Return: None
3092  */
3093 static void
policy_mgr_add_24g_to_pcl(uint32_t * pcl_freqs,uint8_t * pcl_weights,uint32_t pcl_sz,uint32_t * index,uint32_t weight,const uint32_t * chlist_24g,uint8_t chlist_24g_len)3094 policy_mgr_add_24g_to_pcl(uint32_t *pcl_freqs, uint8_t *pcl_weights,
3095 			  uint32_t pcl_sz, uint32_t *index, uint32_t weight,
3096 			  const uint32_t *chlist_24g, uint8_t chlist_24g_len)
3097 {
3098 	uint32_t num_to_add, i;
3099 
3100 	if (*index >= NUM_CHANNELS || *index >= pcl_sz)
3101 		return;
3102 	num_to_add = QDF_MIN((*index + chlist_24g_len), pcl_sz) - *index;
3103 	for (i = 0; i < num_to_add; i++) {
3104 		if ((i + *index) >= NUM_CHANNELS || (i + *index) >= pcl_sz)
3105 			break;
3106 		pcl_weights[i + *index] = weight;
3107 		pcl_freqs[i + *index] = chlist_24g[i];
3108 	}
3109 
3110 	*index += i;
3111 	policy_mgr_debug("Add 24g chlist len %d len %d index %d",
3112 			 chlist_24g_len, num_to_add, *index);
3113 }
3114 
3115 static bool
policy_mgr_2ghz_connection_present(struct policy_mgr_psoc_priv_obj * pm_ctx)3116 policy_mgr_2ghz_connection_present(struct policy_mgr_psoc_priv_obj *pm_ctx)
3117 {
3118 	bool is_2ghz_present = false;
3119 	uint32_t conn_index;
3120 
3121 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3122 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
3123 		conn_index++) {
3124 		if (pm_conc_connection_list[conn_index].in_use &&
3125 		    (WLAN_REG_IS_24GHZ_CH_FREQ(
3126 				pm_conc_connection_list[conn_index].freq))) {
3127 			is_2ghz_present = true;
3128 			break;
3129 		}
3130 	}
3131 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3132 
3133 	return is_2ghz_present;
3134 }
3135 
3136 /**
3137  * policy_mgr_get_channel_list() - provides the channel list
3138  * suggestion for new connection
3139  * @psoc: psoc handle
3140  * @pcl: The preferred channel list enum
3141  * @mode: concurrency mode for which channel list is requested
3142  * @pcl_channels: PCL channels
3143  * @pcl_weights: Weights of the PCL
3144  * @pcl_sz: Max length of the PCL list
3145  * @len: length of the PCL obtained
3146  *
3147  * This function provides the actual channel list based on the
3148  * current regulatory domain derived using preferred channel
3149  * list enum obtained from one of the pcl_table
3150  *
3151  * Return: Channel List
3152  */
policy_mgr_get_channel_list(struct wlan_objmgr_psoc * psoc,enum policy_mgr_pcl_type pcl,enum policy_mgr_con_mode mode,uint32_t * pcl_channels,uint8_t * pcl_weights,uint32_t pcl_sz,uint32_t * len)3153 QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc,
3154 				       enum policy_mgr_pcl_type pcl,
3155 				       enum policy_mgr_con_mode mode,
3156 				       uint32_t *pcl_channels,
3157 				       uint8_t *pcl_weights,
3158 				       uint32_t pcl_sz, uint32_t *len)
3159 {
3160 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3161 	uint32_t num_channels = 0;
3162 	uint32_t chan_index_24 = 0, chan_index_5 = 0, chan_index_6 = 0;
3163 	uint32_t i = 0;
3164 	bool skip_6ghz_channel = false;
3165 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3166 	uint32_t *channel_list, *channel_list_24, *channel_list_5,
3167 		 *sbs_freqs, *channel_list_6, *scc_freqs, *rest_freqs;
3168 	uint32_t sbs_num, scc_num, rest_num;
3169 	bool high_5_band_scc_present = false;
3170 	bool low_5_band_scc_present = false;
3171 
3172 	pm_ctx = policy_mgr_get_context(psoc);
3173 	if (!pm_ctx) {
3174 		policy_mgr_err("Invalid Context");
3175 		return status;
3176 	}
3177 
3178 	if ((!pcl_channels) || (!len)) {
3179 		policy_mgr_err("pcl_channels or len is NULL");
3180 		return status;
3181 	}
3182 
3183 	*len = 0;
3184 	if (PM_MAX_PCL_TYPE == pcl) {
3185 		/* msg */
3186 		policy_mgr_err("pcl is invalid");
3187 		return status;
3188 	}
3189 
3190 	if (PM_NONE == pcl) {
3191 		/* msg */
3192 		policy_mgr_debug("pcl is 0");
3193 		return QDF_STATUS_SUCCESS;
3194 	}
3195 
3196 	channel_list = qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t));
3197 	channel_list_24 = qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t));
3198 	channel_list_5 = qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t));
3199 	sbs_freqs = qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t));
3200 	channel_list_6 = qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t));
3201 	rest_freqs = qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t));
3202 	scc_freqs = qdf_mem_malloc(
3203 			MAX_NUMBER_OF_CONC_CONNECTIONS * sizeof(uint32_t));
3204 	if (!channel_list || !channel_list_24 || !channel_list_5 ||
3205 	    !sbs_freqs || !channel_list_6 || !rest_freqs || !scc_freqs) {
3206 		status = QDF_STATUS_E_NOMEM;
3207 		goto end;
3208 	}
3209 	/* get the channel list for current domain */
3210 	status = policy_mgr_get_valid_chans(psoc, channel_list,
3211 					    &num_channels);
3212 	if (QDF_IS_STATUS_ERROR(status)) {
3213 		policy_mgr_err("Error in getting valid channels");
3214 		goto end;
3215 	}
3216 
3217 	num_channels = QDF_MIN(num_channels, NUM_CHANNELS);
3218 
3219 	/* Let's divide the list in 2.4 & 5 Ghz lists */
3220 	for (i = 0; i < num_channels; i++) {
3221 		if (wlan_reg_is_24ghz_ch_freq(channel_list[i])) {
3222 			channel_list_24[chan_index_24++] = channel_list[i];
3223 		} else if (wlan_reg_is_5ghz_ch_freq(channel_list[i])) {
3224 			channel_list_5[chan_index_5++] = channel_list[i];
3225 		} else if (wlan_reg_is_6ghz_chan_freq(channel_list[i])) {
3226 			/* Add to 5G list until 6G conc support is enabled */
3227 			channel_list_6[chan_index_6++] = channel_list[i];
3228 		}
3229 	}
3230 	if (!policy_mgr_is_6ghz_conc_mode_supported(psoc, mode)) {
3231 		chan_index_6 = 0;
3232 		skip_6ghz_channel = true;
3233 	}
3234 	sbs_num = NUM_CHANNELS;
3235 	scc_num = MAX_NUMBER_OF_CONC_CONNECTIONS;
3236 	rest_num = NUM_CHANNELS;
3237 
3238 	/* In the below switch case, the channel list is populated based on the
3239 	 * pcl. e.g., if the pcl is PM_SCC_CH_24G, the SCC channel group is
3240 	 * populated first followed by the 2.4GHz channel group. Along with
3241 	 * this, the weights are also populated in the same order for each of
3242 	 * these groups. There are three weight groups:
3243 	 * WEIGHT_OF_GROUP1_PCL_CHANNELS, WEIGHT_OF_GROUP2_PCL_CHANNELS and
3244 	 * WEIGHT_OF_GROUP3_PCL_CHANNELS.
3245 	 *
3246 	 * e.g., if pcl is PM_SCC_ON_5_SCC_ON_24_24G: scc on 5GHz (group1)
3247 	 * channels take the weight WEIGHT_OF_GROUP1_PCL_CHANNELS, scc on 2.4GHz
3248 	 * (group2) channels take the weight WEIGHT_OF_GROUP2_PCL_CHANNELS and
3249 	 * 2.4GHz (group3) channels take the weight
3250 	 * WEIGHT_OF_GROUP3_PCL_CHANNELS.
3251 	 *
3252 	 * When the weight to be assigned to the group is known along with the
3253 	 * number of channels, the weights are directly assigned to the
3254 	 * pcl_weights list. But, the channel list is populated using
3255 	 * policy_mgr_get_connection_channels(), the order of weights to be used
3256 	 * is passed as an argument to the function
3257 	 * policy_mgr_get_connection_channels() using
3258 	 * 'enum policy_mgr_pcl_group_id' which indicates the next available
3259 	 * weights to be used and policy_mgr_get_connection_channels() will take
3260 	 * care of the weight assignments.
3261 	 *
3262 	 * e.g., 'enum policy_mgr_pcl_group_id' value of
3263 	 * POLICY_MGR_PCL_GROUP_ID2_ID3 indicates that the next available groups
3264 	 * for weight assignment are WEIGHT_OF_GROUP2_PCL_CHANNELS and
3265 	 * WEIGHT_OF_GROUP3_PCL_CHANNELS and that the
3266 	 * weight WEIGHT_OF_GROUP1_PCL_CHANNELS was already allocated.
3267 	 * So, in the same example, when order is
3268 	 * POLICY_MGR_PCL_ORDER_24G_THEN_5G,
3269 	 * policy_mgr_get_connection_channels() will assign the weight
3270 	 * WEIGHT_OF_GROUP2_PCL_CHANNELS to 2.4GHz channels and assign the
3271 	 * weight WEIGHT_OF_GROUP3_PCL_CHANNELS to 5GHz channels.
3272 	 */
3273 	switch (pcl) {
3274 	case PM_24G:
3275 		policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz,
3276 					  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
3277 					  channel_list_24, chan_index_24);
3278 		status = QDF_STATUS_SUCCESS;
3279 		break;
3280 	case PM_5G:
3281 		policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights,
3282 					 pcl_sz, len,
3283 					 POLICY_MGR_PCL_GROUP_ID1_ID2,
3284 					 channel_list_5, chan_index_5,
3285 					 channel_list_6, chan_index_6);
3286 		status = QDF_STATUS_SUCCESS;
3287 		break;
3288 	case PM_SCC_CH:
3289 	case PM_MCC_CH:
3290 		policy_mgr_get_connection_channels(psoc, mode,
3291 						   POLICY_MGR_PCL_ORDER_NONE,
3292 						   false,
3293 						   POLICY_MGR_PCL_GROUP_ID1_ID2,
3294 						   pcl_channels, pcl_weights,
3295 						   pcl_sz, len);
3296 		status = QDF_STATUS_SUCCESS;
3297 		break;
3298 	case PM_SCC_CH_24G:
3299 	case PM_MCC_CH_24G:
3300 		policy_mgr_get_connection_channels(psoc, mode,
3301 						   POLICY_MGR_PCL_ORDER_NONE,
3302 						   false,
3303 						   POLICY_MGR_PCL_GROUP_ID1_ID2,
3304 						   pcl_channels, pcl_weights,
3305 						   pcl_sz, len);
3306 		policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz,
3307 					  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
3308 					  channel_list_24, chan_index_24);
3309 		status = QDF_STATUS_SUCCESS;
3310 		break;
3311 	case PM_SCC_CH_5G:
3312 	case PM_MCC_CH_5G:
3313 		policy_mgr_get_connection_channels(psoc, mode,
3314 						   POLICY_MGR_PCL_ORDER_NONE,
3315 						   false,
3316 						   POLICY_MGR_PCL_GROUP_ID1_ID2,
3317 						   pcl_channels, pcl_weights,
3318 						   pcl_sz, len);
3319 		policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights,
3320 					 pcl_sz, len,
3321 					 POLICY_MGR_PCL_GROUP_ID2_ID3,
3322 					 channel_list_5, chan_index_5,
3323 					 channel_list_6, chan_index_6);
3324 		status = QDF_STATUS_SUCCESS;
3325 		break;
3326 	case PM_24G_SCC_CH:
3327 	case PM_24G_MCC_CH:
3328 		policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz,
3329 					  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
3330 					  channel_list_24, chan_index_24);
3331 		policy_mgr_get_connection_channels(psoc, mode,
3332 						   POLICY_MGR_PCL_ORDER_NONE,
3333 						   false,
3334 						   POLICY_MGR_PCL_GROUP_ID2_ID3,
3335 						   pcl_channels, pcl_weights,
3336 						   pcl_sz, len);
3337 		status = QDF_STATUS_SUCCESS;
3338 		break;
3339 	case PM_5G_SCC_CH:
3340 	case PM_5G_MCC_CH:
3341 		policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights,
3342 					 pcl_sz, len,
3343 					 POLICY_MGR_PCL_GROUP_ID1_ID2,
3344 					 channel_list_5, chan_index_5,
3345 					 channel_list_6, chan_index_6);
3346 		policy_mgr_get_connection_channels(psoc, mode,
3347 						   POLICY_MGR_PCL_ORDER_NONE,
3348 						   false,
3349 						   POLICY_MGR_PCL_GROUP_ID3_ID4,
3350 						   pcl_channels, pcl_weights,
3351 						   pcl_sz, len);
3352 		status = QDF_STATUS_SUCCESS;
3353 		break;
3354 	case PM_SCC_ON_24_SCC_ON_5:
3355 		policy_mgr_get_connection_channels(
3356 					psoc, mode,
3357 					POLICY_MGR_PCL_ORDER_24G_THEN_5G,
3358 					false,
3359 					POLICY_MGR_PCL_GROUP_ID1_ID2,
3360 					pcl_channels, pcl_weights, pcl_sz, len);
3361 		status = QDF_STATUS_SUCCESS;
3362 		break;
3363 	case PM_SCC_ON_5_SCC_ON_24:
3364 		policy_mgr_get_connection_channels(
3365 					psoc, mode,
3366 					POLICY_MGR_PCL_ORDER_5G_THEN_2G,
3367 					false,
3368 					POLICY_MGR_PCL_GROUP_ID1_ID2,
3369 					pcl_channels, pcl_weights, pcl_sz, len);
3370 		status = QDF_STATUS_SUCCESS;
3371 		break;
3372 	case PM_SCC_ON_24_SCC_ON_5_24G:
3373 		policy_mgr_get_connection_channels(
3374 					psoc, mode,
3375 					POLICY_MGR_PCL_ORDER_24G_THEN_5G,
3376 					false,
3377 					POLICY_MGR_PCL_GROUP_ID1_ID2,
3378 					pcl_channels, pcl_weights, pcl_sz, len);
3379 		policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz,
3380 					  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
3381 					  channel_list_24, chan_index_24);
3382 		status = QDF_STATUS_SUCCESS;
3383 		break;
3384 	case PM_SCC_ON_24_SCC_ON_5_5G:
3385 		policy_mgr_get_connection_channels(
3386 					psoc, mode,
3387 					POLICY_MGR_PCL_ORDER_24G_THEN_5G,
3388 					false,
3389 					POLICY_MGR_PCL_GROUP_ID1_ID2,
3390 					pcl_channels, pcl_weights, pcl_sz, len);
3391 		policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights,
3392 					 pcl_sz, len,
3393 					 POLICY_MGR_PCL_GROUP_ID3_ID4,
3394 					 channel_list_5, chan_index_5,
3395 					 channel_list_6, chan_index_6);
3396 		status = QDF_STATUS_SUCCESS;
3397 		break;
3398 	case PM_SCC_ON_24_CH_24G:
3399 		policy_mgr_get_connection_channels(psoc, mode,
3400 						   POLICY_MGR_PCL_ORDER_2G,
3401 						   true,
3402 						   POLICY_MGR_PCL_GROUP_ID1_ID2,
3403 						   pcl_channels, pcl_weights,
3404 						   pcl_sz, len);
3405 		policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz,
3406 					  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
3407 					  channel_list_24, chan_index_24);
3408 		status = QDF_STATUS_SUCCESS;
3409 		break;
3410 	case PM_SCC_ON_5_CH_5G:
3411 		policy_mgr_get_connection_channels(psoc, mode,
3412 						   POLICY_MGR_PCL_ORDER_5G,
3413 						   false,
3414 						   POLICY_MGR_PCL_GROUP_ID1_ID2,
3415 						   pcl_channels, pcl_weights,
3416 						   pcl_sz, len);
3417 		policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights,
3418 					 pcl_sz, len,
3419 					 POLICY_MGR_PCL_GROUP_ID2_ID3,
3420 					 channel_list_5, chan_index_5,
3421 					 channel_list_6, chan_index_6);
3422 		status = QDF_STATUS_SUCCESS;
3423 		break;
3424 	case PM_SCC_ON_5_SCC_ON_24_24G:
3425 		policy_mgr_get_connection_channels(
3426 					psoc, mode,
3427 					POLICY_MGR_PCL_ORDER_5G_THEN_2G,
3428 					false,
3429 					POLICY_MGR_PCL_GROUP_ID1_ID2,
3430 					pcl_channels, pcl_weights, pcl_sz, len);
3431 		policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz,
3432 					  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
3433 					  channel_list_24, chan_index_24);
3434 		status = QDF_STATUS_SUCCESS;
3435 		break;
3436 	case PM_SCC_ON_5_SCC_ON_24_5G:
3437 		policy_mgr_get_connection_channels(
3438 					psoc, mode,
3439 					POLICY_MGR_PCL_ORDER_5G_THEN_2G,
3440 					false,
3441 					POLICY_MGR_PCL_GROUP_ID1_ID2,
3442 					pcl_channels, pcl_weights, pcl_sz, len);
3443 		policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights,
3444 					 pcl_sz, len,
3445 					 POLICY_MGR_PCL_GROUP_ID3_ID4,
3446 					 channel_list_5, chan_index_5,
3447 					 channel_list_6, chan_index_6);
3448 		status = QDF_STATUS_SUCCESS;
3449 		break;
3450 	case PM_SCC_ON_5_5G_24G:
3451 		policy_mgr_get_connection_channels(psoc, mode,
3452 						   POLICY_MGR_PCL_ORDER_5G,
3453 						   false,
3454 						   POLICY_MGR_PCL_GROUP_ID1_ID2,
3455 						   pcl_channels, pcl_weights,
3456 						   pcl_sz, len);
3457 		policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights,
3458 					 pcl_sz, len,
3459 					 POLICY_MGR_PCL_GROUP_ID2_ID3,
3460 					 channel_list_5, chan_index_5,
3461 					 channel_list_6, chan_index_6);
3462 		policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz,
3463 					  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
3464 					  channel_list_24, chan_index_24);
3465 		status = QDF_STATUS_SUCCESS;
3466 		break;
3467 	case PM_SCC_ON_5_5G_SCC_ON_24G:
3468 		policy_mgr_get_connection_channels(psoc, mode,
3469 						   POLICY_MGR_PCL_ORDER_5G,
3470 						   false,
3471 						   POLICY_MGR_PCL_GROUP_ID1_ID2,
3472 						   pcl_channels, pcl_weights,
3473 						   pcl_sz, len);
3474 		policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights,
3475 					 pcl_sz, len,
3476 					 POLICY_MGR_PCL_GROUP_ID2_ID3,
3477 					 channel_list_5, chan_index_5,
3478 					 channel_list_6, chan_index_6);
3479 		policy_mgr_get_connection_channels(psoc, mode,
3480 						   POLICY_MGR_PCL_ORDER_2G,
3481 						   false,
3482 						   POLICY_MGR_PCL_GROUP_ID3_ID4,
3483 						   pcl_channels, pcl_weights,
3484 						   pcl_sz, len);
3485 		status = QDF_STATUS_SUCCESS;
3486 		break;
3487 
3488 	case PM_24G_SCC_CH_SBS_CH:
3489 		get_sub_channels(psoc,
3490 				 sbs_freqs, &sbs_num,
3491 				 scc_freqs, &scc_num,
3492 				 rest_freqs, &rest_num,
3493 				 channel_list_5, chan_index_5,
3494 				 channel_list_6, chan_index_6);
3495 		add_chlist_to_pcl(pm_ctx->pdev,
3496 				  pcl_channels, pcl_weights, pcl_sz,
3497 				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
3498 				  channel_list_24, chan_index_24,
3499 				  false);
3500 		add_chlist_to_pcl(pm_ctx->pdev,
3501 				  pcl_channels, pcl_weights, pcl_sz,
3502 				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
3503 				  scc_freqs, scc_num,
3504 				  skip_6ghz_channel);
3505 		add_chlist_to_pcl(pm_ctx->pdev,
3506 				  pcl_channels, pcl_weights, pcl_sz,
3507 				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
3508 				  sbs_freqs, sbs_num,
3509 				  skip_6ghz_channel);
3510 		status = QDF_STATUS_SUCCESS;
3511 		break;
3512 	case PM_24G_SCC_CH_SBS_CH_5G:
3513 		get_sub_channels(psoc,
3514 				 sbs_freqs, &sbs_num,
3515 				 scc_freqs, &scc_num,
3516 				 rest_freqs, &rest_num,
3517 				 channel_list_5, chan_index_5,
3518 				 channel_list_6, chan_index_6);
3519 		add_chlist_to_pcl(pm_ctx->pdev,
3520 				  pcl_channels, pcl_weights, pcl_sz,
3521 				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
3522 				  channel_list_24, chan_index_24,
3523 				  false);
3524 		add_chlist_to_pcl(pm_ctx->pdev,
3525 				  pcl_channels, pcl_weights, pcl_sz,
3526 				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
3527 				  scc_freqs, scc_num,
3528 				  skip_6ghz_channel);
3529 		add_chlist_to_pcl(pm_ctx->pdev,
3530 				  pcl_channels, pcl_weights, pcl_sz,
3531 				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
3532 				  sbs_freqs, sbs_num,
3533 				  skip_6ghz_channel);
3534 		add_chlist_to_pcl(pm_ctx->pdev,
3535 				  pcl_channels, pcl_weights, pcl_sz,
3536 				  len, WEIGHT_OF_GROUP4_PCL_CHANNELS,
3537 				  rest_freqs, rest_num,
3538 				  skip_6ghz_channel);
3539 		status = QDF_STATUS_SUCCESS;
3540 		break;
3541 	case PM_24G_SBS_CH_MCC_CH:
3542 		get_sub_channels(psoc,
3543 				 sbs_freqs, &sbs_num,
3544 				 scc_freqs, &scc_num,
3545 				 rest_freqs, &rest_num,
3546 				 channel_list_5, chan_index_5,
3547 				 channel_list_6, chan_index_6);
3548 		add_chlist_to_pcl(pm_ctx->pdev,
3549 				  pcl_channels, pcl_weights, pcl_sz,
3550 				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
3551 				  channel_list_24, chan_index_24,
3552 				  false);
3553 		add_chlist_to_pcl(pm_ctx->pdev,
3554 				  pcl_channels, pcl_weights, pcl_sz,
3555 				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
3556 				  sbs_freqs, sbs_num,
3557 				  skip_6ghz_channel);
3558 		add_chlist_to_pcl(pm_ctx->pdev,
3559 				  pcl_channels, pcl_weights, pcl_sz,
3560 				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
3561 				  scc_freqs, scc_num,
3562 				  skip_6ghz_channel);
3563 		status = QDF_STATUS_SUCCESS;
3564 		break;
3565 	case PM_SBS_CH:
3566 		get_sub_channels(psoc,
3567 				 sbs_freqs, &sbs_num,
3568 				 scc_freqs, &scc_num,
3569 				 rest_freqs, &rest_num,
3570 				 channel_list_5, chan_index_5,
3571 				 channel_list_6, chan_index_6);
3572 		add_chlist_to_pcl(pm_ctx->pdev,
3573 				  pcl_channels, pcl_weights, pcl_sz,
3574 				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
3575 				  sbs_freqs, sbs_num,
3576 				  skip_6ghz_channel);
3577 		add_chlist_to_pcl(pm_ctx->pdev,
3578 				  pcl_channels, pcl_weights, pcl_sz,
3579 				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
3580 				  scc_freqs, scc_num,
3581 				  skip_6ghz_channel);
3582 		status = QDF_STATUS_SUCCESS;
3583 		break;
3584 	case PM_SBS_CH_5G:
3585 		get_sub_channels(psoc,
3586 				 sbs_freqs, &sbs_num,
3587 				 scc_freqs, &scc_num,
3588 				 rest_freqs, &rest_num,
3589 				 channel_list_5, chan_index_5,
3590 				 channel_list_6, chan_index_6);
3591 		add_chlist_to_pcl(pm_ctx->pdev,
3592 				  pcl_channels, pcl_weights, pcl_sz,
3593 				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
3594 				  sbs_freqs, sbs_num,
3595 				  skip_6ghz_channel);
3596 		add_chlist_to_pcl(pm_ctx->pdev,
3597 				  pcl_channels, pcl_weights, pcl_sz,
3598 				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
3599 				  scc_freqs, scc_num,
3600 				  skip_6ghz_channel);
3601 		add_chlist_to_pcl(pm_ctx->pdev,
3602 				  pcl_channels, pcl_weights, pcl_sz,
3603 				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
3604 				  rest_freqs, rest_num,
3605 				  skip_6ghz_channel);
3606 		status = QDF_STATUS_SUCCESS;
3607 		break;
3608 	case PM_SBS_CH_24G_SCC_CH:
3609 		get_sub_channels(psoc,
3610 				 sbs_freqs, &sbs_num,
3611 				 scc_freqs, &scc_num,
3612 				 rest_freqs, &rest_num,
3613 				 channel_list_5, chan_index_5,
3614 				 channel_list_6, chan_index_6);
3615 		add_chlist_to_pcl(pm_ctx->pdev,
3616 				  pcl_channels, pcl_weights, pcl_sz,
3617 				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
3618 				  sbs_freqs, sbs_num,
3619 				  skip_6ghz_channel);
3620 		add_chlist_to_pcl(pm_ctx->pdev,
3621 				  pcl_channels, pcl_weights, pcl_sz,
3622 				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
3623 				  channel_list_24, chan_index_24,
3624 				  false);
3625 		add_chlist_to_pcl(pm_ctx->pdev,
3626 				  pcl_channels, pcl_weights, pcl_sz,
3627 				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
3628 				  scc_freqs, scc_num,
3629 				  skip_6ghz_channel);
3630 		status = QDF_STATUS_SUCCESS;
3631 		break;
3632 	case PM_SBS_CH_SCC_CH_24G:
3633 		get_sub_channels(psoc,
3634 				 sbs_freqs, &sbs_num,
3635 				 scc_freqs, &scc_num,
3636 				 rest_freqs, &rest_num,
3637 				 channel_list_5, chan_index_5,
3638 				 channel_list_6, chan_index_6);
3639 		add_chlist_to_pcl(pm_ctx->pdev,
3640 				  pcl_channels, pcl_weights, pcl_sz,
3641 				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
3642 				  sbs_freqs, sbs_num,
3643 				  skip_6ghz_channel);
3644 		add_chlist_to_pcl(pm_ctx->pdev,
3645 				  pcl_channels, pcl_weights, pcl_sz,
3646 				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
3647 				  scc_freqs, scc_num,
3648 				  skip_6ghz_channel);
3649 		add_chlist_to_pcl(pm_ctx->pdev,
3650 				  pcl_channels, pcl_weights, pcl_sz,
3651 				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
3652 				  channel_list_24, chan_index_24,
3653 				  false);
3654 		status = QDF_STATUS_SUCCESS;
3655 		break;
3656 	case PM_SCC_CH_SBS_CH_24G:
3657 		get_sub_channels(psoc,
3658 				 sbs_freqs, &sbs_num,
3659 				 scc_freqs, &scc_num,
3660 				 rest_freqs, &rest_num,
3661 				 channel_list_5, chan_index_5,
3662 				 channel_list_6, chan_index_6);
3663 		add_chlist_to_pcl(pm_ctx->pdev,
3664 				  pcl_channels, pcl_weights, pcl_sz,
3665 				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
3666 				  scc_freqs, scc_num,
3667 				  skip_6ghz_channel);
3668 		add_chlist_to_pcl(pm_ctx->pdev,
3669 				  pcl_channels, pcl_weights, pcl_sz,
3670 				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
3671 				  sbs_freqs, sbs_num,
3672 				  skip_6ghz_channel);
3673 		add_chlist_to_pcl(pm_ctx->pdev,
3674 				  pcl_channels, pcl_weights, pcl_sz,
3675 				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
3676 				  channel_list_24, chan_index_24,
3677 				  false);
3678 		status = QDF_STATUS_SUCCESS;
3679 		break;
3680 	case PM_SBS_CH_SCC_CH_5G_24G:
3681 		get_sub_channels(psoc,
3682 				 sbs_freqs, &sbs_num,
3683 				 scc_freqs, &scc_num,
3684 				 rest_freqs, &rest_num,
3685 				 channel_list_5, chan_index_5,
3686 				 channel_list_6, chan_index_6);
3687 		add_chlist_to_pcl(pm_ctx->pdev,
3688 				  pcl_channels, pcl_weights, pcl_sz,
3689 				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
3690 				  sbs_freqs, sbs_num,
3691 				  skip_6ghz_channel);
3692 		add_chlist_to_pcl(pm_ctx->pdev,
3693 				  pcl_channels, pcl_weights, pcl_sz,
3694 				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
3695 				  scc_freqs, scc_num,
3696 				  skip_6ghz_channel);
3697 		add_chlist_to_pcl(pm_ctx->pdev,
3698 				  pcl_channels, pcl_weights, pcl_sz,
3699 				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
3700 				  rest_freqs, rest_num,
3701 				  skip_6ghz_channel);
3702 		add_chlist_to_pcl(pm_ctx->pdev,
3703 				  pcl_channels, pcl_weights, pcl_sz,
3704 				  len, WEIGHT_OF_GROUP4_PCL_CHANNELS,
3705 				  channel_list_24, chan_index_24,
3706 				  false);
3707 		status = QDF_STATUS_SUCCESS;
3708 		break;
3709 	case PM_SCC_CH_MCC_CH_SBS_CH_24G:
3710 		get_sub_channels(psoc,
3711 				 sbs_freqs, &sbs_num,
3712 				 scc_freqs, &scc_num,
3713 				 rest_freqs, &rest_num,
3714 				 channel_list_5, chan_index_5,
3715 				 channel_list_6, chan_index_6);
3716 		add_chlist_to_pcl(pm_ctx->pdev,
3717 				  pcl_channels, pcl_weights, pcl_sz,
3718 				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
3719 				  scc_freqs, scc_num,
3720 				  skip_6ghz_channel);
3721 		add_chlist_to_pcl(pm_ctx->pdev,
3722 				  pcl_channels, pcl_weights, pcl_sz,
3723 				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
3724 				  rest_freqs, rest_num,
3725 				  skip_6ghz_channel);
3726 		add_chlist_to_pcl(pm_ctx->pdev,
3727 				  pcl_channels, pcl_weights, pcl_sz,
3728 				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
3729 				  sbs_freqs, sbs_num,
3730 				  skip_6ghz_channel);
3731 		add_chlist_to_pcl(pm_ctx->pdev,
3732 				  pcl_channels, pcl_weights, pcl_sz,
3733 				  len, WEIGHT_OF_GROUP4_PCL_CHANNELS,
3734 				  channel_list_24, chan_index_24,
3735 				  false);
3736 		status = QDF_STATUS_SUCCESS;
3737 		break;
3738 	case PM_SBS_CH_2G:
3739 		get_sub_channels(psoc,
3740 				 sbs_freqs, &sbs_num,
3741 				 scc_freqs, &scc_num,
3742 				 rest_freqs, &rest_num,
3743 				 channel_list_5, chan_index_5,
3744 				 channel_list_6, chan_index_6);
3745 		add_chlist_to_pcl(pm_ctx->pdev,
3746 				  pcl_channels, pcl_weights, pcl_sz,
3747 				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
3748 				  sbs_freqs, sbs_num,
3749 				  skip_6ghz_channel);
3750 		add_chlist_to_pcl(pm_ctx->pdev,
3751 				  pcl_channels, pcl_weights, pcl_sz,
3752 				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
3753 				  channel_list_24, chan_index_24,
3754 				  false);
3755 		status = QDF_STATUS_SUCCESS;
3756 		break;
3757 	case PM_SCC_ON_5G_LOW_5G_LOW_PLUS_SHARED_2G:
3758 		add_sbs_chlist_to_pcl(psoc,  pcl_channels,
3759 				      pcl_weights, pcl_sz,
3760 				      len,
3761 				      skip_6ghz_channel,
3762 				      channel_list_5, chan_index_5,
3763 				      channel_list_6, chan_index_6,
3764 				      POLICY_MGR_PCL_ORDER_SCC_5G_LOW_5G_LOW,
3765 				      &high_5_band_scc_present,
3766 				      &low_5_band_scc_present);
3767 
3768 		/*
3769 		 * If no 2.4 GHZ connection is present and If 2.4 GHZ is shared
3770 		 * with 5 GHz low freq then 2.4 GHz can be added as well.
3771 		 * If no 5 GHz low band connection, 2.4 GHz can be added.
3772 		 */
3773 		if ((!policy_mgr_2ghz_connection_present(pm_ctx) ||
3774 		     !low_5_band_scc_present) &&
3775 		    policy_mgr_sbs_24_shared_with_low_5(pm_ctx))
3776 			add_chlist_to_pcl(pm_ctx->pdev,
3777 					  pcl_channels, pcl_weights, pcl_sz,
3778 					  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
3779 					  channel_list_24, chan_index_24,
3780 					  false);
3781 		status = QDF_STATUS_SUCCESS;
3782 		break;
3783 	case PM_SCC_ON_5G_HIGH_5G_HIGH_PLUS_SHARED_2G:
3784 	case PM_SCC_ON_5G_HIGH_5G_HIGH_SCC_ON_5G_LOW_PLUS_SHARED_2G:
3785 		add_sbs_chlist_to_pcl(psoc,  pcl_channels,
3786 				      pcl_weights, pcl_sz,
3787 				      len,
3788 				      skip_6ghz_channel,
3789 				      channel_list_5, chan_index_5,
3790 				      channel_list_6, chan_index_6,
3791 				      (pcl == PM_SCC_ON_5G_HIGH_5G_HIGH_PLUS_SHARED_2G) ?
3792 				      POLICY_MGR_PCL_ORDER_SCC_5G_HIGH_5G_HIGH :
3793 				      POLICY_MGR_PCL_ORDER_SCC_5G_HIGH_5G_HIGH_SCC_5G_LOW,
3794 				      &high_5_band_scc_present,
3795 				      &low_5_band_scc_present);
3796 		/*
3797 		 * If no 2.4 GHZ connection is present and if 2.4 GHZ is shared
3798 		 * with 5 GHz High freq then 2.4 GHz can be added as well
3799 		 * If no 5 GHz high band connection, 2.4 GHz can be added.
3800 		 */
3801 		if ((!policy_mgr_2ghz_connection_present(pm_ctx) ||
3802 		     !high_5_band_scc_present) &&
3803 		    policy_mgr_sbs_24_shared_with_high_5(pm_ctx))
3804 			add_chlist_to_pcl(pm_ctx->pdev,
3805 					  pcl_channels, pcl_weights, pcl_sz,
3806 					  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
3807 					  channel_list_24, chan_index_24,
3808 					  false);
3809 		status = QDF_STATUS_SUCCESS;
3810 		break;
3811 	case PM_SBS_CH_MCC_CH:
3812 		get_sub_channels(psoc,
3813 				 sbs_freqs, &sbs_num,
3814 				 scc_freqs, &scc_num,
3815 				 rest_freqs, &rest_num,
3816 				 channel_list_5, chan_index_5,
3817 				 channel_list_6, chan_index_6);
3818 		add_chlist_to_pcl(pm_ctx->pdev,
3819 				  pcl_channels, pcl_weights, pcl_sz,
3820 				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
3821 				  sbs_freqs, sbs_num,
3822 				  skip_6ghz_channel);
3823 		add_chlist_to_pcl(pm_ctx->pdev,
3824 				  pcl_channels, pcl_weights, pcl_sz,
3825 				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
3826 				  rest_freqs, rest_num,
3827 				  false);
3828 		status = QDF_STATUS_SUCCESS;
3829 		break;
3830 	case PM_SBS_5G_MCC_24G:
3831 		get_sub_channels(psoc,
3832 				 sbs_freqs, &sbs_num,
3833 				 scc_freqs, &scc_num,
3834 				 rest_freqs, &rest_num,
3835 				 channel_list_5, chan_index_5,
3836 				 channel_list_6, chan_index_6);
3837 		add_chlist_to_pcl(pm_ctx->pdev,
3838 				  pcl_channels, pcl_weights, pcl_sz,
3839 				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
3840 				  sbs_freqs, sbs_num,
3841 				  skip_6ghz_channel);
3842 		add_chlist_to_pcl(pm_ctx->pdev,
3843 				  pcl_channels, pcl_weights, pcl_sz,
3844 				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
3845 				  rest_freqs, rest_num,
3846 				  skip_6ghz_channel);
3847 		add_chlist_to_pcl(pm_ctx->pdev,
3848 				  pcl_channels, pcl_weights, pcl_sz,
3849 				  len, WEIGHT_OF_GROUP3_PCL_CHANNELS,
3850 				  channel_list_24, chan_index_24,
3851 				  false);
3852 		status = QDF_STATUS_SUCCESS;
3853 		break;
3854 	case PM_SCC_ON_24G:
3855 		policy_mgr_get_connection_channels(psoc, mode,
3856 						   POLICY_MGR_PCL_ORDER_2G,
3857 						   true,
3858 						   POLICY_MGR_PCL_GROUP_ID1_ID2,
3859 						   pcl_channels, pcl_weights,
3860 						   pcl_sz, len);
3861 		status = QDF_STATUS_SUCCESS;
3862 		break;
3863 	case PM_SCC_ON_5G_LOW:
3864 		add_sbs_chlist_to_pcl(psoc,  pcl_channels,
3865 				      pcl_weights, pcl_sz,
3866 				      len,
3867 				      skip_6ghz_channel,
3868 				      channel_list_5, chan_index_5,
3869 				      channel_list_6, chan_index_6,
3870 				      POLICY_MGR_PCL_ORDER_SCC_5G_LOW,
3871 				      &high_5_band_scc_present,
3872 				      &low_5_band_scc_present);
3873 		status = QDF_STATUS_SUCCESS;
3874 		break;
3875 	case PM_SCC_ON_5G_HIGH:
3876 		add_sbs_chlist_to_pcl(psoc,  pcl_channels,
3877 				      pcl_weights, pcl_sz,
3878 				      len,
3879 				      skip_6ghz_channel,
3880 				      channel_list_5, chan_index_5,
3881 				      channel_list_6, chan_index_6,
3882 				      POLICY_MGR_PCL_ORDER_SCC_5G_HIGH,
3883 				      &high_5_band_scc_present,
3884 				      &low_5_band_scc_present);
3885 		status = QDF_STATUS_SUCCESS;
3886 		break;
3887 	case PM_SBS_CH_MCC_CH_SCC_ON_24_24G:
3888 		get_sub_channels(psoc,
3889 				 sbs_freqs, &sbs_num,
3890 				 scc_freqs, &scc_num,
3891 				 rest_freqs, &rest_num,
3892 				 channel_list_5, chan_index_5,
3893 				 channel_list_6, chan_index_6);
3894 		add_chlist_to_pcl(pm_ctx->pdev,
3895 				  pcl_channels, pcl_weights, pcl_sz,
3896 				  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
3897 				  sbs_freqs, sbs_num,
3898 				  skip_6ghz_channel);
3899 		add_chlist_to_pcl(pm_ctx->pdev,
3900 				  pcl_channels, pcl_weights, pcl_sz,
3901 				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
3902 				  rest_freqs, rest_num,
3903 				  skip_6ghz_channel);
3904 		policy_mgr_get_connection_channels(psoc, mode,
3905 						   POLICY_MGR_PCL_ORDER_2G,
3906 						   true,
3907 						   POLICY_MGR_PCL_GROUP_ID1_ID2,
3908 						   pcl_channels, pcl_weights,
3909 						   pcl_sz, len);
3910 		policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz,
3911 					  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
3912 					  channel_list_24, chan_index_24);
3913 		status = QDF_STATUS_SUCCESS;
3914 		break;
3915 	case PM_5G_24G:
3916 		policy_mgr_add_5g_to_pcl(psoc, pcl_channels, pcl_weights,
3917 					 pcl_sz, len,
3918 					 POLICY_MGR_PCL_GROUP_ID1_ID2,
3919 					 channel_list_5, chan_index_5,
3920 					 channel_list_6, chan_index_6);
3921 		policy_mgr_add_24g_to_pcl(pcl_channels, pcl_weights, pcl_sz,
3922 					  len, WEIGHT_OF_GROUP1_PCL_CHANNELS,
3923 					  channel_list_24, chan_index_24);
3924 		status = QDF_STATUS_SUCCESS;
3925 		break;
3926 	case PM_MCC_CH_SCC_ON_24G:
3927 		get_sub_channels(psoc,
3928 				 sbs_freqs, &sbs_num,
3929 				 scc_freqs, &scc_num,
3930 				 rest_freqs, &rest_num,
3931 				 channel_list_5, chan_index_5,
3932 				 channel_list_6, chan_index_6);
3933 		add_chlist_to_pcl(pm_ctx->pdev,
3934 				  pcl_channels, pcl_weights, pcl_sz,
3935 				  len, WEIGHT_OF_GROUP2_PCL_CHANNELS,
3936 				  rest_freqs, rest_num,
3937 				  skip_6ghz_channel);
3938 		policy_mgr_get_connection_channels(psoc, mode,
3939 						   POLICY_MGR_PCL_ORDER_2G,
3940 						   true,
3941 						   POLICY_MGR_PCL_GROUP_ID1_ID2,
3942 						   pcl_channels, pcl_weights,
3943 						   pcl_sz, len);
3944 		status = QDF_STATUS_SUCCESS;
3945 		break;
3946 
3947 	case PM_SCC_ON_5G_LOW_MCC_ON_5G_HIGH:
3948 		add_sbs_chlist_to_pcl(
3949 				psoc,  pcl_channels, pcl_weights, pcl_sz, len,
3950 				skip_6ghz_channel, channel_list_5, chan_index_5,
3951 				channel_list_6, chan_index_6,
3952 				POLICY_MGR_PCL_ORDER_SCC_5G_LOW_MCC_5G_HIGH,
3953 				&high_5_band_scc_present,
3954 				&low_5_band_scc_present);
3955 		status = QDF_STATUS_SUCCESS;
3956 		break;
3957 		status = QDF_STATUS_SUCCESS;
3958 		break;
3959 	case PM_SCC_ON_5G_HIGH_MCC_ON_5G_LOW:
3960 		add_sbs_chlist_to_pcl(
3961 				psoc,  pcl_channels, pcl_weights, pcl_sz, len,
3962 				skip_6ghz_channel, channel_list_5, chan_index_5,
3963 				channel_list_6, chan_index_6,
3964 				POLICY_MGR_PCL_ORDER_SCC_5G_LOW_MCC_5G_HIGH,
3965 				&high_5_band_scc_present,
3966 				&low_5_band_scc_present);
3967 
3968 		status = QDF_STATUS_SUCCESS;
3969 		break;
3970 	default:
3971 		policy_mgr_err("unknown pcl value %d", pcl);
3972 		break;
3973 	}
3974 
3975 	policy_mgr_debug("pcl %s: mode %s", pcl_type_to_string(pcl),
3976 			 device_mode_to_string(mode));
3977 	policy_mgr_debug("pcl len %d and weight list sz %d",
3978 			 *len, pcl_sz);
3979 
3980 	policy_mgr_set_weight_of_disabled_inactive_channels_to_zero(psoc,
3981 			pcl_channels, len, pcl_weights, pcl_sz);
3982 
3983 end:
3984 	qdf_mem_free(channel_list);
3985 	qdf_mem_free(channel_list_24);
3986 	qdf_mem_free(channel_list_5);
3987 	qdf_mem_free(sbs_freqs);
3988 	qdf_mem_free(channel_list_6);
3989 	qdf_mem_free(scc_freqs);
3990 	qdf_mem_free(rest_freqs);
3991 
3992 	return status;
3993 }
3994 
policy_mgr_disallow_mcc(struct wlan_objmgr_psoc * psoc,uint32_t ch_freq)3995 bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc,
3996 			     uint32_t ch_freq)
3997 {
3998 	uint32_t index = 0;
3999 	bool match = false;
4000 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4001 
4002 	pm_ctx = policy_mgr_get_context(psoc);
4003 	if (!pm_ctx) {
4004 		policy_mgr_err("Invalid Context");
4005 		return match;
4006 	}
4007 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4008 	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(index)) {
4009 		if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
4010 			if (pm_conc_connection_list[index].freq != ch_freq) {
4011 				match = true;
4012 				break;
4013 			}
4014 		} else if (!WLAN_REG_IS_24GHZ_CH_FREQ
4015 			(pm_conc_connection_list[index].freq)) {
4016 			if (pm_conc_connection_list[index].freq != ch_freq &&
4017 			    !policy_mgr_are_sbs_chan(psoc, ch_freq,
4018 					pm_conc_connection_list[index].freq)) {
4019 				match = true;
4020 				break;
4021 			}
4022 		}
4023 		index++;
4024 	}
4025 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4026 
4027 	return match;
4028 }
4029 
4030 /**
4031  * policy_mgr_allow_same_mac_diff_freq() - Check whether diff freq are allowed
4032  * on same mac
4033  *
4034  * @psoc: Pointer to Psoc
4035  * @ch_freq: channel frequency
4036  *
4037  * Check whether diff freq are allowed on same mac
4038  *
4039  * Return: True/False
4040  */
4041 static
policy_mgr_allow_same_mac_diff_freq(struct wlan_objmgr_psoc * psoc,qdf_freq_t ch_freq)4042 bool policy_mgr_allow_same_mac_diff_freq(struct wlan_objmgr_psoc *psoc,
4043 					 qdf_freq_t ch_freq)
4044 {
4045 	bool allow = true;
4046 
4047 	if ((pm_conc_connection_list[0].mode == PM_NAN_DISC_MODE &&
4048 	     pm_conc_connection_list[1].mode == PM_NDI_MODE) ||
4049 	    (pm_conc_connection_list[0].mode == PM_NDI_MODE &&
4050 	     pm_conc_connection_list[1].mode == PM_NAN_DISC_MODE)) {
4051 		/*
4052 		 * NAN + NDI are managed in Firmware by dividing
4053 		 * up slots. Connection on NDI is re-negotiable
4054 		 * and therefore a 3rd connection with the
4055 		 * same MAC is possible.
4056 		 */
4057 	} else if (!policy_mgr_is_hw_dbs_capable(psoc) &&
4058 		    policy_mgr_is_interband_mcc_supported(psoc)) {
4059 		if (ch_freq !=  pm_conc_connection_list[0].freq &&
4060 		    ch_freq !=  pm_conc_connection_list[1].freq) {
4061 			policy_mgr_rl_debug("don't allow 3rd home channel on same MAC");
4062 			allow = false;
4063 		}
4064 	} else if (policy_mgr_3_freq_always_on_same_mac(psoc, ch_freq,
4065 					pm_conc_connection_list[0].freq,
4066 					pm_conc_connection_list[1].freq)) {
4067 			policy_mgr_rl_debug("don't allow 3rd home channel on same MAC");
4068 			allow = false;
4069 	}
4070 
4071 	return allow;
4072 }
4073 
4074 /**
4075  * policy_mgr_allow_same_mac_same_freq() - check whether given frequency is
4076  * allowed for same mac
4077  *
4078  * @psoc: Pointer to Psoc
4079  * @ch_freq: channel frequency
4080  * @mode: Concurrency Mode
4081  *
4082  * check whether given frequency is allowed for same mac
4083  *
4084  * Return: True/False
4085  */
4086 static
policy_mgr_allow_same_mac_same_freq(struct wlan_objmgr_psoc * psoc,qdf_freq_t ch_freq,enum policy_mgr_con_mode mode)4087 bool policy_mgr_allow_same_mac_same_freq(struct wlan_objmgr_psoc *psoc,
4088 					 qdf_freq_t ch_freq,
4089 					 enum policy_mgr_con_mode mode)
4090 {
4091 	bool allow = true;
4092 
4093 	if (!policy_mgr_is_hw_dbs_capable(psoc) &&
4094 	    policy_mgr_is_interband_mcc_supported(psoc)) {
4095 		policy_mgr_rl_debug("allow 2 intf SCC + new intf ch %d for legacy hw",
4096 				    ch_freq);
4097 	} else if ((pm_conc_connection_list[0].mode == PM_NAN_DISC_MODE &&
4098 		    pm_conc_connection_list[1].mode == PM_NDI_MODE) ||
4099 		    (pm_conc_connection_list[0].mode == PM_NDI_MODE &&
4100 		    pm_conc_connection_list[1].mode == PM_NAN_DISC_MODE)) {
4101 		/*
4102 		 * NAN + NDI are managed in Firmware by dividing
4103 		 * up slots. Connection on NDI is re-negotiable
4104 		 * and therefore a 3rd connection with the
4105 		 * same MAC is possible.
4106 		 */
4107 	} else if (policy_mgr_2_freq_always_on_same_mac(
4108 			psoc, ch_freq, pm_conc_connection_list[0].freq) &&
4109 		   !policy_mgr_is_3rd_conn_on_same_band_allowed(
4110 			psoc, mode, ch_freq)) {
4111 			policy_mgr_rl_debug("don't allow 3rd home channel on same MAC for sta+multi-AP");
4112 			allow = false;
4113 	}
4114 
4115 	return allow;
4116 }
4117 
policy_mgr_allow_new_home_channel(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,qdf_freq_t ch_freq,uint32_t num_connections,bool is_dfs_ch,uint32_t ext_flags)4118 bool policy_mgr_allow_new_home_channel(
4119 	struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode,
4120 	qdf_freq_t ch_freq, uint32_t num_connections, bool is_dfs_ch,
4121 	uint32_t ext_flags)
4122 {
4123 	bool status = true;
4124 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4125 	bool on_same_mac = false, force_switch_without_dis = false;
4126 
4127 	pm_ctx = policy_mgr_get_context(psoc);
4128 	if (!pm_ctx) {
4129 		policy_mgr_err("Invalid Context");
4130 		return false;
4131 	}
4132 
4133 	force_switch_without_dis =
4134 		policy_mgr_get_mcc_to_scc_switch_mode(psoc) ==
4135 		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION;
4136 
4137 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4138 	if (num_connections == 3) {
4139 		status = policy_mgr_allow_4th_new_freq(psoc,
4140 						       ch_freq, mode,
4141 						       ext_flags);
4142 	} else if (num_connections == 2) {
4143 	/* No SCC or MCC combination is allowed with / on DFS channel */
4144 		on_same_mac = policy_mgr_2_freq_always_on_same_mac(psoc,
4145 					pm_conc_connection_list[0].freq,
4146 					pm_conc_connection_list[1].freq);
4147 		if (force_switch_without_dis && is_dfs_ch &&
4148 		    ((pm_conc_connection_list[0].ch_flagext &
4149 		      (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) ||
4150 		     (pm_conc_connection_list[1].ch_flagext &
4151 		      (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)))) {
4152 			policy_mgr_rl_debug("Existing DFS connection, new 3-port DFS connection is not allowed");
4153 			status = false;
4154 		} else if (((pm_conc_connection_list[0].freq !=
4155 			     pm_conc_connection_list[1].freq) ||
4156 			    force_switch_without_dis) && on_same_mac) {
4157 			status = policy_mgr_allow_same_mac_diff_freq(psoc,
4158 								     ch_freq);
4159 		} else if (on_same_mac) {
4160 			status = policy_mgr_allow_same_mac_same_freq(psoc,
4161 								     ch_freq,
4162 								     mode);
4163 		}
4164 	} else if (num_connections == 1 && force_switch_without_dis &&
4165 		   is_dfs_ch &&
4166 		   (pm_conc_connection_list[0].ch_flagext &
4167 		    (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2))) {
4168 		policy_mgr_rl_debug("Existing DFS connection, new 2-port DFS connection is not allowed");
4169 		status = false;
4170 	} else if ((num_connections == 1) &&
4171 		   !policy_mgr_is_hw_dbs_capable(psoc) &&
4172 		   !policy_mgr_is_interband_mcc_supported(psoc)) {
4173 		/* For target which is single mac and doesn't support
4174 		 * interband MCC
4175 		 */
4176 		if ((pm_conc_connection_list[0].mode != PM_NAN_DISC_MODE) &&
4177 		    (mode != PM_NAN_DISC_MODE))
4178 			status = policy_mgr_2_freq_always_on_same_mac(psoc,
4179 								   ch_freq,
4180 					pm_conc_connection_list[0].freq);
4181 	}
4182 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4183 
4184 	return status;
4185 }
4186 
policy_mgr_is_5g_channel_allowed(struct wlan_objmgr_psoc * psoc,uint32_t ch_freq,uint32_t * list,enum policy_mgr_con_mode mode)4187 bool policy_mgr_is_5g_channel_allowed(struct wlan_objmgr_psoc *psoc,
4188 				uint32_t ch_freq, uint32_t *list,
4189 				enum policy_mgr_con_mode mode)
4190 {
4191 	uint32_t index = 0, count = 0;
4192 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4193 
4194 	pm_ctx = policy_mgr_get_context(psoc);
4195 	if (!pm_ctx) {
4196 		policy_mgr_err("Invalid Context");
4197 		return false;
4198 	}
4199 
4200 	count = policy_mgr_mode_specific_connection_count(psoc, mode, list);
4201 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4202 	while (index < count) {
4203 		if ((pm_conc_connection_list[list[index]].ch_flagext &
4204 		     (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) &&
4205 		    WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) &&
4206 		    (ch_freq != pm_conc_connection_list[list[index]].freq &&
4207 		     !policy_mgr_are_sbs_chan(psoc, ch_freq,
4208 				pm_conc_connection_list[list[index]].freq))) {
4209 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4210 			policy_mgr_rl_debug("don't allow MCC if SAP/GO on DFS channel");
4211 			return false;
4212 		}
4213 		index++;
4214 	}
4215 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4216 
4217 	return true;
4218 }
4219 
4220 /**
4221  * policy_mgr_get_pref_force_scc_freq() - Get preferred force SCC
4222  * channel frequency
4223  * @psoc: Pointer to Psoc
4224  * @vdev_id: vdev id
4225  * @intf_ch_freq: prefer force scc frequency
4226  * @sap_ch_freq: sap/go channel starting channel frequency
4227  * @acs_band: acs band
4228  * @allow_6ghz: allow 6 Ghz channel or not
4229  *
4230  * This API will consider protocol 6ghz allow flag - allow_6ghz.
4231  * Also for regdomain, it will consider PCL allow or not.
4232  * For example, if STA is on 6ghz LPI mode, SAP is not allowed
4233  * force scc to 6ghz, see API
4234  * policy_mgr_modify_sap_pcl_for_6G_channels.
4235  *
4236  * Return: QDF_STATUS_SUCCESS if get preferred force scc channel.
4237  */
4238 static QDF_STATUS
policy_mgr_get_pref_force_scc_freq(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,qdf_freq_t * intf_ch_freq,qdf_freq_t sap_ch_freq,uint32_t acs_band,bool allow_6ghz)4239 policy_mgr_get_pref_force_scc_freq(struct wlan_objmgr_psoc *psoc,
4240 				   uint8_t vdev_id,
4241 				   qdf_freq_t *intf_ch_freq,
4242 				   qdf_freq_t sap_ch_freq,
4243 				   uint32_t acs_band,
4244 				   bool allow_6ghz)
4245 {
4246 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4247 	enum policy_mgr_con_mode mode;
4248 	QDF_STATUS status;
4249 	uint32_t i;
4250 	struct policy_mgr_pcl_list pcl;
4251 	bool allow_2ghz_only = false;
4252 	qdf_freq_t scc_ch_freq_on_same_mac = 0;
4253 	qdf_freq_t scc_ch_freq_on_diff_mac = 0;
4254 	qdf_freq_t scc_ch_freq_same_as_sap = 0;
4255 	qdf_freq_t non_scc_ch_freq_on_same_mac = 0;
4256 	qdf_freq_t non_scc_ch_freq_on_diff_mac = 0;
4257 	qdf_freq_t non_scc_ch_freq_same_as_sap = 0;
4258 	enum QDF_OPMODE op_mode;
4259 	qdf_freq_t pcl_freq;
4260 	bool same_mac, sbs_ml_sta_present = false, dbs_ml_sta_present = false;
4261 
4262 	pm_ctx = policy_mgr_get_context(psoc);
4263 	if (!pm_ctx) {
4264 		policy_mgr_err("Invalid Context");
4265 		return QDF_STATUS_E_INVAL;
4266 	}
4267 
4268 	if (policy_mgr_is_mlo_in_mode_dbs(psoc, PM_STA_MODE, NULL, NULL))
4269 		dbs_ml_sta_present = true;
4270 	else if (policy_mgr_is_mlo_in_mode_sbs(psoc, PM_STA_MODE, NULL, NULL))
4271 		sbs_ml_sta_present = true;
4272 
4273 	op_mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id);
4274 	mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, op_mode, vdev_id);
4275 
4276 	qdf_mem_zero(&pcl, sizeof(pcl));
4277 	status = policy_mgr_get_pcl(psoc, mode, pcl.pcl_list, &pcl.pcl_len,
4278 				    pcl.weight_list,
4279 				    QDF_ARRAY_SIZE(pcl.weight_list),
4280 				    vdev_id);
4281 	if (QDF_IS_STATUS_ERROR(status) || !pcl.pcl_len) {
4282 		policy_mgr_err("get pcl failed for mode: %d, pcl len %d", mode,
4283 			       pcl.pcl_len);
4284 		return QDF_STATUS_E_INVAL;
4285 	}
4286 
4287 	if ((acs_band == QCA_ACS_MODE_IEEE80211B ||
4288 	     acs_band == QCA_ACS_MODE_IEEE80211G) &&
4289 	     WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq))
4290 		allow_2ghz_only = true;
4291 
4292 	/*
4293 	 * The preferred force SCC channel is SAP original channel,
4294 	 * and then the SCC channel on the same mac, and then the SCC
4295 	 * channel on the different mac.
4296 	 * Make sure the PCL only contains valid channels - not
4297 	 * causing 3 vif on same mac.
4298 	 * If none of channels are available, we have to keep SAP channel
4299 	 * unchanged, and that may cause SAP MCC.
4300 	 */
4301 	for (i = 0; i < pcl.pcl_len; i++) {
4302 		pcl_freq = pcl.pcl_list[i];
4303 
4304 		if (!allow_6ghz && WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl_freq))
4305 			continue;
4306 		if (allow_2ghz_only && !WLAN_REG_IS_24GHZ_CH_FREQ(pcl_freq))
4307 			continue;
4308 
4309 		/*
4310 		 * If ML STA is present, as ML STA cannot be on same mac,
4311 		 * check same band logic as per the ML hw mode, else
4312 		 * use the API which is hw mode agnostic.
4313 		 */
4314 		if (dbs_ml_sta_present)
4315 			same_mac = policy_mgr_2_freq_same_mac_in_dbs(pm_ctx,
4316 								sap_ch_freq,
4317 								pcl_freq);
4318 		else if (sbs_ml_sta_present)
4319 			same_mac = policy_mgr_2_freq_same_mac_in_sbs(pm_ctx,
4320 								sap_ch_freq,
4321 								pcl_freq);
4322 		else
4323 			same_mac = policy_mgr_2_freq_always_on_same_mac(psoc,
4324 								sap_ch_freq,
4325 								pcl_freq);
4326 		if (!((pm_conc_connection_list[0].in_use &&
4327 		       (pcl_freq == pm_conc_connection_list[0].freq)) ||
4328 		      (pm_conc_connection_list[1].in_use &&
4329 		       (pcl_freq == pm_conc_connection_list[1].freq)) ||
4330 		      (pm_conc_connection_list[2].in_use &&
4331 		       (pcl_freq == pm_conc_connection_list[2].freq)))) {
4332 			if (sap_ch_freq == pcl_freq)
4333 				non_scc_ch_freq_same_as_sap = pcl_freq;
4334 			else if (!non_scc_ch_freq_on_same_mac && same_mac)
4335 				non_scc_ch_freq_on_same_mac = pcl_freq;
4336 			else if (!non_scc_ch_freq_on_diff_mac && !same_mac)
4337 				non_scc_ch_freq_on_diff_mac = pcl_freq;
4338 			continue;
4339 		}
4340 
4341 		if (sap_ch_freq == pcl_freq)
4342 			scc_ch_freq_same_as_sap = pcl_freq;
4343 		else if (!scc_ch_freq_on_same_mac && same_mac)
4344 			scc_ch_freq_on_same_mac = pcl_freq;
4345 		else if (!scc_ch_freq_on_diff_mac && !same_mac)
4346 			scc_ch_freq_on_diff_mac = pcl_freq;
4347 	}
4348 
4349 	if (scc_ch_freq_same_as_sap)
4350 		*intf_ch_freq = scc_ch_freq_same_as_sap;
4351 	else if (scc_ch_freq_on_same_mac)
4352 		*intf_ch_freq = scc_ch_freq_on_same_mac;
4353 	else if (non_scc_ch_freq_same_as_sap)
4354 		*intf_ch_freq = non_scc_ch_freq_same_as_sap;
4355 	else if (scc_ch_freq_on_diff_mac)
4356 		*intf_ch_freq = scc_ch_freq_on_diff_mac;
4357 	else if (non_scc_ch_freq_on_same_mac)
4358 		*intf_ch_freq = non_scc_ch_freq_on_same_mac;
4359 	else if (non_scc_ch_freq_on_diff_mac)
4360 		*intf_ch_freq = non_scc_ch_freq_on_diff_mac;
4361 	else
4362 		*intf_ch_freq = 0;
4363 
4364 	policy_mgr_debug("2ghz_only %d allow_6ghz %d, ml sta SBS:%d DBS:%d, SCC: same_as_sap %d same_mac %d on_diff_mac %d, NON-SCC: same_as_sap %d same_mac %d on_diff_mac %d. intf_ch_freq %d",
4365 			 allow_2ghz_only, allow_6ghz, sbs_ml_sta_present,
4366 			 dbs_ml_sta_present, scc_ch_freq_same_as_sap,
4367 			 scc_ch_freq_on_same_mac, scc_ch_freq_on_diff_mac,
4368 			 non_scc_ch_freq_same_as_sap,
4369 			 non_scc_ch_freq_on_same_mac,
4370 			 non_scc_ch_freq_on_diff_mac, *intf_ch_freq);
4371 
4372 	return QDF_STATUS_SUCCESS;
4373 }
4374 
4375 /**
4376  * policy_mgr_handle_sta_sap_fav_channel() - Get preferred force SCC
4377  * channel frequency using favorite mandatory channel list for STA+SAP
4378  * concurrency
4379  * @psoc: Pointer to Psoc
4380  * @pm_ctx: pm ctx
4381  * @vdev_id: vdev id
4382  * @intf_ch_freq: prefer force scc frequency
4383  * @sap_ch_freq: sap/go channel starting channel frequency
4384  * @acs_band: acs band
4385  *
4386  * Return: QDF_STATUS_SUCCESS if a valid favorite mandatory force scc channel
4387  * is found.
4388  */
4389 static QDF_STATUS
policy_mgr_handle_sta_sap_fav_channel(struct wlan_objmgr_psoc * psoc,struct policy_mgr_psoc_priv_obj * pm_ctx,uint8_t vdev_id,qdf_freq_t sap_ch_freq,qdf_freq_t * intf_ch_freq,uint32_t acs_band)4390 policy_mgr_handle_sta_sap_fav_channel(struct wlan_objmgr_psoc *psoc,
4391 				      struct policy_mgr_psoc_priv_obj *pm_ctx,
4392 				      uint8_t vdev_id, qdf_freq_t sap_ch_freq,
4393 				      qdf_freq_t *intf_ch_freq,
4394 				      uint32_t acs_band)
4395 {
4396 	bool sta_sap_scc_on_indoor_channel_allowed;
4397 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
4398 	qdf_freq_t user_config_freq;
4399 
4400 	 /* intf_ch_freq and SAP freq in same band */
4401 	if (WLAN_REG_IS_24GHZ_CH_FREQ(*intf_ch_freq) ==
4402 	    WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq))
4403 		return policy_mgr_get_sap_mandatory_channel(psoc, sap_ch_freq,
4404 							intf_ch_freq, vdev_id);
4405 
4406 	/* intf_ch_freq and SAP freq in different band */
4407 	/*
4408 	 * STA + SAP where doing SCC on 5 GHz indoor channel.
4409 	 * STA moved/roamed to 2.4 GHz. Move SAP to initially
4410 	 * started channel.
4411 	 *
4412 	 * STA+SAP where STA is moved/roamed to 5GHz indoor
4413 	 * and SAP is on 2.4 GHz due to previous concurrency.
4414 	 * Move SAP to STA channel on SCC.
4415 	 */
4416 	sta_sap_scc_on_indoor_channel_allowed =
4417 		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
4418 
4419 	/*
4420 	 * SAP and interface freq in different band and 5 GHz freq is
4421 	 * indoor
4422 	 */
4423 	if (sta_sap_scc_on_indoor_channel_allowed &&
4424 	    ((wlan_reg_is_freq_indoor(pm_ctx->pdev, sap_ch_freq) &&
4425 	    WLAN_REG_IS_24GHZ_CH_FREQ(*intf_ch_freq)) ||
4426 	    (wlan_reg_is_freq_indoor(pm_ctx->pdev, *intf_ch_freq) &&
4427 	     WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq) &&
4428 	     !(acs_band == QCA_ACS_MODE_IEEE80211B ||
4429 	       acs_band == QCA_ACS_MODE_IEEE80211G)))) {
4430 		status = policy_mgr_get_sap_mandatory_channel(psoc, sap_ch_freq,
4431 							      intf_ch_freq,
4432 							      vdev_id);
4433 		if (QDF_IS_STATUS_SUCCESS(status))
4434 			return status;
4435 	}
4436 
4437 	user_config_freq =
4438 		policy_mgr_get_user_config_sap_freq(psoc, vdev_id);
4439 
4440 	if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq) &&
4441 	    user_config_freq &&
4442 	    !WLAN_REG_IS_24GHZ_CH_FREQ(user_config_freq) &&
4443 	    (wlan_reg_get_channel_state_for_pwrmode(pm_ctx->pdev, *intf_ch_freq,
4444 			REG_CURRENT_PWR_MODE) == CHANNEL_STATE_ENABLE)) {
4445 		status = policy_mgr_get_sap_mandatory_channel(psoc, sap_ch_freq,
4446 							      intf_ch_freq,
4447 							      vdev_id);
4448 		if (QDF_IS_STATUS_SUCCESS(status))
4449 			return status;
4450 	}
4451 
4452 	return status;
4453 }
4454 
4455 QDF_STATUS
policy_mgr_handle_go_sap_fav_channel(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,qdf_freq_t sap_ch_freq,qdf_freq_t * intf_ch_freq)4456 policy_mgr_handle_go_sap_fav_channel(struct wlan_objmgr_psoc *psoc,
4457 				     uint8_t vdev_id, qdf_freq_t sap_ch_freq,
4458 				     qdf_freq_t *intf_ch_freq)
4459 {
4460 	QDF_STATUS status;
4461 	uint8_t go_count;
4462 	uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
4463 	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
4464 	struct policy_mgr_pcl_list pcl;
4465 	uint32_t i;
4466 
4467 	go_count = policy_mgr_get_mode_specific_conn_info(psoc,
4468 							  op_ch_freq_list,
4469 							  vdev_id_list,
4470 							  PM_P2P_GO_MODE);
4471 	if (!go_count)
4472 		return QDF_STATUS_E_FAILURE;
4473 
4474 	/* According to requirement, SAP should move to 2.4 GHz if P2P GO is
4475 	 * on 5G/6G.
4476 	 */
4477 	if (WLAN_REG_IS_24GHZ_CH_FREQ(op_ch_freq_list[0]) ||
4478 	    WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq))
4479 		return QDF_STATUS_E_FAILURE;
4480 
4481 	qdf_mem_zero(&pcl, sizeof(pcl));
4482 	status = policy_mgr_get_pcl_for_existing_conn(
4483 			psoc, PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len,
4484 			pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list),
4485 			false, vdev_id);
4486 	if (QDF_IS_STATUS_ERROR(status)) {
4487 		policy_mgr_err("Unable to get PCL for SAP");
4488 		return status;
4489 	}
4490 
4491 	for (i = 0; i < pcl.pcl_len; i++) {
4492 		if (WLAN_REG_IS_24GHZ_CH_FREQ(pcl.pcl_list[i])) {
4493 			*intf_ch_freq = pcl.pcl_list[i];
4494 			policy_mgr_debug("sap move to %d because GO on %d",
4495 					 *intf_ch_freq, op_ch_freq_list[0]);
4496 			return QDF_STATUS_SUCCESS;
4497 		}
4498 	}
4499 
4500 	return QDF_STATUS_E_FAILURE;
4501 }
4502 
4503 /**
4504  * policy_mgr_handle_sap_fav_channel() - Get preferred force SCC
4505  * channel frequency using favorite mandatory channel list
4506  * @psoc: Pointer to Psoc
4507  * @pm_ctx: pm ctx
4508  * @vdev_id: vdev id
4509  * @intf_ch_freq: prefer force scc frequency
4510  * @sap_ch_freq: sap/go channel starting channel frequency
4511  * @acs_band: acs band
4512  *
4513  * Return: QDF_STATUS_SUCCESS if a valid favorite mandatory force scc channel
4514  * is found.
4515  */
4516 static QDF_STATUS
policy_mgr_handle_sap_fav_channel(struct wlan_objmgr_psoc * psoc,struct policy_mgr_psoc_priv_obj * pm_ctx,uint8_t vdev_id,qdf_freq_t sap_ch_freq,qdf_freq_t * intf_ch_freq,uint32_t acs_band)4517 policy_mgr_handle_sap_fav_channel(struct wlan_objmgr_psoc *psoc,
4518 				  struct policy_mgr_psoc_priv_obj *pm_ctx,
4519 				  uint8_t vdev_id, qdf_freq_t sap_ch_freq,
4520 				  qdf_freq_t *intf_ch_freq,
4521 				  uint32_t acs_band)
4522 {
4523 	QDF_STATUS status;
4524 	uint8_t sta_count, go_count;
4525 
4526 	go_count = policy_mgr_mode_specific_connection_count(psoc,
4527 							     PM_P2P_GO_MODE,
4528 							     NULL);
4529 	if (go_count) {
4530 		status = policy_mgr_handle_go_sap_fav_channel(
4531 					psoc, vdev_id,
4532 					sap_ch_freq, intf_ch_freq);
4533 		if (QDF_IS_STATUS_SUCCESS(status) &&
4534 		    *intf_ch_freq && *intf_ch_freq != sap_ch_freq)
4535 			return QDF_STATUS_SUCCESS;
4536 	}
4537 
4538 	sta_count = policy_mgr_mode_specific_connection_count(psoc,
4539 							      PM_STA_MODE,
4540 							      NULL);
4541 	if (sta_count && sta_count < 2)
4542 		return policy_mgr_handle_sta_sap_fav_channel(
4543 					psoc, pm_ctx, vdev_id,
4544 					sap_ch_freq, intf_ch_freq,
4545 					acs_band);
4546 
4547 	return QDF_STATUS_E_FAILURE;
4548 }
4549 
policy_mgr_check_scc_channel(struct wlan_objmgr_psoc * psoc,qdf_freq_t * intf_ch_freq,qdf_freq_t sap_ch_freq,uint8_t vdev_id,uint8_t cc_mode)4550 void policy_mgr_check_scc_channel(struct wlan_objmgr_psoc *psoc,
4551 				  qdf_freq_t *intf_ch_freq,
4552 				  qdf_freq_t sap_ch_freq,
4553 				  uint8_t vdev_id, uint8_t cc_mode)
4554 {
4555 	uint32_t num_connections, acs_band = QCA_ACS_MODE_IEEE80211ANY;
4556 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4557 	QDF_STATUS status;
4558 	struct policy_mgr_conc_connection_info
4559 			info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
4560 	uint8_t num_cxn_del = 0;
4561 	bool allow_6ghz = true;
4562 	uint8_t sta_count;
4563 
4564 	pm_ctx = policy_mgr_get_context(psoc);
4565 	if (!pm_ctx) {
4566 		policy_mgr_err("Invalid Context");
4567 		return;
4568 	}
4569 
4570 	/* Always do force SCC on non-DBS platforms */
4571 	if (!policy_mgr_is_hw_dbs_capable(psoc))
4572 		return;
4573 
4574 	sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
4575 							      NULL);
4576 	if (pm_ctx->hdd_cbacks.wlan_get_sap_acs_band) {
4577 		status = pm_ctx->hdd_cbacks.wlan_get_sap_acs_band(psoc,
4578 								  vdev_id,
4579 								  &acs_band);
4580 		if (QDF_IS_STATUS_SUCCESS(status))
4581 			policy_mgr_debug("acs_band: %d", acs_band);
4582 	}
4583 
4584 	/* Handle STA/P2P + SAP mandaory freq cases */
4585 	if (cc_mode == QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) {
4586 		status = policy_mgr_handle_sap_fav_channel(
4587 				psoc, pm_ctx, vdev_id, sap_ch_freq,
4588 				intf_ch_freq, acs_band);
4589 		if (QDF_IS_STATUS_SUCCESS(status))
4590 			return;
4591 		policy_mgr_debug("no mandatory channels (%d, %d)", sap_ch_freq,
4592 				 *intf_ch_freq);
4593 	} else if (sta_count && policy_mgr_is_hw_dbs_capable(psoc)) {
4594 		policy_mgr_sap_on_non_psc_channel(psoc, intf_ch_freq, vdev_id);
4595 	}
4596 
4597 	/* Get allow 6Gz before interface entry is temporary deleted */
4598 	if (sap_ch_freq && !WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ch_freq) &&
4599 	    !policy_mgr_get_ap_6ghz_capable(psoc, vdev_id, NULL))
4600 		allow_6ghz = false;
4601 
4602 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4603 	/*
4604 	 * For SAP restart case SAP entry might be present in table,
4605 	 * so delete it temporary
4606 	 */
4607 	policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id, info,
4608 						      &num_cxn_del);
4609 
4610 	num_connections = policy_mgr_get_connection_count(psoc);
4611 	switch (num_connections) {
4612 	case 0:
4613 		/* use sap channel */
4614 		*intf_ch_freq = 0;
4615 		break;
4616 	default:
4617 		if (num_connections > 3) {
4618 			policy_mgr_debug("invalid num_connections: %d",
4619 					 num_connections);
4620 			break;
4621 		}
4622 		/* Use PCL and concurrency combo to get the best channel */
4623 		policy_mgr_get_pref_force_scc_freq(psoc, vdev_id, intf_ch_freq,
4624 						   sap_ch_freq, acs_band,
4625 						   allow_6ghz);
4626 		break;
4627 	}
4628 
4629 	/* Restore the connection entry */
4630 	if (num_cxn_del > 0)
4631 		policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del);
4632 
4633 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4634 }
4635 
policy_mgr_nss_update_cb(struct wlan_objmgr_psoc * psoc,uint8_t tx_status,uint8_t vdev_id,uint8_t next_action,enum policy_mgr_conn_update_reason reason,uint32_t original_vdev_id,uint32_t request_id)4636 void policy_mgr_nss_update_cb(struct wlan_objmgr_psoc *psoc,
4637 			      uint8_t tx_status,
4638 			      uint8_t vdev_id,
4639 			      uint8_t next_action,
4640 			      enum policy_mgr_conn_update_reason reason,
4641 			      uint32_t original_vdev_id, uint32_t request_id)
4642 {
4643 	uint32_t conn_index = 0;
4644 	QDF_STATUS ret;
4645 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4646 
4647 	pm_ctx = policy_mgr_get_context(psoc);
4648 	if (!pm_ctx) {
4649 		policy_mgr_err("Invalid Context");
4650 		return;
4651 	}
4652 
4653 	if (QDF_STATUS_SUCCESS != tx_status)
4654 		policy_mgr_err("nss update failed(%d) for vdev %d",
4655 			tx_status, vdev_id);
4656 
4657 	/*
4658 	 * Check if we are ok to request for HW mode change now
4659 	 */
4660 	conn_index = policy_mgr_get_connection_for_vdev_id(psoc, vdev_id);
4661 	if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) {
4662 		policy_mgr_err("connection not found for vdev %d", vdev_id);
4663 		return;
4664 	}
4665 
4666 	policy_mgr_debug("nss update successful for vdev:%d ori %d reason %d",
4667 			 vdev_id, original_vdev_id, reason);
4668 	if (PM_NOP != next_action) {
4669 		if (reason == POLICY_MGR_UPDATE_REASON_AFTER_CHANNEL_SWITCH)
4670 			policy_mgr_next_actions(psoc, vdev_id, next_action,
4671 						reason, request_id);
4672 		else
4673 			policy_mgr_next_actions(psoc, original_vdev_id,
4674 						next_action, reason,
4675 						request_id);
4676 	} else {
4677 		if (reason == POLICY_MGR_UPDATE_REASON_STA_CONNECT ||
4678 		    reason == POLICY_MGR_UPDATE_REASON_LFR2_ROAM) {
4679 			sme_debug("Continue connect/reassoc on vdev %d request_id %x reason %d",
4680 				  vdev_id, request_id, reason);
4681 			wlan_connect_hw_mode_change_resp(pm_ctx->pdev, vdev_id,
4682 							 request_id,
4683 							 QDF_STATUS_SUCCESS);
4684 		}
4685 		policy_mgr_debug("No action needed right now");
4686 		ret = policy_mgr_set_opportunistic_update(psoc);
4687 		if (!QDF_IS_STATUS_SUCCESS(ret))
4688 			policy_mgr_err("ERROR: set opportunistic_update event failed");
4689 	}
4690 
4691 	return;
4692 }
4693 
4694 QDF_STATUS
policy_mgr_sap_ch_width_update(struct wlan_objmgr_psoc * psoc,enum policy_mgr_conc_next_action next_action,enum policy_mgr_conn_update_reason reason,uint8_t conc_vdev_id,uint32_t request_id)4695 policy_mgr_sap_ch_width_update(struct wlan_objmgr_psoc *psoc,
4696 			       enum policy_mgr_conc_next_action next_action,
4697 			       enum policy_mgr_conn_update_reason reason,
4698 			       uint8_t conc_vdev_id, uint32_t request_id)
4699 {
4700 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
4701 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4702 	uint32_t freq;
4703 	uint8_t sap_vdev_id;
4704 	enum phy_ch_width target_bw;
4705 
4706 	pm_ctx = policy_mgr_get_context(psoc);
4707 	if (!pm_ctx) {
4708 		policy_mgr_err("Invalid Context");
4709 		return status;
4710 	}
4711 
4712 	policy_mgr_debug("action: %d reason: %d", next_action, reason);
4713 
4714 	policy_mgr_get_mode_specific_conn_info(psoc, &freq,
4715 					       &sap_vdev_id,
4716 					       PM_SAP_MODE);
4717 	if (next_action == PM_DOWNGRADE_BW)
4718 		target_bw = CH_WIDTH_160MHZ;
4719 	else
4720 		target_bw = CH_WIDTH_320MHZ;
4721 
4722 	status = pm_ctx->sme_cbacks.sme_sap_update_ch_width(psoc,
4723 							    sap_vdev_id,
4724 							    target_bw, reason,
4725 							    conc_vdev_id,
4726 							    request_id);
4727 	if (QDF_IS_STATUS_ERROR(status))
4728 		policy_mgr_err("vdev %d failed to set BW to %d",
4729 			       sap_vdev_id, target_bw);
4730 
4731 	return status;
4732 }
4733 
policy_mgr_nss_update(struct wlan_objmgr_psoc * psoc,uint8_t new_nss,uint8_t next_action,enum policy_mgr_band band,enum policy_mgr_conn_update_reason reason,uint32_t original_vdev_id,uint32_t request_id)4734 QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc,
4735 		uint8_t  new_nss, uint8_t next_action,
4736 		enum policy_mgr_band band,
4737 		enum policy_mgr_conn_update_reason reason,
4738 		uint32_t original_vdev_id, uint32_t request_id)
4739 {
4740 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
4741 	uint32_t index, count;
4742 	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
4743 	uint32_t conn_index = 0;
4744 	uint32_t vdev_id;
4745 	uint32_t original_nss, ch_freq;
4746 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4747 	enum phy_ch_width ch_width = CH_WIDTH_MAX;
4748 
4749 	pm_ctx = policy_mgr_get_context(psoc);
4750 	if (!pm_ctx) {
4751 		policy_mgr_err("Invalid Context");
4752 		return status;
4753 	}
4754 	if (next_action == PM_DBS2 && band == POLICY_MGR_BAND_5)
4755 		ch_width = CH_WIDTH_40MHZ;
4756 
4757 	count = policy_mgr_mode_specific_connection_count(psoc,
4758 			PM_P2P_GO_MODE, list);
4759 	for (index = 0; index < count; index++) {
4760 		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4761 		vdev_id = pm_conc_connection_list[list[index]].vdev_id;
4762 		original_nss =
4763 		pm_conc_connection_list[list[index]].original_nss;
4764 		ch_freq = pm_conc_connection_list[list[index]].freq;
4765 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4766 		conn_index = policy_mgr_get_connection_for_vdev_id(
4767 			psoc, vdev_id);
4768 		if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) {
4769 			policy_mgr_err("connection not found for vdev %d",
4770 				vdev_id);
4771 			continue;
4772 		}
4773 
4774 		if (original_nss == 2 &&
4775 		    (band == POLICY_MGR_ANY ||
4776 		    (band == POLICY_MGR_BAND_24 &&
4777 		    WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) ||
4778 		    (band == POLICY_MGR_BAND_5 &&
4779 		    WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq)))) {
4780 			status = pm_ctx->sme_cbacks.sme_nss_update_request(
4781 					vdev_id, new_nss, ch_width,
4782 					policy_mgr_nss_update_cb,
4783 					next_action, psoc, reason,
4784 					original_vdev_id, request_id);
4785 			if (!QDF_IS_STATUS_SUCCESS(status)) {
4786 				policy_mgr_err("sme_nss_update_request() failed for vdev %d",
4787 				vdev_id);
4788 			}
4789 		}
4790 	}
4791 
4792 	count = policy_mgr_get_sap_mode_count(psoc, list);
4793 
4794 	for (index = 0; index < count; index++) {
4795 		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4796 		vdev_id = pm_conc_connection_list[list[index]].vdev_id;
4797 		original_nss =
4798 		pm_conc_connection_list[list[index]].original_nss;
4799 		ch_freq = pm_conc_connection_list[list[index]].freq;
4800 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4801 		conn_index = policy_mgr_get_connection_for_vdev_id(
4802 			psoc, vdev_id);
4803 		if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) {
4804 			policy_mgr_err("connection not found for vdev %d",
4805 				vdev_id);
4806 			continue;
4807 		}
4808 		if (original_nss == 2 &&
4809 		    (band == POLICY_MGR_ANY ||
4810 		    (band == POLICY_MGR_BAND_24 &&
4811 		    WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) ||
4812 		    (band == POLICY_MGR_BAND_5 &&
4813 		    WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq)))) {
4814 			status = pm_ctx->sme_cbacks.sme_nss_update_request(
4815 					vdev_id, new_nss, ch_width,
4816 					policy_mgr_nss_update_cb,
4817 					next_action, psoc, reason,
4818 					original_vdev_id, request_id);
4819 			if (!QDF_IS_STATUS_SUCCESS(status)) {
4820 				policy_mgr_err("sme_nss_update_request() failed for vdev %d",
4821 				vdev_id);
4822 			}
4823 		}
4824 	}
4825 
4826 	return status;
4827 }
4828 
policy_mgr_complete_action(struct wlan_objmgr_psoc * psoc,uint8_t new_nss,uint8_t next_action,enum policy_mgr_conn_update_reason reason,uint32_t session_id,uint32_t request_id)4829 QDF_STATUS policy_mgr_complete_action(struct wlan_objmgr_psoc *psoc,
4830 				uint8_t  new_nss, uint8_t next_action,
4831 				enum policy_mgr_conn_update_reason reason,
4832 				uint32_t session_id, uint32_t request_id)
4833 {
4834 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
4835 	enum policy_mgr_band downgrade_band;
4836 
4837 	if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
4838 		policy_mgr_rl_debug("driver isn't dbs capable, no further action needed");
4839 		return QDF_STATUS_E_NOSUPPORT;
4840 	}
4841 
4842 	/* policy_mgr_complete_action() is called by policy_mgr_next_actions().
4843 	 * All other callers of policy_mgr_next_actions() have taken mutex
4844 	 * protection. So, not taking any lock inside
4845 	 * policy_mgr_complete_action() during pm_conc_connection_list access.
4846 	 */
4847 	if (next_action == PM_DBS1)
4848 		downgrade_band = POLICY_MGR_BAND_24;
4849 	else if (next_action == PM_DBS2)
4850 		downgrade_band = POLICY_MGR_BAND_5;
4851 	else
4852 		downgrade_band = POLICY_MGR_ANY;
4853 
4854 	status = policy_mgr_nss_update(psoc, new_nss, next_action,
4855 				       downgrade_band, reason,
4856 				       session_id, request_id);
4857 	if (!QDF_IS_STATUS_SUCCESS(status))
4858 		status = policy_mgr_next_actions(psoc, session_id,
4859 						 next_action, reason,
4860 						 request_id);
4861 
4862 	return status;
4863 }
4864 
policy_mgr_get_mode_by_vdev_id(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)4865 enum policy_mgr_con_mode policy_mgr_get_mode_by_vdev_id(
4866 		struct wlan_objmgr_psoc *psoc,
4867 		uint8_t vdev_id)
4868 {
4869 	enum policy_mgr_con_mode mode = PM_MAX_NUM_OF_MODE;
4870 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4871 	uint32_t conn_index;
4872 
4873 	pm_ctx = policy_mgr_get_context(psoc);
4874 	if (!pm_ctx) {
4875 		policy_mgr_err("Invalid Context");
4876 		return mode;
4877 	}
4878 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4879 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
4880 		conn_index++)
4881 		if ((pm_conc_connection_list[conn_index].vdev_id == vdev_id) &&
4882 			pm_conc_connection_list[conn_index].in_use){
4883 				mode = pm_conc_connection_list[conn_index].mode;
4884 				break;
4885 		}
4886 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4887 
4888 	return mode;
4889 }
4890 
4891 /**
4892  * policy_mgr_init_connection_update() - Initialize connection
4893  * update event
4894  * @pm_ctx: policy mgr context
4895  *
4896  * Initializes the concurrent connection update event
4897  *
4898  * Return: QDF_STATUS
4899  */
policy_mgr_init_connection_update(struct policy_mgr_psoc_priv_obj * pm_ctx)4900 QDF_STATUS policy_mgr_init_connection_update(
4901 		struct policy_mgr_psoc_priv_obj *pm_ctx)
4902 {
4903 	QDF_STATUS qdf_status;
4904 
4905 	qdf_status = qdf_event_create(&pm_ctx->connection_update_done_evt);
4906 
4907 	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
4908 		policy_mgr_err("init event failed");
4909 		return QDF_STATUS_E_FAILURE;
4910 	}
4911 
4912 	return QDF_STATUS_SUCCESS;
4913 }
4914 
4915 enum policy_mgr_conc_next_action
policy_mgr_get_current_pref_hw_mode_dbs_2x2(struct wlan_objmgr_psoc * psoc)4916 		policy_mgr_get_current_pref_hw_mode_dbs_2x2(
4917 		struct wlan_objmgr_psoc *psoc)
4918 {
4919 	uint32_t num_connections;
4920 	uint8_t band1, band2, band3;
4921 	struct policy_mgr_hw_mode_params hw_mode;
4922 	QDF_STATUS status;
4923 
4924 	status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
4925 	if (!QDF_IS_STATUS_SUCCESS(status)) {
4926 		policy_mgr_err("policy_mgr_get_current_hw_mode failed");
4927 		return PM_NOP;
4928 	}
4929 
4930 	num_connections = policy_mgr_get_connection_count(psoc);
4931 
4932 	policy_mgr_debug("chan[0]:%d chan[1]:%d chan[2]:%d num_connections:%d dbs:%d",
4933 		pm_conc_connection_list[0].freq,
4934 		pm_conc_connection_list[1].freq,
4935 		pm_conc_connection_list[2].freq, num_connections,
4936 		hw_mode.dbs_cap);
4937 
4938 	/* If the band of operation of both the MACs is the same,
4939 	 * single MAC is preferred, otherwise DBS is preferred.
4940 	 */
4941 	switch (num_connections) {
4942 	case 1:
4943 		band1 = wlan_reg_freq_to_band(pm_conc_connection_list[0].freq);
4944 		if (band1 == REG_BAND_2G)
4945 			return PM_DBS;
4946 		else
4947 			return PM_NOP;
4948 	case 2:
4949 		band1 = wlan_reg_freq_to_band(pm_conc_connection_list[0].freq);
4950 		band2 = wlan_reg_freq_to_band(pm_conc_connection_list[1].freq);
4951 		if (band1 == REG_BAND_2G || band2 == REG_BAND_2G) {
4952 			if (!hw_mode.dbs_cap)
4953 				return PM_DBS;
4954 			else
4955 				return PM_NOP;
4956 		} else if (band1 == REG_BAND_5G && band2 == REG_BAND_5G) {
4957 			if (policy_mgr_are_sbs_chan(psoc,
4958 					pm_conc_connection_list[0].freq,
4959 					pm_conc_connection_list[1].freq)) {
4960 				if (!hw_mode.sbs_cap)
4961 					return PM_SBS;
4962 				else
4963 					return PM_NOP;
4964 			} else {
4965 				if (hw_mode.sbs_cap || hw_mode.dbs_cap)
4966 					return PM_SINGLE_MAC;
4967 				else
4968 					return PM_NOP;
4969 			}
4970 		} else
4971 			return PM_NOP;
4972 	case 3:
4973 		band1 = wlan_reg_freq_to_band(pm_conc_connection_list[0].freq);
4974 		band2 = wlan_reg_freq_to_band(pm_conc_connection_list[1].freq);
4975 		band3 = wlan_reg_freq_to_band(pm_conc_connection_list[2].freq);
4976 		if (band1 == REG_BAND_2G || band2 == REG_BAND_2G ||
4977 		    band3 == REG_BAND_2G) {
4978 			if (!hw_mode.dbs_cap)
4979 				return PM_DBS;
4980 			else
4981 				return PM_NOP;
4982 		} else if (band1 == REG_BAND_5G && band2 == REG_BAND_5G &&
4983 			   band3 == REG_BAND_5G) {
4984 			if (policy_mgr_are_sbs_chan(psoc,
4985 					pm_conc_connection_list[0].freq,
4986 					pm_conc_connection_list[2].freq) &&
4987 			    policy_mgr_are_sbs_chan(psoc,
4988 					pm_conc_connection_list[1].freq,
4989 					pm_conc_connection_list[2].freq) &&
4990 			    policy_mgr_are_sbs_chan(psoc,
4991 					pm_conc_connection_list[0].freq,
4992 					pm_conc_connection_list[1].freq)) {
4993 				if (!hw_mode.sbs_cap)
4994 					return PM_SBS;
4995 				else
4996 					return PM_NOP;
4997 			} else {
4998 				if (hw_mode.sbs_cap || hw_mode.dbs_cap)
4999 					return PM_SINGLE_MAC;
5000 				else
5001 					return PM_NOP;
5002 			}
5003 		} else
5004 			return PM_NOP;
5005 	default:
5006 		policy_mgr_err("unexpected num_connections value %d",
5007 				num_connections);
5008 		return PM_NOP;
5009 	}
5010 }
5011 
5012 enum policy_mgr_conc_next_action
policy_mgr_get_current_pref_hw_mode_dbs_1x1(struct wlan_objmgr_psoc * psoc)5013 		policy_mgr_get_current_pref_hw_mode_dbs_1x1(
5014 		struct wlan_objmgr_psoc *psoc)
5015 {
5016 	uint32_t num_connections;
5017 	uint8_t band1, band2, band3;
5018 	struct policy_mgr_hw_mode_params hw_mode;
5019 	QDF_STATUS status;
5020 	enum policy_mgr_conc_next_action next_action;
5021 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5022 
5023 	pm_ctx = policy_mgr_get_context(psoc);
5024 	if (!pm_ctx) {
5025 		policy_mgr_err("Invalid Context");
5026 		return PM_NOP;
5027 	}
5028 
5029 	status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
5030 	if (!QDF_IS_STATUS_SUCCESS(status)) {
5031 		policy_mgr_err("policy_mgr_get_current_hw_mode failed");
5032 		return PM_NOP;
5033 	}
5034 
5035 	num_connections = policy_mgr_get_connection_count(psoc);
5036 
5037 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
5038 	policy_mgr_debug("chan[0]:%d chan[1]:%d chan[2]:%d num_connections:%d dbs:%d",
5039 		pm_conc_connection_list[0].freq,
5040 		pm_conc_connection_list[1].freq,
5041 		pm_conc_connection_list[2].freq, num_connections,
5042 		hw_mode.dbs_cap);
5043 
5044 	/* If the band of operation of both the MACs is the same,
5045 	 * single MAC is preferred, otherwise DBS is preferred.
5046 	 */
5047 	switch (num_connections) {
5048 	case 1:
5049 		/* The driver would already be in the required hw mode */
5050 		next_action = PM_NOP;
5051 		break;
5052 	case 2:
5053 		band1 = wlan_reg_freq_to_band(pm_conc_connection_list[0].freq);
5054 		band2 = wlan_reg_freq_to_band(pm_conc_connection_list[1].freq);
5055 		if ((band1 == band2) && (hw_mode.dbs_cap))
5056 			next_action = PM_SINGLE_MAC_UPGRADE;
5057 		else if ((band1 != band2) && (!hw_mode.dbs_cap))
5058 			next_action = PM_DBS_DOWNGRADE;
5059 		else
5060 			next_action = PM_NOP;
5061 
5062 		break;
5063 
5064 	case 3:
5065 		band1 = wlan_reg_freq_to_band(pm_conc_connection_list[0].freq);
5066 		band2 = wlan_reg_freq_to_band(pm_conc_connection_list[1].freq);
5067 		band3 = wlan_reg_freq_to_band(pm_conc_connection_list[2].freq);
5068 		if (((band1 == band2) && (band2 == band3)) &&
5069 				(hw_mode.dbs_cap)) {
5070 			next_action = PM_SINGLE_MAC_UPGRADE;
5071 		} else if (((band1 != band2) || (band2 != band3) ||
5072 					(band1 != band3)) &&
5073 					(!hw_mode.dbs_cap)) {
5074 			next_action = PM_DBS_DOWNGRADE;
5075 		} else {
5076 			next_action = PM_NOP;
5077 		}
5078 		break;
5079 	default:
5080 		policy_mgr_err("unexpected num_connections value %d",
5081 				num_connections);
5082 		next_action = PM_NOP;
5083 		break;
5084 	}
5085 
5086 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
5087 
5088 	return next_action;
5089 }
5090 
5091 enum policy_mgr_conc_next_action
policy_mgr_get_current_pref_hw_mode_dual_dbs(struct wlan_objmgr_psoc * psoc)5092 policy_mgr_get_current_pref_hw_mode_dual_dbs(
5093 	struct wlan_objmgr_psoc *psoc)
5094 {
5095 	enum policy_mgr_conc_next_action next_action;
5096 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5097 	enum policy_mgr_conc_next_action preferred_dbs;
5098 
5099 	pm_ctx = policy_mgr_get_context(psoc);
5100 	if (!pm_ctx) {
5101 		policy_mgr_err("Invalid Context");
5102 		return PM_NOP;
5103 	}
5104 
5105 	next_action = policy_mgr_get_current_pref_hw_mode_dbs_1x1(psoc);
5106 	policy_mgr_info("next_action %d", next_action);
5107 	if (next_action != PM_DBS_DOWNGRADE)
5108 		return next_action;
5109 
5110 	preferred_dbs = policy_mgr_get_preferred_dbs_action_table(
5111 				psoc, INVALID_VDEV_ID, 0, 0);
5112 	if (preferred_dbs == PM_DBS1) {
5113 		next_action = PM_DBS1_DOWNGRADE;
5114 	} else if (preferred_dbs == PM_DBS2) {
5115 		next_action = PM_DBS2_DOWNGRADE;
5116 	} else {
5117 		policy_mgr_err("DBS1 and DBS2 hw mode not supported");
5118 		return PM_NOP;
5119 	}
5120 	policy_mgr_info("preferred_dbs %d", next_action);
5121 	return next_action;
5122 }
5123 
policy_mgr_add_sap_mandatory_chan(struct wlan_objmgr_psoc * psoc,uint32_t ch_freq)5124 void policy_mgr_add_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc,
5125 				       uint32_t ch_freq)
5126 {
5127 	int i;
5128 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5129 
5130 	pm_ctx = policy_mgr_get_context(psoc);
5131 	if (!pm_ctx) {
5132 		policy_mgr_err("Invalid Context");
5133 		return;
5134 	}
5135 
5136 	for (i = 0; i < pm_ctx->sap_mandatory_channels_len; i++) {
5137 		if (ch_freq == pm_ctx->sap_mandatory_channels[i])
5138 			return;
5139 	}
5140 	if (pm_ctx->sap_mandatory_channels_len >= NUM_CHANNELS) {
5141 		policy_mgr_err("mand list overflow (%u)", ch_freq);
5142 		return;
5143 	}
5144 
5145 	policy_mgr_debug("Ch freq: %u", ch_freq);
5146 
5147 	pm_ctx->sap_mandatory_channels[pm_ctx->sap_mandatory_channels_len++]
5148 		= ch_freq;
5149 }
5150 
policy_mgr_get_sap_mandatory_chan_list_len(struct wlan_objmgr_psoc * psoc)5151 uint32_t policy_mgr_get_sap_mandatory_chan_list_len(
5152 		struct wlan_objmgr_psoc *psoc)
5153 {
5154 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5155 
5156 	pm_ctx = policy_mgr_get_context(psoc);
5157 	if (!pm_ctx) {
5158 		policy_mgr_err("Invalid Context");
5159 		return 0;
5160 	}
5161 
5162 	return pm_ctx->sap_mandatory_channels_len;
5163 }
5164 
5165 #if defined(CONFIG_BAND_6GHZ)
5166 /**
5167  * policy_mgr_add_sap_mandatory_6ghz_chan() - Add 6GHz SAP mandatory channel
5168  * list
5169  * @psoc: Pointer to soc
5170  *
5171  * Add the 6GHz PSC VLP channel to SAP mandatory channel list.
5172  *
5173  * Return: None
5174  */
5175 static
policy_mgr_add_sap_mandatory_6ghz_chan(struct wlan_objmgr_psoc * psoc)5176 void  policy_mgr_add_sap_mandatory_6ghz_chan(struct wlan_objmgr_psoc *psoc)
5177 {
5178 	uint32_t ch_freq_list[NUM_CHANNELS] = {0};
5179 	uint32_t len = 0;
5180 	int i;
5181 	QDF_STATUS status;
5182 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5183 	bool is_psd;
5184 	uint16_t tx_power;
5185 	uint16_t eirp_psd_power;
5186 
5187 	pm_ctx = policy_mgr_get_context(psoc);
5188 	if (!pm_ctx) {
5189 		policy_mgr_err("Invalid Context");
5190 		return;
5191 	}
5192 
5193 	status = policy_mgr_get_valid_chans(psoc, ch_freq_list, &len);
5194 	if (QDF_IS_STATUS_ERROR(status)) {
5195 		policy_mgr_err("Error in getting valid channels");
5196 		return;
5197 	}
5198 
5199 	for (i = 0; (i < len) && (i < NUM_CHANNELS) &&
5200 		    (pm_ctx->sap_mandatory_channels_len < NUM_CHANNELS); i++) {
5201 		if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq_list[i]))
5202 			continue;
5203 		if (WLAN_REG_IS_6GHZ_PSC_CHAN_FREQ(ch_freq_list[i])) {
5204 			status = wlan_reg_get_6g_chan_ap_power(
5205 				pm_ctx->pdev, ch_freq_list[i], &is_psd,
5206 				&tx_power, &eirp_psd_power);
5207 			if (status != QDF_STATUS_SUCCESS || !tx_power)
5208 				continue;
5209 
5210 			policy_mgr_debug("Add chan %u to mandatory list",
5211 					 ch_freq_list[i]);
5212 			pm_ctx->sap_mandatory_channels[
5213 				pm_ctx->sap_mandatory_channels_len++] =
5214 				ch_freq_list[i];
5215 		}
5216 	}
5217 }
5218 #else
5219 static inline
policy_mgr_add_sap_mandatory_6ghz_chan(struct wlan_objmgr_psoc * psoc)5220 void  policy_mgr_add_sap_mandatory_6ghz_chan(struct wlan_objmgr_psoc *psoc)
5221 {
5222 }
5223 #endif
5224 
5225 /**
5226  * policy_mgr_init_sap_mandatory_chan_by_band() - Init SAP mandatory channel
5227  * list based on band
5228  * @psoc: Pointer to soc
5229  * @band_bitmap: band bitmap of type reg_wifi_band
5230  *
5231  * Initialize the 2.4G 5G 6G SAP mandatory channels based on band
5232  *
5233  * Return: None
5234  */
5235 static void
policy_mgr_init_sap_mandatory_chan_by_band(struct wlan_objmgr_psoc * psoc,uint32_t band_bitmap)5236 policy_mgr_init_sap_mandatory_chan_by_band(struct wlan_objmgr_psoc *psoc,
5237 					   uint32_t band_bitmap)
5238 {
5239 	uint32_t ch_freq_list[NUM_CHANNELS] = {0};
5240 	uint32_t len = 0;
5241 	int i;
5242 	QDF_STATUS status;
5243 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5244 
5245 	pm_ctx = policy_mgr_get_context(psoc);
5246 	if (!pm_ctx) {
5247 		policy_mgr_err("Invalid Context");
5248 		return;
5249 	}
5250 
5251 	status = policy_mgr_get_valid_chans(psoc, ch_freq_list, &len);
5252 	if (QDF_IS_STATUS_ERROR(status)) {
5253 		policy_mgr_err("Error in getting valid channels");
5254 		return;
5255 	}
5256 	pm_ctx->sap_mandatory_channels_len = 0;
5257 	for (i = 0; (i < len) && (i < NUM_CHANNELS); i++) {
5258 		if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq_list[i])) {
5259 			policy_mgr_debug("Add chan %u to mandatory list",
5260 					ch_freq_list[i]);
5261 			pm_ctx->sap_mandatory_channels[
5262 				pm_ctx->sap_mandatory_channels_len++] =
5263 				ch_freq_list[i];
5264 		}
5265 	}
5266 	if (band_bitmap & BIT(REG_BAND_5G))
5267 		for (i = 0; i < ARRAY_SIZE(sap_mand_5g_freq_list); i++)
5268 			policy_mgr_add_sap_mandatory_chan(
5269 				psoc, sap_mand_5g_freq_list[i]);
5270 	if (band_bitmap & BIT(REG_BAND_6G))
5271 		policy_mgr_add_sap_mandatory_6ghz_chan(psoc);
5272 }
5273 
policy_mgr_init_sap_mandatory_chan(struct wlan_objmgr_psoc * psoc,uint32_t org_ch_freq)5274 void  policy_mgr_init_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc,
5275 					 uint32_t org_ch_freq)
5276 {
5277 	if (WLAN_REG_IS_5GHZ_CH_FREQ(org_ch_freq)) {
5278 		policy_mgr_debug("channel %u, sap mandatory chan list enabled",
5279 				 org_ch_freq);
5280 		policy_mgr_init_sap_mandatory_chan_by_band(
5281 			psoc, BIT(REG_BAND_2G) | BIT(REG_BAND_5G));
5282 		policy_mgr_add_sap_mandatory_chan(
5283 			psoc, org_ch_freq);
5284 	} else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(org_ch_freq)) {
5285 		policy_mgr_init_sap_mandatory_chan_by_band(
5286 				psoc,
5287 				BIT(REG_BAND_2G) | BIT(REG_BAND_5G) |
5288 				BIT(REG_BAND_6G));
5289 	} else {
5290 		policy_mgr_init_sap_mandatory_chan_by_band(
5291 				psoc, BIT(REG_BAND_2G));
5292 	}
5293 }
5294 
policy_mgr_remove_sap_mandatory_chan(struct wlan_objmgr_psoc * psoc,uint32_t ch_freq)5295 void policy_mgr_remove_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc,
5296 					  uint32_t ch_freq)
5297 {
5298 	uint32_t ch_freq_list[NUM_CHANNELS] = {0};
5299 	uint32_t num_chan = 0;
5300 	int i;
5301 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5302 
5303 	pm_ctx = policy_mgr_get_context(psoc);
5304 	if (!pm_ctx) {
5305 		policy_mgr_err("Invalid Context");
5306 		return;
5307 	}
5308 
5309 	if (pm_ctx->sap_mandatory_channels_len >= NUM_CHANNELS) {
5310 		policy_mgr_err("Invalid channel len %d ",
5311 				pm_ctx->sap_mandatory_channels_len);
5312 		return;
5313 	}
5314 
5315 	for (i = 0; i < pm_ctx->sap_mandatory_channels_len; i++) {
5316 		if (ch_freq == pm_ctx->sap_mandatory_channels[i])
5317 			continue;
5318 		ch_freq_list[num_chan++] = pm_ctx->sap_mandatory_channels[i];
5319 	}
5320 
5321 	qdf_mem_zero(pm_ctx->sap_mandatory_channels,
5322 		     pm_ctx->sap_mandatory_channels_len *
5323 		     sizeof(*pm_ctx->sap_mandatory_channels));
5324 	qdf_mem_copy(pm_ctx->sap_mandatory_channels, ch_freq_list,
5325 		     num_chan * sizeof(*pm_ctx->sap_mandatory_channels));
5326 	pm_ctx->sap_mandatory_channels_len = num_chan;
5327 }
5328