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_get_set_utils.c
22  *
23  * WLAN Concurrenct Connection Management APIs
24  *
25  */
26 
27 /* Include files */
28 #include "target_if.h"
29 #include "wlan_policy_mgr_api.h"
30 #include "wlan_policy_mgr_i.h"
31 #include "qdf_types.h"
32 #include "qdf_trace.h"
33 #include "wlan_objmgr_global_obj.h"
34 #include "wlan_objmgr_pdev_obj.h"
35 #include "wlan_objmgr_vdev_obj.h"
36 #include "wlan_nan_api.h"
37 #include "nan_public_structs.h"
38 #include "wlan_reg_services_api.h"
39 #include "wlan_cm_roam_public_struct.h"
40 #include "wlan_mlme_api.h"
41 #include "wlan_mlme_main.h"
42 #include "wlan_mlme_vdev_mgr_interface.h"
43 #include "wlan_mlo_mgr_sta.h"
44 #include "wlan_cm_ucfg_api.h"
45 #include "wlan_cm_roam_api.h"
46 #include "wlan_mlme_ucfg_api.h"
47 #include "wlan_p2p_ucfg_api.h"
48 #include "wlan_mlo_link_force.h"
49 #include "wlan_connectivity_logging.h"
50 #include "wlan_policy_mgr_ll_sap.h"
51 
52 /* invalid channel id. */
53 #define INVALID_CHANNEL_ID 0
54 
55 #define IS_FREQ_ON_MAC_ID(freq_range, freq, mac_id) \
56 	((freq >= freq_range[mac_id].low_2ghz_freq && \
57 	  freq <= freq_range[mac_id].high_2ghz_freq) || \
58 	(freq >= freq_range[mac_id].low_5ghz_freq && \
59 	 freq <= freq_range[mac_id].high_5ghz_freq))
60 
61 /**
62  * policy_mgr_debug_alert() - fatal error alert
63  *
64  * This function will flush host drv log and
65  * disable all level logs.
66  * It can be called in fatal error detected in policy
67  * manager.
68  * This is to avoid host log overwritten in stress
69  * test to help issue debug.
70  *
71  * Return: none
72  */
73 static void
policy_mgr_debug_alert(void)74 policy_mgr_debug_alert(void)
75 {
76 	int module_id;
77 	int qdf_print_idx;
78 
79 	policy_mgr_err("fatal error detected to flush and pause host log");
80 	qdf_logging_flush_logs();
81 	qdf_print_idx = qdf_get_pidx();
82 	for (module_id = 0; module_id < QDF_MODULE_ID_MAX; module_id++)
83 		qdf_print_set_category_verbose(
84 					qdf_print_idx,
85 					module_id, QDF_TRACE_LEVEL_NONE,
86 					0);
87 }
88 
89 QDF_STATUS
policy_mgr_get_allow_mcc_go_diff_bi(struct wlan_objmgr_psoc * psoc,uint8_t * allow_mcc_go_diff_bi)90 policy_mgr_get_allow_mcc_go_diff_bi(struct wlan_objmgr_psoc *psoc,
91 				    uint8_t *allow_mcc_go_diff_bi)
92 {
93 	struct policy_mgr_psoc_priv_obj *pm_ctx;
94 
95 	pm_ctx = policy_mgr_get_context(psoc);
96 	if (!pm_ctx) {
97 		policy_mgr_err("pm_ctx is NULL");
98 		return QDF_STATUS_E_FAILURE;
99 	}
100 	*allow_mcc_go_diff_bi = pm_ctx->cfg.allow_mcc_go_diff_bi;
101 
102 	return QDF_STATUS_SUCCESS;
103 }
104 
policy_mgr_set_dual_mac_feature(struct wlan_objmgr_psoc * psoc,uint8_t dual_mac_feature)105 QDF_STATUS policy_mgr_set_dual_mac_feature(struct wlan_objmgr_psoc *psoc,
106 					   uint8_t dual_mac_feature)
107 {
108 	struct policy_mgr_psoc_priv_obj *pm_ctx;
109 
110 	pm_ctx = policy_mgr_get_context(psoc);
111 	if (!pm_ctx) {
112 		policy_mgr_err("pm_ctx is NULL");
113 		return QDF_STATUS_E_FAILURE;
114 	}
115 
116 	pm_ctx->cfg.dual_mac_feature = dual_mac_feature;
117 
118 	return QDF_STATUS_SUCCESS;
119 }
120 
policy_mgr_get_dual_mac_feature(struct wlan_objmgr_psoc * psoc,uint8_t * dual_mac_feature)121 QDF_STATUS policy_mgr_get_dual_mac_feature(struct wlan_objmgr_psoc *psoc,
122 					   uint8_t *dual_mac_feature)
123 {
124 	struct policy_mgr_psoc_priv_obj *pm_ctx;
125 
126 	pm_ctx = policy_mgr_get_context(psoc);
127 	if (!pm_ctx) {
128 		policy_mgr_err("pm_ctx is NULL");
129 		return QDF_STATUS_E_FAILURE;
130 	}
131 	*dual_mac_feature = pm_ctx->cfg.dual_mac_feature;
132 
133 	return QDF_STATUS_SUCCESS;
134 }
135 
policy_mgr_get_force_1x1(struct wlan_objmgr_psoc * psoc,uint8_t * force_1x1)136 QDF_STATUS policy_mgr_get_force_1x1(struct wlan_objmgr_psoc *psoc,
137 				    uint8_t *force_1x1)
138 {
139 	struct policy_mgr_psoc_priv_obj *pm_ctx;
140 
141 	pm_ctx = policy_mgr_get_context(psoc);
142 	if (!pm_ctx) {
143 		policy_mgr_err("pm_ctx is NULL");
144 		return QDF_STATUS_E_FAILURE;
145 	}
146 	*force_1x1 = pm_ctx->cfg.is_force_1x1_enable;
147 
148 	return QDF_STATUS_SUCCESS;
149 }
150 
policy_mgr_get_max_conc_cxns(struct wlan_objmgr_psoc * psoc)151 uint32_t policy_mgr_get_max_conc_cxns(struct wlan_objmgr_psoc *psoc)
152 {
153 	struct policy_mgr_psoc_priv_obj *pm_ctx;
154 
155 	pm_ctx = policy_mgr_get_context(psoc);
156 	if (!pm_ctx) {
157 		policy_mgr_err("pm_ctx is NULL");
158 		return 0;
159 	}
160 
161 	return pm_ctx->cfg.max_conc_cxns;
162 }
163 
policy_mgr_set_max_conc_cxns(struct wlan_objmgr_psoc * psoc,uint32_t max_conc_cxns)164 QDF_STATUS policy_mgr_set_max_conc_cxns(struct wlan_objmgr_psoc *psoc,
165 					uint32_t max_conc_cxns)
166 {
167 	struct policy_mgr_psoc_priv_obj *pm_ctx;
168 
169 	pm_ctx = policy_mgr_get_context(psoc);
170 	if (!pm_ctx) {
171 		policy_mgr_err("pm_ctx is NULL");
172 		return QDF_STATUS_E_FAILURE;
173 	}
174 
175 	policy_mgr_debug("set max_conc_cxns %d old %d", max_conc_cxns,
176 			 pm_ctx->cfg.max_conc_cxns);
177 	pm_ctx->cfg.max_conc_cxns = max_conc_cxns;
178 
179 	return QDF_STATUS_SUCCESS;
180 }
181 
182 QDF_STATUS
policy_mgr_set_sta_sap_scc_on_dfs_chnl(struct wlan_objmgr_psoc * psoc,uint8_t sta_sap_scc_on_dfs_chnl)183 policy_mgr_set_sta_sap_scc_on_dfs_chnl(struct wlan_objmgr_psoc *psoc,
184 				       uint8_t sta_sap_scc_on_dfs_chnl)
185 {
186 	struct policy_mgr_psoc_priv_obj *pm_ctx;
187 
188 	pm_ctx = policy_mgr_get_context(psoc);
189 	if (!pm_ctx) {
190 		policy_mgr_err("pm_ctx is NULL");
191 		return QDF_STATUS_E_FAILURE;
192 	}
193 	pm_ctx->cfg.sta_sap_scc_on_dfs_chnl = sta_sap_scc_on_dfs_chnl;
194 
195 	return QDF_STATUS_SUCCESS;
196 }
197 
198 QDF_STATUS
policy_mgr_get_sta_sap_scc_on_dfs_chnl(struct wlan_objmgr_psoc * psoc,uint8_t * sta_sap_scc_on_dfs_chnl)199 policy_mgr_get_sta_sap_scc_on_dfs_chnl(struct wlan_objmgr_psoc *psoc,
200 				       uint8_t *sta_sap_scc_on_dfs_chnl)
201 {
202 	struct policy_mgr_psoc_priv_obj *pm_ctx;
203 
204 	pm_ctx = policy_mgr_get_context(psoc);
205 	if (!pm_ctx) {
206 		policy_mgr_err("pm_ctx is NULL");
207 		return QDF_STATUS_E_FAILURE;
208 	}
209 	*sta_sap_scc_on_dfs_chnl = pm_ctx->cfg.sta_sap_scc_on_dfs_chnl;
210 
211 	return QDF_STATUS_SUCCESS;
212 }
213 
214 bool
policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(struct wlan_objmgr_psoc * psoc)215 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(struct wlan_objmgr_psoc *psoc)
216 {
217 	struct policy_mgr_psoc_priv_obj *pm_ctx;
218 
219 	pm_ctx = policy_mgr_get_context(psoc);
220 	if (!pm_ctx) {
221 		policy_mgr_err("pm_ctx is NULL");
222 		return false;
223 	}
224 
225 	return pm_ctx->cfg.sta_sap_scc_on_indoor_channel;
226 }
227 
228 QDF_STATUS
policy_mgr_set_multi_sap_allowed_on_same_band(struct wlan_objmgr_psoc * psoc,bool multi_sap_allowed_on_same_band)229 policy_mgr_set_multi_sap_allowed_on_same_band(struct wlan_objmgr_psoc *psoc,
230 					bool multi_sap_allowed_on_same_band)
231 {
232 	struct policy_mgr_psoc_priv_obj *pm_ctx;
233 
234 	pm_ctx = policy_mgr_get_context(psoc);
235 	if (!pm_ctx) {
236 		policy_mgr_err("pm_ctx is NULL");
237 		return QDF_STATUS_E_FAILURE;
238 	}
239 	pm_ctx->cfg.multi_sap_allowed_on_same_band =
240 				multi_sap_allowed_on_same_band;
241 
242 	return QDF_STATUS_SUCCESS;
243 }
244 
245 QDF_STATUS
policy_mgr_get_multi_sap_allowed_on_same_band(struct wlan_objmgr_psoc * psoc,bool * multi_sap_allowed_on_same_band)246 policy_mgr_get_multi_sap_allowed_on_same_band(struct wlan_objmgr_psoc *psoc,
247 					bool *multi_sap_allowed_on_same_band)
248 {
249 	struct policy_mgr_psoc_priv_obj *pm_ctx;
250 
251 	pm_ctx = policy_mgr_get_context(psoc);
252 	if (!pm_ctx) {
253 		policy_mgr_err("pm_ctx is NULL");
254 		return QDF_STATUS_E_FAILURE;
255 	}
256 	*multi_sap_allowed_on_same_band =
257 				pm_ctx->cfg.multi_sap_allowed_on_same_band;
258 
259 	return QDF_STATUS_SUCCESS;
260 }
261 
262 QDF_STATUS
policy_mgr_set_original_bw_for_sap_restart(struct wlan_objmgr_psoc * psoc,bool use_sap_original_bw)263 policy_mgr_set_original_bw_for_sap_restart(struct wlan_objmgr_psoc *psoc,
264 					   bool use_sap_original_bw)
265 {
266 	struct policy_mgr_psoc_priv_obj *pm_ctx;
267 
268 	pm_ctx = policy_mgr_get_context(psoc);
269 	if (!pm_ctx) {
270 		policy_mgr_err("pm_ctx is NULL");
271 		return QDF_STATUS_E_FAILURE;
272 	}
273 	pm_ctx->cfg.use_sap_original_bw = use_sap_original_bw;
274 
275 	return QDF_STATUS_SUCCESS;
276 }
277 
278 QDF_STATUS
policy_mgr_get_original_bw_for_sap_restart(struct wlan_objmgr_psoc * psoc,bool * use_sap_original_bw)279 policy_mgr_get_original_bw_for_sap_restart(struct wlan_objmgr_psoc *psoc,
280 					   bool *use_sap_original_bw)
281 {
282 	struct policy_mgr_psoc_priv_obj *pm_ctx;
283 
284 	pm_ctx = policy_mgr_get_context(psoc);
285 	if (!pm_ctx) {
286 		policy_mgr_err("pm_ctx is NULL");
287 		return QDF_STATUS_E_FAILURE;
288 	}
289 	*use_sap_original_bw = pm_ctx->cfg.use_sap_original_bw;
290 
291 	return QDF_STATUS_SUCCESS;
292 }
293 
294 QDF_STATUS
policy_mgr_get_dfs_sta_sap_go_scc_movement(struct wlan_objmgr_psoc * psoc,bool * move_sap_go_first)295 policy_mgr_get_dfs_sta_sap_go_scc_movement(struct wlan_objmgr_psoc *psoc,
296 					   bool *move_sap_go_first)
297 {
298 	struct policy_mgr_psoc_priv_obj *pm_ctx;
299 
300 	pm_ctx = policy_mgr_get_context(psoc);
301 	if (!pm_ctx) {
302 		policy_mgr_err("pm_ctx is NULL");
303 		return QDF_STATUS_E_FAILURE;
304 	}
305 	*move_sap_go_first = pm_ctx->cfg.move_sap_go_1st_on_dfs_sta_csa;
306 
307 	return QDF_STATUS_SUCCESS;
308 }
309 
310 static bool
policy_mgr_update_dfs_master_dynamic_enabled(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)311 policy_mgr_update_dfs_master_dynamic_enabled(
312 	struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
313 {
314 	struct policy_mgr_psoc_priv_obj *pm_ctx;
315 	bool sta_on_5g = false;
316 	bool sta_on_2g = false;
317 	uint32_t i;
318 	bool enable = true;
319 
320 	pm_ctx = policy_mgr_get_context(psoc);
321 	if (!pm_ctx) {
322 		policy_mgr_err("pm_ctx is NULL");
323 		return true;
324 	}
325 
326 	if (!pm_ctx->cfg.sta_sap_scc_on_dfs_chnl) {
327 		enable = true;
328 		goto end;
329 	}
330 	if (pm_ctx->cfg.sta_sap_scc_on_dfs_chnl ==
331 	    PM_STA_SAP_ON_DFS_MASTER_MODE_DISABLED) {
332 		enable = false;
333 		goto end;
334 	}
335 	if (pm_ctx->cfg.sta_sap_scc_on_dfs_chnl !=
336 	    PM_STA_SAP_ON_DFS_MASTER_MODE_FLEX) {
337 		policy_mgr_debug("sta_sap_scc_on_dfs_chnl %d unknown",
338 				 pm_ctx->cfg.sta_sap_scc_on_dfs_chnl);
339 		enable = true;
340 		goto end;
341 	}
342 
343 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
344 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
345 		if (!((pm_conc_connection_list[i].vdev_id != vdev_id) &&
346 		      pm_conc_connection_list[i].in_use &&
347 		      (pm_conc_connection_list[i].mode == PM_STA_MODE ||
348 		       pm_conc_connection_list[i].mode == PM_P2P_CLIENT_MODE)))
349 			continue;
350 		if (WLAN_REG_IS_5GHZ_CH_FREQ(pm_conc_connection_list[i].freq))
351 			sta_on_5g = true;
352 		else
353 			sta_on_2g = true;
354 	}
355 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
356 
357 	if (policy_mgr_is_hw_dbs_capable(psoc) && !sta_on_5g)
358 		enable = true;
359 	else if (!sta_on_5g && !sta_on_2g)
360 		enable = true;
361 	else
362 		enable = false;
363 end:
364 	pm_ctx->dynamic_dfs_master_disabled = !enable;
365 	if (!enable)
366 		policy_mgr_debug("sta_sap_scc_on_dfs_chnl %d sta_on_2g %d sta_on_5g %d enable %d",
367 				 pm_ctx->cfg.sta_sap_scc_on_dfs_chnl, sta_on_2g,
368 				 sta_on_5g, enable);
369 
370 	return enable;
371 }
372 
373 bool
policy_mgr_get_dfs_master_dynamic_enabled(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)374 policy_mgr_get_dfs_master_dynamic_enabled(
375 	struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
376 {
377 	struct policy_mgr_psoc_priv_obj *pm_ctx;
378 
379 	pm_ctx = policy_mgr_get_context(psoc);
380 	if (!pm_ctx) {
381 		policy_mgr_err("pm_ctx is NULL");
382 		return true;
383 	}
384 
385 	return policy_mgr_update_dfs_master_dynamic_enabled(psoc, vdev_id);
386 }
387 
388 bool
policy_mgr_get_can_skip_radar_event(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)389 policy_mgr_get_can_skip_radar_event(struct wlan_objmgr_psoc *psoc,
390 				    uint8_t vdev_id)
391 {
392 	struct policy_mgr_psoc_priv_obj *pm_ctx;
393 
394 	pm_ctx = policy_mgr_get_context(psoc);
395 	if (!pm_ctx) {
396 		policy_mgr_err("pm_ctx is NULL");
397 		return false;
398 	}
399 
400 	return pm_ctx->dynamic_dfs_master_disabled;
401 }
402 
403 QDF_STATUS
policy_mgr_get_sta_sap_scc_lte_coex_chnl(struct wlan_objmgr_psoc * psoc,uint8_t * sta_sap_scc_lte_coex)404 policy_mgr_get_sta_sap_scc_lte_coex_chnl(struct wlan_objmgr_psoc *psoc,
405 					 uint8_t *sta_sap_scc_lte_coex)
406 {
407 	struct policy_mgr_psoc_priv_obj *pm_ctx;
408 
409 	pm_ctx = policy_mgr_get_context(psoc);
410 	if (!pm_ctx) {
411 		policy_mgr_err("pm_ctx is NULL");
412 		return QDF_STATUS_E_FAILURE;
413 	}
414 	*sta_sap_scc_lte_coex = pm_ctx->cfg.sta_sap_scc_on_lte_coex_chnl;
415 
416 	return QDF_STATUS_SUCCESS;
417 }
418 
policy_mgr_get_sap_mandt_chnl(struct wlan_objmgr_psoc * psoc,uint8_t * sap_mandt_chnl)419 QDF_STATUS policy_mgr_get_sap_mandt_chnl(struct wlan_objmgr_psoc *psoc,
420 					 uint8_t *sap_mandt_chnl)
421 {
422 	struct policy_mgr_psoc_priv_obj *pm_ctx;
423 
424 	pm_ctx = policy_mgr_get_context(psoc);
425 	if (!pm_ctx) {
426 		policy_mgr_err("pm_ctx is NULL");
427 		return QDF_STATUS_E_FAILURE;
428 	}
429 	*sap_mandt_chnl = pm_ctx->cfg.sap_mandatory_chnl_enable;
430 
431 	return QDF_STATUS_SUCCESS;
432 }
433 
434 QDF_STATUS
policy_mgr_get_indoor_chnl_marking(struct wlan_objmgr_psoc * psoc,uint8_t * indoor_chnl_marking)435 policy_mgr_get_indoor_chnl_marking(struct wlan_objmgr_psoc *psoc,
436 				   uint8_t *indoor_chnl_marking)
437 {
438 	struct policy_mgr_psoc_priv_obj *pm_ctx;
439 
440 	pm_ctx = policy_mgr_get_context(psoc);
441 	if (!pm_ctx) {
442 		policy_mgr_err("pm_ctx is NULL");
443 		return QDF_STATUS_E_FAILURE;
444 	}
445 	*indoor_chnl_marking = pm_ctx->cfg.mark_indoor_chnl_disable;
446 
447 	return QDF_STATUS_SUCCESS;
448 }
449 
policy_mgr_get_mcc_scc_switch(struct wlan_objmgr_psoc * psoc,uint8_t * mcc_scc_switch)450 QDF_STATUS policy_mgr_get_mcc_scc_switch(struct wlan_objmgr_psoc *psoc,
451 					      uint8_t *mcc_scc_switch)
452 {
453 	struct policy_mgr_psoc_priv_obj *pm_ctx;
454 
455 	pm_ctx = policy_mgr_get_context(psoc);
456 	if (!pm_ctx) {
457 		policy_mgr_err("pm_ctx is NULL");
458 		return QDF_STATUS_E_FAILURE;
459 	}
460 	*mcc_scc_switch = pm_ctx->cfg.mcc_to_scc_switch;
461 
462 	return QDF_STATUS_SUCCESS;
463 }
464 
policy_mgr_get_sys_pref(struct wlan_objmgr_psoc * psoc,uint8_t * sys_pref)465 QDF_STATUS policy_mgr_get_sys_pref(struct wlan_objmgr_psoc *psoc,
466 					uint8_t *sys_pref)
467 {
468 	struct policy_mgr_psoc_priv_obj *pm_ctx;
469 
470 	pm_ctx = policy_mgr_get_context(psoc);
471 	if (!pm_ctx) {
472 		policy_mgr_err("pm_ctx is NULL");
473 		return QDF_STATUS_E_FAILURE;
474 	}
475 	*sys_pref = pm_ctx->cfg.sys_pref;
476 
477 	return QDF_STATUS_SUCCESS;
478 }
479 
policy_mgr_set_sys_pref(struct wlan_objmgr_psoc * psoc,uint8_t sys_pref)480 QDF_STATUS policy_mgr_set_sys_pref(struct wlan_objmgr_psoc *psoc,
481 				   uint8_t sys_pref)
482 {
483 	struct policy_mgr_psoc_priv_obj *pm_ctx;
484 
485 	pm_ctx = policy_mgr_get_context(psoc);
486 	if (!pm_ctx) {
487 		policy_mgr_err("pm_ctx is NULL");
488 		return QDF_STATUS_E_FAILURE;
489 	}
490 	pm_ctx->cfg.sys_pref = sys_pref;
491 
492 	return QDF_STATUS_SUCCESS;
493 }
494 
policy_mgr_get_conc_rule1(struct wlan_objmgr_psoc * psoc,uint8_t * conc_rule1)495 QDF_STATUS policy_mgr_get_conc_rule1(struct wlan_objmgr_psoc *psoc,
496 						uint8_t *conc_rule1)
497 {
498 	struct policy_mgr_psoc_priv_obj *pm_ctx;
499 
500 	pm_ctx = policy_mgr_get_context(psoc);
501 	if (!pm_ctx) {
502 		policy_mgr_err("pm_ctx is NULL");
503 		return QDF_STATUS_E_FAILURE;
504 	}
505 	*conc_rule1 = pm_ctx->cfg.conc_rule1;
506 
507 	return QDF_STATUS_SUCCESS;
508 }
509 
policy_mgr_get_conc_rule2(struct wlan_objmgr_psoc * psoc,uint8_t * conc_rule2)510 QDF_STATUS policy_mgr_get_conc_rule2(struct wlan_objmgr_psoc *psoc,
511 						uint8_t *conc_rule2)
512 {
513 	struct policy_mgr_psoc_priv_obj *pm_ctx;
514 
515 	pm_ctx = policy_mgr_get_context(psoc);
516 	if (!pm_ctx) {
517 		policy_mgr_err("pm_ctx is NULL");
518 		return QDF_STATUS_E_FAILURE;
519 	}
520 	*conc_rule2 = pm_ctx->cfg.conc_rule2;
521 
522 	return QDF_STATUS_SUCCESS;
523 }
524 
policy_mgr_get_chnl_select_plcy(struct wlan_objmgr_psoc * psoc,uint32_t * chnl_select_plcy)525 QDF_STATUS policy_mgr_get_chnl_select_plcy(struct wlan_objmgr_psoc *psoc,
526 					   uint32_t *chnl_select_plcy)
527 {
528 	struct policy_mgr_psoc_priv_obj *pm_ctx;
529 
530 	pm_ctx = policy_mgr_get_context(psoc);
531 	if (!pm_ctx) {
532 		policy_mgr_err("pm_ctx is NULL");
533 		return QDF_STATUS_E_FAILURE;
534 	}
535 	*chnl_select_plcy = pm_ctx->cfg.chnl_select_plcy;
536 
537 	return QDF_STATUS_SUCCESS;
538 }
539 
policy_mgr_set_ch_select_plcy(struct wlan_objmgr_psoc * psoc,uint32_t ch_select_policy)540 QDF_STATUS policy_mgr_set_ch_select_plcy(struct wlan_objmgr_psoc *psoc,
541 					 uint32_t ch_select_policy)
542 {
543 	struct policy_mgr_psoc_priv_obj *pm_ctx;
544 
545 	pm_ctx = policy_mgr_get_context(psoc);
546 	if (!pm_ctx) {
547 		policy_mgr_err("pm_ctx is NULL");
548 		return QDF_STATUS_E_FAILURE;
549 	}
550 	pm_ctx->cfg.chnl_select_plcy = ch_select_policy;
551 
552 	return QDF_STATUS_SUCCESS;
553 }
554 
policy_mgr_set_dynamic_mcc_adaptive_sch(struct wlan_objmgr_psoc * psoc,bool dynamic_mcc_adaptive_sched)555 QDF_STATUS policy_mgr_set_dynamic_mcc_adaptive_sch(
556 				struct wlan_objmgr_psoc *psoc,
557 				bool dynamic_mcc_adaptive_sched)
558 {
559 	struct policy_mgr_psoc_priv_obj *pm_ctx;
560 
561 	pm_ctx = policy_mgr_get_context(psoc);
562 	if (!pm_ctx) {
563 		policy_mgr_err("pm_ctx is NULL");
564 		return QDF_STATUS_E_FAILURE;
565 	}
566 	pm_ctx->dynamic_mcc_adaptive_sched = dynamic_mcc_adaptive_sched;
567 
568 	return QDF_STATUS_SUCCESS;
569 }
570 
policy_mgr_get_dynamic_mcc_adaptive_sch(struct wlan_objmgr_psoc * psoc,bool * dynamic_mcc_adaptive_sched)571 QDF_STATUS policy_mgr_get_dynamic_mcc_adaptive_sch(
572 				struct wlan_objmgr_psoc *psoc,
573 				bool *dynamic_mcc_adaptive_sched)
574 {
575 	struct policy_mgr_psoc_priv_obj *pm_ctx;
576 
577 	pm_ctx = policy_mgr_get_context(psoc);
578 	if (!pm_ctx) {
579 		policy_mgr_err("pm_ctx is NULL");
580 		return QDF_STATUS_E_FAILURE;
581 	}
582 	*dynamic_mcc_adaptive_sched = pm_ctx->dynamic_mcc_adaptive_sched;
583 
584 	return QDF_STATUS_SUCCESS;
585 }
586 
policy_mgr_get_mcc_adaptive_sch(struct wlan_objmgr_psoc * psoc,bool * enable_mcc_adaptive_sch)587 QDF_STATUS policy_mgr_get_mcc_adaptive_sch(struct wlan_objmgr_psoc *psoc,
588 					   bool *enable_mcc_adaptive_sch)
589 {
590 	struct policy_mgr_psoc_priv_obj *pm_ctx;
591 
592 	pm_ctx = policy_mgr_get_context(psoc);
593 	if (!pm_ctx) {
594 		policy_mgr_err("pm_ctx is NULL");
595 		return QDF_STATUS_E_FAILURE;
596 	}
597 	*enable_mcc_adaptive_sch = pm_ctx->cfg.enable_mcc_adaptive_sch;
598 
599 	return QDF_STATUS_SUCCESS;
600 }
601 
policy_mgr_get_sta_cxn_5g_band(struct wlan_objmgr_psoc * psoc,uint8_t * enable_sta_cxn_5g_band)602 QDF_STATUS policy_mgr_get_sta_cxn_5g_band(struct wlan_objmgr_psoc *psoc,
603 					  uint8_t *enable_sta_cxn_5g_band)
604 {
605 	struct policy_mgr_psoc_priv_obj *pm_ctx;
606 
607 	pm_ctx = policy_mgr_get_context(psoc);
608 	if (!pm_ctx) {
609 		policy_mgr_err("pm_ctx is NULL");
610 		return QDF_STATUS_E_FAILURE;
611 	}
612 	*enable_sta_cxn_5g_band = pm_ctx->cfg.enable_sta_cxn_5g_band;
613 
614 	return QDF_STATUS_SUCCESS;
615 }
616 
policy_mgr_update_new_hw_mode_index(struct wlan_objmgr_psoc * psoc,uint32_t new_hw_mode_index)617 void policy_mgr_update_new_hw_mode_index(struct wlan_objmgr_psoc *psoc,
618 		uint32_t new_hw_mode_index)
619 {
620 	struct policy_mgr_psoc_priv_obj *pm_ctx;
621 
622 	pm_ctx = policy_mgr_get_context(psoc);
623 	if (!pm_ctx) {
624 		policy_mgr_err("Invalid Context");
625 		return;
626 	}
627 	pm_ctx->new_hw_mode_index = new_hw_mode_index;
628 }
629 
policy_mgr_update_old_hw_mode_index(struct wlan_objmgr_psoc * psoc,uint32_t old_hw_mode_index)630 void policy_mgr_update_old_hw_mode_index(struct wlan_objmgr_psoc *psoc,
631 		uint32_t old_hw_mode_index)
632 {
633 	struct policy_mgr_psoc_priv_obj *pm_ctx;
634 
635 	pm_ctx = policy_mgr_get_context(psoc);
636 	if (!pm_ctx) {
637 		policy_mgr_err("Invalid Context");
638 		return;
639 	}
640 	pm_ctx->old_hw_mode_index = old_hw_mode_index;
641 }
642 
policy_mgr_update_hw_mode_index(struct wlan_objmgr_psoc * psoc,uint32_t new_hw_mode_index)643 void policy_mgr_update_hw_mode_index(struct wlan_objmgr_psoc *psoc,
644 		uint32_t new_hw_mode_index)
645 {
646 	struct policy_mgr_psoc_priv_obj *pm_ctx;
647 
648 	pm_ctx = policy_mgr_get_context(psoc);
649 	if (!pm_ctx) {
650 		policy_mgr_err("Invalid Context");
651 		return;
652 	}
653 	if (POLICY_MGR_DEFAULT_HW_MODE_INDEX == pm_ctx->new_hw_mode_index) {
654 		pm_ctx->new_hw_mode_index = new_hw_mode_index;
655 	} else {
656 		pm_ctx->old_hw_mode_index = pm_ctx->new_hw_mode_index;
657 		pm_ctx->new_hw_mode_index = new_hw_mode_index;
658 	}
659 	policy_mgr_debug("Updated: old_hw_mode_index:%d new_hw_mode_index:%d",
660 		pm_ctx->old_hw_mode_index, pm_ctx->new_hw_mode_index);
661 }
662 
663 /**
664  * policy_mgr_get_num_of_setbits_from_bitmask() - to get num of
665  * setbits from bitmask
666  * @mask: given bitmask
667  *
668  * This helper function should return number of setbits from bitmask
669  *
670  * Return: number of setbits from bitmask
671  */
policy_mgr_get_num_of_setbits_from_bitmask(uint32_t mask)672 static uint32_t policy_mgr_get_num_of_setbits_from_bitmask(uint32_t mask)
673 {
674 	uint32_t num_of_setbits = 0;
675 
676 	while (mask) {
677 		mask &= (mask - 1);
678 		num_of_setbits++;
679 	}
680 	return num_of_setbits;
681 }
682 
683 /**
684  * policy_mgr_map_wmi_channel_width_to_hw_mode_bw() - returns
685  * bandwidth in terms of hw_mode_bandwidth
686  * @width: bandwidth in terms of wmi_channel_width
687  *
688  * This function returns the bandwidth in terms of hw_mode_bandwidth.
689  *
690  * Return: BW in terms of hw_mode_bandwidth.
691  */
policy_mgr_map_wmi_channel_width_to_hw_mode_bw(wmi_channel_width width)692 static enum hw_mode_bandwidth policy_mgr_map_wmi_channel_width_to_hw_mode_bw(
693 		wmi_channel_width width)
694 {
695 	switch (width) {
696 	case WMI_CHAN_WIDTH_20:
697 		return HW_MODE_20_MHZ;
698 	case WMI_CHAN_WIDTH_40:
699 		return HW_MODE_40_MHZ;
700 	case WMI_CHAN_WIDTH_80:
701 		return HW_MODE_80_MHZ;
702 	case WMI_CHAN_WIDTH_160:
703 		return HW_MODE_160_MHZ;
704 	case WMI_CHAN_WIDTH_80P80:
705 		return HW_MODE_80_PLUS_80_MHZ;
706 	case WMI_CHAN_WIDTH_5:
707 		return HW_MODE_5_MHZ;
708 	case WMI_CHAN_WIDTH_10:
709 		return HW_MODE_10_MHZ;
710 #ifdef WLAN_FEATURE_11BE
711 	case WMI_CHAN_WIDTH_320:
712 		return HW_MODE_320_MHZ;
713 #endif
714 	default:
715 		return HW_MODE_BW_NONE;
716 	}
717 
718 	return HW_MODE_BW_NONE;
719 }
720 
policy_mgr_get_hw_mode_params(struct wlan_psoc_host_mac_phy_caps * caps,struct policy_mgr_mac_ss_bw_info * info)721 static void policy_mgr_get_hw_mode_params(
722 		struct wlan_psoc_host_mac_phy_caps *caps,
723 		struct policy_mgr_mac_ss_bw_info *info)
724 {
725 	qdf_freq_t max_5g_freq;
726 
727 	if (!caps) {
728 		policy_mgr_err("Invalid capabilities");
729 		return;
730 	}
731 
732 	info->mac_tx_stream = policy_mgr_get_num_of_setbits_from_bitmask(
733 		QDF_MAX(caps->tx_chain_mask_2G,
734 		caps->tx_chain_mask_5G));
735 	info->mac_rx_stream = policy_mgr_get_num_of_setbits_from_bitmask(
736 		QDF_MAX(caps->rx_chain_mask_2G,
737 		caps->rx_chain_mask_5G));
738 	info->mac_bw = policy_mgr_map_wmi_channel_width_to_hw_mode_bw(
739 		QDF_MAX(caps->max_bw_supported_2G,
740 		caps->max_bw_supported_5G));
741 	info->mac_band_cap = caps->supported_bands;
742 
743 	if (caps->supported_bands & WMI_HOST_WLAN_5G_CAPABILITY) {
744 		max_5g_freq = wlan_reg_max_6ghz_chan_freq() ?
745 				wlan_reg_max_6ghz_chan_freq() :
746 				wlan_reg_max_5ghz_chan_freq();
747 		max_5g_freq = caps->reg_cap_ext.high_5ghz_chan ?
748 				QDF_MIN(caps->reg_cap_ext.high_5ghz_chan,
749 					max_5g_freq) : max_5g_freq;
750 		info->support_6ghz_band =
751 			max_5g_freq > wlan_reg_min_6ghz_chan_freq();
752 	}
753 }
754 
policy_mgr_update_nss_req(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint8_t tx_nss,uint8_t rx_nss)755 QDF_STATUS policy_mgr_update_nss_req(struct wlan_objmgr_psoc *psoc,
756 				     uint8_t vdev_id, uint8_t tx_nss,
757 				     uint8_t rx_nss)
758 {
759 	struct policy_mgr_psoc_priv_obj *pm_ctx;
760 
761 	pm_ctx = policy_mgr_get_context(psoc);
762 	if (!pm_ctx) {
763 		policy_mgr_err("Invalid Context");
764 		return QDF_STATUS_E_FAILURE;
765 	}
766 	return pm_ctx->hdd_cbacks.wlan_set_tx_rx_nss_cb(psoc, vdev_id,
767 							tx_nss, rx_nss);
768 }
769 
770 /**
771  * policy_mgr_set_hw_mode_params() - sets TX-RX stream,
772  * bandwidth and DBS in hw_mode_list
773  * @psoc: PSOC object information
774  * @mac0_ss_bw_info: TX-RX streams, BW for MAC0
775  * @mac1_ss_bw_info: TX-RX streams, BW for MAC1
776  * @pos: refers to hw_mode_list array index
777  * @hw_mode_id: hw mode id value used by firmware
778  * @dbs_mode: dbs_mode for the dbs_hw_mode
779  * @sbs_mode: sbs_mode for the sbs_hw_mode
780  * @emlsr_mode: emlsr_mode for the emlsr_hw_mode
781  *
782  * This function sets TX-RX stream, bandwidth and DBS mode in
783  * hw_mode_list.
784  *
785  * Return: none
786  */
policy_mgr_set_hw_mode_params(struct wlan_objmgr_psoc * psoc,struct policy_mgr_mac_ss_bw_info mac0_ss_bw_info,struct policy_mgr_mac_ss_bw_info mac1_ss_bw_info,uint32_t pos,uint32_t hw_mode_id,uint32_t dbs_mode,uint32_t sbs_mode,uint64_t emlsr_mode)787 static void policy_mgr_set_hw_mode_params(struct wlan_objmgr_psoc *psoc,
788 			struct policy_mgr_mac_ss_bw_info mac0_ss_bw_info,
789 			struct policy_mgr_mac_ss_bw_info mac1_ss_bw_info,
790 			uint32_t pos, uint32_t hw_mode_id, uint32_t dbs_mode,
791 			uint32_t sbs_mode, uint64_t emlsr_mode)
792 {
793 	struct policy_mgr_psoc_priv_obj *pm_ctx;
794 	uint64_t legacy_hwmode_lst;
795 
796 	pm_ctx = policy_mgr_get_context(psoc);
797 	if (!pm_ctx) {
798 		policy_mgr_err("Invalid Context");
799 		return;
800 	}
801 
802 	POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_SET(
803 		pm_ctx->hw_mode.hw_mode_list[pos],
804 		mac0_ss_bw_info.mac_tx_stream);
805 	POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_SET(
806 		pm_ctx->hw_mode.hw_mode_list[pos],
807 		mac0_ss_bw_info.mac_rx_stream);
808 	POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_SET(
809 		pm_ctx->hw_mode.hw_mode_list[pos],
810 		mac0_ss_bw_info.mac_bw);
811 	POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_SET(
812 		pm_ctx->hw_mode.hw_mode_list[pos],
813 		mac1_ss_bw_info.mac_tx_stream);
814 	POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_SET(
815 		pm_ctx->hw_mode.hw_mode_list[pos],
816 		mac1_ss_bw_info.mac_rx_stream);
817 	POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_SET(
818 		pm_ctx->hw_mode.hw_mode_list[pos],
819 		mac1_ss_bw_info.mac_bw);
820 	POLICY_MGR_HW_MODE_DBS_MODE_SET(
821 		pm_ctx->hw_mode.hw_mode_list[pos],
822 		dbs_mode);
823 	POLICY_MGR_HW_MODE_AGILE_DFS_SET(
824 		pm_ctx->hw_mode.hw_mode_list[pos],
825 		HW_MODE_AGILE_DFS_NONE);
826 	POLICY_MGR_HW_MODE_SBS_MODE_SET(
827 		pm_ctx->hw_mode.hw_mode_list[pos],
828 		sbs_mode);
829 	POLICY_MGR_HW_MODE_MAC0_BAND_SET(
830 		pm_ctx->hw_mode.hw_mode_list[pos],
831 		mac0_ss_bw_info.mac_band_cap);
832 	POLICY_MGR_HW_MODE_ID_SET(
833 		pm_ctx->hw_mode.hw_mode_list[pos],
834 		hw_mode_id);
835 
836 	legacy_hwmode_lst = pm_ctx->hw_mode.hw_mode_list[pos];
837 	POLICY_MGR_HW_MODE_EMLSR_MODE_SET(
838 	    pm_ctx->hw_mode.hw_mode_list[pos],
839 	    legacy_hwmode_lst, emlsr_mode);
840 }
841 
policy_mgr_get_radio_combinations(struct wlan_objmgr_psoc * psoc,struct radio_combination * comb,uint32_t comb_max,uint32_t * comb_num)842 QDF_STATUS policy_mgr_get_radio_combinations(struct wlan_objmgr_psoc *psoc,
843 					     struct radio_combination *comb,
844 					     uint32_t comb_max,
845 					     uint32_t *comb_num)
846 {
847 	struct policy_mgr_psoc_priv_obj *pm_ctx;
848 	struct radio_combination *radio_comb;
849 	uint32_t i;
850 	bool dbs_or_sbs_enabled = false;
851 
852 	pm_ctx = policy_mgr_get_context(psoc);
853 	if (!pm_ctx) {
854 		policy_mgr_err("Invalid Context");
855 		return QDF_STATUS_E_FAILURE;
856 	}
857 
858 	*comb_num = 0;
859 	if (policy_mgr_is_hw_dbs_capable(psoc) ||
860 	    policy_mgr_is_hw_sbs_capable(psoc))
861 		dbs_or_sbs_enabled = true;
862 
863 	for (i = 0; i < pm_ctx->radio_comb_num; i++) {
864 		radio_comb = &pm_ctx->radio_combinations[i];
865 		if (!dbs_or_sbs_enabled && radio_comb->hw_mode != MODE_SMM)
866 			continue;
867 		if (*comb_num >= comb_max) {
868 			policy_mgr_err("out of buffer %d max %d",
869 				       pm_ctx->radio_comb_num,
870 				       comb_max);
871 			return QDF_STATUS_E_FAILURE;
872 		}
873 		policy_mgr_debug("radio %d: mode %d mac0 (0x%x, 0x%x), mac1 (0x%x 0x%x)",
874 				 *comb_num,
875 				 radio_comb->hw_mode,
876 				 radio_comb->band_mask[0],
877 				 radio_comb->antenna[0],
878 				 radio_comb->band_mask[1],
879 				 radio_comb->antenna[1]);
880 		qdf_mem_copy(&comb[*comb_num], radio_comb,
881 			     sizeof(*radio_comb));
882 		(*comb_num)++;
883 	}
884 
885 	return QDF_STATUS_SUCCESS;
886 }
887 
888 /**
889  * policy_mgr_add_radio_comb() - Add radio combination
890  * @pm_ctx: bandwidth in terms of wmi_channel_width
891  * @radio: radio combination
892  *
893  * This function adds one radio combination to list
894  *
895  * Return: void
896  */
policy_mgr_add_radio_comb(struct policy_mgr_psoc_priv_obj * pm_ctx,struct radio_combination * radio)897 static void policy_mgr_add_radio_comb(struct policy_mgr_psoc_priv_obj *pm_ctx,
898 				      struct radio_combination *radio)
899 {
900 	uint32_t i;
901 	struct radio_combination *comb;
902 
903 	/* don't add duplicated item */
904 	for (i = 0; i < pm_ctx->radio_comb_num; i++) {
905 		comb = &pm_ctx->radio_combinations[i];
906 		if (radio->hw_mode == comb->hw_mode &&
907 		    radio->band_mask[0] == comb->band_mask[0] &&
908 		    radio->band_mask[1] == comb->band_mask[1] &&
909 		    radio->antenna[0] == comb->antenna[0] &&
910 		    radio->antenna[1] == comb->antenna[1])
911 			return;
912 	}
913 	if (pm_ctx->radio_comb_num == MAX_RADIO_COMBINATION) {
914 		policy_mgr_err("radio combination overflow %d",
915 			       pm_ctx->radio_comb_num);
916 		return;
917 	}
918 	policy_mgr_debug("radio %d: mode %d mac0 (0x%x, 0x%x), mac1 (0x%x 0x%x)",
919 			 pm_ctx->radio_comb_num,
920 			 radio->hw_mode,
921 			 radio->band_mask[0],
922 			 radio->antenna[0],
923 			 radio->band_mask[1],
924 			 radio->antenna[1]);
925 
926 	qdf_mem_copy(&pm_ctx->radio_combinations[pm_ctx->radio_comb_num],
927 		     radio, sizeof(*radio));
928 	pm_ctx->radio_comb_num++;
929 }
930 
931 #define SET_RADIO(_radio, _mode, _mac0_band, _mac1_band,\
932 		  _mac0_antenna, _mac1_antenna) \
933 do { \
934 	(_radio)->hw_mode = _mode; \
935 	(_radio)->band_mask[0] = _mac0_band; \
936 	(_radio)->band_mask[1] = _mac1_band; \
937 	(_radio)->antenna[0] = _mac0_antenna; \
938 	(_radio)->antenna[1] = _mac1_antenna; \
939 } while (0)
940 
941 /**
942  * policy_mgr_update_radio_combination_matrix() - Update radio combination
943  * list
944  * @psoc: psoc object
945  * @mac0_ss_bw_info: mac 0 band/bw info
946  * @mac1_ss_bw_info: mac 1 band/bw info
947  * @dbs_mode: dbs mode
948  * @sbs_mode: sbs mode
949  *
950  * This function updates radio combination list based on hw mode information.
951  *
952  * Return: void
953  */
954 static void
policy_mgr_update_radio_combination_matrix(struct wlan_objmgr_psoc * psoc,struct policy_mgr_mac_ss_bw_info mac0_ss_bw_info,struct policy_mgr_mac_ss_bw_info mac1_ss_bw_info,uint32_t dbs_mode,uint32_t sbs_mode)955 policy_mgr_update_radio_combination_matrix(
956 			struct wlan_objmgr_psoc *psoc,
957 			struct policy_mgr_mac_ss_bw_info mac0_ss_bw_info,
958 			struct policy_mgr_mac_ss_bw_info mac1_ss_bw_info,
959 			uint32_t dbs_mode, uint32_t sbs_mode)
960 {
961 	struct policy_mgr_psoc_priv_obj *pm_ctx;
962 	struct radio_combination radio;
963 
964 	pm_ctx = policy_mgr_get_context(psoc);
965 	if (!pm_ctx) {
966 		policy_mgr_err("Invalid Context");
967 		return;
968 	}
969 
970 	if (!dbs_mode && !sbs_mode) {
971 		if (mac0_ss_bw_info.mac_band_cap &
972 					WMI_HOST_WLAN_2G_CAPABILITY) {
973 			SET_RADIO(&radio, MODE_SMM, BIT(REG_BAND_2G), 0,
974 				  mac0_ss_bw_info.mac_tx_stream, 0);
975 			policy_mgr_add_radio_comb(pm_ctx, &radio);
976 		}
977 		if (mac0_ss_bw_info.mac_band_cap &
978 					WMI_HOST_WLAN_5G_CAPABILITY) {
979 			SET_RADIO(&radio, MODE_SMM, BIT(REG_BAND_5G), 0,
980 				  mac0_ss_bw_info.mac_tx_stream, 0);
981 			policy_mgr_add_radio_comb(pm_ctx, &radio);
982 			if (mac0_ss_bw_info.support_6ghz_band) {
983 				SET_RADIO(&radio, MODE_SMM, BIT(REG_BAND_6G),
984 					  0, mac0_ss_bw_info.mac_tx_stream, 0);
985 				policy_mgr_add_radio_comb(pm_ctx, &radio);
986 			}
987 		}
988 		return;
989 	}
990 	if ((mac0_ss_bw_info.mac_band_cap & WMI_HOST_WLAN_2G_CAPABILITY) &&
991 	    (mac1_ss_bw_info.mac_band_cap & WMI_HOST_WLAN_5G_CAPABILITY)) {
992 		SET_RADIO(&radio, MODE_DBS, BIT(REG_BAND_2G), BIT(REG_BAND_5G),
993 			  mac0_ss_bw_info.mac_tx_stream,
994 			  mac1_ss_bw_info.mac_tx_stream);
995 		policy_mgr_add_radio_comb(pm_ctx, &radio);
996 		if (mac1_ss_bw_info.support_6ghz_band) {
997 			SET_RADIO(&radio, MODE_DBS, BIT(REG_BAND_2G),
998 				  BIT(REG_BAND_6G),
999 				  mac0_ss_bw_info.mac_tx_stream,
1000 				  mac1_ss_bw_info.mac_tx_stream);
1001 			policy_mgr_add_radio_comb(pm_ctx, &radio);
1002 		}
1003 	}
1004 	if ((mac0_ss_bw_info.mac_band_cap & WMI_HOST_WLAN_5G_CAPABILITY) &&
1005 	    (mac1_ss_bw_info.mac_band_cap & WMI_HOST_WLAN_2G_CAPABILITY)) {
1006 		SET_RADIO(&radio, MODE_DBS, BIT(REG_BAND_2G), BIT(REG_BAND_5G),
1007 			  mac1_ss_bw_info.mac_tx_stream,
1008 			  mac0_ss_bw_info.mac_tx_stream);
1009 		policy_mgr_add_radio_comb(pm_ctx, &radio);
1010 		if (mac0_ss_bw_info.support_6ghz_band) {
1011 			SET_RADIO(&radio, MODE_DBS, BIT(REG_BAND_2G),
1012 				  BIT(REG_BAND_6G),
1013 				  mac1_ss_bw_info.mac_tx_stream,
1014 				  mac0_ss_bw_info.mac_tx_stream);
1015 			policy_mgr_add_radio_comb(pm_ctx, &radio);
1016 		}
1017 	}
1018 	if ((mac0_ss_bw_info.mac_band_cap & WMI_HOST_WLAN_5G_CAPABILITY) &&
1019 	    (mac1_ss_bw_info.mac_band_cap & WMI_HOST_WLAN_5G_CAPABILITY)) {
1020 		if (mac0_ss_bw_info.support_6ghz_band) {
1021 			SET_RADIO(&radio, MODE_SBS, BIT(REG_BAND_5G),
1022 				  BIT(REG_BAND_6G),
1023 				  mac1_ss_bw_info.mac_tx_stream,
1024 				  mac0_ss_bw_info.mac_tx_stream);
1025 			policy_mgr_add_radio_comb(pm_ctx, &radio);
1026 		} else if (mac1_ss_bw_info.support_6ghz_band) {
1027 			SET_RADIO(&radio, MODE_SBS, BIT(REG_BAND_5G),
1028 				  BIT(REG_BAND_6G),
1029 				  mac0_ss_bw_info.mac_tx_stream,
1030 				  mac1_ss_bw_info.mac_tx_stream);
1031 			policy_mgr_add_radio_comb(pm_ctx, &radio);
1032 		}
1033 	}
1034 }
1035 
1036 static void
policy_mgr_update_24Ghz_freq_info(struct policy_mgr_freq_range * mac_range,struct wlan_psoc_host_mac_phy_caps * mac_cap)1037 policy_mgr_update_24Ghz_freq_info(struct policy_mgr_freq_range *mac_range,
1038 				  struct wlan_psoc_host_mac_phy_caps *mac_cap)
1039 {
1040 	mac_range->low_2ghz_freq = QDF_MAX(mac_cap->reg_cap_ext.low_2ghz_chan,
1041 					   wlan_reg_min_24ghz_chan_freq());
1042 	mac_range->high_2ghz_freq = mac_cap->reg_cap_ext.high_2ghz_chan ?
1043 				    QDF_MIN(mac_cap->reg_cap_ext.high_2ghz_chan,
1044 					    wlan_reg_max_24ghz_chan_freq()) :
1045 				    wlan_reg_max_24ghz_chan_freq();
1046 }
1047 
1048 static void
policy_mgr_update_5Ghz_freq_info(struct policy_mgr_freq_range * mac_range,struct wlan_psoc_host_mac_phy_caps * mac_cap)1049 policy_mgr_update_5Ghz_freq_info(struct policy_mgr_freq_range *mac_range,
1050 				  struct wlan_psoc_host_mac_phy_caps *mac_cap)
1051 {
1052 	qdf_freq_t max_5g_freq;
1053 
1054 	max_5g_freq = wlan_reg_max_6ghz_chan_freq() ?
1055 			wlan_reg_max_6ghz_chan_freq() :
1056 			wlan_reg_max_5ghz_chan_freq();
1057 
1058 	mac_range->low_5ghz_freq = QDF_MAX(mac_cap->reg_cap_ext.low_5ghz_chan,
1059 					   wlan_reg_min_5ghz_chan_freq());
1060 	mac_range->high_5ghz_freq = mac_cap->reg_cap_ext.high_5ghz_chan ?
1061 				    QDF_MIN(mac_cap->reg_cap_ext.high_5ghz_chan,
1062 					    max_5g_freq) :
1063 				    max_5g_freq;
1064 }
1065 
1066 static void
policy_mgr_update_freq_info(struct policy_mgr_psoc_priv_obj * pm_ctx,struct wlan_psoc_host_mac_phy_caps * mac_cap,enum policy_mgr_mode mode,uint32_t phy_id)1067 policy_mgr_update_freq_info(struct policy_mgr_psoc_priv_obj *pm_ctx,
1068 			    struct wlan_psoc_host_mac_phy_caps *mac_cap,
1069 			    enum policy_mgr_mode mode,
1070 			    uint32_t phy_id)
1071 {
1072 	struct policy_mgr_freq_range *mac_range;
1073 
1074 	mac_range = &pm_ctx->hw_mode.freq_range_caps[mode][phy_id];
1075 	if (mac_cap->supported_bands & WMI_HOST_WLAN_2G_CAPABILITY)
1076 		policy_mgr_update_24Ghz_freq_info(mac_range, mac_cap);
1077 
1078 	if (mac_cap->supported_bands & WMI_HOST_WLAN_5G_CAPABILITY)
1079 		policy_mgr_update_5Ghz_freq_info(mac_range, mac_cap);
1080 }
1081 
1082 static QDF_STATUS
policy_mgr_modify_sbs_freq(struct policy_mgr_psoc_priv_obj * pm_ctx,uint8_t phy_id)1083 policy_mgr_modify_sbs_freq(struct policy_mgr_psoc_priv_obj *pm_ctx,
1084 			   uint8_t phy_id)
1085 {
1086 	uint8_t shared_phy_id;
1087 	struct policy_mgr_freq_range *sbs_mac_range, *shared_mac_range;
1088 	struct policy_mgr_freq_range *non_shared_range;
1089 
1090 	sbs_mac_range = &pm_ctx->hw_mode.freq_range_caps[MODE_SBS][phy_id];
1091 
1092 	/*
1093 	 * if SBS mac range has both 2.4 and 5 Ghz range, i e shared phy_id
1094 	 * keep the range as it is in SBS
1095 	 */
1096 	if (sbs_mac_range->low_2ghz_freq && sbs_mac_range->low_5ghz_freq)
1097 		return QDF_STATUS_SUCCESS;
1098 	if (sbs_mac_range->low_2ghz_freq && !sbs_mac_range->low_5ghz_freq) {
1099 		policy_mgr_err("Invalid DBS/SBS mode with only 2.4Ghz");
1100 		policy_mgr_dump_freq_range_per_mac(sbs_mac_range, MODE_SBS);
1101 		return QDF_STATUS_E_INVAL;
1102 	}
1103 
1104 	non_shared_range = sbs_mac_range;
1105 	/*
1106 	 * if SBS mac range has only 5Ghz then its the non shared phy, so
1107 	 * modify the range as per the shared mac.
1108 	 */
1109 	shared_phy_id = phy_id ? 0 : 1;
1110 	shared_mac_range =
1111 		&pm_ctx->hw_mode.freq_range_caps[MODE_SBS][shared_phy_id];
1112 
1113 	if (shared_mac_range->low_5ghz_freq > non_shared_range->low_5ghz_freq) {
1114 		policy_mgr_debug("High 5Ghz shared");
1115 		/*
1116 		 * If the shared mac lower 5Ghz frequency is greater than
1117 		 * non-shared mac lower 5Ghz frequency then the shared mac has
1118 		 * HIGH 5Ghz shared with 2.4Ghz. So non-shared mac's 5Ghz high
1119 		 * freq should be less than the shared mac's low 5Ghz freq.
1120 		 */
1121 		if (non_shared_range->high_5ghz_freq >=
1122 		    shared_mac_range->low_5ghz_freq)
1123 			non_shared_range->high_5ghz_freq =
1124 				QDF_MAX(shared_mac_range->low_5ghz_freq - 10,
1125 					non_shared_range->low_5ghz_freq);
1126 	} else if (shared_mac_range->high_5ghz_freq <
1127 		   non_shared_range->high_5ghz_freq) {
1128 		policy_mgr_debug("LOW 5Ghz shared");
1129 		/*
1130 		 * If the shared mac high 5Ghz frequency is less than
1131 		 * non-shared mac high 5Ghz frequency then the shared mac has
1132 		 * LOW 5Ghz shared with 2.4Ghz So non-shared mac's 5Ghz low
1133 		 * freq should be greater than the shared mac's high 5Ghz freq.
1134 		 */
1135 		if (shared_mac_range->high_5ghz_freq >=
1136 		    non_shared_range->low_5ghz_freq)
1137 			non_shared_range->low_5ghz_freq =
1138 				QDF_MIN(shared_mac_range->high_5ghz_freq + 10,
1139 					non_shared_range->high_5ghz_freq);
1140 	} else {
1141 		policy_mgr_info("Invalid SBS range with all 5Ghz shared");
1142 		return QDF_STATUS_E_INVAL;
1143 	}
1144 
1145 	return QDF_STATUS_SUCCESS;
1146 }
1147 
1148 static qdf_freq_t
policy_mgr_get_highest_5ghz_freq_frm_range(struct policy_mgr_freq_range * range)1149 policy_mgr_get_highest_5ghz_freq_frm_range(struct policy_mgr_freq_range *range)
1150 {
1151 	uint8_t phy_id;
1152 	qdf_freq_t highest_freq = 0;
1153 	qdf_freq_t max_5g_freq = wlan_reg_max_6ghz_chan_freq() ?
1154 			wlan_reg_max_6ghz_chan_freq() :
1155 			wlan_reg_max_5ghz_chan_freq();
1156 
1157 	for (phy_id = 0; phy_id < MAX_MAC; phy_id++) {
1158 		if (range[phy_id].high_5ghz_freq > highest_freq)
1159 			highest_freq = range[phy_id].high_5ghz_freq;
1160 	}
1161 
1162 	return highest_freq ? highest_freq : max_5g_freq;
1163 }
1164 
1165 static qdf_freq_t
policy_mgr_get_lowest_5ghz_freq_frm_range(struct policy_mgr_freq_range * range)1166 policy_mgr_get_lowest_5ghz_freq_frm_range(struct policy_mgr_freq_range *range)
1167 {
1168 	uint8_t phy_id;
1169 	qdf_freq_t lowest_freq = 0;
1170 
1171 	for (phy_id = 0; phy_id < MAX_MAC; phy_id++) {
1172 		if ((!lowest_freq && range[phy_id].low_5ghz_freq) ||
1173 		    (range[phy_id].low_5ghz_freq < lowest_freq))
1174 			lowest_freq = range[phy_id].low_5ghz_freq;
1175 	}
1176 
1177 	return lowest_freq ? lowest_freq : wlan_reg_min_5ghz_chan_freq();
1178 }
1179 
1180 static void
policy_mgr_fill_lower_share_sbs_freq(struct policy_mgr_psoc_priv_obj * pm_ctx,uint16_t sbs_range_sep,struct policy_mgr_freq_range * ref_freq)1181 policy_mgr_fill_lower_share_sbs_freq(struct policy_mgr_psoc_priv_obj *pm_ctx,
1182 				     uint16_t sbs_range_sep,
1183 				     struct policy_mgr_freq_range *ref_freq)
1184 {
1185 	struct policy_mgr_freq_range *lower_sbs_freq_range;
1186 	uint8_t phy_id;
1187 
1188 	lower_sbs_freq_range =
1189 		pm_ctx->hw_mode.freq_range_caps[MODE_SBS_LOWER_SHARE];
1190 
1191 	for (phy_id = 0; phy_id < MAX_MAC; phy_id++) {
1192 		lower_sbs_freq_range[phy_id].low_2ghz_freq =
1193 						ref_freq[phy_id].low_2ghz_freq;
1194 		lower_sbs_freq_range[phy_id].high_2ghz_freq =
1195 						ref_freq[phy_id].high_2ghz_freq;
1196 
1197 		/* update for shared mac */
1198 		if (lower_sbs_freq_range[phy_id].low_2ghz_freq) {
1199 			lower_sbs_freq_range[phy_id].low_5ghz_freq =
1200 			    policy_mgr_get_lowest_5ghz_freq_frm_range(ref_freq);
1201 			lower_sbs_freq_range[phy_id].high_5ghz_freq =
1202 				sbs_range_sep;
1203 		} else {
1204 			lower_sbs_freq_range[phy_id].low_5ghz_freq =
1205 				sbs_range_sep + 10;
1206 			lower_sbs_freq_range[phy_id].high_5ghz_freq =
1207 			   policy_mgr_get_highest_5ghz_freq_frm_range(ref_freq);
1208 		}
1209 	}
1210 }
1211 
1212 static void
policy_mgr_fill_upper_share_sbs_freq(struct policy_mgr_psoc_priv_obj * pm_ctx,uint16_t sbs_range_sep,struct policy_mgr_freq_range * ref_freq)1213 policy_mgr_fill_upper_share_sbs_freq(struct policy_mgr_psoc_priv_obj *pm_ctx,
1214 				     uint16_t sbs_range_sep,
1215 				     struct policy_mgr_freq_range *ref_freq)
1216 {
1217 	struct policy_mgr_freq_range *upper_sbs_freq_range;
1218 	uint8_t phy_id;
1219 
1220 	upper_sbs_freq_range =
1221 		pm_ctx->hw_mode.freq_range_caps[MODE_SBS_UPPER_SHARE];
1222 
1223 	for (phy_id = 0; phy_id < MAX_MAC; phy_id++) {
1224 		upper_sbs_freq_range[phy_id].low_2ghz_freq =
1225 						ref_freq[phy_id].low_2ghz_freq;
1226 		upper_sbs_freq_range[phy_id].high_2ghz_freq =
1227 						ref_freq[phy_id].high_2ghz_freq;
1228 
1229 		/* update for shared mac */
1230 		if (upper_sbs_freq_range[phy_id].low_2ghz_freq) {
1231 			upper_sbs_freq_range[phy_id].low_5ghz_freq =
1232 				sbs_range_sep + 10;
1233 			upper_sbs_freq_range[phy_id].high_5ghz_freq =
1234 			   policy_mgr_get_highest_5ghz_freq_frm_range(ref_freq);
1235 		} else {
1236 			upper_sbs_freq_range[phy_id].low_5ghz_freq =
1237 			    policy_mgr_get_lowest_5ghz_freq_frm_range(ref_freq);
1238 			upper_sbs_freq_range[phy_id].high_5ghz_freq =
1239 				sbs_range_sep;
1240 		}
1241 	}
1242 }
1243 
1244 static bool
policy_mgr_both_phy_range_updated(struct policy_mgr_psoc_priv_obj * pm_ctx,enum policy_mgr_mode hwmode)1245 policy_mgr_both_phy_range_updated(struct policy_mgr_psoc_priv_obj *pm_ctx,
1246 				  enum policy_mgr_mode hwmode)
1247 {
1248 	struct policy_mgr_freq_range *mac_range;
1249 	uint8_t phy_id;
1250 
1251 	for (phy_id = 0; phy_id < MAX_MAC; phy_id++) {
1252 		mac_range =
1253 			&pm_ctx->hw_mode.freq_range_caps[hwmode][phy_id];
1254 		/* modify SBS/DBS range only when both phy for DBS are filled */
1255 		if (!mac_range->low_2ghz_freq && !mac_range->low_5ghz_freq)
1256 			return false;
1257 	}
1258 
1259 	return true;
1260 }
1261 
1262 static void
policy_mgr_update_sbs_freq_info(struct policy_mgr_psoc_priv_obj * pm_ctx)1263 policy_mgr_update_sbs_freq_info(struct policy_mgr_psoc_priv_obj *pm_ctx)
1264 {
1265 	uint16_t sbs_range_sep;
1266 	struct policy_mgr_freq_range *mac_range;
1267 	uint8_t phy_id;
1268 	QDF_STATUS status;
1269 
1270 	mac_range = pm_ctx->hw_mode.freq_range_caps[MODE_SBS];
1271 
1272 	/*
1273 	 * If sbs_lower_band_end_freq has a value Z, then the frequency range
1274 	 * will be split using that value.
1275 	 */
1276 	sbs_range_sep = pm_ctx->hw_mode.sbs_lower_band_end_freq;
1277 	if (sbs_range_sep) {
1278 		policy_mgr_fill_upper_share_sbs_freq(pm_ctx, sbs_range_sep,
1279 						     mac_range);
1280 		policy_mgr_fill_lower_share_sbs_freq(pm_ctx, sbs_range_sep,
1281 						     mac_range);
1282 		/* Reset the SBS range */
1283 		qdf_mem_zero(mac_range, sizeof(*mac_range) * MAX_MAC);
1284 		return;
1285 	}
1286 
1287 	/*
1288 	 * If sbs_lower_band_end_freq is not set that means FW will send one
1289 	 * shared mac range and one non-shared mac range. so update that freq.
1290 	 */
1291 	for (phy_id = 0; phy_id < MAX_MAC; phy_id++) {
1292 		status = policy_mgr_modify_sbs_freq(pm_ctx, phy_id);
1293 		if (QDF_IS_STATUS_ERROR(status)) {
1294 			/* Reset the SBS range */
1295 			qdf_mem_zero(mac_range, sizeof(*mac_range) * MAX_MAC);
1296 			break;
1297 		}
1298 	}
1299 }
1300 
1301 static void
policy_mgr_update_dbs_freq_info(struct policy_mgr_psoc_priv_obj * pm_ctx)1302 policy_mgr_update_dbs_freq_info(struct policy_mgr_psoc_priv_obj *pm_ctx)
1303 {
1304 	struct policy_mgr_freq_range *mac_range;
1305 	uint8_t phy_id;
1306 
1307 	mac_range = pm_ctx->hw_mode.freq_range_caps[MODE_DBS];
1308 	/* Reset 5Ghz range for shared mac for DBS */
1309 	for (phy_id = 0; phy_id < MAX_MAC; phy_id++) {
1310 		if (mac_range[phy_id].low_2ghz_freq &&
1311 		    mac_range[phy_id].low_5ghz_freq) {
1312 			mac_range[phy_id].low_5ghz_freq = 0;
1313 			mac_range[phy_id].high_5ghz_freq = 0;
1314 		}
1315 	}
1316 }
1317 
1318 static void
policy_mgr_update_mac_freq_info(struct wlan_objmgr_psoc * psoc,struct policy_mgr_psoc_priv_obj * pm_ctx,enum wmi_hw_mode_config_type hw_config_type,uint32_t phy_id,struct wlan_psoc_host_mac_phy_caps * mac_cap)1319 policy_mgr_update_mac_freq_info(struct wlan_objmgr_psoc *psoc,
1320 				struct policy_mgr_psoc_priv_obj *pm_ctx,
1321 				enum wmi_hw_mode_config_type hw_config_type,
1322 				uint32_t phy_id,
1323 				struct wlan_psoc_host_mac_phy_caps *mac_cap)
1324 {
1325 	if (phy_id >= MAX_MAC) {
1326 		policy_mgr_err("mac more than two not supported: %d",
1327 			       phy_id);
1328 		return;
1329 	}
1330 
1331 	policy_mgr_debug("hw_mode_cfg: %d mac: %d band: 0x%x, SBS cutoff freq %d, 2Ghz: %d -> %d 5Ghz: %d -> %d",
1332 			 hw_config_type, phy_id, mac_cap->supported_bands,
1333 			 pm_ctx->hw_mode.sbs_lower_band_end_freq,
1334 			 mac_cap->reg_cap_ext.low_2ghz_chan,
1335 			 mac_cap->reg_cap_ext.high_2ghz_chan,
1336 			 mac_cap->reg_cap_ext.low_5ghz_chan,
1337 			 mac_cap->reg_cap_ext.high_5ghz_chan);
1338 
1339 	switch (hw_config_type) {
1340 	case WMI_HW_MODE_SINGLE:
1341 		if (phy_id) {
1342 			policy_mgr_debug("MAC Phy 1 is not supported");
1343 			break;
1344 		}
1345 		policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_SMM, phy_id);
1346 		break;
1347 
1348 	case WMI_HW_MODE_DBS:
1349 	case WMI_HW_MODE_DBS_2G_5G:
1350 		if (!policy_mgr_both_phy_range_updated(pm_ctx, MODE_DBS))
1351 			policy_mgr_update_freq_info(pm_ctx, mac_cap,
1352 						    MODE_DBS, phy_id);
1353 		break;
1354 	case WMI_HW_MODE_DBS_SBS:
1355 	case WMI_HW_MODE_DBS_OR_SBS:
1356 		policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_DBS, phy_id);
1357 		/*
1358 		 * fill SBS only if freq is provided by FW or
1359 		 * pm_ctx->hw_mode.sbs_lower_band_end_freq is set
1360 		 */
1361 		if (pm_ctx->hw_mode.sbs_lower_band_end_freq ||
1362 		    mac_cap->reg_cap_ext.low_5ghz_chan ||
1363 		    mac_cap->reg_cap_ext.low_2ghz_chan)
1364 			policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_SBS,
1365 						    phy_id);
1366 
1367 		/* Modify the DBS list once both phy info are filled */
1368 		if (policy_mgr_both_phy_range_updated(pm_ctx, MODE_DBS))
1369 			policy_mgr_update_dbs_freq_info(pm_ctx);
1370 		/* Modify the SBS list once both phy info are filled */
1371 		if (policy_mgr_both_phy_range_updated(pm_ctx, MODE_SBS))
1372 			policy_mgr_update_sbs_freq_info(pm_ctx);
1373 		break;
1374 	case WMI_HW_MODE_2G_PHYB:
1375 		if (phy_id)
1376 			policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_SMM,
1377 						    phy_id);
1378 		break;
1379 	case WMI_HW_MODE_SBS:
1380 	case WMI_HW_MODE_SBS_PASSIVE:
1381 		policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_SBS, phy_id);
1382 		/* Modify the SBS Upper Lower list once both phy are filled */
1383 		if (policy_mgr_both_phy_range_updated(pm_ctx, MODE_SBS))
1384 			policy_mgr_update_sbs_freq_info(pm_ctx);
1385 
1386 		break;
1387 	case WMI_HW_MODE_EMLSR:
1388 		policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_EMLSR,
1389 					    phy_id);
1390 		break;
1391 	case WMI_HW_MODE_AUX_EMLSR_SINGLE:
1392 		if (phy_id) {
1393 			policy_mgr_debug("MAC Phy 1 is not supported");
1394 			break;
1395 		}
1396 		policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_EMLSR_SINGLE,
1397 					    phy_id);
1398 		break;
1399 	case WMI_HW_MODE_AUX_EMLSR_SPLIT:
1400 		policy_mgr_update_freq_info(pm_ctx, mac_cap, MODE_EMLSR_SPLIT,
1401 					    phy_id);
1402 		break;
1403 	default:
1404 		policy_mgr_err("HW mode not defined %d",
1405 			       hw_config_type);
1406 		break;
1407 	}
1408 }
1409 
1410 void
policy_mgr_dump_curr_freq_range(struct policy_mgr_psoc_priv_obj * pm_ctx)1411 policy_mgr_dump_curr_freq_range(struct policy_mgr_psoc_priv_obj *pm_ctx)
1412 {
1413 	uint32_t i;
1414 	struct policy_mgr_freq_range *freq_range;
1415 
1416 	freq_range = pm_ctx->hw_mode.cur_mac_freq_range;
1417 	for (i = 0; i < MAX_MAC; i++)
1418 		if (freq_range[i].low_2ghz_freq || freq_range[i].low_5ghz_freq)
1419 			policymgr_nofl_debug("PLCY_MGR_FREQ_RANGE_CUR: mac %d: 2Ghz: %d -> %d, 5Ghz: %d -> %d",
1420 					     i, freq_range[i].low_2ghz_freq,
1421 					     freq_range[i].high_2ghz_freq,
1422 					     freq_range[i].low_5ghz_freq,
1423 					     freq_range[i].high_5ghz_freq);
1424 }
1425 
policy_mgr_hw_mode_to_str(enum policy_mgr_mode hw_mode)1426 static const char *policy_mgr_hw_mode_to_str(enum policy_mgr_mode hw_mode)
1427 {
1428 	if (hw_mode >= MODE_HW_MAX)
1429 		return "Unknown";
1430 
1431 	switch (hw_mode) {
1432 	CASE_RETURN_STRING(MODE_SMM);
1433 	CASE_RETURN_STRING(MODE_DBS);
1434 	CASE_RETURN_STRING(MODE_SBS);
1435 	CASE_RETURN_STRING(MODE_SBS_UPPER_SHARE);
1436 	CASE_RETURN_STRING(MODE_SBS_LOWER_SHARE);
1437 	CASE_RETURN_STRING(MODE_EMLSR);
1438 	CASE_RETURN_STRING(MODE_EMLSR_SINGLE);
1439 	CASE_RETURN_STRING(MODE_EMLSR_SPLIT);
1440 	default:
1441 		return "Unknown";
1442 	}
1443 }
1444 
1445 void
policy_mgr_dump_freq_range_per_mac(struct policy_mgr_freq_range * freq_range,enum policy_mgr_mode hw_mode)1446 policy_mgr_dump_freq_range_per_mac(struct policy_mgr_freq_range *freq_range,
1447 				   enum policy_mgr_mode hw_mode)
1448 {
1449 	uint32_t i;
1450 
1451 	for (i = 0; i < MAX_MAC; i++)
1452 		if (freq_range[i].low_2ghz_freq || freq_range[i].low_5ghz_freq)
1453 			policymgr_nofl_debug("PLCY_MGR_FREQ_RANGE: %s(%d): mac %d: 2Ghz: %d -> %d, 5Ghz: %d -> %d",
1454 					     policy_mgr_hw_mode_to_str(hw_mode),
1455 					     hw_mode, i,
1456 					     freq_range[i].low_2ghz_freq,
1457 					     freq_range[i].high_2ghz_freq,
1458 					     freq_range[i].low_5ghz_freq,
1459 					     freq_range[i].high_5ghz_freq);
1460 }
1461 
1462 static void
policy_mgr_dump_hw_modes_freq_range(struct policy_mgr_psoc_priv_obj * pm_ctx)1463 policy_mgr_dump_hw_modes_freq_range(struct policy_mgr_psoc_priv_obj *pm_ctx)
1464 {
1465 	uint32_t i;
1466 	struct policy_mgr_freq_range *freq_range;
1467 
1468 	for (i = MODE_SMM; i < MODE_HW_MAX; i++) {
1469 		freq_range = pm_ctx->hw_mode.freq_range_caps[i];
1470 		policy_mgr_dump_freq_range_per_mac(freq_range, i);
1471 	}
1472 }
1473 
policy_mgr_dump_sbs_freq_range(struct policy_mgr_psoc_priv_obj * pm_ctx)1474 void policy_mgr_dump_sbs_freq_range(struct policy_mgr_psoc_priv_obj *pm_ctx)
1475 {
1476 	uint32_t i;
1477 	struct policy_mgr_freq_range *freq_range;
1478 
1479 	for (i = MODE_SMM; i < MODE_HW_MAX; i++) {
1480 		if ((i == MODE_SBS) ||
1481 		    (pm_ctx->hw_mode.sbs_lower_band_end_freq &&
1482 		    (i == MODE_SBS_LOWER_SHARE || i == MODE_SBS_UPPER_SHARE))) {
1483 			freq_range = pm_ctx->hw_mode.freq_range_caps[i];
1484 			policy_mgr_dump_freq_range_per_mac(freq_range, i);
1485 		}
1486 	}
1487 }
1488 
1489 static bool
policy_mgr_sbs_range_present(struct policy_mgr_psoc_priv_obj * pm_ctx)1490 policy_mgr_sbs_range_present(struct policy_mgr_psoc_priv_obj *pm_ctx)
1491 {
1492 	if (policy_mgr_both_phy_range_updated(pm_ctx, MODE_SBS) ||
1493 	    (pm_ctx->hw_mode.sbs_lower_band_end_freq &&
1494 	     policy_mgr_both_phy_range_updated(pm_ctx, MODE_SBS_LOWER_SHARE) &&
1495 	     policy_mgr_both_phy_range_updated(pm_ctx, MODE_SBS_UPPER_SHARE)))
1496 		return true;
1497 
1498 	return false;
1499 }
1500 
1501 void
policy_mgr_dump_freq_range(struct policy_mgr_psoc_priv_obj * pm_ctx)1502 policy_mgr_dump_freq_range(struct policy_mgr_psoc_priv_obj *pm_ctx)
1503 {
1504 	policy_mgr_dump_hw_modes_freq_range(pm_ctx);
1505 	policy_mgr_dump_curr_freq_range(pm_ctx);
1506 }
1507 
1508 static void
policy_mgr_update_sbs_lowr_band_end_frq(struct policy_mgr_psoc_priv_obj * pm_ctx,struct tgt_info * info)1509 policy_mgr_update_sbs_lowr_band_end_frq(struct policy_mgr_psoc_priv_obj *pm_ctx,
1510 					struct tgt_info *info)
1511 {
1512 	if (wlan_reg_is_5ghz_ch_freq(info->sbs_lower_band_end_freq) ||
1513 	    wlan_reg_is_6ghz_chan_freq(info->sbs_lower_band_end_freq))
1514 		pm_ctx->hw_mode.sbs_lower_band_end_freq =
1515 						info->sbs_lower_band_end_freq;
1516 }
1517 
policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc * psoc,struct target_psoc_info * tgt_hdl)1518 QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc,
1519 					  struct target_psoc_info *tgt_hdl)
1520 {
1521 	struct wlan_psoc_host_mac_phy_caps *tmp;
1522 	struct wlan_psoc_host_mac_phy_caps_ext2 *cap;
1523 	uint32_t i, j = 0;
1524 	enum wmi_hw_mode_config_type hw_config_type;
1525 	uint32_t dbs_mode, sbs_mode;
1526 	uint64_t emlsr_mode;
1527 	struct policy_mgr_mac_ss_bw_info mac0_ss_bw_info = {0};
1528 	struct policy_mgr_mac_ss_bw_info mac1_ss_bw_info = {0};
1529 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1530 	struct tgt_info *info;
1531 
1532 	pm_ctx = policy_mgr_get_context(psoc);
1533 	if (!pm_ctx) {
1534 		policy_mgr_err("Invalid Context");
1535 		return QDF_STATUS_E_FAILURE;
1536 	}
1537 
1538 	info = &tgt_hdl->info;
1539 	if (!info->service_ext_param.num_hw_modes) {
1540 		policy_mgr_err("Number of HW modes: %d",
1541 			       info->service_ext_param.num_hw_modes);
1542 		return QDF_STATUS_E_FAILURE;
1543 	}
1544 
1545 	/*
1546 	 * This list was updated as part of service ready event. Re-populate
1547 	 * HW mode list from the device capabilities.
1548 	 */
1549 	if (pm_ctx->hw_mode.hw_mode_list) {
1550 		qdf_mem_free(pm_ctx->hw_mode.hw_mode_list);
1551 		pm_ctx->hw_mode.hw_mode_list = NULL;
1552 		policy_mgr_debug("DBS list is freed");
1553 	}
1554 
1555 	/* Reset old freq ranges */
1556 	qdf_mem_zero(pm_ctx->hw_mode.freq_range_caps,
1557 		     sizeof(pm_ctx->hw_mode.freq_range_caps));
1558 	qdf_mem_zero(pm_ctx->hw_mode.cur_mac_freq_range,
1559 		     sizeof(pm_ctx->hw_mode.cur_mac_freq_range));
1560 	pm_ctx->num_dbs_hw_modes = info->service_ext_param.num_hw_modes;
1561 	pm_ctx->hw_mode.hw_mode_list =
1562 		qdf_mem_malloc(sizeof(*pm_ctx->hw_mode.hw_mode_list) *
1563 		pm_ctx->num_dbs_hw_modes);
1564 	if (!pm_ctx->hw_mode.hw_mode_list) {
1565 		pm_ctx->num_dbs_hw_modes = 0;
1566 		return QDF_STATUS_E_NOMEM;
1567 	}
1568 	pm_ctx->radio_comb_num = 0;
1569 	qdf_mem_zero(pm_ctx->radio_combinations,
1570 		     sizeof(pm_ctx->radio_combinations));
1571 
1572 	policy_mgr_debug("Updated HW mode list: Num modes:%d",
1573 		pm_ctx->num_dbs_hw_modes);
1574 
1575 	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
1576 		/* Update for MAC0 */
1577 		tmp = &info->mac_phy_cap[j++];
1578 		policy_mgr_get_hw_mode_params(tmp, &mac0_ss_bw_info);
1579 		dbs_mode = HW_MODE_DBS_NONE;
1580 		sbs_mode = HW_MODE_SBS_NONE;
1581 		emlsr_mode = HW_MODE_EMLSR_NONE;
1582 		mac1_ss_bw_info.mac_tx_stream = 0;
1583 		mac1_ss_bw_info.mac_rx_stream = 0;
1584 		mac1_ss_bw_info.mac_bw = 0;
1585 
1586 		hw_config_type = tmp->hw_mode_config_type;
1587 		if (WMI_BECAP_PHY_GET_HW_MODE_CFG(hw_config_type) ==
1588 		    WMI_HW_MODE_EMLSR)
1589 			hw_config_type = WMI_HW_MODE_EMLSR;
1590 		else if (WMI_BECAP_PHY_GET_HW_MODE_CFG(hw_config_type) ==
1591 			 WMI_HW_MODE_AUX_EMLSR_SINGLE)
1592 			hw_config_type = WMI_HW_MODE_AUX_EMLSR_SINGLE;
1593 		else if (WMI_BECAP_PHY_GET_HW_MODE_CFG(hw_config_type) ==
1594 			 WMI_HW_MODE_AUX_EMLSR_SPLIT)
1595 			hw_config_type = WMI_HW_MODE_AUX_EMLSR_SPLIT;
1596 
1597 		policy_mgr_update_mac_freq_info(psoc, pm_ctx,
1598 						hw_config_type,
1599 						tmp->phy_id, tmp);
1600 
1601 		/* SBS and DBS have dual MAC. Upto 2 MACs are considered. */
1602 		if ((hw_config_type == WMI_HW_MODE_DBS) ||
1603 		    (hw_config_type == WMI_HW_MODE_SBS_PASSIVE) ||
1604 		    (hw_config_type == WMI_HW_MODE_SBS) ||
1605 		    (hw_config_type == WMI_HW_MODE_DBS_OR_SBS)) {
1606 			/* Update for MAC1 */
1607 			tmp = &info->mac_phy_cap[j++];
1608 			policy_mgr_get_hw_mode_params(tmp, &mac1_ss_bw_info);
1609 			policy_mgr_update_mac_freq_info(psoc, pm_ctx,
1610 							hw_config_type,
1611 							tmp->phy_id, tmp);
1612 			if (hw_config_type == WMI_HW_MODE_DBS ||
1613 			    hw_config_type == WMI_HW_MODE_DBS_OR_SBS)
1614 				dbs_mode = HW_MODE_DBS;
1615 			if (policy_mgr_sbs_range_present(pm_ctx) &&
1616 			    ((hw_config_type == WMI_HW_MODE_SBS_PASSIVE) ||
1617 			    (hw_config_type == WMI_HW_MODE_SBS) ||
1618 			    (hw_config_type == WMI_HW_MODE_DBS_OR_SBS)))
1619 				sbs_mode = HW_MODE_SBS;
1620 		} else if (hw_config_type == WMI_HW_MODE_EMLSR ||
1621 			hw_config_type == WMI_HW_MODE_AUX_EMLSR_SPLIT) {
1622 			/* eMLSR mode */
1623 			tmp = &info->mac_phy_cap[j++];
1624 			cap = &info->mac_phy_caps_ext2[i];
1625 			wlan_mlme_set_eml_params(psoc, cap);
1626 			policy_mgr_get_hw_mode_params(tmp, &mac1_ss_bw_info);
1627 			policy_mgr_update_mac_freq_info(psoc, pm_ctx,
1628 							hw_config_type,
1629 							tmp->phy_id, tmp);
1630 			emlsr_mode = HW_MODE_EMLSR;
1631 		} else if (hw_config_type == WMI_HW_MODE_AUX_EMLSR_SINGLE) {
1632 			/* eMLSR mode */
1633 			cap = &info->mac_phy_caps_ext2[i];
1634 			wlan_mlme_set_eml_params(psoc, cap);
1635 			policy_mgr_get_hw_mode_params(tmp, &mac1_ss_bw_info);
1636 			emlsr_mode = HW_MODE_EMLSR;
1637 		}
1638 
1639 		/* Updating HW mode list */
1640 		policy_mgr_set_hw_mode_params(psoc, mac0_ss_bw_info,
1641 			mac1_ss_bw_info, i, tmp->hw_mode_id, dbs_mode,
1642 			sbs_mode, emlsr_mode);
1643 		/* Update radio combination info */
1644 		policy_mgr_update_radio_combination_matrix(
1645 			psoc, mac0_ss_bw_info, mac1_ss_bw_info,
1646 			dbs_mode, sbs_mode);
1647 	}
1648 
1649 	/*
1650 	 * Initializing Current frequency with SMM frequency.
1651 	 */
1652 	policy_mgr_fill_curr_mac_freq_by_hwmode(pm_ctx, MODE_SMM);
1653 	policy_mgr_dump_freq_range(pm_ctx);
1654 
1655 	return QDF_STATUS_SUCCESS;
1656 }
1657 
policy_mgr_update_sbs_freq(struct wlan_objmgr_psoc * psoc,struct target_psoc_info * tgt_hdl)1658 QDF_STATUS policy_mgr_update_sbs_freq(struct wlan_objmgr_psoc *psoc,
1659 				      struct target_psoc_info *tgt_hdl)
1660 {
1661 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1662 	struct tgt_info *info;
1663 
1664 	pm_ctx = policy_mgr_get_context(psoc);
1665 	if (!pm_ctx) {
1666 		policy_mgr_err("Invalid Context");
1667 		return QDF_STATUS_E_FAILURE;
1668 	}
1669 
1670 	info = &tgt_hdl->info;
1671 	policy_mgr_debug("sbs_lower_band_end_freq %d",
1672 			 info->sbs_lower_band_end_freq);
1673 	policy_mgr_update_sbs_lowr_band_end_frq(pm_ctx, info);
1674 
1675 	policy_mgr_update_hw_mode_list(psoc, tgt_hdl);
1676 
1677 	return QDF_STATUS_SUCCESS;
1678 }
1679 
policy_mgr_get_sbs_cut_off_freq(struct wlan_objmgr_psoc * psoc)1680 qdf_freq_t policy_mgr_get_sbs_cut_off_freq(struct wlan_objmgr_psoc *psoc)
1681 {
1682 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1683 	struct policy_mgr_freq_range *first_mac_range, *second_mac_range;
1684 	qdf_freq_t sbs_cut_off_freq = 0;
1685 
1686 	pm_ctx = policy_mgr_get_context(psoc);
1687 	if (!pm_ctx) {
1688 		policy_mgr_err("Invalid Context");
1689 		return 0;
1690 	}
1691 
1692 	if (!policy_mgr_is_hw_sbs_capable(psoc))
1693 		return 0;
1694 
1695 	if (pm_ctx->hw_mode.sbs_lower_band_end_freq)
1696 		return pm_ctx->hw_mode.sbs_lower_band_end_freq;
1697 	/*
1698 	 * if cutoff freq is not available from FW (i.e SBS is not dynamic)
1699 	 * get it from SBS freq range
1700 	 */
1701 	first_mac_range = &pm_ctx->hw_mode.freq_range_caps[MODE_SBS][0];
1702 
1703 	second_mac_range =
1704 		&pm_ctx->hw_mode.freq_range_caps[MODE_SBS][1];
1705 
1706 	/*
1707 	 * SBS range is low 5Ghz shared with 2.4Ghz: The low_5Ghz of shared
1708 	 * mac will be starting of 5Ghz and low_5Ghz of non-shared mac will be
1709 	 * the cutoff freq
1710 	 *
1711 	 * SBS range is high 5Ghz shared with 2.4Ghz: The low_5Ghz of shared
1712 	 * mac will be cutoff freq and low_5Ghz of non-shared mac will be
1713 	 * the starting of 5Ghz
1714 	 *
1715 	 * so, maximum of low_5Ghz will be cutoff freq
1716 	 */
1717 	sbs_cut_off_freq = QDF_MAX(second_mac_range->low_5ghz_freq,
1718 				   first_mac_range->low_5ghz_freq) - 1;
1719 	policy_mgr_debug("sbs cutoff freq %d", sbs_cut_off_freq);
1720 
1721 	return sbs_cut_off_freq;
1722 }
1723 
1724 static bool
policy_mgr_2_freq_same_mac_in_freq_range(struct policy_mgr_psoc_priv_obj * pm_ctx,struct policy_mgr_freq_range * freq_range,qdf_freq_t freq_1,qdf_freq_t freq_2)1725 policy_mgr_2_freq_same_mac_in_freq_range(
1726 				struct policy_mgr_psoc_priv_obj *pm_ctx,
1727 				struct policy_mgr_freq_range *freq_range,
1728 				qdf_freq_t freq_1, qdf_freq_t freq_2)
1729 {
1730 	uint8_t i;
1731 
1732 	for (i = 0; i < MAX_MAC; i++) {
1733 		if (IS_FREQ_ON_MAC_ID(freq_range, freq_1, i) &&
1734 		    IS_FREQ_ON_MAC_ID(freq_range, freq_2, i))
1735 			return true;
1736 	}
1737 
1738 	return false;
1739 }
1740 
policy_mgr_can_2ghz_share_low_high_5ghz_sbs(struct policy_mgr_psoc_priv_obj * pm_ctx)1741 bool policy_mgr_can_2ghz_share_low_high_5ghz_sbs(
1742 			struct policy_mgr_psoc_priv_obj *pm_ctx)
1743 {
1744 	if (pm_ctx->hw_mode.sbs_lower_band_end_freq)
1745 		return true;
1746 
1747 	return false;
1748 }
1749 
1750 bool
policy_mgr_sbs_24_shared_with_high_5(struct policy_mgr_psoc_priv_obj * pm_ctx)1751 policy_mgr_sbs_24_shared_with_high_5(struct policy_mgr_psoc_priv_obj *pm_ctx)
1752 {
1753 	qdf_freq_t sbs_cut_off_freq;
1754 	struct policy_mgr_freq_range freq_range;
1755 	uint8_t i = 0;
1756 
1757 	if (policy_mgr_can_2ghz_share_low_high_5ghz_sbs(pm_ctx))
1758 		return true;
1759 
1760 	sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(pm_ctx->psoc);
1761 	if (!sbs_cut_off_freq) {
1762 		policy_mgr_err("Invalid cut off freq");
1763 		return false;
1764 	}
1765 
1766 	for (i = 0; i < MAX_MAC; i++) {
1767 		freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_SBS][i];
1768 		/*
1769 		 * if 5 GHZ start freq of this mac is greater than cutoff
1770 		 * return true
1771 		 */
1772 		if (freq_range.low_2ghz_freq && freq_range.low_5ghz_freq) {
1773 			if  (sbs_cut_off_freq < freq_range.low_5ghz_freq)
1774 				return true;
1775 		}
1776 	}
1777 
1778 	return false;
1779 }
1780 
1781 bool
policy_mgr_sbs_24_shared_with_low_5(struct policy_mgr_psoc_priv_obj * pm_ctx)1782 policy_mgr_sbs_24_shared_with_low_5(struct policy_mgr_psoc_priv_obj *pm_ctx)
1783 {
1784 	qdf_freq_t sbs_cut_off_freq;
1785 	struct policy_mgr_freq_range freq_range;
1786 	uint8_t i = 0;
1787 
1788 	if (policy_mgr_can_2ghz_share_low_high_5ghz_sbs(pm_ctx))
1789 		return true;
1790 
1791 	sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(pm_ctx->psoc);
1792 	if (!sbs_cut_off_freq) {
1793 		policy_mgr_err("Invalid cut off freq");
1794 		return false;
1795 	}
1796 
1797 	for (i = 0; i < MAX_MAC; i++) {
1798 		freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_SBS][i];
1799 		if (freq_range.low_2ghz_freq && freq_range.high_5ghz_freq) {
1800 			/*
1801 			 * if 5 GHZ end freq of this mac is less than cutoff
1802 			 * return true
1803 			 */
1804 			if  (sbs_cut_off_freq > freq_range.high_5ghz_freq)
1805 				return true;
1806 		}
1807 	}
1808 
1809 	return false;
1810 }
1811 
1812 bool
policy_mgr_2_freq_same_mac_in_dbs(struct policy_mgr_psoc_priv_obj * pm_ctx,qdf_freq_t freq_1,qdf_freq_t freq_2)1813 policy_mgr_2_freq_same_mac_in_dbs(struct policy_mgr_psoc_priv_obj *pm_ctx,
1814 				  qdf_freq_t freq_1, qdf_freq_t freq_2)
1815 {
1816 	struct policy_mgr_freq_range *freq_range;
1817 
1818 	/* Return true if non DBS capable HW */
1819 	if (!policy_mgr_is_hw_dbs_capable(pm_ctx->psoc))
1820 		return true;
1821 
1822 	freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_DBS];
1823 	return policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx, freq_range,
1824 							 freq_1, freq_2);
1825 }
1826 
1827 bool
policy_mgr_2_freq_same_mac_in_sbs(struct policy_mgr_psoc_priv_obj * pm_ctx,qdf_freq_t freq_1,qdf_freq_t freq_2)1828 policy_mgr_2_freq_same_mac_in_sbs(struct policy_mgr_psoc_priv_obj *pm_ctx,
1829 				  qdf_freq_t freq_1, qdf_freq_t freq_2)
1830 {
1831 	struct policy_mgr_freq_range *sbs_low_share;
1832 	struct policy_mgr_freq_range *sbs_uppr_share;
1833 	struct policy_mgr_freq_range *sbs_range;
1834 
1835 	/* Return true if non SBS capable HW */
1836 	if (!policy_mgr_is_hw_sbs_capable(pm_ctx->psoc))
1837 		return true;
1838 
1839 	if (policy_mgr_can_2ghz_share_low_high_5ghz_sbs(pm_ctx)) {
1840 		sbs_uppr_share =
1841 			pm_ctx->hw_mode.freq_range_caps[MODE_SBS_UPPER_SHARE];
1842 		sbs_low_share =
1843 			pm_ctx->hw_mode.freq_range_caps[MODE_SBS_LOWER_SHARE];
1844 		if (policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx,
1845 							     sbs_low_share,
1846 							     freq_1, freq_2) ||
1847 		    policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx,
1848 							     sbs_uppr_share,
1849 							     freq_1, freq_2))
1850 				return true;
1851 
1852 		return false;
1853 	}
1854 
1855 	sbs_range = pm_ctx->hw_mode.freq_range_caps[MODE_SBS];
1856 
1857 	return policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx, sbs_range,
1858 							freq_1, freq_2);
1859 }
1860 
1861 static bool
policy_mgr_is_cur_freq_range_sbs(struct wlan_objmgr_psoc * psoc)1862 policy_mgr_is_cur_freq_range_sbs(struct wlan_objmgr_psoc *psoc)
1863 {
1864 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1865 	struct policy_mgr_freq_range *freq_range;
1866 	uint8_t i;
1867 
1868 	pm_ctx = policy_mgr_get_context(psoc);
1869 	if (!pm_ctx)
1870 		return false;
1871 
1872 	/* Check if any of the mac is shared */
1873 	for (i = 0 ; i < MAX_MAC; i++) {
1874 		freq_range = &pm_ctx->hw_mode.cur_mac_freq_range[i];
1875 		if (freq_range->low_2ghz_freq && freq_range->low_5ghz_freq)
1876 			return true;
1877 	}
1878 
1879 	return false;
1880 }
1881 
policy_mgr_2_freq_always_on_same_mac(struct wlan_objmgr_psoc * psoc,qdf_freq_t freq_1,qdf_freq_t freq_2)1882 bool policy_mgr_2_freq_always_on_same_mac(struct wlan_objmgr_psoc *psoc,
1883 					  qdf_freq_t freq_1, qdf_freq_t freq_2)
1884 {
1885 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1886 	bool is_dbs_mode_same_mac = true;
1887 	bool is_sbs_mode_same_mac = true;
1888 
1889 	pm_ctx = policy_mgr_get_context(psoc);
1890 	if (!pm_ctx)
1891 		return false;
1892 
1893 	is_dbs_mode_same_mac =
1894 		policy_mgr_2_freq_same_mac_in_dbs(pm_ctx, freq_1, freq_2);
1895 
1896 	/* if DBS mode leading to same mac, check for SBS mode */
1897 	if (is_dbs_mode_same_mac)
1898 		is_sbs_mode_same_mac =
1899 			policy_mgr_2_freq_same_mac_in_sbs(pm_ctx, freq_1,
1900 							  freq_2);
1901 
1902 	policy_mgr_rl_debug("freq1 %d freq2 %d: Same mac:: DBS:%d SBS:%d",
1903 			    freq_1, freq_2, is_dbs_mode_same_mac,
1904 			    is_sbs_mode_same_mac);
1905 	/*
1906 	 * if in SBS and DBS mode, both is leading to freqs on same mac,
1907 	 * return true else return false.
1908 	 */
1909 	if (is_dbs_mode_same_mac && is_sbs_mode_same_mac)
1910 		return true;
1911 
1912 	return false;
1913 }
1914 
policy_mgr_are_2_freq_on_same_mac(struct wlan_objmgr_psoc * psoc,qdf_freq_t freq_1,qdf_freq_t freq_2)1915 bool policy_mgr_are_2_freq_on_same_mac(struct wlan_objmgr_psoc *psoc,
1916 				       qdf_freq_t freq_1,
1917 				       qdf_freq_t  freq_2)
1918 {
1919 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1920 	struct policy_mgr_freq_range *freq_range;
1921 	struct policy_mgr_hw_mode_params hw_mode;
1922 	QDF_STATUS status;
1923 	bool cur_range_sbs = false;
1924 
1925 	pm_ctx = policy_mgr_get_context(psoc);
1926 	if (!pm_ctx)
1927 		return false;
1928 
1929 	/* if HW is not DBS return true*/
1930 	if (!policy_mgr_is_hw_dbs_capable(psoc))
1931 		return true;
1932 
1933 	/* HW is DBS/SBS capable */
1934 	status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
1935 	if (!QDF_IS_STATUS_SUCCESS(status)) {
1936 		policy_mgr_err("policy_mgr_get_current_hw_mode failed");
1937 		return false;
1938 	}
1939 
1940 	if (hw_mode.dbs_cap || hw_mode.sbs_cap)
1941 		cur_range_sbs = policy_mgr_is_cur_freq_range_sbs(psoc);
1942 
1943 	freq_range = pm_ctx->hw_mode.cur_mac_freq_range;
1944 	/* current HW is DBS OR SBS check current DBS/SBS freq range */
1945 	if (hw_mode.dbs_cap || hw_mode.sbs_cap) {
1946 		policy_mgr_rl_debug("freq1 %d freq2 %d dbs_cap %d sbs_cap %d, cur range is sbs %d",
1947 				    freq_1, freq_2, hw_mode.dbs_cap,
1948 				    hw_mode.sbs_cap, cur_range_sbs);
1949 		return policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx,
1950 								freq_range,
1951 								freq_1, freq_2);
1952 	}
1953 
1954 	/*
1955 	 * If current HW mode is not DBS/SBS, check if in all supported mode
1956 	 * it they will be on same mac
1957 	 */
1958 	return policy_mgr_2_freq_always_on_same_mac(psoc, freq_1, freq_2);
1959 }
1960 
1961 static bool
policy_mgr_3_freq_same_mac_in_freq_range(struct policy_mgr_psoc_priv_obj * pm_ctx,struct policy_mgr_freq_range * freq_range,qdf_freq_t freq_1,qdf_freq_t freq_2,qdf_freq_t freq_3)1962 policy_mgr_3_freq_same_mac_in_freq_range(
1963 				struct policy_mgr_psoc_priv_obj *pm_ctx,
1964 				struct policy_mgr_freq_range *freq_range,
1965 				qdf_freq_t freq_1, qdf_freq_t freq_2,
1966 				qdf_freq_t freq_3)
1967 {
1968 	uint8_t i;
1969 
1970 	for (i = 0 ; i < MAX_MAC; i++) {
1971 		if (IS_FREQ_ON_MAC_ID(freq_range, freq_1, i) &&
1972 		    IS_FREQ_ON_MAC_ID(freq_range, freq_2, i) &&
1973 		    IS_FREQ_ON_MAC_ID(freq_range, freq_3, i))
1974 			return true;
1975 	}
1976 
1977 	return false;
1978 }
1979 
1980 static bool
policy_mgr_3_freq_same_mac_in_sbs(struct policy_mgr_psoc_priv_obj * pm_ctx,qdf_freq_t freq_1,qdf_freq_t freq_2,qdf_freq_t freq_3)1981 policy_mgr_3_freq_same_mac_in_sbs(struct policy_mgr_psoc_priv_obj *pm_ctx,
1982 				  qdf_freq_t freq_1, qdf_freq_t freq_2,
1983 				  qdf_freq_t freq_3)
1984 {
1985 	struct policy_mgr_freq_range *sbs_low_share;
1986 	struct policy_mgr_freq_range *sbs_uppr_share;
1987 	struct policy_mgr_freq_range *sbs_range;
1988 
1989 	/* Return true if non SBS capable HW */
1990 	if (!policy_mgr_is_hw_sbs_capable(pm_ctx->psoc))
1991 		return true;
1992 
1993 	if (pm_ctx->hw_mode.sbs_lower_band_end_freq) {
1994 		sbs_uppr_share =
1995 			pm_ctx->hw_mode.freq_range_caps[MODE_SBS_UPPER_SHARE];
1996 		sbs_low_share =
1997 			pm_ctx->hw_mode.freq_range_caps[MODE_SBS_LOWER_SHARE];
1998 		if (policy_mgr_3_freq_same_mac_in_freq_range(pm_ctx,
1999 							     sbs_low_share,
2000 							     freq_1, freq_2,
2001 							     freq_3) ||
2002 		    policy_mgr_3_freq_same_mac_in_freq_range(pm_ctx,
2003 							     sbs_uppr_share,
2004 							     freq_1, freq_2,
2005 							     freq_3))
2006 			return true;
2007 
2008 		return false;
2009 	}
2010 
2011 	sbs_range = pm_ctx->hw_mode.freq_range_caps[MODE_SBS];
2012 	return policy_mgr_3_freq_same_mac_in_freq_range(pm_ctx, sbs_range,
2013 							freq_1, freq_2, freq_3);
2014 }
2015 
2016 bool
policy_mgr_3_freq_always_on_same_mac(struct wlan_objmgr_psoc * psoc,qdf_freq_t freq_1,qdf_freq_t freq_2,qdf_freq_t freq_3)2017 policy_mgr_3_freq_always_on_same_mac(struct wlan_objmgr_psoc *psoc,
2018 				     qdf_freq_t freq_1, qdf_freq_t freq_2,
2019 				     qdf_freq_t freq_3)
2020 {
2021 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2022 	struct policy_mgr_freq_range *freq_range;
2023 	bool is_dbs_mode_same_mac = true;
2024 	bool is_sbs_mode_same_mac = true;
2025 
2026 	pm_ctx = policy_mgr_get_context(psoc);
2027 	if (!pm_ctx)
2028 		return false;
2029 
2030 	/* if HW is not DBS return true*/
2031 	if (!policy_mgr_is_hw_dbs_capable(psoc))
2032 		return true;
2033 
2034 	/* Check for DBS mode first */
2035 	freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_DBS];
2036 	is_dbs_mode_same_mac =
2037 		policy_mgr_3_freq_same_mac_in_freq_range(pm_ctx, freq_range,
2038 							 freq_1, freq_2,
2039 							 freq_3);
2040 
2041 	/* if DBS mode leading to same mac, check for SBS mode */
2042 	if (is_dbs_mode_same_mac)
2043 		is_sbs_mode_same_mac =
2044 			policy_mgr_3_freq_same_mac_in_sbs(pm_ctx, freq_1,
2045 							  freq_2, freq_3);
2046 
2047 	policy_mgr_rl_debug("freq1 %d freq2 %d freq3 %d: Same mac:: DBS:%d SBS:%d",
2048 			    freq_1, freq_2, freq_3, is_dbs_mode_same_mac,
2049 			    is_sbs_mode_same_mac);
2050 	/*
2051 	 * if in SBS and DBS mode, both is leading to freqs on same mac,
2052 	 * return true else return false.
2053 	 */
2054 	if (is_dbs_mode_same_mac && is_sbs_mode_same_mac)
2055 		return true;
2056 
2057 	return false;
2058 }
2059 
2060 bool
policy_mgr_are_3_freq_on_same_mac(struct wlan_objmgr_psoc * psoc,qdf_freq_t freq_1,qdf_freq_t freq_2,qdf_freq_t freq_3)2061 policy_mgr_are_3_freq_on_same_mac(struct wlan_objmgr_psoc *psoc,
2062 				  qdf_freq_t freq_1, qdf_freq_t freq_2,
2063 				  qdf_freq_t freq_3)
2064 {
2065 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2066 	struct policy_mgr_freq_range *freq_range;
2067 	QDF_STATUS status;
2068 	struct policy_mgr_hw_mode_params hw_mode;
2069 	bool cur_range_sbs = false;
2070 
2071 	pm_ctx = policy_mgr_get_context(psoc);
2072 	if (!pm_ctx)
2073 		return false;
2074 
2075 	/* if HW is not DBS return true*/
2076 	if (!policy_mgr_is_hw_dbs_capable(psoc))
2077 		return true;
2078 
2079 	/* HW is DBS/SBS capable, get current HW mode */
2080 	status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
2081 	if (!QDF_IS_STATUS_SUCCESS(status)) {
2082 		policy_mgr_err("policy_mgr_get_current_hw_mode failed");
2083 		return false;
2084 	}
2085 	if (hw_mode.dbs_cap || hw_mode.sbs_cap)
2086 		cur_range_sbs = policy_mgr_is_cur_freq_range_sbs(psoc);
2087 
2088 	freq_range = pm_ctx->hw_mode.cur_mac_freq_range;
2089 
2090 	/* current HW is DBS OR SBS check current DBS/SBS freq range */
2091 	if (hw_mode.dbs_cap || hw_mode.sbs_cap) {
2092 		policy_mgr_rl_debug("freq1 %d freq2 %d freq3 %d dbs_cap %d sbs_cap %d, cur range is sbs %d",
2093 				     freq_1, freq_2, freq_3, hw_mode.dbs_cap,
2094 				     hw_mode.sbs_cap, cur_range_sbs);
2095 		return policy_mgr_3_freq_same_mac_in_freq_range(pm_ctx,
2096 							freq_range,
2097 							freq_1, freq_2, freq_3);
2098 	}
2099 	/*
2100 	 * If current HW mode is not DBS/SBS, check if in all supported mode
2101 	 * it they will be on same mac
2102 	 */
2103 	return policy_mgr_3_freq_always_on_same_mac(psoc, freq_1, freq_2,
2104 						    freq_3);
2105 }
2106 
2107 #ifdef FEATURE_FOURTH_CONNECTION
2108 static void
policy_mgr_get_mac_freq_list(struct policy_mgr_freq_range * freq_range,uint8_t mac_id,uint8_t mac_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS],uint8_t mac_mode_list[MAX_NUMBER_OF_CONC_CONNECTIONS],uint8_t * mac_freq_num,qdf_freq_t freq_1,enum policy_mgr_con_mode mode_1,qdf_freq_t freq_2,enum policy_mgr_con_mode mode_2,qdf_freq_t freq_3,enum policy_mgr_con_mode mode_3,qdf_freq_t freq_4,enum policy_mgr_con_mode mode_4)2109 policy_mgr_get_mac_freq_list(struct policy_mgr_freq_range *freq_range,
2110 			     uint8_t mac_id,
2111 			     uint8_t mac_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS],
2112 			     uint8_t mac_mode_list[MAX_NUMBER_OF_CONC_CONNECTIONS],
2113 			     uint8_t *mac_freq_num,
2114 			     qdf_freq_t freq_1, enum policy_mgr_con_mode mode_1,
2115 			     qdf_freq_t freq_2, enum policy_mgr_con_mode mode_2,
2116 			     qdf_freq_t freq_3, enum policy_mgr_con_mode mode_3,
2117 			     qdf_freq_t freq_4, enum policy_mgr_con_mode mode_4)
2118 {
2119 	uint8_t j = 0;
2120 
2121 	if (freq_1 && IS_FREQ_ON_MAC_ID(freq_range, freq_1, mac_id)) {
2122 		mac_freq_list[j] = freq_1;
2123 		mac_mode_list[j++] = mode_1;
2124 	}
2125 	if (freq_2 && IS_FREQ_ON_MAC_ID(freq_range, freq_2, mac_id)) {
2126 		mac_freq_list[j] = freq_2;
2127 		mac_mode_list[j++] = mode_2;
2128 	}
2129 	if (freq_3 && IS_FREQ_ON_MAC_ID(freq_range, freq_3, mac_id)) {
2130 		mac_freq_list[j] = freq_3;
2131 		mac_mode_list[j++] = mode_3;
2132 	}
2133 	if (freq_4 && IS_FREQ_ON_MAC_ID(freq_range, freq_4, mac_id)) {
2134 		mac_freq_list[j] = freq_4;
2135 		mac_mode_list[j++] = mode_4;
2136 	}
2137 
2138 	*mac_freq_num = j;
2139 }
2140 
2141 static bool
policy_mgr_is_supported_hw_mode(struct wlan_objmgr_psoc * psoc,struct policy_mgr_psoc_priv_obj * pm_ctx,enum policy_mgr_mode hw_mode)2142 policy_mgr_is_supported_hw_mode(struct wlan_objmgr_psoc *psoc,
2143 				struct policy_mgr_psoc_priv_obj *pm_ctx,
2144 				enum policy_mgr_mode hw_mode)
2145 {
2146 	if (hw_mode == MODE_SMM)
2147 		return true;
2148 
2149 	if (hw_mode == MODE_DBS)
2150 		return policy_mgr_is_hw_dbs_capable(psoc);
2151 
2152 	if (hw_mode == MODE_SBS_UPPER_SHARE ||
2153 	    hw_mode == MODE_SBS_LOWER_SHARE)
2154 		return policy_mgr_is_hw_sbs_capable(psoc) &&
2155 			pm_ctx->hw_mode.sbs_lower_band_end_freq;
2156 
2157 	if (hw_mode == MODE_SBS)
2158 		return policy_mgr_is_hw_sbs_capable(psoc);
2159 
2160 	return false;
2161 }
2162 
2163 static bool
policy_mgr_mac_freq_list_allow(uint8_t mac_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS],uint8_t mac_mode_list[MAX_NUMBER_OF_CONC_CONNECTIONS],uint8_t mac_freq_num)2164 policy_mgr_mac_freq_list_allow(uint8_t mac_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS],
2165 			       uint8_t mac_mode_list[MAX_NUMBER_OF_CONC_CONNECTIONS],
2166 			       uint8_t mac_freq_num)
2167 {
2168 	uint8_t sta = 0, ap = 0, i;
2169 
2170 	switch (mac_freq_num) {
2171 	case 1:
2172 	case 2:
2173 		return true;
2174 	case 3:
2175 		/* If 3 vifs are active in same mac, target only support:
2176 		 * 3 vifs are in SCC and 3 vifs are :
2177 		 * 1 STA + 2 APs, or 3 APs
2178 		 */
2179 		if (mac_freq_list[0] != mac_freq_list[1] ||
2180 		    mac_freq_list[0] != mac_freq_list[2])
2181 			return false;
2182 		for (i = 0; i < mac_freq_num; i++) {
2183 			if (mac_mode_list[i] == PM_STA_MODE ||
2184 			    mac_mode_list[i] == PM_P2P_CLIENT_MODE)
2185 				sta++;
2186 			else
2187 				ap++;
2188 		}
2189 
2190 		if (sta == 1 && ap == 2)
2191 			return true;
2192 		if (ap == 3)
2193 			return true;
2194 		return false;
2195 	default:
2196 		return false;
2197 	}
2198 }
2199 
2200 #ifdef WLAN_FEATURE_11BE_MLO
2201 static void
policy_mgr_ml_sta_active_freq(struct wlan_objmgr_psoc * psoc,qdf_freq_t ch_freq,enum policy_mgr_con_mode mode,uint32_t ext_flags,qdf_freq_t * ml_sta_link0_freq,qdf_freq_t * ml_sta_link1_freq)2202 policy_mgr_ml_sta_active_freq(struct wlan_objmgr_psoc *psoc,
2203 			      qdf_freq_t ch_freq,
2204 			      enum policy_mgr_con_mode mode,
2205 			      uint32_t ext_flags,
2206 			      qdf_freq_t *ml_sta_link0_freq,
2207 			      qdf_freq_t *ml_sta_link1_freq)
2208 {
2209 	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0;
2210 	uint8_t num_active_ml_sta;
2211 	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
2212 	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
2213 	union conc_ext_flag conc_ext_flags;
2214 
2215 	conc_ext_flags.value = ext_flags;
2216 	/* find the two active ml sta home channels */
2217 	policy_mgr_get_ml_sta_info_psoc(psoc, &num_ml_sta,
2218 					&num_disabled_ml_sta,
2219 					ml_sta_vdev_lst, ml_freq_lst,
2220 					NULL, NULL, NULL);
2221 	if (num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
2222 	    num_disabled_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
2223 	    num_ml_sta <= num_disabled_ml_sta) {
2224 		if (num_ml_sta || num_disabled_ml_sta)
2225 			policy_mgr_rl_debug("unexpected ml sta num %d %d",
2226 					    num_ml_sta, num_disabled_ml_sta);
2227 		return;
2228 	}
2229 	num_active_ml_sta = num_ml_sta;
2230 	if (num_ml_sta >= num_disabled_ml_sta)
2231 		num_active_ml_sta = num_ml_sta - num_disabled_ml_sta;
2232 	if (num_active_ml_sta > 1) {
2233 		*ml_sta_link0_freq = ml_freq_lst[0];
2234 		*ml_sta_link1_freq = ml_freq_lst[1];
2235 	} else if (num_active_ml_sta > 0 && conc_ext_flags.mlo &&
2236 		   mode == PM_STA_MODE) {
2237 		*ml_sta_link0_freq = ml_freq_lst[0];
2238 		*ml_sta_link1_freq = ch_freq;
2239 	}
2240 }
2241 #else
2242 static void
policy_mgr_ml_sta_active_freq(struct wlan_objmgr_psoc * psoc,qdf_freq_t ch_freq,enum policy_mgr_con_mode mode,uint32_t ext_flags,qdf_freq_t * ml_sta_link0_freq,qdf_freq_t * ml_sta_link1_freq)2243 policy_mgr_ml_sta_active_freq(struct wlan_objmgr_psoc *psoc,
2244 			      qdf_freq_t ch_freq,
2245 			      enum policy_mgr_con_mode mode,
2246 			      uint32_t ext_flags,
2247 			      qdf_freq_t *ml_sta_link0_freq,
2248 			      qdf_freq_t *ml_sta_link1_freq)
2249 {
2250 }
2251 #endif
2252 
2253 bool
policy_mgr_allow_4th_new_freq(struct wlan_objmgr_psoc * psoc,qdf_freq_t ch_freq,enum policy_mgr_con_mode mode,uint32_t ext_flags)2254 policy_mgr_allow_4th_new_freq(struct wlan_objmgr_psoc *psoc,
2255 			      qdf_freq_t ch_freq,
2256 			      enum policy_mgr_con_mode mode,
2257 			      uint32_t ext_flags)
2258 {
2259 	struct policy_mgr_conc_connection_info *conn = pm_conc_connection_list;
2260 	uint8_t mac_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
2261 	uint8_t mac_mode_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
2262 	uint8_t mac_freq_num;
2263 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2264 	qdf_freq_t ml_sta_link0_freq = 0;
2265 	qdf_freq_t ml_sta_link1_freq = 0;
2266 	uint8_t i, j;
2267 	struct policy_mgr_freq_range *freq_range;
2268 
2269 	pm_ctx = policy_mgr_get_context(psoc);
2270 	if (!pm_ctx) {
2271 		policy_mgr_err("Invalid Context");
2272 		return false;
2273 	}
2274 
2275 	/* if HW is not DBS return false */
2276 	if (!policy_mgr_is_hw_dbs_capable(psoc))
2277 		return false;
2278 
2279 	/* Find the two active ml sta home channels */
2280 	policy_mgr_ml_sta_active_freq(psoc, ch_freq, mode, ext_flags,
2281 				      &ml_sta_link0_freq,
2282 				      &ml_sta_link1_freq);
2283 
2284 	/* Check if any hw mode can support the 4th channel frequency
2285 	 * and device mode.
2286 	 */
2287 	for (j = 0; j < MODE_HW_MAX; j++) {
2288 		if (!policy_mgr_is_supported_hw_mode(psoc, pm_ctx, j))
2289 			continue;
2290 		freq_range = pm_ctx->hw_mode.freq_range_caps[j];
2291 
2292 		/* If ml sta present, the two links should be in
2293 		 * different mac always. Skip the hw mode which
2294 		 * causes they in same mac.
2295 		 */
2296 		if (ml_sta_link0_freq && ml_sta_link1_freq &&
2297 		    policy_mgr_2_freq_same_mac_in_freq_range(pm_ctx,
2298 							     freq_range,
2299 							     ml_sta_link0_freq,
2300 							     ml_sta_link1_freq))
2301 			continue;
2302 		for (i = 0; i < MAX_MAC; i++) {
2303 			/* Get the freq list which are in the MAC
2304 			 * supported freq range.
2305 			 */
2306 			policy_mgr_get_mac_freq_list(
2307 				freq_range,
2308 				i,
2309 				mac_freq_list, mac_mode_list, &mac_freq_num,
2310 				conn[0].freq, conn[0].mode,
2311 				conn[1].freq, conn[1].mode,
2312 				conn[2].freq, conn[2].mode,
2313 				ch_freq, mode);
2314 
2315 			/* Check the freq & mode list support or not in the
2316 			 * MAC.
2317 			 */
2318 			if (!policy_mgr_mac_freq_list_allow(
2319 				mac_freq_list, mac_mode_list, mac_freq_num))
2320 				break;
2321 		}
2322 
2323 		/* If the frequency/mode combination meet requirement in the
2324 		 * hw mode, then the 4th new ch_freq/mode are allowed to start
2325 		 * in this hw mode.
2326 		 */
2327 		if (i == MAX_MAC) {
2328 			policy_mgr_rl_debug("new freq %d mode %s is allowed in hw mode %s",
2329 					    ch_freq,
2330 					    device_mode_to_string(mode),
2331 					    policy_mgr_hw_mode_to_str(j));
2332 			return true;
2333 		}
2334 	}
2335 	policy_mgr_debug("the 4th new freq %d mode %s is not allowed in any hw mode",
2336 			 ch_freq, device_mode_to_string(mode));
2337 
2338 	return false;
2339 }
2340 #endif
2341 
policy_mgr_are_sbs_chan(struct wlan_objmgr_psoc * psoc,qdf_freq_t freq_1,qdf_freq_t freq_2)2342 bool policy_mgr_are_sbs_chan(struct wlan_objmgr_psoc *psoc, qdf_freq_t freq_1,
2343 			     qdf_freq_t freq_2)
2344 {
2345 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2346 
2347 	pm_ctx = policy_mgr_get_context(psoc);
2348 	if (!pm_ctx)
2349 		return false;
2350 
2351 	if (!policy_mgr_is_hw_sbs_capable(psoc))
2352 		return false;
2353 
2354 	if (WLAN_REG_IS_24GHZ_CH_FREQ(freq_1) ||
2355 	    WLAN_REG_IS_24GHZ_CH_FREQ(freq_2))
2356 		return false;
2357 
2358 	return !policy_mgr_2_freq_same_mac_in_sbs(pm_ctx, freq_1, freq_2);
2359 }
2360 
policy_mgr_is_current_hwmode_sbs(struct wlan_objmgr_psoc * psoc)2361 bool policy_mgr_is_current_hwmode_sbs(struct wlan_objmgr_psoc *psoc)
2362 {
2363 	struct policy_mgr_hw_mode_params hw_mode;
2364 
2365 	if (!policy_mgr_is_hw_sbs_capable(psoc))
2366 		return false;
2367 
2368 	if (QDF_STATUS_SUCCESS !=
2369 	    policy_mgr_get_current_hw_mode(psoc, &hw_mode))
2370 		return false;
2371 
2372 	if (hw_mode.sbs_cap && policy_mgr_is_cur_freq_range_sbs(psoc))
2373 		return true;
2374 
2375 	return false;
2376 }
2377 
policy_mgr_init_dbs_hw_mode(struct wlan_objmgr_psoc * psoc,uint32_t num_dbs_hw_modes,uint32_t * ev_wlan_dbs_hw_mode_list)2378 void policy_mgr_init_dbs_hw_mode(struct wlan_objmgr_psoc *psoc,
2379 		uint32_t num_dbs_hw_modes,
2380 		uint32_t *ev_wlan_dbs_hw_mode_list)
2381 {
2382 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2383 
2384 	pm_ctx = policy_mgr_get_context(psoc);
2385 	if (!pm_ctx) {
2386 		policy_mgr_err("Invalid Context");
2387 		return;
2388 	}
2389 
2390 	pm_ctx->num_dbs_hw_modes = num_dbs_hw_modes;
2391 	pm_ctx->hw_mode.hw_mode_list =
2392 		qdf_mem_malloc(sizeof(*pm_ctx->hw_mode.hw_mode_list) *
2393 		pm_ctx->num_dbs_hw_modes);
2394 	if (!pm_ctx->hw_mode.hw_mode_list) {
2395 		pm_ctx->num_dbs_hw_modes = 0;
2396 		return;
2397 	}
2398 
2399 	qdf_mem_copy(pm_ctx->hw_mode.hw_mode_list,
2400 		ev_wlan_dbs_hw_mode_list,
2401 		(sizeof(*pm_ctx->hw_mode.hw_mode_list) *
2402 		pm_ctx->num_dbs_hw_modes));
2403 
2404 	policy_mgr_dump_dbs_hw_mode(psoc);
2405 }
2406 
policy_mgr_dump_dbs_hw_mode(struct wlan_objmgr_psoc * psoc)2407 void policy_mgr_dump_dbs_hw_mode(struct wlan_objmgr_psoc *psoc)
2408 {
2409 	uint32_t i;
2410 	uint32_t param;
2411 	uint32_t param1;
2412 
2413 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2414 
2415 	pm_ctx = policy_mgr_get_context(psoc);
2416 	if (!pm_ctx) {
2417 		policy_mgr_err("Invalid Context");
2418 		return;
2419 	}
2420 	policy_mgr_debug("old_hw_mode_index=%d, new_hw_mode_index=%d",
2421 			 pm_ctx->old_hw_mode_index, pm_ctx->new_hw_mode_index);
2422 
2423 	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
2424 		param = pm_ctx->hw_mode.hw_mode_list[i];
2425 		param1 = pm_ctx->hw_mode.hw_mode_list[i] >> 32;
2426 		policy_mgr_debug("[%d] 0x%x 0x%x", i, param, param1);
2427 		policy_mgr_debug("[%d]-MAC0: tx_ss:%d rx_ss:%d bw_idx:%d band_cap:%d",
2428 				 i,
2429 				 POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param),
2430 				 POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param),
2431 				 POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(param),
2432 				 POLICY_MGR_HW_MODE_MAC0_BAND_GET(param));
2433 		policy_mgr_debug("[%d]-MAC1: tx_ss:%d rx_ss:%d bw_idx:%d",
2434 				 i,
2435 				 POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param),
2436 				 POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param),
2437 				 POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(param));
2438 		policy_mgr_debug("[%d] DBS:%d SBS:%d hw_mode_id:%d", i,
2439 				 POLICY_MGR_HW_MODE_DBS_MODE_GET(param),
2440 				 POLICY_MGR_HW_MODE_SBS_MODE_GET(param),
2441 				 POLICY_MGR_HW_MODE_ID_GET(param));
2442 	}
2443 }
2444 
policy_mgr_init_dbs_config(struct wlan_objmgr_psoc * psoc,uint32_t scan_config,uint32_t fw_config)2445 void policy_mgr_init_dbs_config(struct wlan_objmgr_psoc *psoc,
2446 		uint32_t scan_config, uint32_t fw_config)
2447 {
2448 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2449 	uint8_t dual_mac_feature;
2450 
2451 	pm_ctx = policy_mgr_get_context(psoc);
2452 	if (!pm_ctx) {
2453 		policy_mgr_err("Invalid Context");
2454 		return;
2455 	}
2456 	pm_ctx->dual_mac_cfg.cur_scan_config = 0;
2457 	pm_ctx->dual_mac_cfg.cur_fw_mode_config = 0;
2458 
2459 	dual_mac_feature = pm_ctx->cfg.dual_mac_feature;
2460 	/* If dual mac features are disabled in the INI, we
2461 	 * need not proceed further
2462 	 */
2463 	if (dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) {
2464 		policy_mgr_err("Disabling dual mac capabilities");
2465 		/* All capabilities are initialized to 0. We can return */
2466 		goto done;
2467 	}
2468 
2469 	/* Initialize concurrent_scan_config_bits with default FW value */
2470 	WMI_DBS_CONC_SCAN_CFG_ASYNC_DBS_SCAN_SET(
2471 		pm_ctx->dual_mac_cfg.cur_scan_config,
2472 		WMI_DBS_CONC_SCAN_CFG_ASYNC_DBS_SCAN_GET(scan_config));
2473 	WMI_DBS_CONC_SCAN_CFG_SYNC_DBS_SCAN_SET(
2474 		pm_ctx->dual_mac_cfg.cur_scan_config,
2475 		WMI_DBS_CONC_SCAN_CFG_SYNC_DBS_SCAN_GET(scan_config));
2476 	WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_SET(
2477 		pm_ctx->dual_mac_cfg.cur_scan_config,
2478 		WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_GET(scan_config));
2479 	WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_SET(
2480 		pm_ctx->dual_mac_cfg.cur_scan_config,
2481 		WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_GET(scan_config));
2482 	WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_SET(
2483 		pm_ctx->dual_mac_cfg.cur_scan_config,
2484 		WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_GET(scan_config));
2485 
2486 	/* Initialize fw_mode_config_bits with default FW value */
2487 	WMI_DBS_FW_MODE_CFG_DBS_SET(
2488 		pm_ctx->dual_mac_cfg.cur_fw_mode_config,
2489 		WMI_DBS_FW_MODE_CFG_DBS_GET(fw_config));
2490 	WMI_DBS_FW_MODE_CFG_AGILE_DFS_SET(
2491 		pm_ctx->dual_mac_cfg.cur_fw_mode_config,
2492 		WMI_DBS_FW_MODE_CFG_AGILE_DFS_GET(fw_config));
2493 	WMI_DBS_FW_MODE_CFG_DBS_FOR_CXN_SET(
2494 		pm_ctx->dual_mac_cfg.cur_fw_mode_config,
2495 		WMI_DBS_FW_MODE_CFG_DBS_FOR_CXN_GET(fw_config));
2496 done:
2497 	/* Initialize the previous scan/fw mode config */
2498 	pm_ctx->dual_mac_cfg.prev_scan_config =
2499 		pm_ctx->dual_mac_cfg.cur_scan_config;
2500 	pm_ctx->dual_mac_cfg.prev_fw_mode_config =
2501 		pm_ctx->dual_mac_cfg.cur_fw_mode_config;
2502 
2503 	policy_mgr_debug("cur_scan_config:%x cur_fw_mode_config:%x",
2504 		pm_ctx->dual_mac_cfg.cur_scan_config,
2505 		pm_ctx->dual_mac_cfg.cur_fw_mode_config);
2506 }
2507 
policy_mgr_init_sbs_fw_config(struct wlan_objmgr_psoc * psoc,uint32_t fw_config)2508 void policy_mgr_init_sbs_fw_config(struct wlan_objmgr_psoc *psoc,
2509 				   uint32_t fw_config)
2510 {
2511 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2512 	bool sbs_enabled;
2513 
2514 	pm_ctx = policy_mgr_get_context(psoc);
2515 	if (!pm_ctx) {
2516 		policy_mgr_err("Invalid Context");
2517 		return;
2518 	}
2519 
2520 	/*
2521 	 * If SBS is not enabled from ini, no need to set SBS bits in fw config
2522 	 */
2523 	sbs_enabled = pm_ctx->cfg.sbs_enable;
2524 	if (!sbs_enabled) {
2525 		policy_mgr_debug("SBS not enabled from ini");
2526 		return;
2527 	}
2528 
2529 	/* Initialize fw_mode_config_bits with default FW value */
2530 	WMI_DBS_FW_MODE_CFG_ASYNC_SBS_SET(
2531 			pm_ctx->dual_mac_cfg.cur_fw_mode_config,
2532 			WMI_DBS_FW_MODE_CFG_ASYNC_SBS_GET(fw_config));
2533 
2534 	policy_mgr_debug("fw_mode config updated from %x to %x",
2535 			 pm_ctx->dual_mac_cfg.prev_fw_mode_config,
2536 			 pm_ctx->dual_mac_cfg.cur_fw_mode_config);
2537 	/* Initialize the previous scan/fw mode config */
2538 	pm_ctx->dual_mac_cfg.prev_fw_mode_config =
2539 		pm_ctx->dual_mac_cfg.cur_fw_mode_config;
2540 }
2541 
policy_mgr_update_dbs_scan_config(struct wlan_objmgr_psoc * psoc)2542 void policy_mgr_update_dbs_scan_config(struct wlan_objmgr_psoc *psoc)
2543 {
2544 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2545 
2546 	pm_ctx = policy_mgr_get_context(psoc);
2547 	if (!pm_ctx) {
2548 		policy_mgr_err("Invalid Context");
2549 		return;
2550 	}
2551 
2552 	pm_ctx->dual_mac_cfg.prev_scan_config =
2553 		pm_ctx->dual_mac_cfg.cur_scan_config;
2554 	pm_ctx->dual_mac_cfg.cur_scan_config =
2555 		pm_ctx->dual_mac_cfg.req_scan_config;
2556 }
2557 
policy_mgr_update_dbs_fw_config(struct wlan_objmgr_psoc * psoc)2558 void policy_mgr_update_dbs_fw_config(struct wlan_objmgr_psoc *psoc)
2559 {
2560 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2561 
2562 	pm_ctx = policy_mgr_get_context(psoc);
2563 	if (!pm_ctx) {
2564 		policy_mgr_err("Invalid Context");
2565 		return;
2566 	}
2567 
2568 	pm_ctx->dual_mac_cfg.prev_fw_mode_config =
2569 		pm_ctx->dual_mac_cfg.cur_fw_mode_config;
2570 	pm_ctx->dual_mac_cfg.cur_fw_mode_config =
2571 		pm_ctx->dual_mac_cfg.req_fw_mode_config;
2572 }
2573 
policy_mgr_update_dbs_req_config(struct wlan_objmgr_psoc * psoc,uint32_t scan_config,uint32_t fw_mode_config)2574 void policy_mgr_update_dbs_req_config(struct wlan_objmgr_psoc *psoc,
2575 		uint32_t scan_config, uint32_t fw_mode_config)
2576 {
2577 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2578 
2579 	pm_ctx = policy_mgr_get_context(psoc);
2580 	if (!pm_ctx) {
2581 		policy_mgr_err("Invalid Context");
2582 		return;
2583 	}
2584 	pm_ctx->dual_mac_cfg.req_scan_config = scan_config;
2585 	pm_ctx->dual_mac_cfg.req_fw_mode_config = fw_mode_config;
2586 }
2587 
policy_mgr_get_dbs_plus_agile_scan_config(struct wlan_objmgr_psoc * psoc)2588 bool policy_mgr_get_dbs_plus_agile_scan_config(struct wlan_objmgr_psoc *psoc)
2589 {
2590 	uint32_t scan_config;
2591 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2592 
2593 	if (policy_mgr_is_dual_mac_disabled_in_ini(psoc))
2594 		return false;
2595 
2596 
2597 	pm_ctx = policy_mgr_get_context(psoc);
2598 	if (!pm_ctx) {
2599 		policy_mgr_err("Invalid Context");
2600 		/* We take that it is disabled and proceed */
2601 		return false;
2602 	}
2603 	scan_config = pm_ctx->dual_mac_cfg.cur_scan_config;
2604 
2605 	return WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_GET(scan_config);
2606 }
2607 
policy_mgr_get_single_mac_scan_with_dfs_config(struct wlan_objmgr_psoc * psoc)2608 bool policy_mgr_get_single_mac_scan_with_dfs_config(
2609 		struct wlan_objmgr_psoc *psoc)
2610 {
2611 	uint32_t scan_config;
2612 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2613 
2614 	if (policy_mgr_is_dual_mac_disabled_in_ini(psoc))
2615 		return false;
2616 
2617 
2618 	pm_ctx = policy_mgr_get_context(psoc);
2619 	if (!pm_ctx) {
2620 		policy_mgr_err("Invalid Context");
2621 		/* We take that it is disabled and proceed */
2622 		return false;
2623 	}
2624 	scan_config = pm_ctx->dual_mac_cfg.cur_scan_config;
2625 
2626 	return WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_GET(scan_config);
2627 }
2628 
policy_mgr_get_num_dbs_hw_modes(struct wlan_objmgr_psoc * psoc)2629 int8_t policy_mgr_get_num_dbs_hw_modes(struct wlan_objmgr_psoc *psoc)
2630 {
2631 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2632 
2633 	pm_ctx = policy_mgr_get_context(psoc);
2634 	if (!pm_ctx) {
2635 		policy_mgr_err("Invalid Context");
2636 		return -EINVAL;
2637 	}
2638 	return pm_ctx->num_dbs_hw_modes;
2639 }
2640 
policy_mgr_find_if_fw_supports_dbs(struct wlan_objmgr_psoc * psoc)2641 bool policy_mgr_find_if_fw_supports_dbs(struct wlan_objmgr_psoc *psoc)
2642 {
2643 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2644 	struct wmi_unified *wmi_handle;
2645 	bool dbs_support;
2646 
2647 	pm_ctx = policy_mgr_get_context(psoc);
2648 
2649 	if (!pm_ctx) {
2650 		policy_mgr_err("Invalid Context");
2651 		return false;
2652 	}
2653 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
2654 	if (!wmi_handle) {
2655 		policy_mgr_debug("Invalid WMI handle");
2656 		return false;
2657 	}
2658 	dbs_support =
2659 	wmi_service_enabled(wmi_handle,
2660 			    wmi_service_dual_band_simultaneous_support);
2661 
2662 	/* The agreement with FW is that: To know if the target is DBS
2663 	 * capable, DBS needs to be supported both in the HW mode list
2664 	 * and in the service ready event
2665 	 */
2666 	if (!dbs_support)
2667 		return false;
2668 
2669 	return true;
2670 }
2671 
policy_mgr_find_if_hwlist_has_dbs(struct wlan_objmgr_psoc * psoc)2672 bool policy_mgr_find_if_hwlist_has_dbs(struct wlan_objmgr_psoc *psoc)
2673 {
2674 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2675 	uint32_t param, i, found = 0;
2676 
2677 	pm_ctx = policy_mgr_get_context(psoc);
2678 
2679 	if (!pm_ctx) {
2680 		policy_mgr_err("Invalid Context");
2681 		return false;
2682 	}
2683 	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
2684 		param = pm_ctx->hw_mode.hw_mode_list[i];
2685 		if (POLICY_MGR_HW_MODE_DBS_MODE_GET(param)) {
2686 			found = 1;
2687 			break;
2688 		}
2689 	}
2690 	if (found)
2691 		return true;
2692 
2693 	return false;
2694 }
2695 
policy_mgr_find_if_hwlist_has_sbs(struct wlan_objmgr_psoc * psoc)2696 static bool policy_mgr_find_if_hwlist_has_sbs(struct wlan_objmgr_psoc *psoc)
2697 {
2698 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2699 	uint32_t param, i;
2700 
2701 	pm_ctx = policy_mgr_get_context(psoc);
2702 
2703 	if (!pm_ctx) {
2704 		policy_mgr_err("Invalid Context");
2705 		return false;
2706 	}
2707 	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
2708 		param = pm_ctx->hw_mode.hw_mode_list[i];
2709 		if (POLICY_MGR_HW_MODE_SBS_MODE_GET(param)) {
2710 			return true;
2711 		}
2712 	}
2713 
2714 	return false;
2715 }
2716 
policy_mgr_is_dbs_scan_allowed(struct wlan_objmgr_psoc * psoc)2717 bool policy_mgr_is_dbs_scan_allowed(struct wlan_objmgr_psoc *psoc)
2718 {
2719 	uint8_t dbs_type = DISABLE_DBS_CXN_AND_SCAN;
2720 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2721 
2722 	pm_ctx = policy_mgr_get_context(psoc);
2723 	if (!pm_ctx) {
2724 		policy_mgr_err("Invalid Context");
2725 		return false;
2726 	}
2727 
2728 	if (!policy_mgr_find_if_fw_supports_dbs(psoc) ||
2729 	    !policy_mgr_find_if_hwlist_has_dbs(psoc))
2730 		return false;
2731 
2732 	policy_mgr_get_dual_mac_feature(psoc, &dbs_type);
2733 	/*
2734 	 * If DBS support for scan is disabled through INI then DBS is not
2735 	 * supported for scan.
2736 	 *
2737 	 * For DBS scan check the INI value explicitly
2738 	 */
2739 	switch (dbs_type) {
2740 	case DISABLE_DBS_CXN_AND_SCAN:
2741 	case ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN:
2742 		return false;
2743 	default:
2744 		return true;
2745 	}
2746 }
2747 
policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc * psoc)2748 bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc)
2749 {
2750 	if (!policy_mgr_is_dbs_enable(psoc))
2751 		return false;
2752 
2753 	if (!policy_mgr_find_if_fw_supports_dbs(psoc))
2754 		return false;
2755 
2756 	if (!policy_mgr_find_if_hwlist_has_dbs(psoc)) {
2757 		policymgr_nofl_debug("HW mode list has no DBS");
2758 		return false;
2759 	}
2760 
2761 	return true;
2762 }
2763 
policy_mgr_is_hw_emlsr_capable(struct wlan_objmgr_psoc * psoc)2764 bool policy_mgr_is_hw_emlsr_capable(struct wlan_objmgr_psoc *psoc)
2765 {
2766 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2767 	uint64_t param, i;
2768 
2769 	pm_ctx = policy_mgr_get_context(psoc);
2770 
2771 	if (!pm_ctx) {
2772 		policy_mgr_err("Invalid Context");
2773 		return false;
2774 	}
2775 	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
2776 		param = pm_ctx->hw_mode.hw_mode_list[i];
2777 		if (POLICY_MGR_HW_MODE_EMLSR_MODE_GET(param))
2778 			return true;
2779 	}
2780 
2781 	return false;
2782 }
2783 
policy_mgr_is_current_hwmode_dbs(struct wlan_objmgr_psoc * psoc)2784 bool policy_mgr_is_current_hwmode_dbs(struct wlan_objmgr_psoc *psoc)
2785 {
2786 	struct policy_mgr_hw_mode_params hw_mode;
2787 
2788 	if (!policy_mgr_is_hw_dbs_capable(psoc))
2789 		return false;
2790 
2791 	if (QDF_STATUS_SUCCESS != policy_mgr_get_current_hw_mode(psoc,
2792 								 &hw_mode))
2793 		return false;
2794 
2795 	if (!hw_mode.dbs_cap)
2796 		return false;
2797 
2798 	/* sbs is not enabled and dbs_cap is set return true */
2799 	if (!policy_mgr_is_hw_sbs_capable(psoc))
2800 		return true;
2801 
2802 	/* sbs is enabled and dbs_cap is set then check the freq range */
2803 	if (!policy_mgr_is_cur_freq_range_sbs(psoc))
2804 		return true;
2805 
2806 	return false;
2807 }
2808 
policy_mgr_is_pcl_weightage_required(struct wlan_objmgr_psoc * psoc)2809 bool policy_mgr_is_pcl_weightage_required(struct wlan_objmgr_psoc *psoc)
2810 {
2811 	struct wlan_mlme_psoc_ext_obj *mlme_obj;
2812 	struct dual_sta_policy *dual_sta_policy;
2813 
2814 	mlme_obj = mlme_get_psoc_ext_obj(psoc);
2815 	if (!mlme_obj)
2816 		return true;
2817 
2818 	dual_sta_policy = &mlme_obj->cfg.gen.dual_sta_policy;
2819 
2820 	if (dual_sta_policy->concurrent_sta_policy  ==
2821 		QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY &&
2822 		dual_sta_policy->primary_vdev_id != WLAN_UMAC_VDEV_ID_MAX) {
2823 		return false;
2824 	}
2825 
2826 	return true;
2827 }
2828 
policy_mgr_is_interband_mcc_supported(struct wlan_objmgr_psoc * psoc)2829 bool policy_mgr_is_interband_mcc_supported(struct wlan_objmgr_psoc *psoc)
2830 {
2831 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2832 	struct wmi_unified *wmi_handle;
2833 
2834 	pm_ctx = policy_mgr_get_context(psoc);
2835 
2836 	if (!pm_ctx) {
2837 		policy_mgr_err("Invalid Context");
2838 		return false;
2839 	}
2840 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
2841 	if (!wmi_handle) {
2842 		policy_mgr_debug("Invalid WMI handle");
2843 		return false;
2844 	}
2845 
2846 	return !wmi_service_enabled(wmi_handle,
2847 				    wmi_service_no_interband_mcc_support);
2848 }
2849 
policy_mgr_is_sbs_enable(struct wlan_objmgr_psoc * psoc)2850 static bool policy_mgr_is_sbs_enable(struct wlan_objmgr_psoc *psoc)
2851 {
2852 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2853 
2854 	pm_ctx = policy_mgr_get_context(psoc);
2855 	if (!pm_ctx) {
2856 		policy_mgr_err("Invalid Context");
2857 		return false;
2858 	}
2859 
2860 	/*
2861 	 * if gEnableSBS is not set then policy_mgr_init_sbs_fw_config won't
2862 	 * enable Async SBS fw config bit
2863 	 */
2864 	if (WMI_DBS_FW_MODE_CFG_ASYNC_SBS_GET(
2865 			pm_ctx->dual_mac_cfg.cur_fw_mode_config))
2866 		return true;
2867 
2868 	return false;
2869 }
2870 
policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc * psoc)2871 bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc)
2872 {
2873 	if (!policy_mgr_is_sbs_enable(psoc)) {
2874 		policy_mgr_rl_debug("SBS INI is disabled");
2875 		return false;
2876 	}
2877 
2878 	if (!policy_mgr_find_if_fw_supports_dbs(psoc)) {
2879 		policy_mgr_rl_debug("fw doesn't support dual band");
2880 		return false;
2881 	}
2882 
2883 	if (!policy_mgr_find_if_hwlist_has_sbs(psoc)) {
2884 		policy_mgr_rl_debug("HW mode list has no SBS");
2885 		return false;
2886 	}
2887 
2888 	return true;
2889 }
2890 
policy_mgr_get_dbs_hw_modes(struct wlan_objmgr_psoc * psoc,bool * one_by_one_dbs,bool * two_by_two_dbs)2891 QDF_STATUS policy_mgr_get_dbs_hw_modes(struct wlan_objmgr_psoc *psoc,
2892 		bool *one_by_one_dbs, bool *two_by_two_dbs)
2893 {
2894 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2895 	uint32_t i;
2896 	int8_t found_one_by_one = -EINVAL, found_two_by_two = -EINVAL;
2897 	uint32_t conf1_tx_ss, conf1_rx_ss;
2898 	uint32_t conf2_tx_ss, conf2_rx_ss;
2899 
2900 	*one_by_one_dbs = false;
2901 	*two_by_two_dbs = false;
2902 
2903 	if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
2904 		policy_mgr_rl_debug("HW is not DBS capable");
2905 		/* Caller will understand that DBS is disabled */
2906 		return QDF_STATUS_SUCCESS;
2907 
2908 	}
2909 
2910 	pm_ctx = policy_mgr_get_context(psoc);
2911 	if (!pm_ctx) {
2912 		policy_mgr_err("Invalid Context");
2913 		return QDF_STATUS_E_FAILURE;
2914 	}
2915 
2916 	/* To check 1x1 capability */
2917 	policy_mgr_get_tx_rx_ss_from_config(HW_MODE_SS_1x1,
2918 			&conf1_tx_ss, &conf1_rx_ss);
2919 	/* To check 2x2 capability */
2920 	policy_mgr_get_tx_rx_ss_from_config(HW_MODE_SS_2x2,
2921 			&conf2_tx_ss, &conf2_rx_ss);
2922 
2923 	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
2924 		uint32_t t_conf0_tx_ss, t_conf0_rx_ss;
2925 		uint32_t t_conf1_tx_ss, t_conf1_rx_ss;
2926 		uint32_t dbs_mode;
2927 
2928 		t_conf0_tx_ss = POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(
2929 				pm_ctx->hw_mode.hw_mode_list[i]);
2930 		t_conf0_rx_ss = POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(
2931 				pm_ctx->hw_mode.hw_mode_list[i]);
2932 		t_conf1_tx_ss = POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(
2933 				pm_ctx->hw_mode.hw_mode_list[i]);
2934 		t_conf1_rx_ss = POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(
2935 				pm_ctx->hw_mode.hw_mode_list[i]);
2936 		dbs_mode = POLICY_MGR_HW_MODE_DBS_MODE_GET(
2937 				pm_ctx->hw_mode.hw_mode_list[i]);
2938 
2939 		if (((((t_conf0_tx_ss == conf1_tx_ss) &&
2940 		    (t_conf0_rx_ss == conf1_rx_ss)) ||
2941 		    ((t_conf1_tx_ss == conf1_tx_ss) &&
2942 		    (t_conf1_rx_ss == conf1_rx_ss))) &&
2943 		    (dbs_mode == HW_MODE_DBS)) &&
2944 		    (found_one_by_one < 0)) {
2945 			found_one_by_one = i;
2946 			policy_mgr_debug("1x1 hw_mode index %d found", i);
2947 			/* Once an entry is found, need not check for 1x1
2948 			 * again
2949 			 */
2950 			continue;
2951 		}
2952 
2953 		if (((((t_conf0_tx_ss == conf2_tx_ss) &&
2954 		    (t_conf0_rx_ss == conf2_rx_ss)) ||
2955 		    ((t_conf1_tx_ss == conf2_tx_ss) &&
2956 		    (t_conf1_rx_ss == conf2_rx_ss))) &&
2957 		    (dbs_mode == HW_MODE_DBS)) &&
2958 		    (found_two_by_two < 0)) {
2959 			found_two_by_two = i;
2960 			policy_mgr_debug("2x2 hw_mode index %d found", i);
2961 			/* Once an entry is found, need not check for 2x2
2962 			 * again
2963 			 */
2964 			continue;
2965 		}
2966 	}
2967 
2968 	if (found_one_by_one >= 0)
2969 		*one_by_one_dbs = true;
2970 	if (found_two_by_two >= 0)
2971 		*two_by_two_dbs = true;
2972 
2973 	return QDF_STATUS_SUCCESS;
2974 }
2975 
policy_mgr_get_current_hw_mode(struct wlan_objmgr_psoc * psoc,struct policy_mgr_hw_mode_params * hw_mode)2976 QDF_STATUS policy_mgr_get_current_hw_mode(struct wlan_objmgr_psoc *psoc,
2977 		struct policy_mgr_hw_mode_params *hw_mode)
2978 {
2979 	QDF_STATUS status;
2980 	uint32_t old_hw_index = 0, new_hw_index = 0;
2981 
2982 	status = policy_mgr_get_old_and_new_hw_index(psoc, &old_hw_index,
2983 			&new_hw_index);
2984 	if (QDF_STATUS_SUCCESS != status) {
2985 		policy_mgr_err("Failed to get HW mode index");
2986 		return QDF_STATUS_E_FAILURE;
2987 	}
2988 
2989 	if (new_hw_index == POLICY_MGR_DEFAULT_HW_MODE_INDEX) {
2990 		policy_mgr_err("HW mode is not yet initialized");
2991 		return QDF_STATUS_E_FAILURE;
2992 	}
2993 
2994 	status = policy_mgr_get_hw_mode_from_idx(psoc, new_hw_index, hw_mode);
2995 	if (QDF_STATUS_SUCCESS != status) {
2996 		policy_mgr_err("Failed to get HW mode index");
2997 		return QDF_STATUS_E_FAILURE;
2998 	}
2999 	return QDF_STATUS_SUCCESS;
3000 }
3001 
policy_mgr_is_dbs_enable(struct wlan_objmgr_psoc * psoc)3002 bool policy_mgr_is_dbs_enable(struct wlan_objmgr_psoc *psoc)
3003 {
3004 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3005 
3006 	if (policy_mgr_is_dual_mac_disabled_in_ini(psoc)) {
3007 		policy_mgr_rl_debug("DBS is disabled from ini");
3008 		return false;
3009 	}
3010 
3011 	pm_ctx = policy_mgr_get_context(psoc);
3012 	if (!pm_ctx) {
3013 		policy_mgr_err("Invalid Context");
3014 		return false;
3015 	}
3016 
3017 	if (WMI_DBS_FW_MODE_CFG_DBS_GET(
3018 			pm_ctx->dual_mac_cfg.cur_fw_mode_config))
3019 		return true;
3020 
3021 	return false;
3022 }
3023 
policy_mgr_is_hw_dbs_2x2_capable(struct wlan_objmgr_psoc * psoc)3024 bool policy_mgr_is_hw_dbs_2x2_capable(struct wlan_objmgr_psoc *psoc)
3025 {
3026 	struct dbs_nss nss_dbs = {0};
3027 	uint32_t nss;
3028 
3029 	nss = policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs);
3030 	if (nss >= HW_MODE_SS_2x2 && (nss_dbs.mac0_ss == nss_dbs.mac1_ss))
3031 		return true;
3032 	else
3033 		return false;
3034 }
3035 
policy_mgr_is_hw_dbs_required_for_band(struct wlan_objmgr_psoc * psoc,enum hw_mode_mac_band_cap band)3036 bool policy_mgr_is_hw_dbs_required_for_band(struct wlan_objmgr_psoc *psoc,
3037 					    enum hw_mode_mac_band_cap band)
3038 {
3039 	struct dbs_nss nss_dbs = {0};
3040 	uint32_t nss;
3041 
3042 	nss = policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs);
3043 	if (nss >= HW_MODE_SS_1x1 && nss_dbs.mac0_ss >= nss_dbs.mac1_ss &&
3044 	    !(nss_dbs.single_mac0_band_cap & band))
3045 		return true;
3046 	else
3047 		return false;
3048 }
3049 
policy_mgr_is_dp_hw_dbs_capable(struct wlan_objmgr_psoc * psoc)3050 bool policy_mgr_is_dp_hw_dbs_capable(struct wlan_objmgr_psoc *psoc)
3051 {
3052 	return policy_mgr_find_if_hwlist_has_dbs(psoc);
3053 }
3054 
3055 /*
3056  * policy_mgr_is_2x2_1x1_dbs_capable() - check 2x2+1x1 DBS supported or not
3057  * @psoc: PSOC object data
3058  *
3059  * This routine is called to check 2x2 5G + 1x1 2G (DBS1) or
3060  * 2x2 2G + 1x1 5G (DBS2) support or not.
3061  * Either DBS1 or DBS2 supported
3062  *
3063  * Return: true/false
3064  */
policy_mgr_is_2x2_1x1_dbs_capable(struct wlan_objmgr_psoc * psoc)3065 bool policy_mgr_is_2x2_1x1_dbs_capable(struct wlan_objmgr_psoc *psoc)
3066 {
3067 	struct dbs_nss nss_dbs;
3068 	uint32_t nss;
3069 
3070 	nss = policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs);
3071 	if (nss >= HW_MODE_SS_2x2 && (nss_dbs.mac0_ss > nss_dbs.mac1_ss))
3072 		return true;
3073 	else
3074 		return false;
3075 }
3076 
3077 /*
3078  * policy_mgr_is_2x2_5G_1x1_2G_dbs_capable() - check Genoa DBS1 enabled or not
3079  * @psoc: PSOC object data
3080  *
3081  * This routine is called to check support DBS1 or not.
3082  * Notes: DBS1: 2x2 5G + 1x1 2G.
3083  * This function will call policy_mgr_get_hw_mode_idx_from_dbs_hw_list to match
3084  * the HW mode from hw mode list. The parameters will also be matched to
3085  * 2x2 5G +2x2 2G HW mode. But firmware will not report 2x2 5G + 2x2 2G alone
3086  * with 2x2 5G + 1x1 2G at same time. So, it is safe to find DBS1 with
3087  * policy_mgr_get_hw_mode_idx_from_dbs_hw_list.
3088  *
3089  * Return: true/false
3090  */
policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(struct wlan_objmgr_psoc * psoc)3091 bool policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(struct wlan_objmgr_psoc *psoc)
3092 {
3093 	return policy_mgr_is_2x2_1x1_dbs_capable(psoc) &&
3094 		(policy_mgr_get_hw_mode_idx_from_dbs_hw_list(
3095 					psoc,
3096 					HW_MODE_SS_2x2,
3097 					HW_MODE_80_MHZ,
3098 					HW_MODE_SS_1x1, HW_MODE_40_MHZ,
3099 					HW_MODE_MAC_BAND_5G,
3100 					HW_MODE_DBS,
3101 					HW_MODE_AGILE_DFS_NONE,
3102 					HW_MODE_SBS_NONE) >= 0);
3103 }
3104 
3105 /*
3106  * policy_mgr_is_2x2_2G_1x1_5G_dbs_capable() - check Genoa DBS2 enabled or not
3107  * @psoc: PSOC object data
3108  *
3109  * This routine is called to check support DBS2 or not.
3110  * Notes: DBS2: 2x2 2G + 1x1 5G
3111  *
3112  * Return: true/false
3113  */
policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(struct wlan_objmgr_psoc * psoc)3114 bool policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(struct wlan_objmgr_psoc *psoc)
3115 {
3116 	return policy_mgr_is_2x2_1x1_dbs_capable(psoc) &&
3117 		(policy_mgr_get_hw_mode_idx_from_dbs_hw_list(
3118 					psoc,
3119 					HW_MODE_SS_2x2,
3120 					HW_MODE_40_MHZ,
3121 					HW_MODE_SS_1x1, HW_MODE_40_MHZ,
3122 					HW_MODE_MAC_BAND_2G,
3123 					HW_MODE_DBS,
3124 					HW_MODE_AGILE_DFS_NONE,
3125 					HW_MODE_SBS_NONE) >= 0);
3126 }
3127 
policy_mgr_get_connection_count(struct wlan_objmgr_psoc * psoc)3128 uint32_t policy_mgr_get_connection_count(struct wlan_objmgr_psoc *psoc)
3129 {
3130 	uint32_t conn_index, count = 0;
3131 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3132 
3133 	pm_ctx = policy_mgr_get_context(psoc);
3134 	if (!pm_ctx) {
3135 		policy_mgr_err("Invalid Context");
3136 		return count;
3137 	}
3138 
3139 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3140 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
3141 		conn_index++) {
3142 		if (pm_conc_connection_list[conn_index].in_use)
3143 			count++;
3144 	}
3145 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3146 
3147 	return count;
3148 }
3149 
3150 uint32_t
policy_mgr_get_connection_count_with_mlo(struct wlan_objmgr_psoc * psoc)3151 policy_mgr_get_connection_count_with_mlo(struct wlan_objmgr_psoc *psoc)
3152 {
3153 	uint32_t conn_index, count = 0;
3154 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3155 	enum policy_mgr_con_mode mode;
3156 	bool is_mlo = false, count_mlo = false;
3157 
3158 	pm_ctx = policy_mgr_get_context(psoc);
3159 	if (!pm_ctx) {
3160 		policy_mgr_err("Invalid Context");
3161 		return count;
3162 	}
3163 
3164 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3165 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
3166 		conn_index++) {
3167 		if (pm_conc_connection_list[conn_index].in_use) {
3168 			is_mlo = policy_mgr_is_ml_vdev_id(psoc,
3169 				   pm_conc_connection_list[conn_index].vdev_id);
3170 			mode = pm_conc_connection_list[conn_index].mode;
3171 			if (is_mlo && (mode == PM_STA_MODE)) {
3172 				if (!count_mlo) {
3173 					count_mlo = true;
3174 					count++;
3175 				}
3176 			} else {
3177 				count++;
3178 			}
3179 		}
3180 	}
3181 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3182 
3183 	return count;
3184 }
3185 
policy_mgr_mode_specific_vdev_id(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode)3186 uint32_t policy_mgr_mode_specific_vdev_id(struct wlan_objmgr_psoc *psoc,
3187 					  enum policy_mgr_con_mode mode)
3188 {
3189 	uint32_t conn_index = 0;
3190 	uint32_t vdev_id = WLAN_INVALID_VDEV_ID;
3191 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3192 
3193 	pm_ctx = policy_mgr_get_context(psoc);
3194 	if (!pm_ctx) {
3195 		policy_mgr_err("Invalid Context");
3196 		return vdev_id;
3197 	}
3198 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3199 	/*
3200 	 * Note: This gives you the first vdev id of the mode type in a
3201 	 * sta+sta or sap+sap or p2p + p2p case
3202 	 */
3203 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
3204 		conn_index++) {
3205 		if ((pm_conc_connection_list[conn_index].mode == mode) &&
3206 			pm_conc_connection_list[conn_index].in_use) {
3207 			vdev_id = pm_conc_connection_list[conn_index].vdev_id;
3208 			break;
3209 		}
3210 	}
3211 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3212 
3213 	return vdev_id;
3214 }
3215 
policy_mgr_mode_get_macid_by_vdev_id(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id)3216 uint32_t policy_mgr_mode_get_macid_by_vdev_id(struct wlan_objmgr_psoc *psoc,
3217 					      uint32_t vdev_id)
3218 {
3219 	uint32_t conn_index = 0;
3220 	uint32_t mac_id = 0xFF;
3221 	enum policy_mgr_con_mode mode;
3222 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3223 
3224 	pm_ctx = policy_mgr_get_context(psoc);
3225 	if (!pm_ctx) {
3226 		policy_mgr_err("Invalid Context");
3227 		return vdev_id;
3228 	}
3229 	mode = policy_mgr_con_mode_by_vdev_id(psoc, vdev_id);
3230 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3231 
3232 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
3233 		conn_index++) {
3234 		if ((pm_conc_connection_list[conn_index].mode == mode) &&
3235 		    pm_conc_connection_list[conn_index].in_use &&
3236 		    vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
3237 			mac_id = pm_conc_connection_list[conn_index].mac;
3238 			break;
3239 		}
3240 	}
3241 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3242 
3243 	return mac_id;
3244 }
3245 
policy_mgr_mode_specific_connection_count(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint32_t * list)3246 uint32_t policy_mgr_mode_specific_connection_count(
3247 		struct wlan_objmgr_psoc *psoc,
3248 		enum policy_mgr_con_mode mode,
3249 		uint32_t *list)
3250 {
3251 	uint32_t conn_index = 0, count = 0;
3252 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3253 
3254 	pm_ctx = policy_mgr_get_context(psoc);
3255 	if (!pm_ctx) {
3256 		policy_mgr_err("Invalid Context");
3257 		return count;
3258 	}
3259 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3260 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
3261 		conn_index++) {
3262 		if ((pm_conc_connection_list[conn_index].mode == mode) &&
3263 			pm_conc_connection_list[conn_index].in_use) {
3264 			if (list)
3265 				list[count] = conn_index;
3266 			 count++;
3267 		}
3268 	}
3269 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3270 
3271 	return count;
3272 }
3273 
policy_mgr_get_sap_mode_count(struct wlan_objmgr_psoc * psoc,uint32_t * list)3274 uint32_t policy_mgr_get_sap_mode_count(struct wlan_objmgr_psoc *psoc,
3275 				       uint32_t *list)
3276 {
3277 	uint32_t count;
3278 
3279 	count = policy_mgr_mode_specific_connection_count(psoc, PM_SAP_MODE,
3280 							  list);
3281 
3282 	count += policy_mgr_mode_specific_connection_count(
3283 						psoc,
3284 						PM_LL_LT_SAP_MODE,
3285 						list ? &list[count] : NULL);
3286 	return count;
3287 }
3288 
policy_mgr_get_beaconing_mode_count(struct wlan_objmgr_psoc * psoc,uint32_t * list)3289 uint32_t policy_mgr_get_beaconing_mode_count(struct wlan_objmgr_psoc *psoc,
3290 					     uint32_t *list)
3291 {
3292 	uint32_t count;
3293 
3294 	count = policy_mgr_get_sap_mode_count(psoc, list);
3295 
3296 	count += policy_mgr_mode_specific_connection_count(
3297 						psoc,
3298 						PM_P2P_GO_MODE,
3299 						list ? &list[count] : NULL);
3300 	return count;
3301 }
3302 
policy_mgr_check_conn_with_mode_and_vdev_id(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint32_t vdev_id)3303 QDF_STATUS policy_mgr_check_conn_with_mode_and_vdev_id(
3304 		struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode,
3305 		uint32_t vdev_id)
3306 {
3307 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
3308 	uint32_t conn_index = 0;
3309 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3310 
3311 	pm_ctx = policy_mgr_get_context(psoc);
3312 	if (!pm_ctx) {
3313 		policy_mgr_err("Invalid Context");
3314 		return qdf_status;
3315 	}
3316 
3317 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3318 	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
3319 		if ((pm_conc_connection_list[conn_index].mode == mode) &&
3320 		    (pm_conc_connection_list[conn_index].vdev_id == vdev_id)) {
3321 			qdf_status = QDF_STATUS_SUCCESS;
3322 			break;
3323 		}
3324 		conn_index++;
3325 	}
3326 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3327 	return qdf_status;
3328 }
3329 
policy_mgr_soc_set_dual_mac_cfg_cb(enum set_hw_mode_status status,uint32_t scan_config,uint32_t fw_mode_config)3330 void policy_mgr_soc_set_dual_mac_cfg_cb(enum set_hw_mode_status status,
3331 		uint32_t scan_config,
3332 		uint32_t fw_mode_config)
3333 {
3334 	policy_mgr_debug("Status:%d for scan_config:%x fw_mode_config:%x",
3335 			 status, scan_config, fw_mode_config);
3336 }
3337 
policy_mgr_set_dual_mac_scan_config(struct wlan_objmgr_psoc * psoc,uint8_t dbs_val,uint8_t dbs_plus_agile_scan_val,uint8_t single_mac_scan_with_dbs_val)3338 void policy_mgr_set_dual_mac_scan_config(struct wlan_objmgr_psoc *psoc,
3339 		uint8_t dbs_val,
3340 		uint8_t dbs_plus_agile_scan_val,
3341 		uint8_t single_mac_scan_with_dbs_val)
3342 {
3343 	struct policy_mgr_dual_mac_config cfg;
3344 	QDF_STATUS status;
3345 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3346 
3347 	pm_ctx = policy_mgr_get_context(psoc);
3348 	if (!pm_ctx) {
3349 		policy_mgr_err("Invalid Context");
3350 		return;
3351 	}
3352 
3353 	/* Any non-zero positive value is treated as 1 */
3354 	if (dbs_val != 0)
3355 		dbs_val = 1;
3356 	if (dbs_plus_agile_scan_val != 0)
3357 		dbs_plus_agile_scan_val = 1;
3358 	if (single_mac_scan_with_dbs_val != 0)
3359 		single_mac_scan_with_dbs_val = 1;
3360 
3361 	status = policy_mgr_get_updated_scan_config(psoc, &cfg.scan_config,
3362 			dbs_val,
3363 			dbs_plus_agile_scan_val,
3364 			single_mac_scan_with_dbs_val);
3365 	if (status != QDF_STATUS_SUCCESS) {
3366 		policy_mgr_err("policy_mgr_get_updated_scan_config failed %d",
3367 			status);
3368 		return;
3369 	}
3370 
3371 	status = policy_mgr_get_updated_fw_mode_config(psoc,
3372 			&cfg.fw_mode_config,
3373 			policy_mgr_get_dbs_config(psoc),
3374 			policy_mgr_get_agile_dfs_config(psoc));
3375 	if (status != QDF_STATUS_SUCCESS) {
3376 		policy_mgr_err("policy_mgr_get_updated_fw_mode_config failed %d",
3377 			status);
3378 		return;
3379 	}
3380 
3381 	cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
3382 
3383 	policy_mgr_debug("scan_config:%x fw_mode_config:%x",
3384 			cfg.scan_config, cfg.fw_mode_config);
3385 
3386 	status = pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config(cfg);
3387 	if (status != QDF_STATUS_SUCCESS)
3388 		policy_mgr_err("sme_soc_set_dual_mac_config failed %d", status);
3389 }
3390 
policy_mgr_set_dual_mac_fw_mode_config(struct wlan_objmgr_psoc * psoc,uint8_t dbs,uint8_t dfs)3391 void policy_mgr_set_dual_mac_fw_mode_config(struct wlan_objmgr_psoc *psoc,
3392 			uint8_t dbs, uint8_t dfs)
3393 {
3394 	struct policy_mgr_dual_mac_config cfg;
3395 	QDF_STATUS status;
3396 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3397 
3398 	pm_ctx = policy_mgr_get_context(psoc);
3399 	if (!pm_ctx) {
3400 		policy_mgr_err("Invalid Context");
3401 		return;
3402 	}
3403 
3404 	/* Any non-zero positive value is treated as 1 */
3405 	if (dbs != 0)
3406 		dbs = 1;
3407 	if (dfs != 0)
3408 		dfs = 1;
3409 
3410 	status = policy_mgr_get_updated_scan_config(psoc, &cfg.scan_config,
3411 			policy_mgr_get_dbs_scan_config(psoc),
3412 			policy_mgr_get_dbs_plus_agile_scan_config(psoc),
3413 			policy_mgr_get_single_mac_scan_with_dfs_config(psoc));
3414 	if (status != QDF_STATUS_SUCCESS) {
3415 		policy_mgr_err("policy_mgr_get_updated_scan_config failed %d",
3416 			status);
3417 		return;
3418 	}
3419 
3420 	status = policy_mgr_get_updated_fw_mode_config(psoc,
3421 				&cfg.fw_mode_config, dbs, dfs);
3422 	if (status != QDF_STATUS_SUCCESS) {
3423 		policy_mgr_err("policy_mgr_get_updated_fw_mode_config failed %d",
3424 			status);
3425 		return;
3426 	}
3427 
3428 	cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
3429 
3430 	policy_mgr_debug("scan_config:%x fw_mode_config:%x",
3431 			cfg.scan_config, cfg.fw_mode_config);
3432 
3433 	status = pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config(cfg);
3434 	if (status != QDF_STATUS_SUCCESS)
3435 		policy_mgr_err("sme_soc_set_dual_mac_config failed %d", status);
3436 }
3437 
policy_mgr_is_scc_with_this_vdev_id(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)3438 bool policy_mgr_is_scc_with_this_vdev_id(struct wlan_objmgr_psoc *psoc,
3439 					 uint8_t vdev_id)
3440 {
3441 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3442 	uint32_t i, ch_freq;
3443 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3444 
3445 	pm_ctx = policy_mgr_get_context(psoc);
3446 	if (!pm_ctx) {
3447 		policy_mgr_err("Invalid Context");
3448 		return false;
3449 	}
3450 
3451 	/* Get the channel freq for a given vdev_id */
3452 	status = policy_mgr_get_chan_by_session_id(psoc, vdev_id,
3453 						   &ch_freq);
3454 	if (QDF_IS_STATUS_ERROR(status)) {
3455 		policy_mgr_err("Failed to get channel for vdev:%d", vdev_id);
3456 		return false;
3457 	}
3458 
3459 	/* Compare given vdev_id freq against other vdev_id's */
3460 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3461 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
3462 		if ((pm_conc_connection_list[i].vdev_id != vdev_id) &&
3463 		    (pm_conc_connection_list[i].in_use) &&
3464 		    (pm_conc_connection_list[i].freq == ch_freq)) {
3465 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3466 			return true;
3467 		}
3468 	}
3469 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3470 
3471 	return false;
3472 }
3473 
policy_mgr_is_mcc_with_this_vdev_id(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint8_t * mcc_vdev_id)3474 bool policy_mgr_is_mcc_with_this_vdev_id(struct wlan_objmgr_psoc *psoc,
3475 					 uint8_t vdev_id, uint8_t *mcc_vdev_id)
3476 {
3477 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3478 	uint32_t i, ch_freq;
3479 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3480 
3481 	if (mcc_vdev_id)
3482 		*mcc_vdev_id = WLAN_INVALID_VDEV_ID;
3483 
3484 	pm_ctx = policy_mgr_get_context(psoc);
3485 	if (!pm_ctx) {
3486 		policy_mgr_err("Invalid Context");
3487 		return false;
3488 	}
3489 
3490 	/* Get the channel freq for a given vdev_id */
3491 	status = policy_mgr_get_chan_by_session_id(psoc, vdev_id, &ch_freq);
3492 	if (QDF_IS_STATUS_ERROR(status)) {
3493 		policy_mgr_err("Failed to get channel for vdev:%d", vdev_id);
3494 		return false;
3495 	}
3496 
3497 	/* Compare given vdev_id freq against other vdev_id's */
3498 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3499 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
3500 		if (pm_conc_connection_list[i].vdev_id == vdev_id)
3501 			continue;
3502 
3503 		if (!pm_conc_connection_list[i].in_use)
3504 			continue;
3505 
3506 		if (pm_conc_connection_list[i].freq != ch_freq &&
3507 		    policy_mgr_are_2_freq_on_same_mac(psoc,
3508 						      pm_conc_connection_list[i].freq,
3509 						      ch_freq)) {
3510 			if (mcc_vdev_id)
3511 				*mcc_vdev_id = pm_conc_connection_list[i].vdev_id;
3512 
3513 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3514 			return true;
3515 		}
3516 	}
3517 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3518 
3519 	return false;
3520 }
3521 
policy_mgr_is_mcc_on_any_sta_vdev(struct wlan_objmgr_psoc * psoc)3522 bool policy_mgr_is_mcc_on_any_sta_vdev(struct wlan_objmgr_psoc *psoc)
3523 {
3524 	uint8_t connection_count, i;
3525 	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
3526 
3527 	connection_count =
3528 		policy_mgr_get_mode_specific_conn_info(psoc, NULL, vdev_id_list,
3529 						       PM_STA_MODE);
3530 	if (!connection_count)
3531 		return false;
3532 
3533 	for (i = 0; i < connection_count; i++)
3534 		if (policy_mgr_is_mcc_with_this_vdev_id(psoc, vdev_id_list[i],
3535 							NULL))
3536 			return true;
3537 
3538 	return false;
3539 }
3540 
policy_mgr_current_concurrency_is_scc(struct wlan_objmgr_psoc * psoc)3541 bool policy_mgr_current_concurrency_is_scc(struct wlan_objmgr_psoc *psoc)
3542 {
3543 	uint32_t num_connections = 0;
3544 	bool is_scc = false;
3545 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3546 
3547 	pm_ctx = policy_mgr_get_context(psoc);
3548 	if (!pm_ctx) {
3549 		policy_mgr_err("Invalid Context");
3550 		return is_scc;
3551 	}
3552 
3553 	num_connections = policy_mgr_get_connection_count(psoc);
3554 
3555 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3556 	switch (num_connections) {
3557 	case 1:
3558 		break;
3559 	case 2:
3560 		if (pm_conc_connection_list[0].freq ==
3561 		    pm_conc_connection_list[1].freq &&
3562 		    policy_mgr_are_2_freq_on_same_mac(psoc,
3563 			pm_conc_connection_list[0].freq,
3564 			pm_conc_connection_list[1].freq))
3565 			is_scc = true;
3566 		break;
3567 	case 3:
3568 		/*
3569 		 * In DBS/SBS mode 2 freq are different and on different mac.
3570 		 * Thus if any of 2 freq are same that mean one of the MAC is
3571 		 * in SCC.
3572 		 * For non DBS/SBS, if all 3 freq are same then its SCC
3573 		 */
3574 		if ((policy_mgr_is_current_hwmode_dbs(psoc) ||
3575 		     policy_mgr_is_current_hwmode_sbs(psoc)) &&
3576 		    (pm_conc_connection_list[0].freq ==
3577 		     pm_conc_connection_list[1].freq ||
3578 		     pm_conc_connection_list[0].freq ==
3579 		     pm_conc_connection_list[2].freq ||
3580 		     pm_conc_connection_list[1].freq ==
3581 		     pm_conc_connection_list[2].freq))
3582 			is_scc = true;
3583 		else if ((pm_conc_connection_list[0].freq ==
3584 			  pm_conc_connection_list[1].freq) &&
3585 			 (pm_conc_connection_list[0].freq ==
3586 			  pm_conc_connection_list[2].freq))
3587 			is_scc = true;
3588 
3589 		break;
3590 	default:
3591 		policy_mgr_debug("unexpected num_connections value %d",
3592 				 num_connections);
3593 		break;
3594 	}
3595 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3596 
3597 	return is_scc;
3598 }
3599 
policy_mgr_current_concurrency_is_mcc(struct wlan_objmgr_psoc * psoc)3600 bool policy_mgr_current_concurrency_is_mcc(struct wlan_objmgr_psoc *psoc)
3601 {
3602 	uint32_t num_connections = 0;
3603 	bool is_mcc = false;
3604 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3605 
3606 	pm_ctx = policy_mgr_get_context(psoc);
3607 	if (!pm_ctx) {
3608 		policy_mgr_err("Invalid Context");
3609 		return is_mcc;
3610 	}
3611 
3612 	num_connections = policy_mgr_get_connection_count(psoc);
3613 	if (!num_connections)
3614 		return is_mcc;
3615 
3616 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3617 	switch (num_connections) {
3618 	case 1:
3619 		break;
3620 	case 2:
3621 		if (pm_conc_connection_list[0].freq !=
3622 		    pm_conc_connection_list[1].freq &&
3623 		    policy_mgr_are_2_freq_on_same_mac(psoc,
3624 			pm_conc_connection_list[0].freq,
3625 			pm_conc_connection_list[1].freq))
3626 			is_mcc = true;
3627 		break;
3628 	case 3:
3629 		/*
3630 		 * Check if any 2 different freq is on same MAC.
3631 		 * Return true if any of the different freq is on same MAC.
3632 		 */
3633 		if ((pm_conc_connection_list[0].freq !=
3634 		     pm_conc_connection_list[1].freq &&
3635 		     policy_mgr_are_2_freq_on_same_mac(psoc,
3636 			pm_conc_connection_list[0].freq,
3637 			pm_conc_connection_list[1].freq)) ||
3638 		    (pm_conc_connection_list[0].freq !=
3639 		     pm_conc_connection_list[2].freq &&
3640 		     policy_mgr_are_2_freq_on_same_mac(psoc,
3641 			pm_conc_connection_list[0].freq,
3642 			pm_conc_connection_list[2].freq)) ||
3643 		    (pm_conc_connection_list[1].freq !=
3644 		     pm_conc_connection_list[2].freq &&
3645 		     policy_mgr_are_2_freq_on_same_mac(psoc,
3646 			pm_conc_connection_list[1].freq,
3647 			pm_conc_connection_list[2].freq)))
3648 			is_mcc = true;
3649 		break;
3650 	default:
3651 		policy_mgr_debug("unexpected num_connections value %d",
3652 				 num_connections);
3653 		break;
3654 	}
3655 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3656 
3657 	return is_mcc;
3658 }
3659 
policy_mgr_is_sap_p2pgo_on_dfs(struct wlan_objmgr_psoc * psoc)3660 bool policy_mgr_is_sap_p2pgo_on_dfs(struct wlan_objmgr_psoc *psoc)
3661 {
3662 	int index, count;
3663 	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
3664 	struct policy_mgr_psoc_priv_obj *pm_ctx = NULL;
3665 
3666 	if (psoc)
3667 		pm_ctx = policy_mgr_get_context(psoc);
3668 
3669 	if (!pm_ctx) {
3670 		policy_mgr_err("Invalid Context");
3671 		return false;
3672 	}
3673 
3674 	index = 0;
3675 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3676 	count = policy_mgr_mode_specific_connection_count(psoc,
3677 							  PM_SAP_MODE,
3678 							  list);
3679 	while (index < count) {
3680 		if (pm_conc_connection_list[list[index]].ch_flagext &
3681 		    (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) {
3682 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3683 			return true;
3684 		}
3685 		index++;
3686 	}
3687 	count = policy_mgr_mode_specific_connection_count(psoc,
3688 							  PM_P2P_GO_MODE,
3689 							  list);
3690 	index = 0;
3691 	while (index < count) {
3692 		if (pm_conc_connection_list[list[index]].ch_flagext &
3693 		    (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) {
3694 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3695 			return true;
3696 		}
3697 		index++;
3698 	}
3699 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3700 	return false;
3701 }
3702 
3703 /**
3704  * policy_mgr_set_concurrency_mode() - To set concurrency mode
3705  * @psoc: PSOC object data
3706  * @mode: device mode
3707  *
3708  * This routine is called to set the concurrency mode
3709  *
3710  * Return: NONE
3711  */
policy_mgr_set_concurrency_mode(struct wlan_objmgr_psoc * psoc,enum QDF_OPMODE mode)3712 void policy_mgr_set_concurrency_mode(struct wlan_objmgr_psoc *psoc,
3713 				     enum QDF_OPMODE mode)
3714 {
3715 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3716 
3717 	pm_ctx = policy_mgr_get_context(psoc);
3718 	if (!pm_ctx) {
3719 		policy_mgr_err("Invalid context");
3720 		return;
3721 	}
3722 
3723 	switch (mode) {
3724 	case QDF_STA_MODE:
3725 	case QDF_P2P_CLIENT_MODE:
3726 	case QDF_P2P_GO_MODE:
3727 	case QDF_SAP_MODE:
3728 	case QDF_MONITOR_MODE:
3729 		pm_ctx->concurrency_mode |= (1 << mode);
3730 		pm_ctx->no_of_open_sessions[mode]++;
3731 		break;
3732 	default:
3733 		break;
3734 	}
3735 
3736 	policy_mgr_debug("concurrency_mode = 0x%x Number of open sessions for mode %d = %d",
3737 			 pm_ctx->concurrency_mode, mode,
3738 		pm_ctx->no_of_open_sessions[mode]);
3739 }
3740 
3741 /**
3742  * policy_mgr_clear_concurrency_mode() - To clear concurrency mode
3743  * @psoc: PSOC object data
3744  * @mode: device mode
3745  *
3746  * This routine is called to clear the concurrency mode
3747  *
3748  * Return: NONE
3749  */
policy_mgr_clear_concurrency_mode(struct wlan_objmgr_psoc * psoc,enum QDF_OPMODE mode)3750 void policy_mgr_clear_concurrency_mode(struct wlan_objmgr_psoc *psoc,
3751 				       enum QDF_OPMODE mode)
3752 {
3753 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3754 
3755 	pm_ctx = policy_mgr_get_context(psoc);
3756 	if (!pm_ctx) {
3757 		policy_mgr_err("Invalid context");
3758 		return;
3759 	}
3760 
3761 	switch (mode) {
3762 	case QDF_STA_MODE:
3763 	case QDF_P2P_CLIENT_MODE:
3764 	case QDF_P2P_GO_MODE:
3765 	case QDF_SAP_MODE:
3766 	case QDF_MONITOR_MODE:
3767 		pm_ctx->no_of_open_sessions[mode]--;
3768 		if (!(pm_ctx->no_of_open_sessions[mode]))
3769 			pm_ctx->concurrency_mode &= (~(1 << mode));
3770 		break;
3771 	default:
3772 		break;
3773 	}
3774 
3775 	policy_mgr_debug("concurrency_mode = 0x%x Number of open sessions for mode %d = %d",
3776 			 pm_ctx->concurrency_mode, mode,
3777 			 pm_ctx->no_of_open_sessions[mode]);
3778 }
3779 
3780 /**
3781  * policy_mgr_validate_conn_info() - validate conn info list
3782  * @psoc: PSOC object data
3783  *
3784  * This function will check connection list to see duplicated
3785  * vdev entry existing or not.
3786  *
3787  * Return: true if conn list is in abnormal state.
3788  */
3789 static bool
policy_mgr_validate_conn_info(struct wlan_objmgr_psoc * psoc)3790 policy_mgr_validate_conn_info(struct wlan_objmgr_psoc *psoc)
3791 {
3792 	uint32_t i, j, conn_num = 0;
3793 	bool panic = false;
3794 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3795 
3796 	pm_ctx = policy_mgr_get_context(psoc);
3797 	if (!pm_ctx) {
3798 		policy_mgr_err("Invalid Context");
3799 		return true;
3800 	}
3801 
3802 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3803 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
3804 		if (pm_conc_connection_list[i].in_use) {
3805 			for (j = i + 1; j < MAX_NUMBER_OF_CONC_CONNECTIONS;
3806 									j++) {
3807 				if (pm_conc_connection_list[j].in_use &&
3808 				    pm_conc_connection_list[i].vdev_id ==
3809 				    pm_conc_connection_list[j].vdev_id) {
3810 					policy_mgr_debug(
3811 					"dup entry %d",
3812 					pm_conc_connection_list[i].vdev_id);
3813 					panic = true;
3814 				}
3815 			}
3816 			conn_num++;
3817 		}
3818 	}
3819 	if (panic)
3820 		policy_mgr_err("dup entry");
3821 
3822 	for (i = 0, j = 0; i < QDF_MAX_NO_OF_MODE; i++)
3823 		j += pm_ctx->no_of_active_sessions[i];
3824 
3825 	if (j != conn_num) {
3826 		policy_mgr_err("active session/conn count mismatch %d %d",
3827 			       j, conn_num);
3828 		panic = true;
3829 	}
3830 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3831 
3832 	if (panic)
3833 		policy_mgr_debug_alert();
3834 
3835 	return panic;
3836 }
3837 
3838 #ifdef WLAN_FEATURE_11BE_MLO
policy_mgr_is_ml_vdev_id(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)3839 bool policy_mgr_is_ml_vdev_id(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
3840 {
3841 	struct wlan_objmgr_vdev *vdev;
3842 	bool is_mlo = false;
3843 
3844 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
3845 						    WLAN_POLICY_MGR_ID);
3846 	if (!vdev)
3847 		return is_mlo;
3848 
3849 	if (wlan_vdev_mlme_is_mlo_vdev(vdev))
3850 		is_mlo = true;
3851 
3852 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
3853 
3854 	return is_mlo;
3855 }
3856 
3857 /*
3858  * policy_mgr_get_ml_sta_info() - Get number of ML STA vdev ids and freq list
3859  * @pm_ctx: pm_ctx ctx
3860  * @num_ml_sta: Return number of ML STA present
3861  * @num_disabled_ml_sta: Return number of disabled ML STA links
3862  * @ml_vdev_lst: Return ML STA vdev id list
3863  * @ml_freq_lst: Return ML STA freq list
3864  * @num_non_ml: Return number of non-ML STA present
3865  * @non_ml_vdev_lst: Return non-ML STA vdev id list
3866  * @non_ml_freq_lst: Return non-ML STA freq list
3867  *
3868  * Return: void
3869  */
3870 static void
policy_mgr_get_ml_sta_info(struct policy_mgr_psoc_priv_obj * pm_ctx,uint8_t * num_ml_sta,uint8_t * num_disabled_ml_sta,uint8_t * ml_vdev_lst,qdf_freq_t * ml_freq_lst,uint8_t * num_non_ml,uint8_t * non_ml_vdev_lst,qdf_freq_t * non_ml_freq_lst)3871 policy_mgr_get_ml_sta_info(struct policy_mgr_psoc_priv_obj *pm_ctx,
3872 			   uint8_t *num_ml_sta,
3873 			   uint8_t *num_disabled_ml_sta,
3874 			   uint8_t *ml_vdev_lst,
3875 			   qdf_freq_t *ml_freq_lst,
3876 			   uint8_t *num_non_ml,
3877 			   uint8_t *non_ml_vdev_lst,
3878 			   qdf_freq_t *non_ml_freq_lst)
3879 {
3880 	struct wlan_objmgr_vdev *vdev;
3881 	uint8_t vdev_id, conn_index;
3882 	qdf_freq_t freq;
3883 
3884 	*num_ml_sta = 0;
3885 	*num_disabled_ml_sta = 0;
3886 	if (num_non_ml)
3887 		*num_non_ml = 0;
3888 
3889 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3890 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
3891 	     conn_index++) {
3892 		if (!pm_conc_connection_list[conn_index].in_use)
3893 			continue;
3894 		if (pm_conc_connection_list[conn_index].mode != PM_STA_MODE)
3895 			continue;
3896 		vdev_id = pm_conc_connection_list[conn_index].vdev_id;
3897 		freq = pm_conc_connection_list[conn_index].freq;
3898 
3899 		/* add ml sta vdev and freq list */
3900 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(pm_ctx->psoc,
3901 							    vdev_id,
3902 							    WLAN_POLICY_MGR_ID);
3903 		if (!vdev) {
3904 			policy_mgr_err("invalid vdev for id %d", vdev_id);
3905 			continue;
3906 		}
3907 
3908 		if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
3909 			ml_vdev_lst[*num_ml_sta] = vdev_id;
3910 			ml_freq_lst[(*num_ml_sta)++] = freq;
3911 		} else if (num_non_ml) {
3912 			if (non_ml_vdev_lst)
3913 				non_ml_vdev_lst[*num_non_ml] = vdev_id;
3914 			if (non_ml_freq_lst)
3915 				non_ml_freq_lst[*num_non_ml] = freq;
3916 			(*num_non_ml)++;
3917 		}
3918 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
3919 	}
3920 	/* Get disabled link info as well and keep it at last */
3921 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_DISABLE_LINK;
3922 	     conn_index++) {
3923 		if (!pm_disabled_ml_links[conn_index].in_use)
3924 			continue;
3925 		if (pm_disabled_ml_links[conn_index].mode != PM_STA_MODE)
3926 			continue;
3927 		ml_vdev_lst[*num_ml_sta] =
3928 				pm_disabled_ml_links[conn_index].vdev_id;
3929 		ml_freq_lst[(*num_ml_sta)++] =
3930 			pm_disabled_ml_links[conn_index].freq;
3931 		(*num_disabled_ml_sta)++;
3932 	}
3933 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3934 }
3935 
3936 void
policy_mgr_get_ml_sta_info_psoc(struct wlan_objmgr_psoc * psoc,uint8_t * num_ml_sta,uint8_t * num_disabled_ml_sta,uint8_t * ml_vdev_lst,qdf_freq_t * ml_freq_lst,uint8_t * num_non_ml,uint8_t * non_ml_vdev_lst,qdf_freq_t * non_ml_freq_lst)3937 policy_mgr_get_ml_sta_info_psoc(struct wlan_objmgr_psoc *psoc,
3938 				uint8_t *num_ml_sta,
3939 				uint8_t *num_disabled_ml_sta,
3940 				uint8_t *ml_vdev_lst,
3941 				qdf_freq_t *ml_freq_lst,
3942 				uint8_t *num_non_ml,
3943 				uint8_t *non_ml_vdev_lst,
3944 				qdf_freq_t *non_ml_freq_lst)
3945 {
3946 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3947 
3948 	pm_ctx = policy_mgr_get_context(psoc);
3949 	if (!pm_ctx) {
3950 		policy_mgr_err("Invalid pm_ctx");
3951 		return;
3952 	}
3953 
3954 	return policy_mgr_get_ml_sta_info(pm_ctx,
3955 					  num_ml_sta,
3956 					  num_disabled_ml_sta,
3957 					  ml_vdev_lst,
3958 					  ml_freq_lst,
3959 					  num_non_ml,
3960 					  non_ml_vdev_lst,
3961 					  non_ml_freq_lst);
3962 }
3963 
policy_mgr_get_disabled_ml_links_count(struct wlan_objmgr_psoc * psoc)3964 uint32_t policy_mgr_get_disabled_ml_links_count(struct wlan_objmgr_psoc *psoc)
3965 {
3966 	uint32_t i, count = 0;
3967 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3968 
3969 	pm_ctx = policy_mgr_get_context(psoc);
3970 	if (!pm_ctx) {
3971 		policy_mgr_err("Invalid pm_ctx");
3972 		return count;
3973 	}
3974 
3975 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3976 	for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) {
3977 		if (pm_disabled_ml_links[i].in_use)
3978 			count++;
3979 	}
3980 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3981 
3982 	return count;
3983 }
3984 
3985 static QDF_STATUS
policy_mgr_delete_from_disabled_links(struct policy_mgr_psoc_priv_obj * pm_ctx,uint8_t vdev_id)3986 policy_mgr_delete_from_disabled_links(struct policy_mgr_psoc_priv_obj *pm_ctx,
3987 				      uint8_t vdev_id)
3988 {
3989 	int i;
3990 
3991 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3992 	for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) {
3993 		if (pm_disabled_ml_links[i].in_use &&
3994 		    pm_disabled_ml_links[i].vdev_id == vdev_id) {
3995 			pm_disabled_ml_links[i].in_use = false;
3996 			policy_mgr_debug("Disabled link removed for vdev %d",
3997 					 vdev_id);
3998 			break;
3999 		}
4000 	}
4001 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4002 	/* Return failure if not found */
4003 	if (i >= MAX_NUMBER_OF_DISABLE_LINK)
4004 		return QDF_STATUS_E_EXISTS;
4005 
4006 	return QDF_STATUS_SUCCESS;
4007 }
4008 
policy_mgr_move_vdev_from_disabled_to_connection_tbl(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)4009 void policy_mgr_move_vdev_from_disabled_to_connection_tbl(
4010 						struct wlan_objmgr_psoc *psoc,
4011 						uint8_t vdev_id)
4012 {
4013 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4014 	QDF_STATUS status;
4015 	enum QDF_OPMODE mode;
4016 
4017 	pm_ctx = policy_mgr_get_context(psoc);
4018 	if (!pm_ctx) {
4019 		policy_mgr_err("Invalid pm_ctx");
4020 		return;
4021 	}
4022 	mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id);
4023 	if (mode != QDF_STA_MODE) {
4024 		policy_mgr_err("vdev %d opmode %d is not STA", vdev_id, mode);
4025 		return;
4026 	}
4027 
4028 	if (!policy_mgr_is_ml_vdev_id(psoc, vdev_id)) {
4029 		policy_mgr_err("vdev %d is not ML", vdev_id);
4030 		return;
4031 	}
4032 
4033 	status = policy_mgr_delete_from_disabled_links(pm_ctx, vdev_id);
4034 	if (QDF_IS_STATUS_ERROR(status)) {
4035 		policy_mgr_debug("Disabled link not found for vdev %d",
4036 				 vdev_id);
4037 		return;
4038 	}
4039 
4040 	/*
4041 	 * Add entry to pm_conc_connection_list if remove from disabled links
4042 	 * was success
4043 	 */
4044 	policy_mgr_incr_active_session(psoc, mode, vdev_id);
4045 }
4046 
4047 static QDF_STATUS
policy_mgr_add_to_disabled_links(struct policy_mgr_psoc_priv_obj * pm_ctx,qdf_freq_t freq,enum QDF_OPMODE mode,uint8_t vdev_id)4048 policy_mgr_add_to_disabled_links(struct policy_mgr_psoc_priv_obj *pm_ctx,
4049 				 qdf_freq_t freq, enum QDF_OPMODE mode,
4050 				 uint8_t vdev_id)
4051 {
4052 	int i;
4053 	enum policy_mgr_con_mode pm_mode;
4054 
4055 	pm_mode = policy_mgr_qdf_opmode_to_pm_con_mode(pm_ctx->psoc, mode,
4056 						       vdev_id);
4057 
4058 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4059 	for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) {
4060 		if (pm_disabled_ml_links[i].in_use &&
4061 		    pm_disabled_ml_links[i].vdev_id == vdev_id)
4062 			break;
4063 	}
4064 
4065 	if (i < MAX_NUMBER_OF_DISABLE_LINK) {
4066 		pm_disabled_ml_links[i].freq = freq;
4067 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4068 		policy_mgr_debug("Disabled link already present vdev %d, pm_mode %d, update freq %d",
4069 				 vdev_id, pm_mode, freq);
4070 
4071 		return QDF_STATUS_E_EXISTS;
4072 	}
4073 
4074 	for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) {
4075 		if (!pm_disabled_ml_links[i].in_use) {
4076 			/* add in empty place */
4077 			pm_disabled_ml_links[i].vdev_id = vdev_id;
4078 			pm_disabled_ml_links[i].mode = pm_mode;
4079 			pm_disabled_ml_links[i].in_use = true;
4080 			pm_disabled_ml_links[i].freq = freq;
4081 			policy_mgr_debug("Disabled link added vdev id: %d freq: %d pm_mode %d",
4082 					 vdev_id, freq, pm_mode);
4083 			break;
4084 		}
4085 	}
4086 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4087 	if (i >= MAX_NUMBER_OF_DISABLE_LINK) {
4088 		policy_mgr_err("No empty entry found to disable link for vdev %d",
4089 			       vdev_id);
4090 		return QDF_STATUS_E_RESOURCES;
4091 	}
4092 
4093 	return QDF_STATUS_SUCCESS;
4094 }
4095 
policy_mgr_move_vdev_from_connection_to_disabled_tbl(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)4096 void policy_mgr_move_vdev_from_connection_to_disabled_tbl(
4097 						struct wlan_objmgr_psoc *psoc,
4098 						uint8_t vdev_id)
4099 {
4100 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4101 	qdf_freq_t freq;
4102 	enum QDF_OPMODE mode;
4103 	QDF_STATUS status;
4104 
4105 	pm_ctx = policy_mgr_get_context(psoc);
4106 	if (!pm_ctx) {
4107 		policy_mgr_err("Invalid pm_ctx");
4108 		return;
4109 	}
4110 
4111 	mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id);
4112 	if (mode != QDF_STA_MODE) {
4113 		policy_mgr_err("vdev %d opmode %d is not STA", vdev_id, mode);
4114 		return;
4115 	}
4116 
4117 	if (!policy_mgr_is_ml_vdev_id(psoc, vdev_id)) {
4118 		policy_mgr_err("vdev %d is not ML", vdev_id);
4119 		return;
4120 	}
4121 	freq = wlan_get_operation_chan_freq_vdev_id(pm_ctx->pdev, vdev_id);
4122 	status = policy_mgr_check_conn_with_mode_and_vdev_id(psoc, PM_STA_MODE,
4123 							     vdev_id);
4124 	/*
4125 	 * Remove entry if present in pm_conc_connection_list, if not just add
4126 	 * it in disabled table.
4127 	 */
4128 	if (QDF_IS_STATUS_SUCCESS(status))
4129 		policy_mgr_decr_session_set_pcl(psoc, mode, vdev_id);
4130 	else
4131 		policy_mgr_debug("Connection tbl dont have vdev %d in STA mode, Add it in disabled tbl",
4132 				 vdev_id);
4133 
4134 	policy_mgr_add_to_disabled_links(pm_ctx, freq, mode, vdev_id);
4135 	policy_mgr_dump_current_concurrency(psoc);
4136 }
4137 
4138 static bool
policy_mgr_vdev_disabled_by_link_force(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,bool peer_assoc)4139 policy_mgr_vdev_disabled_by_link_force(struct wlan_objmgr_psoc *psoc,
4140 				       struct wlan_objmgr_vdev *vdev,
4141 				       bool peer_assoc)
4142 {
4143 	uint16_t dynamic_inactive = 0, forced_inactive = 0;
4144 	uint16_t link_id;
4145 
4146 	if (ml_is_nlink_service_supported(psoc) &&
4147 	    !peer_assoc) {
4148 		ml_nlink_get_dynamic_inactive_links(psoc, vdev,
4149 						    &dynamic_inactive,
4150 						    &forced_inactive);
4151 		link_id = wlan_vdev_get_link_id(vdev);
4152 		if ((forced_inactive | dynamic_inactive) &
4153 		    (1 << link_id)) {
4154 			policy_mgr_debug("vdev %d linkid %d is forced inactived 0x%0x dyn 0x%x",
4155 					 wlan_vdev_get_id(vdev),
4156 					 link_id, forced_inactive,
4157 					 dynamic_inactive);
4158 			return true;
4159 		}
4160 	}
4161 
4162 	return false;
4163 }
4164 
4165 bool
policy_mgr_ml_link_vdev_need_to_be_disabled(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,bool peer_assoc)4166 policy_mgr_ml_link_vdev_need_to_be_disabled(struct wlan_objmgr_psoc *psoc,
4167 					    struct wlan_objmgr_vdev *vdev,
4168 					    bool peer_assoc)
4169 {
4170 	union conc_ext_flag conc_ext_flags;
4171 
4172 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
4173 		return false;
4174 
4175 	/* Check only for link vdev */
4176 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev) ||
4177 	    !wlan_vdev_mlme_is_mlo_link_vdev(vdev))
4178 		return false;
4179 
4180 	/* Check vdev is disabled by link force command */
4181 	if (policy_mgr_vdev_disabled_by_link_force(psoc, vdev,
4182 						   peer_assoc))
4183 		return true;
4184 
4185 	conc_ext_flags.value = policy_mgr_get_conc_ext_flags(vdev, false);
4186 	/*
4187 	 * For non-assoc link vdev set link as disabled if concurrency is
4188 	 * not allowed
4189 	 */
4190 	return !policy_mgr_is_concurrency_allowed(psoc, PM_STA_MODE,
4191 					wlan_get_operation_chan_freq(vdev),
4192 					HW_MODE_20_MHZ,
4193 					conc_ext_flags.value, NULL);
4194 }
4195 
4196 static void
policy_mgr_enable_disable_link_from_vdev_bitmask(struct wlan_objmgr_psoc * psoc,unsigned long enable_vdev_mask,unsigned long disable_vdev_mask,uint8_t start_vdev_id)4197 policy_mgr_enable_disable_link_from_vdev_bitmask(struct wlan_objmgr_psoc *psoc,
4198 						 unsigned long enable_vdev_mask,
4199 						 unsigned long disable_vdev_mask,
4200 						 uint8_t start_vdev_id)
4201 {
4202 	uint8_t i;
4203 
4204 	/* Enable required link if enable_vdev_mask preset */
4205 	for (i = 0; enable_vdev_mask && i < WLAN_MAX_VDEVS; i++) {
4206 		if (qdf_test_and_clear_bit(i, &enable_vdev_mask))
4207 			policy_mgr_move_vdev_from_disabled_to_connection_tbl(
4208 							psoc,
4209 							i + start_vdev_id);
4210 	}
4211 
4212 	/* Disable required link if disable_mask preset */
4213 	for (i = 0; disable_vdev_mask && i < WLAN_MAX_VDEVS; i++) {
4214 		if (qdf_test_and_clear_bit(i, &disable_vdev_mask))
4215 			policy_mgr_move_vdev_from_connection_to_disabled_tbl(
4216 							psoc,
4217 							i + start_vdev_id);
4218 	}
4219 }
4220 
4221 static void
policy_mgr_set_link_in_progress(struct policy_mgr_psoc_priv_obj * pm_ctx,bool set_link_in_progress)4222 policy_mgr_set_link_in_progress(struct policy_mgr_psoc_priv_obj *pm_ctx,
4223 				bool set_link_in_progress)
4224 {
4225 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4226 	if (set_link_in_progress)
4227 		qdf_atomic_inc(&pm_ctx->link_in_progress);
4228 	else {
4229 		if (qdf_atomic_read(&pm_ctx->link_in_progress) > 0)
4230 			qdf_atomic_dec(&pm_ctx->link_in_progress);
4231 	}
4232 
4233 	/* if set link has started reset the event, else complete the event */
4234 	if (qdf_atomic_read(&pm_ctx->link_in_progress))
4235 		qdf_event_reset(&pm_ctx->set_link_update_done_evt);
4236 	else
4237 		qdf_event_set(&pm_ctx->set_link_update_done_evt);
4238 
4239 	policy_mgr_debug("link_in_progress %d",
4240 			 qdf_atomic_read(&pm_ctx->link_in_progress));
4241 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4242 }
4243 
4244 static bool
policy_mgr_get_link_in_progress(struct policy_mgr_psoc_priv_obj * pm_ctx)4245 policy_mgr_get_link_in_progress(struct policy_mgr_psoc_priv_obj *pm_ctx)
4246 {
4247 	bool value;
4248 
4249 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4250 	value = qdf_atomic_read(&pm_ctx->link_in_progress);
4251 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4252 	if (value)
4253 		policy_mgr_debug("set_link_in_progress %d", value);
4254 
4255 	return value;
4256 }
4257 
policy_mgr_is_set_link_in_progress(struct wlan_objmgr_psoc * psoc)4258 bool policy_mgr_is_set_link_in_progress(struct wlan_objmgr_psoc *psoc)
4259 {
4260 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4261 
4262 	pm_ctx = policy_mgr_get_context(psoc);
4263 	if (!pm_ctx) {
4264 		policy_mgr_err("Invalid Context");
4265 		return false;
4266 	}
4267 
4268 	return policy_mgr_get_link_in_progress(pm_ctx);
4269 }
4270 
4271 /*
4272  * policy_mgr_trigger_roam_on_link_removal() - Trigger roam on link removal
4273  * @vdev: vdev object
4274  *
4275  * In multilink ML STA, if one link is removed by AP, and no other active
4276  * link, trigger roam by roaming invoke command.
4277  *
4278  * Return: void
4279  */
4280 static void
policy_mgr_trigger_roam_on_link_removal(struct wlan_objmgr_vdev * vdev)4281 policy_mgr_trigger_roam_on_link_removal(struct wlan_objmgr_vdev *vdev)
4282 {
4283 	struct wlan_objmgr_psoc *psoc;
4284 	struct wlan_objmgr_pdev *pdev;
4285 	struct wlan_objmgr_vdev *ml_vdev;
4286 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4287 	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0;
4288 	uint8_t num_active_ml_sta;
4289 	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
4290 	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
4291 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
4292 	uint8_t assoc_vdev_id = WLAN_INVALID_VDEV_ID;
4293 	uint8_t removed_vdev_id = WLAN_INVALID_VDEV_ID;
4294 	struct qdf_mac_addr bssid;
4295 	QDF_STATUS status;
4296 	bool ml_sta_is_not_connected = false;
4297 	uint32_t i;
4298 
4299 	psoc = wlan_vdev_get_psoc(vdev);
4300 	if (!psoc) {
4301 		policy_mgr_err("Failed to get psoc");
4302 		return;
4303 	}
4304 	pdev = wlan_vdev_get_pdev(vdev);
4305 	if (!pdev) {
4306 		policy_mgr_err("Failed to get pdev");
4307 		return;
4308 	}
4309 	pm_ctx = policy_mgr_get_context(psoc);
4310 	if (!pm_ctx) {
4311 		policy_mgr_err("Invalid Context");
4312 		return;
4313 	}
4314 
4315 	policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta,
4316 				   ml_sta_vdev_lst, ml_freq_lst,
4317 				   NULL, NULL, NULL);
4318 	if (!num_ml_sta) {
4319 		policy_mgr_debug("unexpected event, no ml sta");
4320 		return;
4321 	}
4322 	if (num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
4323 	    num_disabled_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
4324 	    num_ml_sta <= num_disabled_ml_sta) {
4325 		policy_mgr_debug("unexpected ml sta num %d %d",
4326 				 num_ml_sta, num_disabled_ml_sta);
4327 		return;
4328 	}
4329 	num_active_ml_sta = num_ml_sta;
4330 	if (num_ml_sta >= num_disabled_ml_sta)
4331 		num_active_ml_sta = num_ml_sta - num_disabled_ml_sta;
4332 
4333 	for (i = 0; i < num_active_ml_sta; i++) {
4334 		if (!wlan_get_vdev_link_removed_flag_by_vdev_id(
4335 					psoc, ml_sta_vdev_lst[i]))
4336 			break;
4337 	}
4338 
4339 	/* After link removal, one link is still active, no need invoke
4340 	 * roaming.
4341 	 * For Single link MLO, FW will do roaming automatically.
4342 	 */
4343 	if (i < num_active_ml_sta || num_ml_sta < 2)
4344 		return;
4345 
4346 	/* For multi-link MLO STA, if one link is removed and no other active
4347 	 * link, then trigger roaming. the other link may have concurrency
4348 	 * limitation and can't be active.
4349 	 */
4350 	for (i = 0; i < num_ml_sta; i++) {
4351 		if (removed_vdev_id == WLAN_INVALID_VDEV_ID &&
4352 		    wlan_get_vdev_link_removed_flag_by_vdev_id(
4353 			psoc, ml_sta_vdev_lst[i])) {
4354 			policy_mgr_debug("removal link vdev %d is removed ",
4355 					 vdev_id);
4356 			removed_vdev_id = ml_sta_vdev_lst[i];
4357 		}
4358 		ml_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
4359 						pm_ctx->psoc,
4360 						ml_sta_vdev_lst[i],
4361 						WLAN_POLICY_MGR_ID);
4362 		if (!ml_vdev) {
4363 			policy_mgr_err("invalid vdev for id %d",
4364 				       ml_sta_vdev_lst[i]);
4365 			continue;
4366 		}
4367 		if (!wlan_cm_is_vdev_connected(ml_vdev)) {
4368 			policy_mgr_debug("ml sta vdev %d is not connected state",
4369 					 ml_sta_vdev_lst[i]);
4370 			ml_sta_is_not_connected = true;
4371 		}
4372 
4373 		wlan_objmgr_vdev_release_ref(ml_vdev, WLAN_POLICY_MGR_ID);
4374 
4375 		if (assoc_vdev_id == WLAN_INVALID_VDEV_ID &&
4376 		    !wlan_vdev_mlme_get_is_mlo_link(psoc,
4377 						    ml_sta_vdev_lst[i]))
4378 			assoc_vdev_id = ml_sta_vdev_lst[i];
4379 	}
4380 	if (removed_vdev_id == WLAN_INVALID_VDEV_ID) {
4381 		policy_mgr_debug("no link removed, unexpected");
4382 		return;
4383 	}
4384 	if (assoc_vdev_id == WLAN_INVALID_VDEV_ID) {
4385 		policy_mgr_debug("no find assoc vdev, unexpected");
4386 		return;
4387 	}
4388 	if (ml_sta_is_not_connected) {
4389 		policy_mgr_debug("ml sta is non-connected state, don't trigger roam");
4390 		return;
4391 	}
4392 	/* trigger roaming */
4393 	policy_mgr_debug("link removal detected, try roaming on vdev id: %d",
4394 			 assoc_vdev_id);
4395 	qdf_zero_macaddr(&bssid);
4396 	status = wlan_cm_roam_invoke(pdev, assoc_vdev_id, &bssid, 0,
4397 				     CM_ROAMING_LINK_REMOVAL);
4398 	if (QDF_IS_STATUS_ERROR(status))
4399 		policy_mgr_err("roam invoke failed");
4400 }
4401 
4402 /*
4403  * policy_mgr_update_dynamic_inactive_bitmap() - Update dynamic inactive links
4404  * @psoc: psoc object
4405  * @vdev: vdev object
4406  * @req: req of set link command
4407  * @resp: resp of set link command
4408  *
4409  * If MLO_LINK_FORCE_MODE_INACTIVE_NUM force mode with control flag -
4410  * "dynamic_force_link_num" enabled was sent to firmware,
4411  * host will need to select same num of links to be dyamic inactive
4412  * links. And move corresponding vdevs to disabled policy mgr connection table.
4413  *
4414  * Return: void
4415  */
4416 static void
policy_mgr_update_dynamic_inactive_bitmap(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,struct mlo_link_set_active_req * req,struct mlo_link_set_active_resp * resp)4417 policy_mgr_update_dynamic_inactive_bitmap(
4418 			struct wlan_objmgr_psoc *psoc,
4419 			struct wlan_objmgr_vdev *vdev,
4420 			struct mlo_link_set_active_req *req,
4421 			struct mlo_link_set_active_resp *resp)
4422 {
4423 	uint32_t candidate_inactive_links, inactive_links;
4424 	uint32_t standby_links;
4425 	uint32_t dyn_inactive_links = 0;
4426 	uint8_t dyn_num = 0, num = 0, i;
4427 	uint8_t link_ids[MAX_MLO_LINK_ID * 2];
4428 	struct ml_link_force_state curr_state = {0};
4429 	uint8_t force_inactive_num = 0;
4430 	uint32_t force_inactive_num_bitmap = 0;
4431 	uint32_t force_inactive_bitmap;
4432 
4433 	ml_nlink_get_curr_force_state(psoc, vdev, &curr_state);
4434 
4435 	switch (req->param.force_mode) {
4436 	case MLO_LINK_FORCE_MODE_ACTIVE:
4437 	case MLO_LINK_FORCE_MODE_INACTIVE:
4438 	case MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE:
4439 	case MLO_LINK_FORCE_MODE_ACTIVE_NUM:
4440 	case MLO_LINK_FORCE_MODE_NO_FORCE:
4441 		if (!curr_state.curr_dynamic_inactive_bitmap)
4442 			return;
4443 
4444 		force_inactive_num = curr_state.force_inactive_num;
4445 		force_inactive_num_bitmap =
4446 			curr_state.force_inactive_num_bitmap;
4447 		force_inactive_bitmap = curr_state.force_inactive_bitmap;
4448 		break;
4449 	case MLO_LINK_FORCE_MODE_INACTIVE_NUM:
4450 		if (!req->param.control_flags.dynamic_force_link_num) {
4451 			if (!curr_state.curr_dynamic_inactive_bitmap)
4452 				return;
4453 			dyn_inactive_links = 0;
4454 			dyn_num = 0;
4455 			goto update;
4456 		}
4457 
4458 		force_inactive_num = curr_state.force_inactive_num;
4459 		force_inactive_num_bitmap =
4460 			curr_state.force_inactive_num_bitmap;
4461 		force_inactive_bitmap = curr_state.force_inactive_bitmap;
4462 		break;
4463 	default:
4464 		return;
4465 	}
4466 
4467 	/* force inactive num "clear" case, return 0 - no
4468 	 * dynamic inactive links.
4469 	 */
4470 	if (!force_inactive_num) {
4471 		dyn_inactive_links = 0;
4472 		dyn_num = 0;
4473 		goto update;
4474 	}
4475 
4476 	/* 1. If standby link is force inactive,
4477 	 * select the standby link as dynamic inactive link firstly.
4478 	 */
4479 	standby_links = ml_nlink_get_standby_link_bitmap(psoc, vdev);
4480 	candidate_inactive_links =
4481 		force_inactive_num_bitmap &
4482 		force_inactive_bitmap &
4483 		standby_links;
4484 	inactive_links = candidate_inactive_links;
4485 	num = ml_nlink_convert_link_bitmap_to_ids(candidate_inactive_links,
4486 						  QDF_ARRAY_SIZE(link_ids),
4487 						  link_ids);
4488 
4489 	/* 2. If non standby link is force inactive,
4490 	 *  select the non standby link as second option.
4491 	 */
4492 	if (num < force_inactive_num &&
4493 	    num < QDF_ARRAY_SIZE(link_ids)) {
4494 		candidate_inactive_links =
4495 			force_inactive_num_bitmap &
4496 			force_inactive_bitmap &
4497 			~inactive_links;
4498 		num += ml_nlink_convert_link_bitmap_to_ids(
4499 				candidate_inactive_links,
4500 				QDF_ARRAY_SIZE(link_ids) - num,
4501 				&link_ids[num]);
4502 		inactive_links |= candidate_inactive_links;
4503 	}
4504 
4505 	/* 3. If standby link is present (may not be force inactive),
4506 	 * select the standby link as dynamic inactive link.
4507 	 */
4508 	if (num < force_inactive_num &&
4509 	    num < QDF_ARRAY_SIZE(link_ids)) {
4510 		candidate_inactive_links =
4511 			force_inactive_num_bitmap &
4512 			standby_links;
4513 		num += ml_nlink_convert_link_bitmap_to_ids(
4514 				candidate_inactive_links,
4515 				QDF_ARRAY_SIZE(link_ids) - num,
4516 				&link_ids[num]);
4517 		inactive_links |= candidate_inactive_links;
4518 	}
4519 
4520 	/* 4. If there are links inactive from fw event's
4521 	 * curr_inactive_linkid_bitmap, select the current inactive
4522 	 * links as last option. note: those link may not be force
4523 	 * inactive.
4524 	 */
4525 	if (num < force_inactive_num &&
4526 	    num < QDF_ARRAY_SIZE(link_ids)) {
4527 		candidate_inactive_links =
4528 			force_inactive_num_bitmap &
4529 			resp->curr_inactive_linkid_bitmap &
4530 			~inactive_links;
4531 		num += ml_nlink_convert_link_bitmap_to_ids(
4532 				candidate_inactive_links,
4533 				QDF_ARRAY_SIZE(link_ids) - num,
4534 				&link_ids[num]);
4535 		inactive_links |= candidate_inactive_links;
4536 	}
4537 
4538 	for (i = 0; i < num; i++) {
4539 		if (dyn_num >= force_inactive_num)
4540 			break;
4541 		dyn_inactive_links |= 1 << link_ids[i];
4542 		dyn_num++;
4543 	}
4544 
4545 update:
4546 	policy_mgr_debug("inactive link num %d bitmap 0x%x force inactive 0x%x curr 0x%x dyn links 0x%x num %d",
4547 			 force_inactive_num,
4548 			 force_inactive_num_bitmap,
4549 			 resp->inactive_linkid_bitmap,
4550 			 resp->curr_inactive_linkid_bitmap,
4551 			 dyn_inactive_links, dyn_num);
4552 
4553 	ml_nlink_set_dynamic_inactive_links(psoc, vdev, dyn_inactive_links);
4554 }
4555 
4556 static void
policy_mgr_handle_vdev_active_inactive_resp(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,struct mlo_link_set_active_req * req,struct mlo_link_set_active_resp * resp)4557 policy_mgr_handle_vdev_active_inactive_resp(
4558 					struct wlan_objmgr_psoc *psoc,
4559 					struct wlan_objmgr_vdev *vdev,
4560 					struct mlo_link_set_active_req *req,
4561 					struct mlo_link_set_active_resp *resp)
4562 {
4563 	uint8_t i;
4564 	uint8_t vdev_id_num = 0;
4565 	uint8_t vdev_ids[WLAN_MLO_MAX_VDEVS] = {0};
4566 	uint32_t assoc_bitmap = 0;
4567 	uint16_t dynamic_inactive_bitmap = 0;
4568 	uint16_t forced_inactive_bitmap = 0;
4569 
4570 	/* convert link id to vdev id and update vdev status based
4571 	 * on both inactive and active bitmap.
4572 	 * In link bitmap based WMI event (use_ieee_link_id = true),
4573 	 * target will always indicate current force inactive and
4574 	 * active bitmaps to host. For links in inactive_linkid_bitmap,
4575 	 * they will be moved to policy mgr disable connection table.
4576 	 * for other links, they will be in active tables.
4577 	 */
4578 	ml_nlink_get_dynamic_inactive_links(psoc, vdev,
4579 					    &dynamic_inactive_bitmap,
4580 					    &forced_inactive_bitmap);
4581 	resp->inactive_linkid_bitmap |= dynamic_inactive_bitmap;
4582 	ml_nlink_convert_linkid_bitmap_to_vdev_bitmap(
4583 		psoc, vdev, resp->inactive_linkid_bitmap,
4584 		&assoc_bitmap,
4585 		&resp->inactive_sz, resp->inactive,
4586 		&vdev_id_num, vdev_ids);
4587 
4588 	ml_nlink_convert_linkid_bitmap_to_vdev_bitmap(
4589 		psoc, vdev,
4590 		(~resp->inactive_linkid_bitmap) & assoc_bitmap,
4591 		NULL,
4592 		&resp->active_sz, resp->active,
4593 		&vdev_id_num, vdev_ids);
4594 	for (i = 0; i < resp->inactive_sz; i++)
4595 		policy_mgr_enable_disable_link_from_vdev_bitmask(
4596 				psoc, 0, resp->inactive[i], i * 32);
4597 	for (i = 0; i < resp->active_sz; i++)
4598 		policy_mgr_enable_disable_link_from_vdev_bitmask(
4599 				psoc, resp->active[i], 0, i * 32);
4600 }
4601 
4602 static void
policy_mgr_handle_force_active_resp(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,struct mlo_link_set_active_req * req,struct mlo_link_set_active_resp * resp)4603 policy_mgr_handle_force_active_resp(struct wlan_objmgr_psoc *psoc,
4604 				    struct wlan_objmgr_vdev *vdev,
4605 				    struct mlo_link_set_active_req *req,
4606 				    struct mlo_link_set_active_resp *resp)
4607 {
4608 	uint8_t i;
4609 	uint32_t assoc_bitmap = 0;
4610 
4611 	if (resp->use_ieee_link_id) {
4612 		/* save link force active bitmap */
4613 		ml_nlink_set_curr_force_active_state(
4614 			psoc, vdev, req->param.force_cmd.ieee_link_id_bitmap,
4615 			req->param.control_flags.overwrite_force_active_bitmap ?
4616 			LINK_OVERWRITE : LINK_ADD);
4617 
4618 		policy_mgr_update_dynamic_inactive_bitmap(psoc, vdev, req,
4619 							  resp);
4620 
4621 		/* update vdev active inactive status */
4622 		policy_mgr_handle_vdev_active_inactive_resp(psoc, vdev, req,
4623 							    resp);
4624 		return;
4625 	}
4626 	ml_nlink_convert_vdev_bitmap_to_linkid_bitmap(
4627 		psoc, vdev, req->param.num_vdev_bitmap,
4628 		req->param.vdev_bitmap, &resp->active_linkid_bitmap,
4629 		&assoc_bitmap);
4630 	ml_nlink_set_curr_force_active_state(
4631 		psoc, vdev, resp->active_linkid_bitmap, LINK_ADD);
4632 
4633 	for (i = 0; i < resp->active_sz; i++)
4634 		policy_mgr_enable_disable_link_from_vdev_bitmask(
4635 				psoc, resp->active[i], 0, i * 32);
4636 }
4637 
4638 static void
policy_mgr_handle_force_inactive_resp(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,struct mlo_link_set_active_req * req,struct mlo_link_set_active_resp * resp)4639 policy_mgr_handle_force_inactive_resp(struct wlan_objmgr_psoc *psoc,
4640 				      struct wlan_objmgr_vdev *vdev,
4641 				      struct mlo_link_set_active_req *req,
4642 				      struct mlo_link_set_active_resp *resp)
4643 {
4644 	uint8_t i;
4645 	uint32_t assoc_bitmap = 0;
4646 
4647 	if (resp->use_ieee_link_id) {
4648 		/* save link force inactive bitmap */
4649 		ml_nlink_set_curr_force_inactive_state(
4650 			psoc, vdev, req->param.force_cmd.ieee_link_id_bitmap,
4651 			req->param.control_flags.overwrite_force_inactive_bitmap ?
4652 			LINK_OVERWRITE : LINK_ADD);
4653 
4654 		policy_mgr_update_dynamic_inactive_bitmap(psoc, vdev, req,
4655 							  resp);
4656 
4657 		/* update vdev active inactive status */
4658 		policy_mgr_handle_vdev_active_inactive_resp(psoc, vdev, req,
4659 							    resp);
4660 		return;
4661 	}
4662 	ml_nlink_convert_vdev_bitmap_to_linkid_bitmap(
4663 		psoc, vdev, req->param.num_vdev_bitmap,
4664 		req->param.vdev_bitmap, &resp->inactive_linkid_bitmap,
4665 		&assoc_bitmap);
4666 	ml_nlink_set_curr_force_inactive_state(
4667 		psoc, vdev, resp->inactive_linkid_bitmap, LINK_ADD);
4668 
4669 	for (i = 0; i < resp->inactive_sz; i++)
4670 		policy_mgr_enable_disable_link_from_vdev_bitmask(
4671 				psoc, 0, resp->inactive[i], i * 32);
4672 }
4673 
4674 static void
policy_mgr_handle_force_active_num_resp(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,struct mlo_link_set_active_req * req,struct mlo_link_set_active_resp * resp)4675 policy_mgr_handle_force_active_num_resp(struct wlan_objmgr_psoc *psoc,
4676 					struct wlan_objmgr_vdev *vdev,
4677 					struct mlo_link_set_active_req *req,
4678 					struct mlo_link_set_active_resp *resp)
4679 {
4680 	uint8_t i;
4681 	uint32_t assoc_bitmap = 0;
4682 	uint32_t link_bitmap = 0;
4683 
4684 	if (resp->use_ieee_link_id) {
4685 		/* save force num and force num bitmap */
4686 		ml_nlink_set_curr_force_active_num_state(
4687 			psoc, vdev, req->param.force_cmd.link_num,
4688 			req->param.force_cmd.ieee_link_id_bitmap);
4689 
4690 		policy_mgr_update_dynamic_inactive_bitmap(psoc, vdev, req,
4691 							  resp);
4692 
4693 		/* update vdev active inactive status */
4694 		policy_mgr_handle_vdev_active_inactive_resp(psoc, vdev, req,
4695 							    resp);
4696 		return;
4697 	}
4698 	ml_nlink_convert_vdev_bitmap_to_linkid_bitmap(
4699 		psoc, vdev, req->param.num_vdev_bitmap,
4700 		req->param.vdev_bitmap,
4701 		&link_bitmap,
4702 		&assoc_bitmap);
4703 	ml_nlink_set_curr_force_active_num_state(
4704 		psoc, vdev, req->param.link_num[0].num_of_link,
4705 		link_bitmap);
4706 	/*
4707 	 * When the host sends a set link command with force link num
4708 	 * and dynamic flag set, FW may not process it immediately.
4709 	 * In this case FW buffer the request and sends a response as
4710 	 * success to the host with VDEV bitmap as zero.
4711 	 * FW ensures that the number of active links will be equal to
4712 	 * the link num sent via WMI_MLO_LINK_SET_ACTIVE_CMDID command.
4713 	 * So the host should also fill the mlo policy_mgr table as per
4714 	 * request.
4715 	 */
4716 	if (req->param.control_flags.dynamic_force_link_num) {
4717 		policy_mgr_debug("Enable ML vdev(s) as sent in req");
4718 		for (i = 0; i < req->param.num_vdev_bitmap; i++)
4719 			policy_mgr_enable_disable_link_from_vdev_bitmask(
4720 				psoc,
4721 				req->param.vdev_bitmap[i], 0, i * 32);
4722 		return;
4723 	}
4724 
4725 	/*
4726 	 * MLO_LINK_FORCE_MODE_ACTIVE_NUM return which vdev is active
4727 	 * So XOR of the requested ML vdev and active vdev bit will give
4728 	 * the vdev bits to disable
4729 	 */
4730 	for (i = 0; i < resp->active_sz; i++)
4731 		policy_mgr_enable_disable_link_from_vdev_bitmask(
4732 			psoc, resp->active[i],
4733 			resp->active[i] ^ req->param.vdev_bitmap[i],
4734 			i * 32);
4735 }
4736 
4737 static void
policy_mgr_handle_force_inactive_num_resp(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,struct mlo_link_set_active_req * req,struct mlo_link_set_active_resp * resp)4738 policy_mgr_handle_force_inactive_num_resp(
4739 				struct wlan_objmgr_psoc *psoc,
4740 				struct wlan_objmgr_vdev *vdev,
4741 				struct mlo_link_set_active_req *req,
4742 				struct mlo_link_set_active_resp *resp)
4743 {
4744 	uint8_t i;
4745 	uint32_t assoc_bitmap = 0;
4746 	uint32_t link_bitmap = 0;
4747 
4748 	if (resp->use_ieee_link_id) {
4749 		/* save force num and force num bitmap */
4750 		ml_nlink_set_curr_force_inactive_num_state(
4751 			psoc, vdev, req->param.force_cmd.link_num,
4752 			req->param.force_cmd.ieee_link_id_bitmap);
4753 		policy_mgr_update_dynamic_inactive_bitmap(psoc, vdev, req,
4754 							  resp);
4755 
4756 		/* update vdev active inactive status */
4757 		policy_mgr_handle_vdev_active_inactive_resp(psoc, vdev, req,
4758 							    resp);
4759 		return;
4760 	}
4761 	ml_nlink_convert_vdev_bitmap_to_linkid_bitmap(
4762 		psoc, vdev, req->param.num_vdev_bitmap,
4763 		req->param.vdev_bitmap,
4764 		&link_bitmap,
4765 		&assoc_bitmap);
4766 	ml_nlink_set_curr_force_inactive_num_state(
4767 		psoc, vdev, req->param.link_num[0].num_of_link,
4768 		link_bitmap);
4769 
4770 	/*
4771 	 * MLO_LINK_FORCE_MODE_INACTIVE_NUM return which vdev is
4772 	 * inactive So XOR of the requested ML vdev and inactive vdev
4773 	 * bit will give the vdev bits to be enable.
4774 	 */
4775 	for (i = 0; i < resp->inactive_sz; i++)
4776 		policy_mgr_enable_disable_link_from_vdev_bitmask(
4777 			psoc,
4778 			resp->inactive[i] ^ req->param.vdev_bitmap[i],
4779 			resp->inactive[i], i * 32);
4780 }
4781 
4782 static void
policy_mgr_handle_force_active_inactive_resp(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,struct mlo_link_set_active_req * req,struct mlo_link_set_active_resp * resp)4783 policy_mgr_handle_force_active_inactive_resp(
4784 				struct wlan_objmgr_psoc *psoc,
4785 				struct wlan_objmgr_vdev *vdev,
4786 				struct mlo_link_set_active_req *req,
4787 				struct mlo_link_set_active_resp *resp)
4788 {
4789 	uint8_t i;
4790 	uint32_t assoc_bitmap = 0;
4791 
4792 	if (resp->use_ieee_link_id) {
4793 		/* save link active/inactive bitmap */
4794 		ml_nlink_set_curr_force_active_state(
4795 			psoc, vdev, req->param.force_cmd.ieee_link_id_bitmap,
4796 			req->param.control_flags.overwrite_force_active_bitmap ?
4797 			LINK_OVERWRITE : LINK_ADD);
4798 		ml_nlink_set_curr_force_inactive_state(
4799 			psoc, vdev, req->param.force_cmd.ieee_link_id_bitmap2,
4800 			req->param.control_flags.overwrite_force_inactive_bitmap ?
4801 			LINK_OVERWRITE : LINK_ADD);
4802 
4803 		policy_mgr_update_dynamic_inactive_bitmap(psoc, vdev, req,
4804 							  resp);
4805 
4806 		/* update vdev active inactive status */
4807 		policy_mgr_handle_vdev_active_inactive_resp(psoc, vdev, req,
4808 							    resp);
4809 		return;
4810 	}
4811 	ml_nlink_convert_vdev_bitmap_to_linkid_bitmap(
4812 		psoc, vdev, req->param.num_inactive_vdev_bitmap,
4813 		req->param.inactive_vdev_bitmap,
4814 		&resp->inactive_linkid_bitmap,
4815 		&assoc_bitmap);
4816 	ml_nlink_set_curr_force_inactive_state(
4817 		psoc, vdev, resp->inactive_linkid_bitmap, LINK_ADD);
4818 	ml_nlink_convert_vdev_bitmap_to_linkid_bitmap(
4819 		psoc, vdev, req->param.num_vdev_bitmap,
4820 		req->param.vdev_bitmap,
4821 		&resp->active_linkid_bitmap,
4822 		&assoc_bitmap);
4823 	ml_nlink_set_curr_force_active_state(
4824 		psoc, vdev, resp->active_linkid_bitmap, LINK_ADD);
4825 
4826 	for (i = 0; i < resp->inactive_sz; i++)
4827 		policy_mgr_enable_disable_link_from_vdev_bitmask(
4828 				psoc, 0, resp->inactive[i], i * 32);
4829 	for (i = 0; i < resp->active_sz; i++)
4830 		policy_mgr_enable_disable_link_from_vdev_bitmask(
4831 				psoc, resp->active[i], 0, i * 32);
4832 }
4833 
4834 static void
policy_mgr_handle_no_force_resp(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,struct mlo_link_set_active_req * req,struct mlo_link_set_active_resp * resp)4835 policy_mgr_handle_no_force_resp(struct wlan_objmgr_psoc *psoc,
4836 				struct wlan_objmgr_vdev *vdev,
4837 				struct mlo_link_set_active_req *req,
4838 				struct mlo_link_set_active_resp *resp)
4839 {
4840 	uint8_t i;
4841 	uint32_t assoc_bitmap = 0;
4842 	uint32_t link_bitmap = 0;
4843 
4844 	if (resp->use_ieee_link_id) {
4845 		/* update link inactive/active bitmap */
4846 		if (req->param.force_cmd.ieee_link_id_bitmap) {
4847 			ml_nlink_set_curr_force_inactive_state(
4848 				psoc, vdev,
4849 				req->param.force_cmd.ieee_link_id_bitmap,
4850 				LINK_CLR);
4851 			ml_nlink_set_curr_force_active_state(
4852 				psoc, vdev,
4853 				req->param.force_cmd.ieee_link_id_bitmap,
4854 				LINK_CLR);
4855 		} else {
4856 			/* special handling for no force to clear all */
4857 			ml_nlink_clr_force_state(psoc, vdev);
4858 		}
4859 
4860 		policy_mgr_update_dynamic_inactive_bitmap(psoc, vdev, req,
4861 							  resp);
4862 		/* update vdev active inactive status */
4863 		policy_mgr_handle_vdev_active_inactive_resp(psoc, vdev, req,
4864 							    resp);
4865 		return;
4866 	}
4867 
4868 	ml_nlink_convert_vdev_bitmap_to_linkid_bitmap(
4869 		psoc, vdev, req->param.num_vdev_bitmap,
4870 		req->param.vdev_bitmap,
4871 		&link_bitmap, &assoc_bitmap);
4872 
4873 	ml_nlink_set_curr_force_inactive_state(
4874 		psoc, vdev, link_bitmap, LINK_CLR);
4875 	ml_nlink_set_curr_force_active_state(
4876 		psoc, vdev, link_bitmap, LINK_CLR);
4877 	ml_nlink_set_curr_force_active_num_state(
4878 		psoc, vdev, 0, 0);
4879 	ml_nlink_set_curr_force_inactive_num_state(
4880 		psoc, vdev, 0, 0);
4881 
4882 	/* Enable all the ML vdev id sent in request */
4883 	for (i = 0; i < req->param.num_vdev_bitmap; i++)
4884 		policy_mgr_enable_disable_link_from_vdev_bitmask(
4885 			psoc, req->param.vdev_bitmap[i], 0, i * 32);
4886 }
4887 
4888 static void
policy_mgr_handle_link_enable_disable_resp(struct wlan_objmgr_vdev * vdev,void * arg,struct mlo_link_set_active_resp * resp)4889 policy_mgr_handle_link_enable_disable_resp(struct wlan_objmgr_vdev *vdev,
4890 					  void *arg,
4891 					  struct mlo_link_set_active_resp *resp)
4892 {
4893 	struct mlo_link_set_active_req *req = arg;
4894 	struct wlan_objmgr_psoc *psoc;
4895 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4896 	QDF_STATUS status = QDF_STATUS_SUCCESS;
4897 
4898 	psoc = wlan_vdev_get_psoc(vdev);
4899 	if (!psoc) {
4900 		policy_mgr_err("Psoc is Null");
4901 		return;
4902 	}
4903 	pm_ctx = policy_mgr_get_context(psoc);
4904 	if (!pm_ctx) {
4905 		policy_mgr_err("Invalid Context");
4906 		return;
4907 	}
4908 
4909 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4910 	if (!req || !resp) {
4911 		policy_mgr_err("arguments or event empty for vdev %d",
4912 			       wlan_vdev_get_id(vdev));
4913 		goto complete_evnt;
4914 	}
4915 
4916 	if (resp->status) {
4917 		policy_mgr_err("Set link status %d, for mode %d reason %d vdev bitmask 0x%x",
4918 			       resp->status, req->param.force_mode,
4919 			       req->param.reason, req->param.vdev_bitmap[0]);
4920 		goto complete_evnt;
4921 	}
4922 
4923 	policy_mgr_debug("Req mode %d reason %d, bitmask[0] = 0x%x, resp: active %d inactive %d, active[0] 0x%x inactive[0] 0x%x",
4924 			 req->param.force_mode, req->param.reason,
4925 			 req->param.vdev_bitmap[0],
4926 			 resp->active_sz, resp->inactive_sz,
4927 			 resp->active[0], resp->inactive[0]);
4928 	switch (req->param.force_mode) {
4929 	case MLO_LINK_FORCE_MODE_ACTIVE:
4930 		policy_mgr_handle_force_active_resp(psoc, vdev, req, resp);
4931 		break;
4932 	case MLO_LINK_FORCE_MODE_INACTIVE:
4933 		policy_mgr_handle_force_inactive_resp(psoc, vdev, req, resp);
4934 		break;
4935 	case MLO_LINK_FORCE_MODE_ACTIVE_NUM:
4936 		policy_mgr_handle_force_active_num_resp(psoc, vdev, req, resp);
4937 		break;
4938 	case MLO_LINK_FORCE_MODE_INACTIVE_NUM:
4939 		policy_mgr_handle_force_inactive_num_resp(psoc, vdev, req,
4940 							  resp);
4941 		break;
4942 	case MLO_LINK_FORCE_MODE_NO_FORCE:
4943 		policy_mgr_handle_no_force_resp(psoc, vdev, req, resp);
4944 		break;
4945 	case MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE:
4946 		policy_mgr_handle_force_active_inactive_resp(psoc, vdev, req,
4947 							     resp);
4948 		break;
4949 	default:
4950 		policy_mgr_err("Invalid request req mode %d",
4951 			       req->param.force_mode);
4952 		break;
4953 	}
4954 	if (req->param.reason == MLO_LINK_FORCE_REASON_LINK_REMOVAL)
4955 		policy_mgr_trigger_roam_on_link_removal(vdev);
4956 
4957 complete_evnt:
4958 	policy_mgr_set_link_in_progress(pm_ctx, false);
4959 	if (ml_is_nlink_service_supported(psoc) &&
4960 	    req && resp && !resp->status &&
4961 	    req->param.control_flags.post_re_evaluate)
4962 		status = ml_nlink_conn_change_notify(
4963 			psoc, wlan_vdev_get_id(vdev),
4964 			ml_nlink_connection_updated_evt, NULL);
4965 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4966 
4967 	/* reschedule force scc workqueue after link state changes */
4968 	if (req && resp && !resp->status &&
4969 	    status == QDF_STATUS_SUCCESS)
4970 		policy_mgr_check_concurrent_intf_and_restart_sap(psoc, false);
4971 }
4972 #else
4973 static inline QDF_STATUS
policy_mgr_delete_from_disabled_links(struct policy_mgr_psoc_priv_obj * pm_ctx,uint8_t vdev_id)4974 policy_mgr_delete_from_disabled_links(struct policy_mgr_psoc_priv_obj *pm_ctx,
4975 				      uint8_t vdev_id)
4976 {
4977 	return QDF_STATUS_SUCCESS;
4978 }
4979 #endif
4980 
policy_mgr_is_mlo_sta_disconnected(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)4981 bool policy_mgr_is_mlo_sta_disconnected(struct wlan_objmgr_psoc *psoc,
4982 					 uint8_t vdev_id)
4983 {
4984 	struct wlan_objmgr_vdev *vdev;
4985 	bool disconnected;
4986 
4987 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
4988 						    WLAN_POLICY_MGR_ID);
4989 	if (!vdev)
4990 		return true;
4991 	/* mlo mgr has no corresponding protocol api used in non-osif/hdd
4992 	 * component. Todo: clean up to use internal API
4993 	 */
4994 	disconnected = ucfg_mlo_is_mld_disconnected(vdev);
4995 
4996 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
4997 
4998 	return disconnected;
4999 }
5000 
policy_mgr_incr_active_session(struct wlan_objmgr_psoc * psoc,enum QDF_OPMODE mode,uint8_t session_id)5001 void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc,
5002 				enum QDF_OPMODE mode,
5003 				uint8_t session_id)
5004 {
5005 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5006 	uint32_t conn_6ghz_flag = 0;
5007 
5008 	pm_ctx = policy_mgr_get_context(psoc);
5009 	if (!pm_ctx) {
5010 		policy_mgr_err("Invalid Context");
5011 		return;
5012 	}
5013 
5014 	/*
5015 	 * Need to acquire mutex as entire functionality in this function
5016 	 * is in critical section
5017 	 */
5018 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
5019 	switch (mode) {
5020 	case QDF_STA_MODE:
5021 	case QDF_P2P_CLIENT_MODE:
5022 	case QDF_P2P_GO_MODE:
5023 	case QDF_SAP_MODE:
5024 	case QDF_NAN_DISC_MODE:
5025 	case QDF_NDI_MODE:
5026 		pm_ctx->no_of_active_sessions[mode]++;
5027 		break;
5028 	default:
5029 		break;
5030 	}
5031 
5032 	if (mode == QDF_NDI_MODE &&
5033 	    pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt)
5034 		pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt(
5035 				psoc, session_id,
5036 				pm_ctx->no_of_active_sessions[mode]);
5037 
5038 	if (mode != QDF_NAN_DISC_MODE && pm_ctx->dp_cbacks.hdd_v2_flow_pool_map)
5039 		pm_ctx->dp_cbacks.hdd_v2_flow_pool_map(session_id);
5040 	if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE)
5041 		policy_mgr_get_ap_6ghz_capable(psoc, session_id,
5042 					       &conn_6ghz_flag);
5043 
5044 	policy_mgr_debug("No.# of active sessions for mode %d = %d",
5045 		mode, pm_ctx->no_of_active_sessions[mode]);
5046 	policy_mgr_incr_connection_count(psoc, session_id, mode);
5047 
5048 	if ((policy_mgr_mode_specific_connection_count(
5049 		psoc, PM_STA_MODE, NULL) > 0) && (mode != QDF_STA_MODE)) {
5050 		/* Send set pcl for all the connected STA vdev */
5051 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
5052 		polic_mgr_send_pcl_to_fw(psoc, mode);
5053 		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
5054 	}
5055 
5056 	/* Notify tdls */
5057 	if (pm_ctx->tdls_cbacks.tdls_notify_increment_session)
5058 		pm_ctx->tdls_cbacks.tdls_notify_increment_session(psoc);
5059 
5060 	/*
5061 	 * Disable LRO/GRO if P2P or SAP connection has come up or
5062 	 * there are more than one STA connections
5063 	 */
5064 	if ((policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, NULL) > 1) ||
5065 	    (policy_mgr_get_beaconing_mode_count(psoc, NULL) > 0) ||
5066 	    (policy_mgr_mode_specific_connection_count(psoc, PM_P2P_CLIENT_MODE, NULL) >
5067 									0) ||
5068 	    (policy_mgr_mode_specific_connection_count(psoc,
5069 						       PM_NDI_MODE,
5070 						       NULL) > 0)) {
5071 		if (pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency)
5072 			pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency(true);
5073 	};
5074 
5075 	/* Enable RPS if SAP interface has come up */
5076 	if (policy_mgr_get_sap_mode_count(psoc, NULL) == 1) {
5077 		if (pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb)
5078 			pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb(true);
5079 	}
5080 	if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE)
5081 		policy_mgr_init_ap_6ghz_capable(psoc, session_id,
5082 						conn_6ghz_flag);
5083 	if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE ||
5084 	    mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE)
5085 		policy_mgr_update_dfs_master_dynamic_enabled(psoc, session_id);
5086 
5087 	policy_mgr_dump_current_concurrency(psoc);
5088 
5089 	if (policy_mgr_update_indoor_concurrency(psoc, session_id, 0, CONNECT))
5090 		wlan_reg_recompute_current_chan_list(psoc, pm_ctx->pdev);
5091 
5092 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
5093 	if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE)
5094 		ml_nlink_conn_change_notify(
5095 			psoc, session_id, ml_nlink_ap_started_evt, NULL);
5096 }
5097 
5098 /**
5099  * policy_mgr_update_sta_scc_info_for_later_check() - function to update sta/sap
5100  * scc channel frequency and later check flag.
5101  * @pm_ctx: policy manager context pointer
5102  * @mode: operation mode
5103  * @vdev_id: vdev id
5104  *
5105  * Return: None
5106  */
policy_mgr_update_sta_scc_info_for_later_check(struct policy_mgr_psoc_priv_obj * pm_ctx,enum QDF_OPMODE mode,uint8_t vdev_id)5107 static void policy_mgr_update_sta_scc_info_for_later_check(
5108 		struct policy_mgr_psoc_priv_obj *pm_ctx,
5109 		enum QDF_OPMODE mode,
5110 		uint8_t vdev_id)
5111 {
5112 	uint32_t conn_index = 0;
5113 	qdf_freq_t sta_freq = 0;
5114 
5115 	if (mode != QDF_STA_MODE && mode != QDF_P2P_CLIENT_MODE)
5116 		return;
5117 
5118 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
5119 	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
5120 		if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
5121 			sta_freq = pm_conc_connection_list[conn_index].freq;
5122 			break;
5123 		}
5124 		conn_index++;
5125 	}
5126 
5127 	if (!sta_freq)
5128 		goto release_mutex;
5129 
5130 	/*
5131 	 * When STA disconnected, we need to move DFS SAP
5132 	 * to Non-DFS if g_sta_sap_scc_on_dfs_chan enabled.
5133 	 * The same if g_sta_sap_scc_on_lte_coex_chan enabled,
5134 	 * need to move SAP on unsafe channel to safe channel.
5135 	 * The flag will be checked by
5136 	 * policy_mgr_is_sap_restart_required_after_sta_disconnect.
5137 	 */
5138 	conn_index = 0;
5139 	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
5140 		if (pm_conc_connection_list[conn_index].freq == sta_freq &&
5141 		    (pm_conc_connection_list[conn_index].mode == PM_SAP_MODE ||
5142 		    pm_conc_connection_list[conn_index].mode ==
5143 		    PM_P2P_GO_MODE)) {
5144 			pm_ctx->last_disconn_sta_freq = sta_freq;
5145 			break;
5146 		}
5147 		conn_index++;
5148 	}
5149 
5150 release_mutex:
5151 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
5152 }
5153 
policy_mgr_decr_active_session(struct wlan_objmgr_psoc * psoc,enum QDF_OPMODE mode,uint8_t session_id)5154 QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc,
5155 				enum QDF_OPMODE mode,
5156 				uint8_t session_id)
5157 {
5158 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5159 	QDF_STATUS qdf_status;
5160 	bool mcc_mode;
5161 	uint32_t session_count, cur_freq;
5162 	enum hw_mode_bandwidth max_bw;
5163 
5164 	pm_ctx = policy_mgr_get_context(psoc);
5165 	if (!pm_ctx) {
5166 		policy_mgr_err("context is NULL");
5167 		return QDF_STATUS_E_EMPTY;
5168 	}
5169 
5170 	qdf_status = policy_mgr_check_conn_with_mode_and_vdev_id(psoc,
5171 			policy_mgr_qdf_opmode_to_pm_con_mode(psoc, mode,
5172 							     session_id),
5173 			session_id);
5174 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
5175 		policy_mgr_debug("No connection with mode:%d vdev_id:%d",
5176 			policy_mgr_qdf_opmode_to_pm_con_mode(psoc, mode,
5177 							     session_id),
5178 			session_id);
5179 		/*
5180 		 * In case of disconnect try delete the link from disabled link
5181 		 * as well, if its not present in pm_conc_connection_list,
5182 		 * it can be present in pm_disabled_ml_links.
5183 		 */
5184 		policy_mgr_delete_from_disabled_links(pm_ctx, session_id);
5185 		policy_mgr_dump_current_concurrency(psoc);
5186 		return qdf_status;
5187 	}
5188 	policy_mgr_update_sta_scc_info_for_later_check(pm_ctx,
5189 						       mode,
5190 						       session_id);
5191 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
5192 	switch (mode) {
5193 	case QDF_STA_MODE:
5194 	case QDF_P2P_CLIENT_MODE:
5195 	case QDF_P2P_GO_MODE:
5196 	case QDF_SAP_MODE:
5197 	case QDF_NAN_DISC_MODE:
5198 	case QDF_NDI_MODE:
5199 		if (pm_ctx->no_of_active_sessions[mode])
5200 			pm_ctx->no_of_active_sessions[mode]--;
5201 		break;
5202 	default:
5203 		break;
5204 	}
5205 
5206 	policy_mgr_get_chan_by_session_id(psoc, session_id, &cur_freq);
5207 
5208 	policy_mgr_decr_connection_count(psoc, session_id);
5209 	session_count = pm_ctx->no_of_active_sessions[mode];
5210 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
5211 
5212 	if (mode != QDF_NAN_DISC_MODE &&
5213 	    pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap)
5214 		pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap(session_id);
5215 
5216 	if (mode == QDF_NDI_MODE &&
5217 	    pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt)
5218 		pm_ctx->hdd_cbacks.wlan_hdd_indicate_active_ndp_cnt(
5219 				psoc, session_id, session_count);
5220 
5221 	policy_mgr_debug("No.# of active sessions for mode %d = %d",
5222 			 mode, session_count);
5223 
5224 	/* Notify tdls */
5225 	if (pm_ctx->tdls_cbacks.tdls_notify_decrement_session)
5226 		pm_ctx->tdls_cbacks.tdls_notify_decrement_session(psoc);
5227 	/* Enable LRO/GRO if there no concurrency */
5228 	if ((policy_mgr_get_connection_count(psoc) == 0) ||
5229 	    ((policy_mgr_mode_specific_connection_count(psoc,
5230 							PM_STA_MODE,
5231 							NULL) == 1) &&
5232 	     (policy_mgr_get_beaconing_mode_count(psoc, NULL) == 0) &&
5233 	     (policy_mgr_mode_specific_connection_count(psoc,
5234 							PM_P2P_CLIENT_MODE,
5235 							NULL) == 0) &&
5236 	     (policy_mgr_mode_specific_connection_count(psoc,
5237 							PM_NDI_MODE,
5238 							NULL) == 0))) {
5239 		if (pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency)
5240 			pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency(false);
5241 	};
5242 
5243 	/* Disable RPS if SAP interface has come up */
5244 	if (policy_mgr_get_sap_mode_count(psoc, NULL) == 0) {
5245 		if (pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb)
5246 			pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb(false);
5247 	}
5248 
5249 	policy_mgr_dump_current_concurrency(psoc);
5250 
5251 	/*
5252 	 * Check mode of entry being removed. Update mcc_mode only when STA
5253 	 * or SAP since IPA only cares about these two
5254 	 */
5255 	if (mode == QDF_STA_MODE || mode == QDF_SAP_MODE) {
5256 		mcc_mode = policy_mgr_current_concurrency_is_mcc(psoc);
5257 
5258 		if (pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb)
5259 			pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb(mcc_mode);
5260 
5261 		if (pm_ctx->dp_cbacks.hdd_ipa_set_perf_level_bw) {
5262 			max_bw = policy_mgr_get_connection_max_channel_width(
5263 					psoc);
5264 			policy_mgr_debug("max channel width %d", max_bw);
5265 			pm_ctx->dp_cbacks.hdd_ipa_set_perf_level_bw(max_bw);
5266 		}
5267 	}
5268 
5269 	if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE ||
5270 	    mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE)
5271 		policy_mgr_update_dfs_master_dynamic_enabled(psoc, session_id);
5272 
5273 	if (!pm_ctx->last_disconn_sta_freq) {
5274 		if (policy_mgr_update_indoor_concurrency(psoc, session_id,
5275 		    cur_freq, DISCONNECT_WITHOUT_CONCURRENCY))
5276 			wlan_reg_recompute_current_chan_list(psoc,
5277 							     pm_ctx->pdev);
5278 	}
5279 
5280 	if (wlan_reg_get_keep_6ghz_sta_cli_connection(pm_ctx->pdev) &&
5281 	    (mode == QDF_STA_MODE || mode == QDF_P2P_CLIENT_MODE))
5282 		wlan_reg_recompute_current_chan_list(psoc, pm_ctx->pdev);
5283 
5284 	return qdf_status;
5285 }
5286 
policy_mgr_incr_connection_count(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id,enum QDF_OPMODE op_mode)5287 QDF_STATUS policy_mgr_incr_connection_count(struct wlan_objmgr_psoc *psoc,
5288 					    uint32_t vdev_id,
5289 					    enum QDF_OPMODE op_mode)
5290 {
5291 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
5292 	uint32_t conn_index;
5293 	struct policy_mgr_vdev_entry_info conn_table_entry = {0};
5294 	enum policy_mgr_chain_mode chain_mask = POLICY_MGR_ONE_ONE;
5295 	uint8_t nss_2g = 0, nss_5g = 0;
5296 	enum policy_mgr_con_mode mode;
5297 	uint32_t ch_freq;
5298 	uint32_t nss = 0;
5299 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5300 	bool update_conn = true;
5301 
5302 	pm_ctx = policy_mgr_get_context(psoc);
5303 	if (!pm_ctx) {
5304 		policy_mgr_err("context is NULL");
5305 		return status;
5306 	}
5307 
5308 	conn_index = policy_mgr_get_connection_count(psoc);
5309 	if (pm_ctx->cfg.max_conc_cxns < conn_index) {
5310 		policy_mgr_err("exceeded max connection limit %d",
5311 			pm_ctx->cfg.max_conc_cxns);
5312 		return status;
5313 	}
5314 
5315 	if (op_mode == QDF_NAN_DISC_MODE) {
5316 		status = wlan_nan_get_connection_info(psoc, &conn_table_entry);
5317 		if (QDF_IS_STATUS_ERROR(status)) {
5318 			policy_mgr_err("Can't get NAN Connection info");
5319 			return status;
5320 		}
5321 	} else if (pm_ctx->wma_cbacks.wma_get_connection_info) {
5322 		status = pm_ctx->wma_cbacks.wma_get_connection_info(
5323 				vdev_id, &conn_table_entry);
5324 		if (QDF_STATUS_SUCCESS != status) {
5325 			policy_mgr_err("can't find vdev_id %d in connection table",
5326 			vdev_id);
5327 			return status;
5328 		}
5329 	} else {
5330 		policy_mgr_err("wma_get_connection_info is NULL");
5331 		return QDF_STATUS_E_FAILURE;
5332 	}
5333 
5334 	mode =  policy_mgr_qdf_opmode_to_pm_con_mode(psoc, op_mode, vdev_id);
5335 
5336 	ch_freq = conn_table_entry.mhz;
5337 	status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g);
5338 	if (QDF_IS_STATUS_SUCCESS(status)) {
5339 		if ((WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) && nss_2g > 1) ||
5340 		    (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && nss_5g > 1))
5341 			chain_mask = POLICY_MGR_TWO_TWO;
5342 		else
5343 			chain_mask = POLICY_MGR_ONE_ONE;
5344 		nss = (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) ? nss_2g : nss_5g;
5345 	} else {
5346 		policy_mgr_err("Error in getting nss");
5347 	}
5348 
5349 	if (mode == PM_STA_MODE || mode == PM_P2P_CLIENT_MODE)
5350 		update_conn = false;
5351 
5352 	/* add the entry */
5353 	policy_mgr_update_conc_list(psoc, conn_index,
5354 			mode,
5355 			ch_freq,
5356 			policy_mgr_get_bw(conn_table_entry.chan_width),
5357 			conn_table_entry.mac_id,
5358 			chain_mask,
5359 			nss, vdev_id, true, update_conn,
5360 			conn_table_entry.ch_flagext);
5361 	policy_mgr_debug("Add at idx:%d vdev %d mac=%d",
5362 		conn_index, vdev_id,
5363 		conn_table_entry.mac_id);
5364 
5365 	return QDF_STATUS_SUCCESS;
5366 }
5367 
policy_mgr_decr_connection_count(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id)5368 QDF_STATUS policy_mgr_decr_connection_count(struct wlan_objmgr_psoc *psoc,
5369 					uint32_t vdev_id)
5370 {
5371 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
5372 	uint32_t conn_index = 0, next_conn_index = 0;
5373 	bool found = false;
5374 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5375 	bool panic = false;
5376 
5377 	pm_ctx = policy_mgr_get_context(psoc);
5378 	if (!pm_ctx) {
5379 		policy_mgr_err("Invalid Context");
5380 		return status;
5381 	}
5382 
5383 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
5384 	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
5385 		if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
5386 			/* debug msg */
5387 			found = true;
5388 			break;
5389 		}
5390 		conn_index++;
5391 	}
5392 	if (!found) {
5393 		policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list",
5394 			vdev_id);
5395 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
5396 		return status;
5397 	}
5398 	next_conn_index = conn_index + 1;
5399 	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(next_conn_index)) {
5400 		pm_conc_connection_list[conn_index].vdev_id =
5401 			pm_conc_connection_list[next_conn_index].vdev_id;
5402 		pm_conc_connection_list[conn_index].mode =
5403 			pm_conc_connection_list[next_conn_index].mode;
5404 		pm_conc_connection_list[conn_index].mac =
5405 			pm_conc_connection_list[next_conn_index].mac;
5406 		pm_conc_connection_list[conn_index].freq =
5407 			pm_conc_connection_list[next_conn_index].freq;
5408 		pm_conc_connection_list[conn_index].bw =
5409 			pm_conc_connection_list[next_conn_index].bw;
5410 		pm_conc_connection_list[conn_index].chain_mask =
5411 			pm_conc_connection_list[next_conn_index].chain_mask;
5412 		pm_conc_connection_list[conn_index].original_nss =
5413 			pm_conc_connection_list[next_conn_index].original_nss;
5414 		pm_conc_connection_list[conn_index].in_use =
5415 			pm_conc_connection_list[next_conn_index].in_use;
5416 		pm_conc_connection_list[conn_index].ch_flagext =
5417 			pm_conc_connection_list[next_conn_index].ch_flagext;
5418 		conn_index++;
5419 		next_conn_index++;
5420 	}
5421 
5422 	/* clean up the entry */
5423 	qdf_mem_zero(&pm_conc_connection_list[next_conn_index - 1],
5424 		sizeof(*pm_conc_connection_list));
5425 
5426 	conn_index = 0;
5427 	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
5428 		if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
5429 			panic = true;
5430 			break;
5431 		}
5432 		conn_index++;
5433 	}
5434 
5435 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
5436 	if (panic) {
5437 		policy_mgr_err("dup entry occur");
5438 		policy_mgr_debug_alert();
5439 	}
5440 	if (pm_ctx->conc_cbacks.connection_info_update)
5441 		pm_ctx->conc_cbacks.connection_info_update();
5442 
5443 	return QDF_STATUS_SUCCESS;
5444 }
5445 
policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc * psoc,uint32_t * ch_freq_list,uint8_t * vdev_id,enum policy_mgr_con_mode mode)5446 uint32_t policy_mgr_get_mode_specific_conn_info(
5447 		struct wlan_objmgr_psoc *psoc,
5448 		uint32_t *ch_freq_list, uint8_t *vdev_id,
5449 		enum policy_mgr_con_mode mode)
5450 {
5451 
5452 	uint32_t count = 0, index = 0;
5453 	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
5454 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5455 
5456 	pm_ctx = policy_mgr_get_context(psoc);
5457 	if (!pm_ctx) {
5458 		policy_mgr_err("Invalid Context");
5459 		return count;
5460 	}
5461 	if (!vdev_id) {
5462 		policy_mgr_err("Null pointer error");
5463 		return count;
5464 	}
5465 
5466 	count = policy_mgr_mode_specific_connection_count(
5467 				psoc, mode, list);
5468 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
5469 	if (count == 1) {
5470 		if (ch_freq_list)
5471 			*ch_freq_list =
5472 				pm_conc_connection_list[list[index]].freq;
5473 		*vdev_id =
5474 			pm_conc_connection_list[list[index]].vdev_id;
5475 	} else {
5476 		for (index = 0; index < count; index++) {
5477 			if (ch_freq_list)
5478 				ch_freq_list[index] =
5479 			pm_conc_connection_list[list[index]].freq;
5480 
5481 			vdev_id[index] =
5482 			pm_conc_connection_list[list[index]].vdev_id;
5483 		}
5484 	}
5485 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
5486 
5487 	return count;
5488 }
5489 
policy_mgr_get_sap_mode_info(struct wlan_objmgr_psoc * psoc,uint32_t * ch_freq_list,uint8_t * vdev_id)5490 uint32_t policy_mgr_get_sap_mode_info(struct wlan_objmgr_psoc *psoc,
5491 				      uint32_t *ch_freq_list, uint8_t *vdev_id)
5492 {
5493 	uint32_t count;
5494 
5495 	count = policy_mgr_get_mode_specific_conn_info(psoc, ch_freq_list,
5496 						       vdev_id, PM_SAP_MODE);
5497 
5498 	count += policy_mgr_get_mode_specific_conn_info(
5499 				psoc,
5500 				ch_freq_list ? &ch_freq_list[count] : NULL,
5501 				vdev_id ? &vdev_id[count] : NULL,
5502 				PM_LL_LT_SAP_MODE);
5503 	return count;
5504 }
5505 
policy_mgr_get_beaconing_mode_info(struct wlan_objmgr_psoc * psoc,uint32_t * ch_freq_list,uint8_t * vdev_id)5506 uint32_t policy_mgr_get_beaconing_mode_info(struct wlan_objmgr_psoc *psoc,
5507 					    uint32_t *ch_freq_list,
5508 					    uint8_t *vdev_id)
5509 {
5510 	uint32_t count;
5511 
5512 	count = policy_mgr_get_sap_mode_info(psoc, ch_freq_list, vdev_id);
5513 
5514 	count += policy_mgr_get_mode_specific_conn_info(
5515 				psoc,
5516 				ch_freq_list ? &ch_freq_list[count] : NULL,
5517 				vdev_id ? &vdev_id[count] : NULL,
5518 				PM_P2P_GO_MODE);
5519 	return count;
5520 }
5521 
policy_mgr_get_ml_and_non_ml_sta_count(struct wlan_objmgr_psoc * psoc,uint8_t * num_ml,uint8_t * ml_idx,uint8_t * num_non_ml,uint8_t * non_ml_idx,qdf_freq_t * freq_list,uint8_t * vdev_id_list)5522 void policy_mgr_get_ml_and_non_ml_sta_count(struct wlan_objmgr_psoc *psoc,
5523 					    uint8_t *num_ml, uint8_t *ml_idx,
5524 					    uint8_t *num_non_ml,
5525 					    uint8_t *non_ml_idx,
5526 					    qdf_freq_t *freq_list,
5527 					    uint8_t *vdev_id_list)
5528 {
5529 	uint32_t sta_num = 0;
5530 	uint8_t i;
5531 	struct wlan_objmgr_vdev *temp_vdev;
5532 
5533 	*num_ml = 0;
5534 	*num_non_ml = 0;
5535 
5536 	sta_num = policy_mgr_get_mode_specific_conn_info(psoc, freq_list,
5537 							 vdev_id_list,
5538 							 PM_STA_MODE);
5539 	if (!sta_num)
5540 		return;
5541 
5542 	for (i = 0; i < sta_num; i++) {
5543 		temp_vdev =
5544 			wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
5545 							    vdev_id_list[i],
5546 							    WLAN_POLICY_MGR_ID);
5547 		if (!temp_vdev) {
5548 			policy_mgr_err("invalid vdev for id %d",
5549 				       vdev_id_list[i]);
5550 			*num_ml = 0;
5551 			*num_non_ml = 0;
5552 			return;
5553 		}
5554 
5555 		if (wlan_vdev_mlme_is_mlo_vdev(temp_vdev)) {
5556 			if (ml_idx)
5557 				ml_idx[*num_ml] = i;
5558 			(*num_ml)++;
5559 		} else {
5560 			if (non_ml_idx)
5561 				non_ml_idx[*num_non_ml] = i;
5562 			(*num_non_ml)++;
5563 		}
5564 
5565 		wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_POLICY_MGR_ID);
5566 	}
5567 }
5568 
policy_mgr_concurrent_sta_on_different_mac(struct wlan_objmgr_psoc * psoc)5569 bool policy_mgr_concurrent_sta_on_different_mac(struct wlan_objmgr_psoc *psoc)
5570 {
5571 	uint8_t num_ml = 0, num_non_ml = 0;
5572 	uint8_t ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
5573 	uint8_t non_ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
5574 	qdf_freq_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
5575 	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
5576 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5577 	bool is_different_mac = false;
5578 	int i;
5579 
5580 	if (!policy_mgr_is_hw_dbs_capable(psoc))
5581 		return false;
5582 
5583 	pm_ctx = policy_mgr_get_context(psoc);
5584 	if (!pm_ctx) {
5585 		policy_mgr_err("Invalid Context");
5586 		return false;
5587 	}
5588 
5589 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
5590 	policy_mgr_get_ml_and_non_ml_sta_count(psoc, &num_ml, ml_idx,
5591 					       &num_non_ml, non_ml_idx,
5592 					       freq_list, vdev_id_list);
5593 	if (num_ml + num_non_ml < 2 || !num_non_ml)
5594 		goto out;
5595 
5596 	/*
5597 	 * If more than 1 Non-ML STA is present, check whether they are
5598 	 * within the same band.
5599 	 */
5600 	for (i = 1; i < num_non_ml; i++) {
5601 		if (!policy_mgr_2_freq_always_on_same_mac(psoc,
5602 							  freq_list[non_ml_idx[i]],
5603 							  freq_list[non_ml_idx[0]])) {
5604 			is_different_mac = true;
5605 			goto out;
5606 		}
5607 	}
5608 
5609 	if (num_non_ml >= 2)
5610 		goto out;
5611 
5612 	/* ML STA + Non-ML STA */
5613 	for (i = 0; i < num_ml; i++) {
5614 		if (!policy_mgr_2_freq_always_on_same_mac(psoc,
5615 							  freq_list[ml_idx[i]],
5616 							  freq_list[non_ml_idx[0]])) {
5617 			is_different_mac = true;
5618 			goto out;
5619 		}
5620 	}
5621 
5622 out:
5623 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
5624 	policy_mgr_debug("Non-ML STA count %d, ML STA count %d, sta concurrency on different mac %d",
5625 			 num_non_ml, num_ml, is_different_mac);
5626 
5627 	return is_different_mac;
5628 }
5629 
policy_mgr_max_concurrent_connections_reached(struct wlan_objmgr_psoc * psoc)5630 bool policy_mgr_max_concurrent_connections_reached(
5631 		struct wlan_objmgr_psoc *psoc)
5632 {
5633 	uint8_t i = 0, j = 0;
5634 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5635 
5636 	pm_ctx = policy_mgr_get_context(psoc);
5637 	if (pm_ctx) {
5638 		for (i = 0; i < QDF_MAX_NO_OF_MODE; i++)
5639 			j += pm_ctx->no_of_active_sessions[i];
5640 		return j >
5641 			(pm_ctx->cfg.max_conc_cxns - 1);
5642 	}
5643 
5644 	return false;
5645 }
5646 
policy_mgr_is_sub_20_mhz_enabled(struct wlan_objmgr_psoc * psoc)5647 static bool policy_mgr_is_sub_20_mhz_enabled(struct wlan_objmgr_psoc *psoc)
5648 {
5649 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5650 
5651 	pm_ctx = policy_mgr_get_context(psoc);
5652 	if (!pm_ctx) {
5653 		policy_mgr_err("Invalid Context");
5654 		return false;
5655 	}
5656 
5657 	return pm_ctx->user_cfg.sub_20_mhz_enabled;
5658 }
5659 
5660 /**
5661  * policy_mgr_allow_wapi_concurrency() - Check if WAPI concurrency is allowed
5662  * @pm_ctx: policy_mgr_psoc_priv_obj policy mgr context
5663  *
5664  * This routine is called to check vdev security mode allowed in concurrency.
5665  * At present, WAPI security mode is not allowed to run concurrency with any
5666  * other vdev if the hardware doesn't support WAPI concurrency.
5667  *
5668  * Return: true - allow
5669  */
5670 static bool
policy_mgr_allow_wapi_concurrency(struct policy_mgr_psoc_priv_obj * pm_ctx)5671 policy_mgr_allow_wapi_concurrency(struct policy_mgr_psoc_priv_obj *pm_ctx)
5672 {
5673 	struct wlan_objmgr_pdev *pdev = pm_ctx->pdev;
5674 	struct wmi_unified *wmi_handle;
5675 	struct wlan_objmgr_psoc *psoc;
5676 
5677 	if (!pdev) {
5678 		policy_mgr_debug("pdev is Null");
5679 		return false;
5680 	}
5681 
5682 	psoc = wlan_pdev_get_psoc(pdev);
5683 	if (!psoc)
5684 		return false;
5685 
5686 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
5687 	if (!wmi_handle) {
5688 		policy_mgr_debug("Invalid WMI handle");
5689 		return false;
5690 	}
5691 
5692 	if (!wmi_service_enabled(wmi_handle,
5693 				 wmi_service_wapi_concurrency_supported) &&
5694 	    mlme_is_wapi_sta_active(pdev) &&
5695 	    policy_mgr_get_connection_count(pm_ctx->psoc) > 0)
5696 		return false;
5697 
5698 	return true;
5699 }
5700 
5701 #ifdef FEATURE_FOURTH_CONNECTION
policy_mgr_is_concurrency_allowed_4_port(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint32_t ch_freq,struct policy_mgr_pcl_list pcl)5702 static bool policy_mgr_is_concurrency_allowed_4_port(
5703 					struct wlan_objmgr_psoc *psoc,
5704 					enum policy_mgr_con_mode mode,
5705 					uint32_t ch_freq,
5706 					struct policy_mgr_pcl_list pcl)
5707 {
5708 	uint32_t i;
5709 	struct policy_mgr_psoc_priv_obj *pm_ctx = NULL;
5710 	uint8_t sap_cnt, go_cnt, ll_lt_sap_vdev_id;
5711 
5712 	ll_lt_sap_vdev_id = wlan_policy_mgr_get_ll_lt_sap_vdev_id(psoc);
5713 
5714 	if (ll_lt_sap_vdev_id != WLAN_INVALID_VDEV_ID) {
5715 		policy_mgr_debug("LL_LT_SAP vdev %d present avoid 4th port concurrency",
5716 				 ll_lt_sap_vdev_id);
5717 		return false;
5718 	}
5719 	/* new STA may just have ssid, no channel until bssid assigned */
5720 	if (ch_freq == 0 && mode == PM_STA_MODE)
5721 		return true;
5722 
5723 	sap_cnt = policy_mgr_mode_specific_connection_count(psoc,
5724 							    PM_SAP_MODE, NULL);
5725 
5726 	go_cnt = policy_mgr_mode_specific_connection_count(psoc,
5727 							   PM_P2P_GO_MODE, NULL);
5728 	if (sap_cnt || go_cnt) {
5729 		pm_ctx = policy_mgr_get_context(psoc);
5730 		if (!pm_ctx) {
5731 			policy_mgr_err("context is NULL");
5732 			return false;
5733 		}
5734 
5735 		if (!policy_mgr_is_force_scc(psoc)) {
5736 			policy_mgr_err("couldn't start 4th port for bad force scc cfg");
5737 			return false;
5738 		}
5739 
5740 		if (!policy_mgr_is_dbs_enable(psoc)) {
5741 			policy_mgr_err(
5742 				"Couldn't start 4th port for bad cfg of dual mac");
5743 			return false;
5744 		}
5745 		for (i = 0; i < pcl.pcl_len; i++)
5746 			if (ch_freq == pcl.pcl_list[i])
5747 				return true;
5748 
5749 		policy_mgr_err("4th port failed on ch freq %d with mode %d",
5750 			       ch_freq, mode);
5751 
5752 		return false;
5753 	}
5754 
5755 	return true;
5756 }
5757 #else
policy_mgr_is_concurrency_allowed_4_port(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint32_t ch_freq,struct policy_mgr_pcl_list pcl)5758 static inline bool policy_mgr_is_concurrency_allowed_4_port(
5759 				struct wlan_objmgr_psoc *psoc,
5760 				enum policy_mgr_con_mode mode,
5761 				uint32_t ch_freq,
5762 				struct policy_mgr_pcl_list pcl)
5763 {return false; }
5764 #endif
5765 
5766 bool
policy_mgr_allow_multiple_sta_connections(struct wlan_objmgr_psoc * psoc)5767 policy_mgr_allow_multiple_sta_connections(struct wlan_objmgr_psoc *psoc)
5768 {
5769 	struct wmi_unified *wmi_handle;
5770 
5771 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
5772 	if (!wmi_handle) {
5773 		policy_mgr_debug("Invalid WMI handle");
5774 		return false;
5775 	}
5776 	if (!wmi_service_enabled(wmi_handle,
5777 				 wmi_service_sta_plus_sta_support)) {
5778 		policy_mgr_rl_debug("STA+STA is not supported");
5779 		return false;
5780 	}
5781 
5782 	return true;
5783 }
5784 
5785 #if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX)
policy_mgr_is_6ghz_conc_mode_supported(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode)5786 bool policy_mgr_is_6ghz_conc_mode_supported(
5787 	struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode)
5788 {
5789 	if (mode == PM_STA_MODE || mode == PM_SAP_MODE ||
5790 	    mode == PM_P2P_CLIENT_MODE || mode == PM_P2P_GO_MODE)
5791 		return true;
5792 	else
5793 		return false;
5794 }
5795 #endif
5796 
5797 /**
5798  * policy_mgr_is_6g_channel_allowed() - Check new 6Ghz connection
5799  * allowed or not
5800  * @psoc: Pointer to soc
5801  * @mode: new connection mode
5802  * @ch_freq: channel freq
5803  *
5804  * 1. Only STA/SAP are allowed on 6Ghz.
5805  * 2. If there is DFS beacon entity existing on 5G band, 5G+6G MCC is not
5806  * allowed.
5807  *
5808  *  Return: true if supports else false.
5809  */
policy_mgr_is_6g_channel_allowed(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint32_t ch_freq)5810 static bool policy_mgr_is_6g_channel_allowed(
5811 	struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode,
5812 	uint32_t ch_freq)
5813 {
5814 	uint32_t conn_index = 0;
5815 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5816 	struct policy_mgr_conc_connection_info *conn;
5817 	bool is_dfs;
5818 
5819 	pm_ctx = policy_mgr_get_context(psoc);
5820 	if (!pm_ctx) {
5821 		policy_mgr_err("Invalid Context");
5822 		return false;
5823 	}
5824 	if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq)) {
5825 		policy_mgr_rl_debug("Not a 6Ghz channel Freq");
5826 		return true;
5827 	}
5828 	/* Only STA/SAP is supported on 6Ghz currently */
5829 	if (!policy_mgr_is_6ghz_conc_mode_supported(psoc, mode)) {
5830 		policy_mgr_rl_debug("mode %d for 6ghz not supported", mode);
5831 		return false;
5832 	}
5833 
5834 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
5835 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
5836 				conn_index++) {
5837 		conn = &pm_conc_connection_list[conn_index];
5838 		if (!conn->in_use)
5839 			continue;
5840 		is_dfs = (conn->ch_flagext &
5841 			(IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) &&
5842 			WLAN_REG_IS_5GHZ_CH_FREQ(conn->freq);
5843 		if (policy_mgr_is_beaconing_mode(conn->mode) &&
5844 		    is_dfs && (ch_freq != conn->freq &&
5845 			       !policy_mgr_are_sbs_chan(psoc, ch_freq,
5846 							conn->freq))) {
5847 			policy_mgr_rl_debug("don't allow MCC if SAP/GO on DFS channel");
5848 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
5849 			return false;
5850 		}
5851 	}
5852 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
5853 
5854 	return true;
5855 }
5856 
5857 #ifdef WLAN_FEATURE_11BE_MLO
policy_mgr_is_acs_2ghz_only_sap(struct wlan_objmgr_psoc * psoc,uint8_t sap_vdev_id)5858 static bool policy_mgr_is_acs_2ghz_only_sap(struct wlan_objmgr_psoc *psoc,
5859 					    uint8_t sap_vdev_id)
5860 {
5861 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5862 	uint32_t acs_band = QCA_ACS_MODE_IEEE80211ANY;
5863 
5864 	pm_ctx = policy_mgr_get_context(psoc);
5865 	if (!pm_ctx) {
5866 		policy_mgr_err("Invalid Context");
5867 		return false;
5868 	}
5869 
5870 	if (pm_ctx->hdd_cbacks.wlan_get_sap_acs_band)
5871 		pm_ctx->hdd_cbacks.wlan_get_sap_acs_band(psoc,
5872 							 sap_vdev_id,
5873 							 &acs_band);
5874 
5875 	if (acs_band == QCA_ACS_MODE_IEEE80211B ||
5876 	    acs_band == QCA_ACS_MODE_IEEE80211G)
5877 		return true;
5878 
5879 	return false;
5880 }
5881 
policy_mgr_vdev_is_force_inactive(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)5882 bool policy_mgr_vdev_is_force_inactive(struct wlan_objmgr_psoc *psoc,
5883 				       uint8_t vdev_id)
5884 {
5885 	bool force_inactive = false;
5886 	uint8_t conn_index;
5887 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5888 
5889 	pm_ctx = policy_mgr_get_context(psoc);
5890 	if (!pm_ctx) {
5891 		policy_mgr_err("Invalid Context");
5892 		return false;
5893 	}
5894 
5895 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
5896 	/* Get disabled link info as well and keep it at last */
5897 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_DISABLE_LINK;
5898 	     conn_index++) {
5899 		if (pm_disabled_ml_links[conn_index].in_use &&
5900 		    pm_disabled_ml_links[conn_index].mode == PM_STA_MODE &&
5901 		    pm_disabled_ml_links[conn_index].vdev_id == vdev_id) {
5902 			force_inactive = true;
5903 			break;
5904 		}
5905 	}
5906 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
5907 
5908 	return force_inactive;
5909 }
5910 
5911 /* MCC avoidance priority value for different legacy connection type.
5912  * Internal macro, not expected used other code.
5913  * Bigger value have higher priority.
5914  */
5915 #define PRIORITY_STA	3
5916 #define PRIORITY_SAP	2
5917 #define PRIORITY_P2P	1
5918 #define PRIORITY_OTHER	0
5919 
5920 uint8_t
policy_mgr_get_legacy_conn_info(struct wlan_objmgr_psoc * psoc,uint8_t * vdev_lst,qdf_freq_t * freq_lst,enum policy_mgr_con_mode * mode_lst,uint8_t lst_sz)5921 policy_mgr_get_legacy_conn_info(struct wlan_objmgr_psoc *psoc,
5922 				uint8_t *vdev_lst,
5923 				qdf_freq_t *freq_lst,
5924 				enum policy_mgr_con_mode *mode_lst,
5925 				uint8_t lst_sz)
5926 {
5927 	struct policy_mgr_psoc_priv_obj *pm_ctx;
5928 	uint8_t conn_index, j = 0, i, k, n;
5929 	struct wlan_objmgr_vdev *vdev;
5930 	uint8_t vdev_id;
5931 	uint8_t has_priority[MAX_NUMBER_OF_CONC_CONNECTIONS];
5932 
5933 	pm_ctx = policy_mgr_get_context(psoc);
5934 	if (!pm_ctx) {
5935 		policy_mgr_err("Invalid Context");
5936 		return 0;
5937 	}
5938 
5939 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
5940 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
5941 	     conn_index++) {
5942 		if (j >= lst_sz)
5943 			break;
5944 		if (!pm_conc_connection_list[conn_index].in_use)
5945 			continue;
5946 		vdev_id = pm_conc_connection_list[conn_index].vdev_id;
5947 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
5948 				pm_ctx->psoc, vdev_id, WLAN_POLICY_MGR_ID);
5949 		if (!vdev) {
5950 			policy_mgr_err("invalid vdev for id %d", vdev_id);
5951 			continue;
5952 		}
5953 
5954 		if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
5955 		    pm_conc_connection_list[conn_index].mode ==
5956 							PM_STA_MODE) {
5957 			wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
5958 			continue;
5959 		}
5960 		if (pm_conc_connection_list[conn_index].mode !=
5961 							PM_STA_MODE &&
5962 		    pm_conc_connection_list[conn_index].mode !=
5963 							PM_SAP_MODE &&
5964 		    pm_conc_connection_list[conn_index].mode !=
5965 							PM_P2P_CLIENT_MODE &&
5966 		    pm_conc_connection_list[conn_index].mode !=
5967 							PM_P2P_GO_MODE) {
5968 			wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
5969 			continue;
5970 		}
5971 
5972 		/* Set mcc avoidance priority value. The bigger value
5973 		 * have higher priority to avoid MCC. In 3 Port concurrency
5974 		 * case, usually we can only meet the higher priority intf's
5975 		 * MCC avoidance by force inactive link.
5976 		 */
5977 		if (pm_conc_connection_list[conn_index].mode == PM_STA_MODE)
5978 			has_priority[j] = PRIORITY_STA;
5979 		else if (pm_conc_connection_list[conn_index].mode ==
5980 							PM_SAP_MODE &&
5981 			 policy_mgr_is_acs_2ghz_only_sap(psoc, vdev_id))
5982 			has_priority[j] = PRIORITY_SAP;
5983 		else if ((pm_conc_connection_list[conn_index].mode ==
5984 							PM_P2P_CLIENT_MODE ||
5985 			  pm_conc_connection_list[conn_index].mode ==
5986 							PM_P2P_GO_MODE) &&
5987 			 policy_mgr_is_vdev_high_tput_or_low_latency(
5988 							psoc, vdev_id))
5989 			has_priority[j] = PRIORITY_P2P;
5990 		else
5991 			has_priority[j] = PRIORITY_OTHER;
5992 
5993 		vdev_lst[j] = vdev_id;
5994 		freq_lst[j] = pm_conc_connection_list[conn_index].freq;
5995 		mode_lst[j] = pm_conc_connection_list[conn_index].mode;
5996 		policy_mgr_debug("vdev %d freq %d mode %s pri %d",
5997 				 vdev_id, freq_lst[j],
5998 				 device_mode_to_string(mode_lst[j]),
5999 				 has_priority[j]);
6000 		j++;
6001 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
6002 	}
6003 	/* sort the list based on priority */
6004 	for (i = 0; i < j; i++) {
6005 		uint8_t tmp_vdev_lst;
6006 		qdf_freq_t tmp_freq_lst;
6007 		enum policy_mgr_con_mode tmp_mode_lst;
6008 
6009 		n = i;
6010 		for (k = i + 1; k < j; k++) {
6011 			if (has_priority[n] < has_priority[k])
6012 				n = k;
6013 			else if ((has_priority[n] == has_priority[k]) &&
6014 				 (vdev_lst[n] > vdev_lst[k]))
6015 				n = k;
6016 		}
6017 		if (n == i)
6018 			continue;
6019 		tmp_vdev_lst = vdev_lst[i];
6020 		tmp_freq_lst = freq_lst[i];
6021 		tmp_mode_lst = mode_lst[i];
6022 
6023 		vdev_lst[i] = vdev_lst[n];
6024 		freq_lst[i] = freq_lst[n];
6025 		mode_lst[i] = mode_lst[n];
6026 
6027 		vdev_lst[n] = tmp_vdev_lst;
6028 		freq_lst[n] = tmp_freq_lst;
6029 		mode_lst[n] = tmp_mode_lst;
6030 	}
6031 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
6032 
6033 	return j;
6034 }
6035 
6036 static void
policy_mgr_fill_ml_active_link_vdev_bitmap(struct mlo_link_set_active_req * req,uint8_t * mlo_vdev_lst,uint32_t num_mlo_vdev)6037 policy_mgr_fill_ml_active_link_vdev_bitmap(struct mlo_link_set_active_req *req,
6038 					   uint8_t *mlo_vdev_lst,
6039 					   uint32_t num_mlo_vdev)
6040 {
6041 	uint32_t entry_idx, entry_offset, vdev_idx;
6042 	uint8_t vdev_id;
6043 
6044 	for (vdev_idx = 0; vdev_idx < num_mlo_vdev; vdev_idx++) {
6045 		vdev_id = mlo_vdev_lst[vdev_idx];
6046 		entry_idx = vdev_id / 32;
6047 		entry_offset = vdev_id % 32;
6048 		if (entry_idx >= MLO_LINK_NUM_SZ) {
6049 			policy_mgr_err("Invalid entry_idx %d num_mlo_vdev %d vdev %d",
6050 				       entry_idx, num_mlo_vdev, vdev_id);
6051 			continue;
6052 		}
6053 		req->param.vdev_bitmap[entry_idx] |= (1 << entry_offset);
6054 		/* update entry number if entry index changed */
6055 		if (req->param.num_vdev_bitmap < entry_idx + 1)
6056 			req->param.num_vdev_bitmap = entry_idx + 1;
6057 	}
6058 
6059 	policy_mgr_debug("num_vdev_bitmap %d vdev_bitmap[0] = 0x%x, vdev_bitmap[1] = 0x%x",
6060 			 req->param.num_vdev_bitmap, req->param.vdev_bitmap[0],
6061 			 req->param.vdev_bitmap[1]);
6062 }
6063 
6064 static void
policy_mgr_fill_ml_inactive_link_vdev_bitmap(struct mlo_link_set_active_req * req,uint8_t * mlo_inactive_vdev_lst,uint32_t num_mlo_inactive_vdev)6065 policy_mgr_fill_ml_inactive_link_vdev_bitmap(
6066 				struct mlo_link_set_active_req *req,
6067 				uint8_t *mlo_inactive_vdev_lst,
6068 				uint32_t num_mlo_inactive_vdev)
6069 {
6070 	uint32_t entry_idx, entry_offset, vdev_idx;
6071 	uint8_t vdev_id;
6072 
6073 	for (vdev_idx = 0; vdev_idx < num_mlo_inactive_vdev; vdev_idx++) {
6074 		vdev_id = mlo_inactive_vdev_lst[vdev_idx];
6075 		entry_idx = vdev_id / 32;
6076 		entry_offset = vdev_id % 32;
6077 		if (entry_idx >= MLO_LINK_NUM_SZ) {
6078 			policy_mgr_err("Invalid entry_idx %d num_mlo_vdev %d vdev %d",
6079 				       entry_idx, num_mlo_inactive_vdev,
6080 				       vdev_id);
6081 			continue;
6082 		}
6083 		req->param.inactive_vdev_bitmap[entry_idx] |=
6084 							(1 << entry_offset);
6085 		/* update entry number if entry index changed */
6086 		if (req->param.num_inactive_vdev_bitmap < entry_idx + 1)
6087 			req->param.num_inactive_vdev_bitmap = entry_idx + 1;
6088 	}
6089 
6090 	policy_mgr_debug("num_vdev_bitmap %d inactive_vdev_bitmap[0] = 0x%x, inactive_vdev_bitmap[1] = 0x%x",
6091 			 req->param.num_inactive_vdev_bitmap,
6092 			 req->param.inactive_vdev_bitmap[0],
6093 			 req->param.inactive_vdev_bitmap[1]);
6094 }
6095 
6096 /*
6097  * policy_mgr_handle_ml_sta_link_state_allowed() - Check ml sta connection to
6098  * allow link state change.
6099  * @psoc: psoc object
6100  * @reason: set link state reason
6101  *
6102  * If ml sta is not "connected" state, no need to do link state handling.
6103  * After disconnected, target will clear the force active/inactive state
6104  * and host will remove the connection entry finally.
6105  * After roaming done, active/inactive will be re-calculated.
6106  *
6107  * Return: QDF_STATUS_SUCCESS if link state is allowed to change
6108  */
6109 static QDF_STATUS
policy_mgr_handle_ml_sta_link_state_allowed(struct wlan_objmgr_psoc * psoc,enum mlo_link_force_reason reason)6110 policy_mgr_handle_ml_sta_link_state_allowed(struct wlan_objmgr_psoc *psoc,
6111 					    enum mlo_link_force_reason reason)
6112 {
6113 	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0, num_non_ml = 0;
6114 	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
6115 	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
6116 	struct policy_mgr_psoc_priv_obj *pm_ctx;
6117 	struct wlan_objmgr_vdev *vdev;
6118 	bool ml_sta_is_not_connected = false;
6119 	bool ml_sta_is_link_removal = false;
6120 	uint8_t i;
6121 	QDF_STATUS status = QDF_STATUS_SUCCESS;
6122 
6123 	pm_ctx = policy_mgr_get_context(psoc);
6124 	if (!pm_ctx) {
6125 		policy_mgr_err("Invalid Context");
6126 		return QDF_STATUS_E_INVAL;
6127 	}
6128 
6129 	policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta,
6130 				   ml_sta_vdev_lst, ml_freq_lst, &num_non_ml,
6131 				   NULL, NULL);
6132 	if (!num_ml_sta || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS) {
6133 		policy_mgr_debug("ml sta num is %d", num_ml_sta);
6134 		return QDF_STATUS_E_INVAL;
6135 	}
6136 
6137 	for (i = 0; i < num_ml_sta; i++) {
6138 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(pm_ctx->psoc,
6139 							    ml_sta_vdev_lst[i],
6140 							    WLAN_POLICY_MGR_ID);
6141 		if (!vdev) {
6142 			policy_mgr_err("invalid vdev for id %d",
6143 				       ml_sta_vdev_lst[i]);
6144 			continue;
6145 		}
6146 		if (!wlan_cm_is_vdev_connected(vdev)) {
6147 			policy_mgr_debug("ml sta vdev %d is not connected state",
6148 					 ml_sta_vdev_lst[i]);
6149 			ml_sta_is_not_connected = true;
6150 		}
6151 		if (wlan_get_vdev_link_removed_flag_by_vdev_id(
6152 						psoc, ml_sta_vdev_lst[i])) {
6153 			policy_mgr_debug("ml sta vdev %d link removed",
6154 					 ml_sta_vdev_lst[i]);
6155 			ml_sta_is_link_removal = true;
6156 		}
6157 
6158 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
6159 	}
6160 
6161 	if (ml_sta_is_not_connected) {
6162 		status = QDF_STATUS_E_FAILURE;
6163 	} else if (reason != MLO_LINK_FORCE_REASON_LINK_REMOVAL) {
6164 		if (ml_sta_is_link_removal)
6165 			status = QDF_STATUS_E_FAILURE;
6166 	}
6167 	policy_mgr_debug("set link reason %d status %d rm %d", reason, status,
6168 			 ml_sta_is_link_removal);
6169 
6170 	return status;
6171 }
6172 
6173 /*
6174  * policy_mgr_validate_set_mlo_link_cb() - Callback to check whether
6175  * it is allowed to set mlo sta link state.
6176  * @psoc: psoc object
6177  * @param: set mlo link parameter
6178  *
6179  * This api will be used as callback to be called by mlo_link_set_active
6180  * in serialization context.
6181  *
6182  * Return: QDF_STATUS_SUCCESS if set mlo link is allowed
6183  */
6184 static QDF_STATUS
policy_mgr_validate_set_mlo_link_cb(struct wlan_objmgr_psoc * psoc,struct mlo_link_set_active_param * param)6185 policy_mgr_validate_set_mlo_link_cb(struct wlan_objmgr_psoc *psoc,
6186 				    struct mlo_link_set_active_param *param)
6187 {
6188 	return policy_mgr_handle_ml_sta_link_state_allowed(psoc,
6189 							   param->reason);
6190 }
6191 
6192 uint32_t
policy_mgr_get_active_vdev_bitmap(struct wlan_objmgr_psoc * psoc)6193 policy_mgr_get_active_vdev_bitmap(struct wlan_objmgr_psoc *psoc)
6194 {
6195 	struct policy_mgr_psoc_priv_obj *pm_ctx;
6196 
6197 	pm_ctx = policy_mgr_get_context(psoc);
6198 	if (!pm_ctx) {
6199 		policy_mgr_err("Invalid Context");
6200 		return QDF_STATUS_E_INVAL;
6201 	}
6202 
6203 	policy_mgr_debug("active link bitmap value: %d",
6204 			 pm_ctx->active_vdev_bitmap);
6205 
6206 	return pm_ctx->active_vdev_bitmap;
6207 }
6208 
6209 /**
6210  * policy_mgr_mlo_sta_set_link_by_linkid() - wrapper API to call set link
6211  * by link id bitmap API
6212  * @psoc: psoc object
6213  * @vdev: vdev object
6214  * @reason: Reason for which link is forced
6215  * @mode: Force reason
6216  * @link_num: valid for MLO_LINK_FORCE_MODE_ACTIVE_NUM and
6217  *  MLO_LINK_FORCE_MODE_INACTIVE_NUM.
6218  * @num_mlo_vdev: number of mlo vdev in array mlo_vdev_lst
6219  * @mlo_vdev_lst: MLO STA vdev list
6220  * @num_mlo_inactive_vdev: number of mlo vdev in array mlo_inactive_vdev_lst
6221  * @mlo_inactive_vdev_lst: MLO STA vdev list
6222  *
6223  * This is internal wrapper of policy_mgr_mlo_sta_set_nlink to convert
6224  * vdev based set link to link id based API for being compatible with old code.
6225  * New code to use policy_mgr_mlo_sta_set_nlink directly as much as possible.
6226  *
6227  * Return: QDF_STATUS
6228  */
6229 static QDF_STATUS
policy_mgr_mlo_sta_set_link_by_linkid(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,enum mlo_link_force_reason reason,enum mlo_link_force_mode mode,uint8_t link_num,uint8_t num_mlo_vdev,uint8_t * mlo_vdev_lst,uint8_t num_mlo_inactive_vdev,uint8_t * mlo_inactive_vdev_lst)6230 policy_mgr_mlo_sta_set_link_by_linkid(struct wlan_objmgr_psoc *psoc,
6231 				      struct wlan_objmgr_vdev *vdev,
6232 				      enum mlo_link_force_reason reason,
6233 				      enum mlo_link_force_mode mode,
6234 				      uint8_t link_num,
6235 				      uint8_t num_mlo_vdev,
6236 				      uint8_t *mlo_vdev_lst,
6237 				      uint8_t num_mlo_inactive_vdev,
6238 				      uint8_t *mlo_inactive_vdev_lst)
6239 {
6240 	uint32_t link_bitmap = 0;
6241 	uint32_t link_bitmap2 = 0;
6242 	uint32_t assoc_bitmap = 0;
6243 	uint32_t vdev_bitmap[MLO_VDEV_BITMAP_SZ];
6244 	uint32_t vdev_bitmap2[MLO_VDEV_BITMAP_SZ];
6245 	uint8_t i, idx;
6246 	uint32_t link_control_flags = 0;
6247 	uint8_t vdev_per_bitmap = MLO_MAX_VDEV_COUNT_PER_BIMTAP_ELEMENT;
6248 
6249 	qdf_mem_zero(vdev_bitmap, sizeof(vdev_bitmap));
6250 	qdf_mem_zero(vdev_bitmap2, sizeof(vdev_bitmap2));
6251 
6252 	for (i = 0; i < num_mlo_vdev; i++) {
6253 		idx = mlo_vdev_lst[i] / vdev_per_bitmap;
6254 		if (idx >= MLO_VDEV_BITMAP_SZ)
6255 			return QDF_STATUS_E_INVAL;
6256 		vdev_bitmap[idx] |= 1 << (mlo_vdev_lst[i] % vdev_per_bitmap);
6257 	}
6258 
6259 	for (i = 0; i < num_mlo_inactive_vdev; i++) {
6260 		idx = mlo_inactive_vdev_lst[i] / vdev_per_bitmap;
6261 		if (idx >= MLO_VDEV_BITMAP_SZ)
6262 			return QDF_STATUS_E_INVAL;
6263 		vdev_bitmap2[idx] |=
6264 			1 << (mlo_inactive_vdev_lst[i] % vdev_per_bitmap);
6265 	}
6266 
6267 	ml_nlink_convert_vdev_bitmap_to_linkid_bitmap(
6268 		psoc, vdev, MLO_VDEV_BITMAP_SZ, vdev_bitmap,
6269 		&link_bitmap, &assoc_bitmap);
6270 
6271 	ml_nlink_convert_vdev_bitmap_to_linkid_bitmap(
6272 		psoc, vdev, MLO_VDEV_BITMAP_SZ, vdev_bitmap2,
6273 		&link_bitmap2, &assoc_bitmap);
6274 
6275 	switch (mode) {
6276 	case MLO_LINK_FORCE_MODE_ACTIVE:
6277 		link_control_flags = link_ctrl_f_overwrite_active_bitmap;
6278 		break;
6279 	case MLO_LINK_FORCE_MODE_INACTIVE:
6280 		if (reason != MLO_LINK_FORCE_REASON_LINK_REMOVAL)
6281 			link_control_flags =
6282 				link_ctrl_f_overwrite_inactive_bitmap;
6283 		break;
6284 	case MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE:
6285 		if (reason != MLO_LINK_FORCE_REASON_LINK_REMOVAL)
6286 			link_control_flags =
6287 				link_ctrl_f_overwrite_active_bitmap |
6288 				link_ctrl_f_overwrite_inactive_bitmap;
6289 		break;
6290 	case MLO_LINK_FORCE_MODE_ACTIVE_NUM:
6291 		link_control_flags = link_ctrl_f_dynamic_force_link_num;
6292 		break;
6293 	case MLO_LINK_FORCE_MODE_INACTIVE_NUM:
6294 		link_control_flags = link_ctrl_f_dynamic_force_link_num;
6295 		break;
6296 	case MLO_LINK_FORCE_MODE_NO_FORCE:
6297 		link_control_flags = 0;
6298 		break;
6299 	default:
6300 		policy_mgr_err("Invalid force mode: %d", mode);
6301 		return QDF_STATUS_E_INVAL;
6302 	}
6303 
6304 	return policy_mgr_mlo_sta_set_nlink(psoc, wlan_vdev_get_id(vdev),
6305 					    reason, mode,
6306 					    link_num, link_bitmap,
6307 					    link_bitmap2, link_control_flags);
6308 }
6309 
6310 /**
6311  * policy_mgr_mlo_sta_set_link_ext() - Set links for MLO STA
6312  * @psoc: psoc object
6313  * @reason: Reason for which link is forced
6314  * @mode: Force reason
6315  * @num_mlo_vdev: number of mlo vdev
6316  * @mlo_vdev_lst: MLO STA vdev list
6317  * @num_mlo_inactive_vdev: number of mlo vdev
6318  * @mlo_inactive_vdev_lst: MLO STA vdev list
6319  *
6320  * Interface manager Set links for MLO STA. And it supports to
6321  * add inactive vdev list.
6322  *
6323  * Return: QDF_STATUS
6324  */
6325 static QDF_STATUS
policy_mgr_mlo_sta_set_link_ext(struct wlan_objmgr_psoc * psoc,enum mlo_link_force_reason reason,enum mlo_link_force_mode mode,uint8_t num_mlo_vdev,uint8_t * mlo_vdev_lst,uint8_t num_mlo_inactive_vdev,uint8_t * mlo_inactive_vdev_lst)6326 policy_mgr_mlo_sta_set_link_ext(struct wlan_objmgr_psoc *psoc,
6327 				enum mlo_link_force_reason reason,
6328 				enum mlo_link_force_mode mode,
6329 				uint8_t num_mlo_vdev, uint8_t *mlo_vdev_lst,
6330 				uint8_t num_mlo_inactive_vdev,
6331 				uint8_t *mlo_inactive_vdev_lst)
6332 {
6333 	struct mlo_link_set_active_req *req;
6334 	QDF_STATUS status;
6335 	struct policy_mgr_psoc_priv_obj *pm_ctx;
6336 	struct wlan_objmgr_vdev *vdev;
6337 
6338 	if (!num_mlo_vdev) {
6339 		policy_mgr_err("invalid 0 num_mlo_vdev");
6340 		return QDF_STATUS_E_INVAL;
6341 	}
6342 
6343 	pm_ctx = policy_mgr_get_context(psoc);
6344 	if (!pm_ctx) {
6345 		policy_mgr_err("Invalid Context");
6346 		return QDF_STATUS_E_INVAL;
6347 	}
6348 
6349 	req = qdf_mem_malloc(sizeof(*req));
6350 	if (!req)
6351 		return QDF_STATUS_E_NOMEM;
6352 
6353 	/*
6354 	 * Use one of the ML vdev as, if called from disconnect the caller vdev
6355 	 * may get deleted, and thus flush serialization command.
6356 	 */
6357 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, mlo_vdev_lst[0],
6358 						    WLAN_POLICY_MGR_ID);
6359 	if (!vdev) {
6360 		policy_mgr_err("vdev %d: invalid vdev", mlo_vdev_lst[0]);
6361 		qdf_mem_free(req);
6362 		return QDF_STATUS_E_FAILURE;
6363 	}
6364 
6365 	policy_mgr_debug("vdev %d: mode %d num_mlo_vdev %d reason %d",
6366 			 wlan_vdev_get_id(vdev), mode, num_mlo_vdev, reason);
6367 
6368 	req->ctx.vdev = vdev;
6369 	req->param.reason = reason;
6370 	req->param.force_mode = mode;
6371 	req->ctx.set_mlo_link_cb = policy_mgr_handle_link_enable_disable_resp;
6372 	req->ctx.validate_set_mlo_link_cb =
6373 		policy_mgr_validate_set_mlo_link_cb;
6374 	req->ctx.cb_arg = req;
6375 
6376 	/* set MLO vdev bit mask for all case */
6377 	policy_mgr_fill_ml_active_link_vdev_bitmap(req, mlo_vdev_lst,
6378 						   num_mlo_vdev);
6379 
6380 	pm_ctx->active_vdev_bitmap = req->param.vdev_bitmap[0];
6381 	pm_ctx->inactive_vdev_bitmap = req->param.vdev_bitmap[1];
6382 
6383 	if (mode == MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE)
6384 		policy_mgr_fill_ml_inactive_link_vdev_bitmap(
6385 			req, mlo_inactive_vdev_lst, num_mlo_inactive_vdev);
6386 
6387 	/*
6388 	 * Fill number of links for MLO_LINK_FORCE_MODE_ACTIVE_NUM or
6389 	 * MLO_LINK_FORCE_MODE_INACTIVE_NUM mode.
6390 	 */
6391 	if (mode == MLO_LINK_FORCE_MODE_ACTIVE_NUM ||
6392 	    mode == MLO_LINK_FORCE_MODE_INACTIVE_NUM) {
6393 		req->param.num_link_entry = 1;
6394 		req->param.link_num[0].num_of_link = num_mlo_vdev - 1;
6395 	}
6396 
6397 	if (ml_is_nlink_service_supported(psoc)) {
6398 		status =
6399 		policy_mgr_mlo_sta_set_link_by_linkid(psoc, vdev, reason,
6400 						      mode,
6401 						      req->param.link_num[0].
6402 						      num_of_link,
6403 						      num_mlo_vdev,
6404 						      mlo_vdev_lst,
6405 						      num_mlo_inactive_vdev,
6406 						      mlo_inactive_vdev_lst);
6407 		qdf_mem_free(req);
6408 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
6409 
6410 		if (status != QDF_STATUS_E_PENDING) {
6411 			policy_mgr_err("set_link_by_linkid status %d", status);
6412 			return status;
6413 		}
6414 		return QDF_STATUS_SUCCESS;
6415 	}
6416 
6417 	policy_mgr_set_link_in_progress(pm_ctx, true);
6418 
6419 	status = mlo_ser_set_link_req(req);
6420 	if (QDF_IS_STATUS_ERROR(status)) {
6421 		policy_mgr_err("vdev %d: Failed to set link mode %d num_mlo_vdev %d reason %d",
6422 			       wlan_vdev_get_id(vdev), mode, num_mlo_vdev,
6423 			       reason);
6424 		qdf_mem_free(req);
6425 		policy_mgr_set_link_in_progress(pm_ctx, false);
6426 	}
6427 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
6428 	return status;
6429 }
6430 
6431 QDF_STATUS
policy_mgr_mlo_sta_set_link(struct wlan_objmgr_psoc * psoc,enum mlo_link_force_reason reason,enum mlo_link_force_mode mode,uint8_t num_mlo_vdev,uint8_t * mlo_vdev_lst)6432 policy_mgr_mlo_sta_set_link(struct wlan_objmgr_psoc *psoc,
6433 			    enum mlo_link_force_reason reason,
6434 			    enum mlo_link_force_mode mode,
6435 			    uint8_t num_mlo_vdev, uint8_t *mlo_vdev_lst)
6436 {
6437 	return policy_mgr_mlo_sta_set_link_ext(psoc, reason, mode, num_mlo_vdev,
6438 					       mlo_vdev_lst, 0, NULL);
6439 }
6440 
6441 QDF_STATUS
policy_mgr_mlo_sta_set_nlink(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,enum mlo_link_force_reason reason,enum mlo_link_force_mode mode,uint8_t link_num,uint16_t link_bitmap,uint16_t link_bitmap2,uint32_t link_control_flags)6442 policy_mgr_mlo_sta_set_nlink(struct wlan_objmgr_psoc *psoc,
6443 			     uint8_t vdev_id,
6444 			     enum mlo_link_force_reason reason,
6445 			     enum mlo_link_force_mode mode,
6446 			     uint8_t link_num,
6447 			     uint16_t link_bitmap,
6448 			     uint16_t link_bitmap2,
6449 			     uint32_t link_control_flags)
6450 {
6451 	struct mlo_link_set_active_req *req;
6452 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
6453 	struct policy_mgr_psoc_priv_obj *pm_ctx;
6454 	struct wlan_objmgr_vdev *vdev;
6455 
6456 	pm_ctx = policy_mgr_get_context(psoc);
6457 	if (!pm_ctx) {
6458 		policy_mgr_err("Invalid Context");
6459 		return QDF_STATUS_E_INVAL;
6460 	}
6461 
6462 	req = qdf_mem_malloc(sizeof(*req));
6463 	if (!req)
6464 		return QDF_STATUS_E_NOMEM;
6465 
6466 	vdev =
6467 	wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
6468 					     vdev_id,
6469 					     WLAN_POLICY_MGR_ID);
6470 	if (!vdev) {
6471 		policy_mgr_err("invalid vdev for id %d",
6472 			       vdev_id);
6473 		qdf_mem_free(req);
6474 		return QDF_STATUS_E_INVAL;
6475 	}
6476 
6477 	policy_mgr_set_link_in_progress(pm_ctx, true);
6478 
6479 	policy_mgr_debug("vdev %d: mode %d %s reason %d bitmap 0x%x 0x%x ctrl 0x%x",
6480 			 wlan_vdev_get_id(vdev), mode,
6481 			 force_mode_to_string(mode), reason,
6482 			 link_bitmap, link_bitmap2,
6483 			 link_control_flags);
6484 
6485 	req->ctx.vdev = vdev;
6486 	req->param.reason = reason;
6487 	req->param.force_mode = mode;
6488 	req->param.use_ieee_link_id = true;
6489 	req->param.force_cmd.ieee_link_id_bitmap = link_bitmap;
6490 	req->param.force_cmd.ieee_link_id_bitmap2 = link_bitmap2;
6491 	req->param.force_cmd.link_num = link_num;
6492 	if (link_control_flags & link_ctrl_f_overwrite_active_bitmap)
6493 		req->param.control_flags.overwrite_force_active_bitmap = true;
6494 	if (link_control_flags & link_ctrl_f_overwrite_inactive_bitmap)
6495 		req->param.control_flags.overwrite_force_inactive_bitmap =
6496 									true;
6497 	if (link_control_flags & link_ctrl_f_dynamic_force_link_num)
6498 		req->param.control_flags.dynamic_force_link_num = true;
6499 	if (link_control_flags & link_ctrl_f_post_re_evaluate)
6500 		req->param.control_flags.post_re_evaluate = true;
6501 
6502 	status =
6503 	wlan_vdev_get_bss_peer_mld_mac(vdev,
6504 				       &req->param.force_cmd.ap_mld_mac_addr);
6505 	if (QDF_IS_STATUS_ERROR(status)) {
6506 		policy_mgr_err("fail to get ap mld addr for vdev %d",
6507 			       wlan_vdev_get_id(vdev));
6508 		goto end;
6509 	}
6510 	if (qdf_is_macaddr_zero(&req->param.force_cmd.ap_mld_mac_addr)) {
6511 		policy_mgr_err("get ap zero mld addr for vdev %d",
6512 			       wlan_vdev_get_id(vdev));
6513 		goto end;
6514 	}
6515 
6516 	req->ctx.set_mlo_link_cb = policy_mgr_handle_link_enable_disable_resp;
6517 	req->ctx.validate_set_mlo_link_cb =
6518 		policy_mgr_validate_set_mlo_link_cb;
6519 	req->ctx.cb_arg = req;
6520 	status = mlo_ser_set_link_req(req);
6521 end:
6522 	if (QDF_IS_STATUS_ERROR(status)) {
6523 		policy_mgr_err("vdev %d: Failed to set link mode %d num_mlo_vdev %d reason %d",
6524 			       wlan_vdev_get_id(vdev), mode, link_num,
6525 			       reason);
6526 		qdf_mem_free(req);
6527 		policy_mgr_set_link_in_progress(pm_ctx, false);
6528 	} else {
6529 		status = QDF_STATUS_E_PENDING;
6530 	}
6531 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
6532 
6533 	return status;
6534 }
6535 
6536 uint32_t
policy_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev * vdev,bool force_mlo)6537 policy_mgr_get_conc_ext_flags(struct wlan_objmgr_vdev *vdev, bool force_mlo)
6538 {
6539 	struct wlan_objmgr_vdev *assoc_vdev;
6540 	union conc_ext_flag conc_ext_flags;
6541 
6542 	conc_ext_flags.value = 0;
6543 	if (!vdev || wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
6544 		return conc_ext_flags.value;
6545 
6546 	if (!force_mlo && !wlan_vdev_mlme_is_mlo_vdev(vdev))
6547 		return conc_ext_flags.value;
6548 
6549 	conc_ext_flags.mlo = 1;
6550 	if (wlan_vdev_mlme_is_mlo_link_vdev(vdev)) {
6551 		assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev);
6552 		if (assoc_vdev && ucfg_cm_is_vdev_active(assoc_vdev))
6553 			conc_ext_flags.mlo_link_assoc_connected = 1;
6554 	}
6555 
6556 	return conc_ext_flags.value;
6557 }
6558 
6559 /**
6560  * policy_mgr_allow_sta_concurrency() - check whether STA concurrency is allowed
6561  * @psoc: Pointer to soc
6562  * @freq: frequency to be checked
6563  * @ext_flags: extended flags for concurrency check
6564  *
6565  *  Return: true if supports else false.
6566  */
6567 static bool
policy_mgr_allow_sta_concurrency(struct wlan_objmgr_psoc * psoc,qdf_freq_t freq,uint32_t ext_flags)6568 policy_mgr_allow_sta_concurrency(struct wlan_objmgr_psoc *psoc,
6569 				 qdf_freq_t freq,
6570 				 uint32_t ext_flags)
6571 {
6572 	uint32_t conn_index = 0;
6573 	struct policy_mgr_psoc_priv_obj *pm_ctx;
6574 	struct wlan_objmgr_vdev *vdev;
6575 	bool is_mlo, mlo_sta_present = false;
6576 	uint8_t vdev_id, sta_cnt = 0;
6577 	enum policy_mgr_con_mode mode;
6578 	union conc_ext_flag conc_ext_flags;
6579 
6580 	pm_ctx = policy_mgr_get_context(psoc);
6581 	if (!pm_ctx) {
6582 		policy_mgr_err("Invalid Context");
6583 		return false;
6584 	}
6585 
6586 	conc_ext_flags.value = ext_flags;
6587 
6588 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
6589 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
6590 	     conn_index++) {
6591 		mode = pm_conc_connection_list[conn_index].mode;
6592 		if (mode != PM_STA_MODE ||
6593 		    !pm_conc_connection_list[conn_index].in_use)
6594 			continue;
6595 
6596 		vdev_id = pm_conc_connection_list[conn_index].vdev_id;
6597 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
6598 							    WLAN_POLICY_MGR_ID);
6599 		if (!vdev)
6600 			continue;
6601 
6602 		is_mlo = wlan_vdev_mlme_is_mlo_vdev(vdev);
6603 
6604 		/* Skip the link vdev for MLO STA */
6605 		if (wlan_vdev_mlme_is_mlo_link_vdev(vdev))
6606 			goto next;
6607 
6608 		sta_cnt++;
6609 		if (!is_mlo)
6610 			goto next;
6611 
6612 		mlo_sta_present = true;
6613 next:
6614 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
6615 	}
6616 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
6617 
6618 	/* Reject if multiple STA connections are not allowed */
6619 	if (sta_cnt &&
6620 	    !policy_mgr_allow_multiple_sta_connections(psoc)) {
6621 		policy_mgr_rl_debug("Disallow Multiple STA connections");
6622 		return false;
6623 	}
6624 
6625 	if (mlo_sta_present && conc_ext_flags.mlo_link_assoc_connected) {
6626 		policy_mgr_rl_debug("Allow secondary MLO link");
6627 		return true;
6628 	}
6629 
6630 	if (conc_ext_flags.mlo && mlo_sta_present) {
6631 		policy_mgr_rl_debug("Disallow ML STA when ML STA is present");
6632 		return false;
6633 	}
6634 
6635 	/*
6636 	 * Reject a 3rd STA.
6637 	 * Treat a MLO STA(including the primary and secondary link vdevs)
6638 	 * as 1 STA here.
6639 	 */
6640 	if (sta_cnt >= 2) {
6641 		policy_mgr_rl_debug("Disallow 3rd STA");
6642 		return false;
6643 	}
6644 
6645 	return true;
6646 }
6647 
6648 bool
policy_mgr_is_mlo_sap_concurrency_allowed(struct wlan_objmgr_psoc * psoc,bool is_new_vdev_mlo,uint8_t new_vdev_id)6649 policy_mgr_is_mlo_sap_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
6650 					  bool is_new_vdev_mlo,
6651 					  uint8_t new_vdev_id)
6652 {
6653 	struct policy_mgr_psoc_priv_obj *pm_ctx;
6654 	uint32_t conn_index;
6655 	bool ret = false, mlo_sap_present = false;
6656 	struct wlan_objmgr_vdev *vdev;
6657 	uint32_t vdev_id;
6658 
6659 	pm_ctx = policy_mgr_get_context(psoc);
6660 	if (!pm_ctx) {
6661 		policy_mgr_err("Invalid Context");
6662 		return ret;
6663 	}
6664 
6665 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
6666 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
6667 		 conn_index++) {
6668 		if (!pm_conc_connection_list[conn_index].in_use ||
6669 		    (pm_conc_connection_list[conn_index].mode != PM_SAP_MODE))
6670 			continue;
6671 
6672 		vdev_id = pm_conc_connection_list[conn_index].vdev_id;
6673 		if (vdev_id == new_vdev_id)
6674 			continue;
6675 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
6676 							    WLAN_POLICY_MGR_ID);
6677 		if (!vdev) {
6678 			policy_mgr_err("vdev for vdev_id:%d is NULL", vdev_id);
6679 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
6680 			return ret;
6681 		}
6682 
6683 		/* As only one ML SAP is allowed, break after one ML SAP
6684 		 * instance found in the policy manager list.
6685 		 */
6686 		if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
6687 			mlo_sap_present = true;
6688 			wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
6689 			break;
6690 		}
6691 
6692 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
6693 	}
6694 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
6695 
6696 	if (is_new_vdev_mlo && mlo_sap_present)
6697 		ret = false;
6698 	else
6699 		ret = true;
6700 
6701 	return ret;
6702 }
6703 
6704 QDF_STATUS
policy_mgr_link_switch_notifier_cb(struct wlan_objmgr_vdev * vdev,struct wlan_mlo_link_switch_req * req,enum wlan_mlo_link_switch_notify_reason notify_reason)6705 policy_mgr_link_switch_notifier_cb(struct wlan_objmgr_vdev *vdev,
6706 				   struct wlan_mlo_link_switch_req *req,
6707 				   enum wlan_mlo_link_switch_notify_reason notify_reason)
6708 {
6709 	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
6710 	struct policy_mgr_psoc_priv_obj *pm_ctx;
6711 	uint8_t vdev_id = req->vdev_id;
6712 	uint8_t curr_ieee_link_id = req->curr_ieee_link_id;
6713 	uint8_t new_ieee_link_id = req->new_ieee_link_id;
6714 	uint32_t new_primary_freq = req->new_primary_freq;
6715 	QDF_STATUS status;
6716 	union conc_ext_flag conc_ext_flags;
6717 	struct policy_mgr_conc_connection_info
6718 			info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
6719 	uint8_t num_del = 0;
6720 	struct ml_nlink_change_event data;
6721 	uint16_t dyn_inact_bmap = 0, force_inact_bmap = 0;
6722 
6723 	if (notify_reason > MLO_LINK_SWITCH_NOTIFY_REASON_PRE_START_POST_SER)
6724 		return QDF_STATUS_SUCCESS;
6725 
6726 	pm_ctx = policy_mgr_get_context(psoc);
6727 	if (!pm_ctx) {
6728 		policy_mgr_err("Invalid Context");
6729 		return QDF_STATUS_E_INVAL;
6730 	}
6731 
6732 	policy_mgr_debug("target link %d freq %d curr link %d notify reason %d link switch reason %d vdev %d",
6733 			 new_ieee_link_id, new_primary_freq,
6734 			 curr_ieee_link_id, notify_reason, req->reason,
6735 			 vdev_id);
6736 	qdf_mem_zero(&data, sizeof(data));
6737 	data.evt.link_switch.curr_ieee_link_id = curr_ieee_link_id;
6738 	data.evt.link_switch.new_ieee_link_id = new_ieee_link_id;
6739 	data.evt.link_switch.new_primary_freq = new_primary_freq;
6740 	data.evt.link_switch.reason = req->reason;
6741 	status = ml_nlink_conn_change_notify(psoc, vdev_id,
6742 					     ml_nlink_link_switch_start_evt,
6743 					     &data);
6744 	if (QDF_IS_STATUS_ERROR(status))
6745 		return status;
6746 
6747 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
6748 
6749 	policy_mgr_store_and_del_conn_info_by_vdev_id(
6750 		psoc, vdev_id, info, &num_del);
6751 	conc_ext_flags.value =
6752 	policy_mgr_get_conc_ext_flags(vdev, true);
6753 	ml_nlink_get_dynamic_inactive_links(psoc, vdev, &dyn_inact_bmap,
6754 					    &force_inact_bmap);
6755 
6756 	if (!(dyn_inact_bmap & BIT(new_ieee_link_id)) &&
6757 	    !policy_mgr_is_concurrency_allowed(psoc, PM_STA_MODE,
6758 					       new_primary_freq,
6759 					       HW_MODE_20_MHZ,
6760 					       conc_ext_flags.value,
6761 					       NULL)) {
6762 		status = QDF_STATUS_E_INVAL;
6763 		policy_mgr_debug("target link %d freq %d not allowed by conc rule",
6764 				 new_ieee_link_id, new_primary_freq);
6765 	}
6766 
6767 	if (num_del > 0)
6768 		policy_mgr_restore_deleted_conn_info(psoc, info, num_del);
6769 
6770 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
6771 
6772 	return status;
6773 }
6774 
policy_mgr_is_non_ml_sta_present(struct wlan_objmgr_psoc * psoc)6775 bool policy_mgr_is_non_ml_sta_present(struct wlan_objmgr_psoc *psoc)
6776 {
6777 	uint32_t conn_index = 0;
6778 	struct policy_mgr_psoc_priv_obj *pm_ctx;
6779 	struct wlan_objmgr_vdev *vdev;
6780 	bool non_ml_sta_present = false;
6781 	uint8_t vdev_id;
6782 
6783 	pm_ctx = policy_mgr_get_context(psoc);
6784 	if (!pm_ctx) {
6785 		policy_mgr_err("Invalid Context");
6786 		return false;
6787 	}
6788 
6789 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
6790 	for (conn_index = 0;
6791 	     conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
6792 	     conn_index++) {
6793 		if (pm_conc_connection_list[conn_index].mode != PM_STA_MODE ||
6794 		    !pm_conc_connection_list[conn_index].in_use)
6795 			continue;
6796 
6797 		vdev_id = pm_conc_connection_list[conn_index].vdev_id;
6798 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
6799 							    WLAN_POLICY_MGR_ID);
6800 		if (!vdev)
6801 			continue;
6802 
6803 		if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
6804 			non_ml_sta_present = true;
6805 			wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
6806 			break;
6807 		}
6808 
6809 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
6810 	}
6811 
6812 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
6813 	return non_ml_sta_present;
6814 }
6815 
policy_mgr_is_mlo_sta_present(struct wlan_objmgr_psoc * psoc)6816 bool policy_mgr_is_mlo_sta_present(struct wlan_objmgr_psoc *psoc)
6817 {
6818 	uint32_t conn_index = 0;
6819 	struct policy_mgr_psoc_priv_obj *pm_ctx;
6820 	struct wlan_objmgr_vdev *vdev;
6821 	bool mlo_sta_present = false;
6822 	uint8_t vdev_id;
6823 
6824 	pm_ctx = policy_mgr_get_context(psoc);
6825 	if (!pm_ctx) {
6826 		policy_mgr_err("Invalid Context");
6827 		return false;
6828 	}
6829 
6830 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
6831 	for (conn_index = 0;
6832 	     conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS && !mlo_sta_present;
6833 	     conn_index++) {
6834 		if (pm_conc_connection_list[conn_index].mode != PM_STA_MODE ||
6835 		    !pm_conc_connection_list[conn_index].in_use)
6836 			continue;
6837 
6838 		vdev_id = pm_conc_connection_list[conn_index].vdev_id;
6839 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
6840 							    WLAN_POLICY_MGR_ID);
6841 		if (!vdev)
6842 			continue;
6843 
6844 		mlo_sta_present = wlan_vdev_mlme_is_mlo_vdev(vdev);
6845 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
6846 	}
6847 
6848 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
6849 	return mlo_sta_present;
6850 }
6851 
policy_mgr_is_mlo_in_mode_sbs(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint8_t * mlo_vdev_lst,uint8_t * num_mlo)6852 bool policy_mgr_is_mlo_in_mode_sbs(struct wlan_objmgr_psoc *psoc,
6853 				   enum policy_mgr_con_mode mode,
6854 				   uint8_t *mlo_vdev_lst, uint8_t *num_mlo)
6855 {
6856 	uint32_t mode_num = 0;
6857 	uint8_t i, mlo_idx = 0;
6858 	struct wlan_objmgr_vdev *temp_vdev;
6859 	qdf_freq_t mlo_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
6860 	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
6861 	bool is_sbs_link = true;
6862 
6863 	mode_num = policy_mgr_get_mode_specific_conn_info(psoc, NULL,
6864 							 vdev_id_list, mode);
6865 	if (!mode_num || mode_num < 2)
6866 		return false;
6867 
6868 	for (i = 0; i < mode_num; i++) {
6869 		temp_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
6870 							vdev_id_list[i],
6871 							WLAN_POLICY_MGR_ID);
6872 		if (!temp_vdev) {
6873 			policy_mgr_err("invalid vdev for id %d",
6874 				       vdev_id_list[i]);
6875 			return false;
6876 		}
6877 
6878 		if (wlan_vdev_mlme_is_mlo_vdev(temp_vdev)) {
6879 			if (mlo_vdev_lst)
6880 				mlo_vdev_lst[mlo_idx] = vdev_id_list[i];
6881 			mlo_freq_list[mlo_idx] =
6882 				wlan_get_operation_chan_freq(temp_vdev);
6883 			if (wlan_reg_is_24ghz_ch_freq(mlo_freq_list[mlo_idx]))
6884 				is_sbs_link = false;
6885 			mlo_idx++;
6886 		}
6887 		wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_POLICY_MGR_ID);
6888 	}
6889 
6890 	if (num_mlo)
6891 		*num_mlo = mlo_idx;
6892 	if (mlo_idx < 2)
6893 		is_sbs_link = false;
6894 	if (is_sbs_link &&
6895 	    !policy_mgr_are_sbs_chan(psoc, mlo_freq_list[0],
6896 				     mlo_freq_list[1])) {
6897 		policy_mgr_debug("Freq %d and %d are not SBS, set SBS false",
6898 				 mlo_freq_list[0],
6899 				 mlo_freq_list[1]);
6900 		is_sbs_link = false;
6901 	}
6902 
6903 	return is_sbs_link;
6904 }
6905 
policy_mgr_is_mlo_in_mode_dbs(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint8_t * mlo_vdev_lst,uint8_t * num_mlo)6906 bool policy_mgr_is_mlo_in_mode_dbs(struct wlan_objmgr_psoc *psoc,
6907 				   enum policy_mgr_con_mode mode,
6908 				   uint8_t *mlo_vdev_lst, uint8_t *num_mlo)
6909 {
6910 	uint32_t mode_num = 0;
6911 	uint8_t i, mlo_idx = 0;
6912 	struct wlan_objmgr_vdev *temp_vdev;
6913 	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
6914 	bool has_2g_link = false;
6915 	bool has_5g_link = false;
6916 	qdf_freq_t mlo_freq;
6917 
6918 	mode_num = policy_mgr_get_mode_specific_conn_info(psoc, NULL,
6919 							  vdev_id_list, mode);
6920 	if (!mode_num || mode_num < 2)
6921 		return false;
6922 
6923 	for (i = 0; i < mode_num; i++) {
6924 		temp_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
6925 							psoc,
6926 							vdev_id_list[i],
6927 							WLAN_POLICY_MGR_ID);
6928 		if (!temp_vdev) {
6929 			policy_mgr_err("invalid vdev for id %d",
6930 				       vdev_id_list[i]);
6931 			return false;
6932 		}
6933 
6934 		if (wlan_vdev_mlme_is_mlo_vdev(temp_vdev)) {
6935 			if (mlo_vdev_lst)
6936 				mlo_vdev_lst[mlo_idx] = vdev_id_list[i];
6937 			mlo_freq =
6938 				wlan_get_operation_chan_freq(temp_vdev);
6939 			if (wlan_reg_is_24ghz_ch_freq(mlo_freq))
6940 				has_2g_link = true;
6941 			else
6942 				has_5g_link = true;
6943 			mlo_idx++;
6944 		}
6945 		wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_POLICY_MGR_ID);
6946 	}
6947 
6948 	if (num_mlo)
6949 		*num_mlo = mlo_idx;
6950 
6951 	return has_2g_link && has_5g_link;
6952 }
6953 
policy_mgr_is_curr_hwmode_emlsr(struct wlan_objmgr_psoc * psoc)6954 bool policy_mgr_is_curr_hwmode_emlsr(struct wlan_objmgr_psoc *psoc)
6955 {
6956 	struct policy_mgr_hw_mode_params hw_mode;
6957 
6958 	if (!policy_mgr_is_hw_emlsr_capable(psoc))
6959 		return false;
6960 
6961 	if (QDF_STATUS_SUCCESS != policy_mgr_get_current_hw_mode(psoc,
6962 								 &hw_mode))
6963 		return false;
6964 
6965 	if (!hw_mode.emlsr_cap)
6966 		return false;
6967 
6968 	return true;
6969 }
6970 
policy_mgr_is_mlo_in_mode_emlsr(struct wlan_objmgr_psoc * psoc,uint8_t * mlo_vdev_lst,uint8_t * num_mlo)6971 bool policy_mgr_is_mlo_in_mode_emlsr(struct wlan_objmgr_psoc *psoc,
6972 				     uint8_t *mlo_vdev_lst, uint8_t *num_mlo)
6973 {
6974 	bool emlsr_connection = false;
6975 	uint32_t mode_num = 0;
6976 	uint8_t i, mlo_idx = 0;
6977 	struct wlan_objmgr_vdev *temp_vdev;
6978 	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
6979 	struct policy_mgr_psoc_priv_obj *pm_ctx;
6980 
6981 	pm_ctx = policy_mgr_get_context(psoc);
6982 	if (!pm_ctx) {
6983 		policy_mgr_err("Invalid Context");
6984 		return false;
6985 	}
6986 
6987 	mode_num = policy_mgr_get_mode_specific_conn_info(psoc, NULL,
6988 							  vdev_id_list,
6989 							  PM_STA_MODE);
6990 
6991 	for (i = 0; i < mode_num; i++) {
6992 		temp_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
6993 							psoc, vdev_id_list[i],
6994 							WLAN_POLICY_MGR_ID);
6995 		if (!temp_vdev) {
6996 			policy_mgr_err("invalid vdev for id %d",
6997 				       vdev_id_list[i]);
6998 			goto end;
6999 		}
7000 
7001 		if (wlan_vdev_mlme_is_mlo_vdev(temp_vdev)) {
7002 			if (mlo_vdev_lst)
7003 				mlo_vdev_lst[mlo_idx] = vdev_id_list[i];
7004 			mlo_idx++;
7005 		}
7006 		/* Check if existing vdev is eMLSR STA */
7007 		if (wlan_vdev_mlme_cap_get(temp_vdev, WLAN_VDEV_C_EMLSR_CAP))
7008 			emlsr_connection = true;
7009 
7010 		wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_POLICY_MGR_ID);
7011 	}
7012 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
7013 	for (i = 0; i < MAX_NUMBER_OF_DISABLE_LINK; i++) {
7014 		if (!pm_disabled_ml_links[i].in_use)
7015 			continue;
7016 		if (pm_disabled_ml_links[i].mode != PM_STA_MODE)
7017 			continue;
7018 		temp_vdev =
7019 		wlan_objmgr_get_vdev_by_id_from_psoc(
7020 					psoc, pm_disabled_ml_links[i].vdev_id,
7021 					WLAN_POLICY_MGR_ID);
7022 		if (!temp_vdev) {
7023 			policy_mgr_err("invalid inactive vdev for id %d",
7024 				       pm_disabled_ml_links[i].vdev_id);
7025 			continue;
7026 		}
7027 		/* Check if existing vdev is eMLSR STA */
7028 		if (wlan_vdev_mlme_cap_get(temp_vdev, WLAN_VDEV_C_EMLSR_CAP))
7029 			emlsr_connection = true;
7030 		wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_POLICY_MGR_ID);
7031 	}
7032 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
7033 end:
7034 	if (num_mlo)
7035 		*num_mlo = mlo_idx;
7036 
7037 	return emlsr_connection;
7038 }
7039 
policy_mgr_restore_no_force(struct wlan_objmgr_psoc * psoc,uint8_t num_mlo,uint8_t mlo_vdev_lst[],bool conc_con_coming_up)7040 static void policy_mgr_restore_no_force(struct wlan_objmgr_psoc *psoc,
7041 					uint8_t num_mlo,
7042 					uint8_t mlo_vdev_lst[],
7043 					bool conc_con_coming_up)
7044 {
7045 	struct ml_link_force_state force_cmd = {0};
7046 	QDF_STATUS status;
7047 	struct wlan_objmgr_vdev *vdev;
7048 
7049 	if (num_mlo < 1) {
7050 		policy_mgr_err("invalid num_mlo %d",
7051 			       num_mlo);
7052 		return;
7053 	}
7054 
7055 	vdev =
7056 	wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
7057 					     mlo_vdev_lst[0],
7058 					     WLAN_POLICY_MGR_ID);
7059 	if (!vdev) {
7060 		policy_mgr_err("invalid vdev for id %d",
7061 			       mlo_vdev_lst[0]);
7062 		return;
7063 	}
7064 
7065 	ml_nlink_get_curr_force_state(psoc, vdev, &force_cmd);
7066 	if (!conc_con_coming_up || force_cmd.force_active_bitmap) {
7067 		if (ml_is_nlink_service_supported(psoc))
7068 			status = policy_mgr_mlo_sta_set_nlink(
7069 					psoc, mlo_vdev_lst[0],
7070 					MLO_LINK_FORCE_REASON_DISCONNECT,
7071 					MLO_LINK_FORCE_MODE_NO_FORCE,
7072 					0, 0, 0, 0);
7073 		else
7074 			status = policy_mgr_mlo_sta_set_link(
7075 					psoc,
7076 					MLO_LINK_FORCE_REASON_DISCONNECT,
7077 					MLO_LINK_FORCE_MODE_NO_FORCE,
7078 					num_mlo, mlo_vdev_lst);
7079 		/* If concurrency vdev is coming up and force active bitmap
7080 		 * is present, we need to wait for the respone of no force
7081 		 * command.
7082 		 */
7083 		if (force_cmd.force_active_bitmap && conc_con_coming_up) {
7084 			if (status == QDF_STATUS_E_PENDING)
7085 				policy_mgr_wait_for_set_link_update(psoc);
7086 			else
7087 				policy_mgr_err("status %d", status);
7088 
7089 			ml_nlink_get_curr_force_state(psoc, vdev, &force_cmd);
7090 			ml_nlink_dump_force_state(&force_cmd, "");
7091 		}
7092 	}
7093 
7094 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
7095 }
7096 
policy_mgr_handle_emlsr_sta_concurrency(struct wlan_objmgr_psoc * psoc,bool conc_con_coming_up,bool emlsr_sta_coming_up)7097 void policy_mgr_handle_emlsr_sta_concurrency(struct wlan_objmgr_psoc *psoc,
7098 					     bool conc_con_coming_up,
7099 					     bool emlsr_sta_coming_up)
7100 {
7101 	uint8_t num_mlo = 0;
7102 	uint8_t mlo_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
7103 	bool is_mlo_emlsr = false;
7104 	uint8_t num_disabled_ml_sta = 0;
7105 	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
7106 	struct policy_mgr_psoc_priv_obj *pm_ctx;
7107 
7108 	pm_ctx = policy_mgr_get_context(psoc);
7109 	if (!pm_ctx) {
7110 		policy_mgr_err("Invalid Context");
7111 		return;
7112 	}
7113 
7114 	is_mlo_emlsr = policy_mgr_is_mlo_in_mode_emlsr(psoc, mlo_vdev_lst,
7115 						       &num_mlo);
7116 	policy_mgr_debug("num_mlo %d is_mlo_emlsr %d conc_con_coming_up: %d",
7117 			 num_mlo, is_mlo_emlsr, conc_con_coming_up);
7118 
7119 	if (!is_mlo_emlsr)
7120 		return;
7121 
7122 	if (num_mlo < 2) {
7123 		policy_mgr_debug("conc_con_coming_up %d num mlo sta links %d",
7124 				 conc_con_coming_up, num_mlo);
7125 		policy_mgr_get_ml_sta_info(pm_ctx, &num_mlo,
7126 					   &num_disabled_ml_sta,
7127 					   mlo_vdev_lst, ml_freq_lst,
7128 					   NULL, NULL, NULL);
7129 		if (policy_mgr_get_connection_count(psoc) != 1 ||
7130 		    !num_disabled_ml_sta)
7131 			return;
7132 	}
7133 
7134 	if (conc_con_coming_up ||
7135 	    (emlsr_sta_coming_up &&
7136 	     policy_mgr_get_connection_count(psoc) > 2)) {
7137 		/*
7138 		 * If any force active link bitmap is present, we have to
7139 		 * clear the force active bitmap from target. Otherwise that
7140 		 * will be conflict with the force inactive num bitmap, then
7141 		 * target can't handle force inactive num 1 command to exit
7142 		 * EMLSR.
7143 		 */
7144 		if (conc_con_coming_up)
7145 			policy_mgr_restore_no_force(psoc, num_mlo,
7146 						    mlo_vdev_lst,
7147 						    conc_con_coming_up);
7148 
7149 		/*
7150 		 * Force disable one of the links (FW will decide which link) if
7151 		 * 1) EMLSR STA is present and SAP/STA/NAN connection comes up.
7152 		 * 2) There is a legacy connection (SAP/P2P/NAN) and a STA comes
7153 		 * up in EMLSR mode.
7154 		 */
7155 		policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_CONNECT,
7156 					    MLO_LINK_FORCE_MODE_INACTIVE_NUM,
7157 					    num_mlo, mlo_vdev_lst);
7158 		return;
7159 	}
7160 
7161 	if (!conc_con_coming_up && emlsr_sta_coming_up)
7162 		/*
7163 		 * No force i.e. Re-enable the disabled link if-
7164 		 * 1) EMLSR STA is present and new SAP/STA/NAN connection goes
7165 		 *    down. One of the links was disabled while a new connection
7166 		 *    came up.
7167 		 * 2) Legacy connection (SAP/P2P/NAN) goes down and if STA is
7168 		 *    EMLSR capable. One of the links was disabled after EMLSR
7169 		 *    association.
7170 		 */
7171 		policy_mgr_restore_no_force(psoc, num_mlo,
7172 					    mlo_vdev_lst,
7173 					    conc_con_coming_up);
7174 }
7175 
7176 bool
policy_mgr_is_emlsr_sta_concurrency_present(struct wlan_objmgr_psoc * psoc)7177 policy_mgr_is_emlsr_sta_concurrency_present(struct wlan_objmgr_psoc *psoc)
7178 {
7179 	uint8_t num_mlo = 0;
7180 
7181 	if (policy_mgr_is_mlo_in_mode_emlsr(psoc, NULL, &num_mlo) &&
7182 	    num_mlo < policy_mgr_get_connection_count(psoc))
7183 		return true;
7184 
7185 	return false;
7186 }
7187 
7188 static uint8_t
policy_mgr_get_affected_links_for_sta_sta(struct wlan_objmgr_psoc * psoc,uint8_t num_ml,qdf_freq_t * freq_list,uint8_t * vdev_id_list,uint8_t * ml_vdev_lst,uint8_t * ml_idx,qdf_freq_t freq)7189 policy_mgr_get_affected_links_for_sta_sta(struct wlan_objmgr_psoc *psoc,
7190 					  uint8_t num_ml, qdf_freq_t *freq_list,
7191 					  uint8_t *vdev_id_list,
7192 					  uint8_t *ml_vdev_lst,
7193 					  uint8_t *ml_idx, qdf_freq_t freq)
7194 {
7195 	uint8_t i = 0;
7196 	bool same_band_sta_allowed;
7197 
7198 	/*
7199 	 * STA freq:      ML STA combo:  SBS Action
7200 	 * ---------------------------------------------------
7201 	 * 2Ghz           2Ghz+5/6Ghz    Disable 2Ghz(Same MAC)
7202 	 * 5Ghz           2Ghz+5/6Ghz    Disable 2.4Ghz if 5Ghz lead to SBS
7203 	 *                               (SBS, same MAC) and same band STA
7204 	 *                               allowed, else disable 5/6Ghz
7205 	 *                               (NON SBS, same MAC)
7206 	 * 5Ghz(lower)    5Ghz+6Ghz      Disable 5Ghz (NON SBS, same MAC)
7207 	 * 5Ghz(higher)   5Ghz+6Ghz      Disable 6Ghz (NON SBS, Same MAC)
7208 	 * 2Ghz           5Ghz+6Ghz      Disable Any
7209 	 */
7210 
7211 	/* If non-ML STA is 2.4Ghz disable 2.4Ghz if present OR disable any */
7212 	if (wlan_reg_is_24ghz_ch_freq(freq)) {
7213 		while (i < num_ml) {
7214 			if (wlan_reg_is_24ghz_ch_freq(freq_list[ml_idx[i]])) {
7215 				/* Affected ML STA link on 2.4Ghz */
7216 				ml_vdev_lst[0] = vdev_id_list[ml_idx[i]];
7217 				return 1;
7218 			}
7219 			/* Fill non effected vdev in list */
7220 			ml_vdev_lst[i] = vdev_id_list[ml_idx[i]];
7221 			i++;
7222 		}
7223 		/* No link affected return num_ml to disable any */
7224 		return i;
7225 	}
7226 
7227 	/* This mean non-ML STA is 5Ghz */
7228 
7229 	/* check if ML STA is DBS */
7230 	i = 0;
7231 	while (i < num_ml &&
7232 	       !wlan_reg_is_24ghz_ch_freq(freq_list[ml_idx[i]]))
7233 		i++;
7234 
7235 	same_band_sta_allowed = wlan_cm_same_band_sta_allowed(psoc);
7236 
7237 	/*
7238 	 * if ML STA is DBS ie 2.4Ghz link present and if same_band_sta_allowed
7239 	 * is false, disable 5/6Ghz link to make sure we dont have all link
7240 	 * on 5Ghz
7241 	 */
7242 	if (i < num_ml && !same_band_sta_allowed)
7243 		goto check_dbs_ml;
7244 
7245 	/* check if any link lead to SBS, so that we can disable the other*/
7246 	i = 0;
7247 	while (i < num_ml &&
7248 	       !policy_mgr_are_sbs_chan(psoc, freq, freq_list[ml_idx[i]]))
7249 		i++;
7250 
7251 	/*
7252 	 * if i < num_ml then i is the SBS link, in this case disable the other
7253 	 * non SBS link, this mean ML STA is 5+6 or 2+5/6.
7254 	 */
7255 	if (i < num_ml) {
7256 		i = 0;
7257 		while (i < num_ml) {
7258 			if (!policy_mgr_are_sbs_chan(psoc, freq,
7259 						     freq_list[ml_idx[i]])) {
7260 				/* Affected non SBS ML STA link */
7261 				ml_vdev_lst[0] = vdev_id_list[ml_idx[i]];
7262 				return 1;
7263 			}
7264 			/* Fill non effected vdev in list */
7265 			ml_vdev_lst[i] = vdev_id_list[ml_idx[i]];
7266 			i++;
7267 		}
7268 		/* All link lead to SBS, disable any, This should not happen */
7269 		return i;
7270 	}
7271 
7272 check_dbs_ml:
7273 	/*
7274 	 * None of the link can lead to SBS, i.e. its 2+ 5/6 ML STA in this case
7275 	 * disable 5Ghz link.
7276 	 */
7277 	i = 0;
7278 	while (i < num_ml) {
7279 		if (!wlan_reg_is_24ghz_ch_freq(freq_list[ml_idx[i]])) {
7280 			/* Affected 5/6Ghz ML STA link */
7281 			ml_vdev_lst[0] = vdev_id_list[ml_idx[i]];
7282 			return 1;
7283 		}
7284 		/* Fill non effected vdev in list */
7285 		ml_vdev_lst[i] = vdev_id_list[ml_idx[i]];
7286 		i++;
7287 	}
7288 
7289 	/* No link affected, This should not happen */
7290 	return i;
7291 }
7292 
7293 /*
7294  * policy_mgr_get_concurrent_num_links() - get links which are affected
7295  * if no affected then return num ml. Also fills the ml_vdev_lst to send.
7296  * @num_ml: number of ML vdev
7297  * @freq_list: freq list of all vdev
7298  * @vdev_id_list: vdev id list
7299  * @ml_vdev_lst: ML vdev list
7300  * @ml_idx: ML index
7301  * @freq: non ML STA freq
7302  *
7303  * Return: number of the affected links, else total link and ml_vdev_lst list.
7304  */
7305 static uint8_t
policy_mgr_get_concurrent_num_links(struct wlan_objmgr_vdev * vdev,uint8_t num_ml,qdf_freq_t * freq_list,uint8_t * vdev_id_list,uint8_t * ml_vdev_lst,uint8_t * ml_idx,qdf_freq_t freq)7306 policy_mgr_get_concurrent_num_links(struct wlan_objmgr_vdev *vdev,
7307 				    uint8_t num_ml, qdf_freq_t *freq_list,
7308 				    uint8_t *vdev_id_list,
7309 				    uint8_t *ml_vdev_lst,
7310 				    uint8_t *ml_idx, qdf_freq_t freq)
7311 {
7312 	uint8_t i = 0;
7313 	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
7314 
7315 	if (!psoc)
7316 		return 0;
7317 
7318 	while (i < num_ml && (freq_list[ml_idx[i]] != freq))
7319 		i++;
7320 
7321 	if (i < num_ml) {
7322 		/* if one link is SCC then no need to disable any link */
7323 		policy_mgr_debug("vdev %d: ML vdev %d lead to SCC, STA freq %d ML freq %d, no need to disable link",
7324 				 wlan_vdev_get_id(vdev),
7325 				 vdev_id_list[ml_idx[i]],
7326 				 freq, freq_list[ml_idx[i]]);
7327 		return 0;
7328 	}
7329 
7330 
7331 	return policy_mgr_get_affected_links_for_sta_sta(psoc, num_ml,
7332 							 freq_list,
7333 							 vdev_id_list,
7334 							 ml_vdev_lst,
7335 							 ml_idx, freq);
7336 }
7337 
7338 static void
policy_mgr_ml_sta_concurrency_on_connect(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,uint8_t num_ml,uint8_t * ml_idx,uint8_t num_non_ml,uint8_t * non_ml_idx,qdf_freq_t * freq_list,uint8_t * vdev_id_list)7339 policy_mgr_ml_sta_concurrency_on_connect(struct wlan_objmgr_psoc *psoc,
7340 				    struct wlan_objmgr_vdev *vdev,
7341 				    uint8_t num_ml, uint8_t *ml_idx,
7342 				    uint8_t num_non_ml, uint8_t *non_ml_idx,
7343 				    qdf_freq_t *freq_list,
7344 				    uint8_t *vdev_id_list)
7345 {
7346 	qdf_freq_t freq = 0;
7347 	struct wlan_channel *bss_chan;
7348 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
7349 	uint8_t ml_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
7350 	uint8_t affected_links = 0;
7351 	enum mlo_link_force_mode mode = MLO_LINK_FORCE_MODE_ACTIVE_NUM;
7352 
7353 	/* non ML STA doesn't exist, no need to change to link.*/
7354 	if (!num_non_ml)
7355 		return;
7356 
7357 	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
7358 		freq = freq_list[non_ml_idx[0]];
7359 	} else {
7360 		bss_chan = wlan_vdev_mlme_get_bss_chan(vdev);
7361 		if (bss_chan)
7362 			freq = bss_chan->ch_freq;
7363 	}
7364 	policy_mgr_debug("vdev %d: Freq %d (non ML vdev id %d), is ML STA %d",
7365 			 vdev_id, freq, vdev_id_list[non_ml_idx[0]],
7366 			 wlan_vdev_mlme_is_mlo_vdev(vdev));
7367 	if (!freq)
7368 		return;
7369 
7370 	affected_links =
7371 		policy_mgr_get_concurrent_num_links(vdev, num_ml, freq_list,
7372 						    vdev_id_list, ml_vdev_lst,
7373 						    ml_idx, freq);
7374 
7375 	if (!affected_links) {
7376 		policy_mgr_debug("vdev %d: no affected link found", vdev_id);
7377 		return;
7378 	}
7379 	policy_mgr_debug("affected link found: %u vdev_id: %u",
7380 			 affected_links, ml_vdev_lst[0]);
7381 
7382 	/*
7383 	 * If affected link is less than num_ml, ie not all link are affected,
7384 	 * send MLO_LINK_FORCE_MODE_INACTIVE.
7385 	 */
7386 	if (affected_links < num_ml &&
7387 	    affected_links <= MAX_NUMBER_OF_CONC_CONNECTIONS) {
7388 		if (mlo_is_sta_inactivity_allowed_with_quiet(psoc, vdev_id_list,
7389 							     num_ml, ml_idx,
7390 							     affected_links,
7391 							     ml_vdev_lst)) {
7392 			mode = MLO_LINK_FORCE_MODE_INACTIVE;
7393 		} else {
7394 			policy_mgr_debug("vdev %d: force inactivity is not allowed",
7395 					 ml_vdev_lst[0]);
7396 			return;
7397 		}
7398 	}
7399 
7400 	policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_CONNECT,
7401 				    mode, affected_links, ml_vdev_lst);
7402 }
7403 
7404 static void
policy_mgr_get_disabled_ml_sta_idx(struct wlan_objmgr_psoc * psoc,uint8_t * ml_sta,uint8_t * ml_idx,qdf_freq_t * freq_list,uint8_t * vdev_id_list,uint8_t next_idx)7405 policy_mgr_get_disabled_ml_sta_idx(struct wlan_objmgr_psoc *psoc,
7406 				   uint8_t *ml_sta,
7407 				   uint8_t *ml_idx,
7408 				   qdf_freq_t *freq_list,
7409 				   uint8_t *vdev_id_list, uint8_t next_idx)
7410 {
7411 	uint8_t conn_index, fill_index = next_idx;
7412 	struct policy_mgr_psoc_priv_obj *pm_ctx;
7413 
7414 	pm_ctx = policy_mgr_get_context(psoc);
7415 	if (!pm_ctx) {
7416 		policy_mgr_err("Invalid Context");
7417 		return;
7418 	}
7419 
7420 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
7421 	/* Get disabled link info as well and keep it at last */
7422 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_DISABLE_LINK;
7423 	     conn_index++) {
7424 		if (!pm_disabled_ml_links[conn_index].in_use)
7425 			continue;
7426 		if (pm_disabled_ml_links[conn_index].mode != PM_STA_MODE)
7427 			continue;
7428 		if ((fill_index >= MAX_NUMBER_OF_CONC_CONNECTIONS) ||
7429 		    (*ml_sta >= MAX_NUMBER_OF_CONC_CONNECTIONS)) {
7430 			policy_mgr_err("Invalid fill_index: %d or ml_sta: %d",
7431 				       fill_index, *ml_sta);
7432 			break;
7433 		}
7434 		vdev_id_list[fill_index] =
7435 				pm_disabled_ml_links[conn_index].vdev_id;
7436 		freq_list[fill_index] = pm_disabled_ml_links[conn_index].freq;
7437 		ml_idx[(*ml_sta)++] = fill_index++;
7438 	}
7439 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
7440 }
7441 
7442 /**
7443  * policy_mgr_handle_ml_sta_link_concurrency() - Handle STA+ML_STA concurrency
7444  * @psoc: PSOC object information
7445  * @vdev: vdev of the changed interface caller
7446  *
7447  * Return: void
7448  */
7449 static QDF_STATUS
policy_mgr_handle_ml_sta_link_concurrency(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)7450 policy_mgr_handle_ml_sta_link_concurrency(struct wlan_objmgr_psoc *psoc,
7451 					  struct wlan_objmgr_vdev *vdev)
7452 {
7453 	uint8_t num_ml = 0, num_non_ml = 0, next_idx, disabled_links;
7454 	uint8_t ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
7455 	uint8_t non_ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
7456 	qdf_freq_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
7457 	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
7458 	struct policy_mgr_psoc_priv_obj *pm_ctx;
7459 
7460 	pm_ctx = policy_mgr_get_context(psoc);
7461 	if (!pm_ctx) {
7462 		policy_mgr_err("Invalid Context");
7463 		return QDF_STATUS_E_INVAL;
7464 	}
7465 
7466 	/* Skip non STA connection handling */
7467 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
7468 		return QDF_STATUS_E_INVAL;
7469 
7470 	/*
7471 	 * Skip this in case of SAP/P2P Concurrencies, to avoid renable of
7472 	 * the link, disabled by SAP/P2P logic, as this API only consider
7473 	 * STA specific counts and ignore other counts.
7474 	 */
7475 	if (policy_mgr_get_beaconing_mode_count(psoc, NULL) ||
7476 	    policy_mgr_mode_specific_connection_count(psoc,
7477 						      PM_P2P_CLIENT_MODE,
7478 						      NULL)) {
7479 		policy_mgr_debug("SAP/GO/CLI exist ignore this check");
7480 		return QDF_STATUS_E_INVAL;
7481 	}
7482 
7483 	policy_mgr_get_ml_and_non_ml_sta_count(psoc, &num_ml, ml_idx,
7484 					       &num_non_ml, non_ml_idx,
7485 					       freq_list, vdev_id_list);
7486 	/* Skip non STA+STA cases */
7487 	if (!num_ml || !num_non_ml)
7488 		return QDF_STATUS_E_INVAL;
7489 
7490 	next_idx = num_ml + num_non_ml;
7491 	policy_mgr_get_disabled_ml_sta_idx(psoc, &num_ml, ml_idx,
7492 					   freq_list, vdev_id_list, next_idx);
7493 
7494 	disabled_links = num_ml - (next_idx - num_non_ml);
7495 	policy_mgr_debug("vdev %d: num_ml %d num_non_ml %d disabled_links: %d",
7496 			 wlan_vdev_get_id(vdev), num_ml, num_non_ml,
7497 			 disabled_links);
7498 
7499 	/* ML STA is not up or not sufficient links to disable */
7500 	if (num_ml < 2 || num_ml > MAX_NUMBER_OF_CONC_CONNECTIONS ||
7501 	    num_ml - disabled_links < 2) {
7502 		policy_mgr_debug("ML STA is not up or not sufficient links to disable");
7503 		return QDF_STATUS_E_INVAL;
7504 	}
7505 	/*
7506 	 * TODO: Check if both link enable/ link switch is possible when
7507 	 * secondary STA switch happens to a new channel due to CSA
7508 	 */
7509 
7510 	policy_mgr_ml_sta_concurrency_on_connect(psoc, vdev, num_ml,
7511 						 ml_idx, num_non_ml,
7512 						 non_ml_idx, freq_list,
7513 						 vdev_id_list);
7514 	return QDF_STATUS_SUCCESS;
7515 }
7516 
7517 static bool
policy_mgr_is_mode_p2p_sap(enum policy_mgr_con_mode mode)7518 policy_mgr_is_mode_p2p_sap(enum policy_mgr_con_mode mode)
7519 {
7520 	return (policy_mgr_is_beaconing_mode(mode) ||
7521 		(mode == PM_P2P_CLIENT_MODE));
7522 }
7523 
7524 bool
policy_mgr_is_vdev_high_tput_or_low_latency(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)7525 policy_mgr_is_vdev_high_tput_or_low_latency(struct wlan_objmgr_psoc *psoc,
7526 					    uint8_t vdev_id)
7527 {
7528 	struct wlan_objmgr_vdev *vdev;
7529 	bool is_vdev_ll_ht;
7530 
7531 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
7532 						    WLAN_POLICY_MGR_ID);
7533 	if (!vdev) {
7534 		policy_mgr_err("invalid vdev for id %d", vdev_id);
7535 		return false;
7536 	}
7537 	is_vdev_ll_ht = wlan_is_vdev_traffic_ll_ht(vdev);
7538 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
7539 
7540 	return is_vdev_ll_ht;
7541 }
7542 
7543 bool
policy_mgr_check_2ghz_only_sap_affected_link(struct wlan_objmgr_psoc * psoc,uint8_t sap_vdev_id,qdf_freq_t sap_ch_freq,uint8_t ml_ch_freq_num,qdf_freq_t * ml_freq_lst)7544 policy_mgr_check_2ghz_only_sap_affected_link(
7545 			struct wlan_objmgr_psoc *psoc,
7546 			uint8_t sap_vdev_id,
7547 			qdf_freq_t sap_ch_freq,
7548 			uint8_t ml_ch_freq_num,
7549 			qdf_freq_t *ml_freq_lst)
7550 {
7551 	uint8_t i;
7552 	struct policy_mgr_psoc_priv_obj *pm_ctx;
7553 	struct wlan_objmgr_vdev *vdev;
7554 	enum QDF_OPMODE op_mode;
7555 
7556 	pm_ctx = policy_mgr_get_context(psoc);
7557 	if (!pm_ctx) {
7558 		policy_mgr_err("Invalid Context");
7559 		return false;
7560 	}
7561 
7562 	if (!WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq))
7563 		return false;
7564 
7565 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
7566 				psoc, sap_vdev_id,
7567 				WLAN_POLICY_MGR_ID);
7568 	if (!vdev) {
7569 		policy_mgr_debug("vdev is null %d", sap_vdev_id);
7570 		return false;
7571 	}
7572 	op_mode = wlan_vdev_mlme_get_opmode(vdev);
7573 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
7574 	if (op_mode != QDF_SAP_MODE)
7575 		return false;
7576 
7577 	if (!policy_mgr_is_acs_2ghz_only_sap(psoc, sap_vdev_id))
7578 		return false;
7579 
7580 	/* If 2G ml STA exist, force scc will happen, no link
7581 	 * to get affected.
7582 	 */
7583 	for (i = 0; i < ml_ch_freq_num; i++)
7584 		if (WLAN_REG_IS_24GHZ_CH_FREQ(ml_freq_lst[i]))
7585 			return false;
7586 
7587 	/* If All ml STA are 5/6 band, force SCC will not happen
7588 	 * for 2G only SAP, so return true to indicate one
7589 	 * link get affected.
7590 	 */
7591 	return true;
7592 }
7593 
7594 /*
7595  * policy_mgr_get_affected_links_for_go_sap_cli() - Check if any of the P2P OR
7596  * SAP is causing MCC with a ML link and also is configured high tput or low
7597  * latency
7598  * @psoc: psoc ctx
7599  * @num_ml_sta: Number of ML STA present
7600  * @ml_vdev_lst: ML STA vdev id list
7601  * @ml_freq_lst: ML STA freq list
7602  * @num_p2p_sap: Number of P2P and SAP present
7603  * @p2p_sap_vdev_lst: P2P and SAP vdev id list
7604  * @p2p_sap_freq_lst: P2P and SAP freq list
7605  *
7606  * Return: Number of links causing MCC with any of the P2P or SAP which is
7607  * configured high tput or low latency
7608  */
7609 static uint8_t
policy_mgr_get_affected_links_for_go_sap_cli(struct wlan_objmgr_psoc * psoc,uint8_t num_ml_sta,uint8_t * ml_vdev_lst,qdf_freq_t * ml_freq_lst,uint8_t num_p2p_sap,uint8_t * p2p_sap_vdev_lst,qdf_freq_t * p2p_sap_freq_lst)7610 policy_mgr_get_affected_links_for_go_sap_cli(struct wlan_objmgr_psoc *psoc,
7611 					     uint8_t num_ml_sta,
7612 					     uint8_t *ml_vdev_lst,
7613 					     qdf_freq_t *ml_freq_lst,
7614 					     uint8_t num_p2p_sap,
7615 					     uint8_t *p2p_sap_vdev_lst,
7616 					     qdf_freq_t *p2p_sap_freq_lst)
7617 {
7618 	uint8_t i = 0, k = 0, num_affected_links = 0;
7619 
7620 	if (!num_p2p_sap || num_ml_sta < 2)
7621 		return num_affected_links;
7622 
7623 	while (i < num_ml_sta) {
7624 		/* if any link is causing MCC with GO/GC/AP, set mcc as true.*/
7625 		for (k = 0; k < num_p2p_sap; k++) {
7626 			/* Continue if SCC */
7627 			if (ml_freq_lst[i] == p2p_sap_freq_lst[k])
7628 				continue;
7629 
7630 			/* SAP MCC with MLO STA link is not preferred.
7631 			 * If SAP is 2Ghz only by ACS and two ML link are
7632 			 * 5/6 band, then force SCC may not happen. In such
7633 			 * case inactive one link.
7634 			 */
7635 			if (policy_mgr_check_2ghz_only_sap_affected_link(
7636 					psoc, p2p_sap_vdev_lst[k],
7637 					p2p_sap_freq_lst[k],
7638 					num_ml_sta, ml_freq_lst)) {
7639 				policy_mgr_debug("2G only SAP vdev %d ch freq %d is not SCC with any MLO STA link",
7640 						 p2p_sap_vdev_lst[k],
7641 						 p2p_sap_freq_lst[k]);
7642 				num_affected_links++;
7643 				continue;
7644 			}
7645 
7646 			/* Continue if high tput or low latency is not set */
7647 			if (!policy_mgr_is_vdev_high_tput_or_low_latency(
7648 						psoc, p2p_sap_vdev_lst[k]))
7649 				continue;
7650 
7651 			/* If both freq are on same mac then its MCC */
7652 			if (policy_mgr_are_2_freq_on_same_mac(psoc,
7653 							ml_freq_lst[i],
7654 							p2p_sap_freq_lst[k])) {
7655 				policy_mgr_debug("ml sta vdev %d (freq %d) and p2p/sap vdev %d (freq %d) are MCC",
7656 						 ml_vdev_lst[i], ml_freq_lst[i],
7657 						 p2p_sap_vdev_lst[k],
7658 						 p2p_sap_freq_lst[k]);
7659 				num_affected_links++;
7660 			}
7661 		}
7662 		i++;
7663 	}
7664 
7665 	return num_affected_links;
7666 }
7667 
7668 /*
7669  * policy_mgr_get_ml_sta_and_p2p_cli_go_sap_info() - Get number of ML STA,
7670  * P2P and SAP interfaces and their vdev ids and freq list
7671  * @pm_ctx: pm_ctx ctx
7672  * @num_ml_sta: Return number of ML STA present
7673  * @num_disabled_ml_sta: Return number of disabled ML STA links
7674  * @ml_vdev_lst: Return ML STA vdev id list
7675  * @ml_freq_lst: Return ML STA freq list
7676  * @num_p2p_sap: Return number of P2P and SAP present
7677  * @p2p_sap_vdev_lst: Return P2P and SAP vdev id list
7678  * @p2p_sap_freq_lst: Return P2P and SAP freq list
7679  *
7680  * Return: void
7681  */
7682 static void
policy_mgr_get_ml_sta_and_p2p_cli_go_sap_info(struct policy_mgr_psoc_priv_obj * pm_ctx,uint8_t * num_ml_sta,uint8_t * num_disabled_ml_sta,uint8_t * ml_vdev_lst,qdf_freq_t * ml_freq_lst,uint8_t * num_p2p_sap,uint8_t * p2p_sap_vdev_lst,qdf_freq_t * p2p_sap_freq_lst)7683 policy_mgr_get_ml_sta_and_p2p_cli_go_sap_info(
7684 					struct policy_mgr_psoc_priv_obj *pm_ctx,
7685 					uint8_t *num_ml_sta,
7686 					uint8_t *num_disabled_ml_sta,
7687 					uint8_t *ml_vdev_lst,
7688 					qdf_freq_t *ml_freq_lst,
7689 					uint8_t *num_p2p_sap,
7690 					uint8_t *p2p_sap_vdev_lst,
7691 					qdf_freq_t *p2p_sap_freq_lst)
7692 {
7693 	enum policy_mgr_con_mode mode;
7694 	uint8_t vdev_id, conn_index;
7695 	qdf_freq_t freq;
7696 
7697 	*num_p2p_sap = 0;
7698 
7699 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
7700 	policy_mgr_get_ml_sta_info(pm_ctx, num_ml_sta, num_disabled_ml_sta,
7701 				   ml_vdev_lst, ml_freq_lst, NULL, NULL, NULL);
7702 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
7703 	     conn_index++) {
7704 		if (!pm_conc_connection_list[conn_index].in_use)
7705 			continue;
7706 		mode = pm_conc_connection_list[conn_index].mode;
7707 		if (!policy_mgr_is_mode_p2p_sap(mode))
7708 			continue;
7709 		vdev_id = pm_conc_connection_list[conn_index].vdev_id;
7710 		freq = pm_conc_connection_list[conn_index].freq;
7711 
7712 		/* add p2p and sap vdev and freq list */
7713 		p2p_sap_vdev_lst[*num_p2p_sap] = vdev_id;
7714 		p2p_sap_freq_lst[(*num_p2p_sap)++] = freq;
7715 	}
7716 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
7717 }
7718 
7719 /*
7720  * policy_mgr_is_ml_sta_links_in_mcc() - Check ML links are in MCC or not
7721  * @psoc: psoc ctx
7722  * @ml_freq_lst: ML STA freq list
7723  * @ml_vdev_lst: ML STA vdev id list
7724  * @ml_linkid_lst: ML STA link id list
7725  * @num_ml_sta: Number of total ML STA links
7726  * @affected_linkid_bitmap: link id bitmap which home channels are in MCC
7727  * with each other
7728  *
7729  * Return: true if ML link in MCC else false
7730  */
7731 bool
policy_mgr_is_ml_sta_links_in_mcc(struct wlan_objmgr_psoc * psoc,qdf_freq_t * ml_freq_lst,uint8_t * ml_vdev_lst,uint8_t * ml_linkid_lst,uint8_t num_ml_sta,uint32_t * affected_linkid_bitmap)7732 policy_mgr_is_ml_sta_links_in_mcc(struct wlan_objmgr_psoc *psoc,
7733 				  qdf_freq_t *ml_freq_lst,
7734 				  uint8_t *ml_vdev_lst,
7735 				  uint8_t *ml_linkid_lst,
7736 				  uint8_t num_ml_sta,
7737 				  uint32_t *affected_linkid_bitmap)
7738 {
7739 	uint8_t i, j;
7740 	uint32_t link_id_bitmap;
7741 
7742 	for (i = 0; i < num_ml_sta; i++) {
7743 		link_id_bitmap = 0;
7744 		if (ml_linkid_lst)
7745 			link_id_bitmap = 1 << ml_linkid_lst[i];
7746 		for (j = i + 1; j < num_ml_sta; j++) {
7747 			if (ml_freq_lst[i] != ml_freq_lst[j] &&
7748 			    policy_mgr_2_freq_always_on_same_mac(
7749 					psoc, ml_freq_lst[i], ml_freq_lst[j])) {
7750 				if (ml_vdev_lst)
7751 					policy_mgr_debug("vdev %d and %d are in MCC with freq %d and freq %d",
7752 							 ml_vdev_lst[i],
7753 							 ml_vdev_lst[j],
7754 							 ml_freq_lst[i],
7755 							 ml_freq_lst[j]);
7756 				if (ml_linkid_lst) {
7757 					link_id_bitmap |= 1 << ml_linkid_lst[j];
7758 					policy_mgr_debug("link %d and %d are in MCC with freq %d and freq %d",
7759 							 ml_linkid_lst[i],
7760 							 ml_linkid_lst[j],
7761 							 ml_freq_lst[i],
7762 							 ml_freq_lst[j]);
7763 					if (affected_linkid_bitmap)
7764 						*affected_linkid_bitmap =
7765 							link_id_bitmap;
7766 				}
7767 				return true;
7768 			}
7769 		}
7770 	}
7771 
7772 	return false;
7773 }
7774 
7775 QDF_STATUS
policy_mgr_is_ml_links_in_mcc_allowed(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,uint8_t * ml_sta_vdev_lst,uint8_t * num_ml_sta)7776 policy_mgr_is_ml_links_in_mcc_allowed(struct wlan_objmgr_psoc *psoc,
7777 				      struct wlan_objmgr_vdev *vdev,
7778 				      uint8_t *ml_sta_vdev_lst,
7779 				      uint8_t *num_ml_sta)
7780 {
7781 	uint8_t num_disabled_ml_sta = 0;
7782 	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
7783 	struct policy_mgr_psoc_priv_obj *pm_ctx;
7784 
7785 	pm_ctx = policy_mgr_get_context(psoc);
7786 	if (!pm_ctx) {
7787 		policy_mgr_err("Invalid Context");
7788 		return QDF_STATUS_E_FAILURE;
7789 	}
7790 
7791 	policy_mgr_get_ml_sta_info(pm_ctx, num_ml_sta, &num_disabled_ml_sta,
7792 				   ml_sta_vdev_lst, ml_freq_lst,
7793 				   NULL, NULL, NULL);
7794 	if (*num_ml_sta < 2 || *num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
7795 	    num_disabled_ml_sta) {
7796 		policy_mgr_debug("num_ml_sta invalid %d or link already disabled%d",
7797 				 *num_ml_sta, num_disabled_ml_sta);
7798 		return QDF_STATUS_E_FAILURE;
7799 	}
7800 
7801 	if (!policy_mgr_is_ml_sta_links_in_mcc(psoc, ml_freq_lst,
7802 					       ml_sta_vdev_lst, NULL,
7803 					       *num_ml_sta,
7804 					       NULL))
7805 		return QDF_STATUS_E_FAILURE;
7806 
7807 	/*
7808 	 * eMLSR is allowed in MCC mode also. So, don't disable any links
7809 	 * if current connection happens in eMLSR mode.
7810 	 */
7811 	if (policy_mgr_is_mlo_in_mode_emlsr(psoc, NULL, NULL)) {
7812 		policy_mgr_debug("Don't disable eMLSR links");
7813 		return QDF_STATUS_E_FAILURE;
7814 	}
7815 
7816 	return QDF_STATUS_SUCCESS;
7817 }
7818 
7819 /**
7820  * policy_mgr_handle_mcc_ml_sta() - disables one ML STA link if causing MCC
7821  * DBS - if ML STA links on 5 GHz + 6 GHz
7822  * SBS - if both ML STA links on 5 GHz high/5 GHz low
7823  * non-SBS - any combo (5/6 GHz + 5/6 GHz OR 2 GHz + 5/6 GHz)
7824  * @psoc: psoc ctx
7825  * @vdev: Pointer to vdev object
7826  *
7827  * Return: Success if MCC link is disabled else failure
7828  */
7829 static QDF_STATUS
policy_mgr_handle_mcc_ml_sta(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)7830 policy_mgr_handle_mcc_ml_sta(struct wlan_objmgr_psoc *psoc,
7831 			     struct wlan_objmgr_vdev *vdev)
7832 {
7833 	uint8_t num_ml_sta = 0;
7834 	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
7835 	QDF_STATUS status;
7836 
7837 	if ((wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE))
7838 		return QDF_STATUS_E_FAILURE;
7839 
7840 	status = policy_mgr_is_ml_links_in_mcc_allowed(psoc, vdev,
7841 						       ml_sta_vdev_lst,
7842 						       &num_ml_sta);
7843 	if (QDF_IS_STATUS_ERROR(status))
7844 		return QDF_STATUS_E_FAILURE;
7845 
7846 	policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_CONNECT,
7847 				    MLO_LINK_FORCE_MODE_ACTIVE_NUM,
7848 				    num_ml_sta, ml_sta_vdev_lst);
7849 
7850 	return QDF_STATUS_SUCCESS;
7851 }
7852 
7853 /*
7854  * policy_mgr_sta_ml_link_enable_allowed() - Check with given ML links and
7855  * existing concurrencies, a disabled ml link can be enabled back.
7856  * @psoc: psoc ctx
7857  * @num_disabled_ml_sta: Number of existing disabled links
7858  * @num_ml_sta: Number of total ML STA links
7859  * @ml_freq_lst: ML STA freq list
7860  * @ml_vdev_lst: ML STA vdev id list
7861  *
7862  * Return: if link can be enabled or not
7863  */
7864 static bool
policy_mgr_sta_ml_link_enable_allowed(struct wlan_objmgr_psoc * psoc,uint8_t num_disabled_ml_sta,uint8_t num_ml_sta,qdf_freq_t * ml_freq_lst,uint8_t * ml_vdev_lst)7865 policy_mgr_sta_ml_link_enable_allowed(struct wlan_objmgr_psoc *psoc,
7866 				      uint8_t num_disabled_ml_sta,
7867 				      uint8_t num_ml_sta,
7868 				      qdf_freq_t *ml_freq_lst,
7869 				      uint8_t *ml_vdev_lst)
7870 {
7871 	union conc_ext_flag conc_ext_flags;
7872 	uint8_t disabled_link_vdev_id;
7873 	qdf_freq_t disabled_link_freq;
7874 	struct wlan_objmgr_vdev *vdev;
7875 
7876 	/* If no link is disabled nothing to do */
7877 	if (!num_disabled_ml_sta || num_ml_sta < 2)
7878 		return false;
7879 	if (policy_mgr_is_ml_sta_links_in_mcc(psoc, ml_freq_lst, ml_vdev_lst,
7880 					      NULL, num_ml_sta,
7881 					      NULL))
7882 		return false;
7883 	/* Disabled link is at the last index */
7884 	disabled_link_vdev_id = ml_vdev_lst[num_ml_sta - 1];
7885 	disabled_link_freq = ml_freq_lst[num_ml_sta - 1];
7886 	policy_mgr_debug("disabled_link_vdev_id %d disabled_link_freq %d",
7887 			 disabled_link_vdev_id, disabled_link_freq);
7888 	if (!disabled_link_freq)
7889 		return false;
7890 
7891 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, disabled_link_vdev_id,
7892 						    WLAN_POLICY_MGR_ID);
7893 	if (!vdev) {
7894 		policy_mgr_err("invalid vdev for id %d", disabled_link_vdev_id);
7895 		return false;
7896 	}
7897 	conc_ext_flags.value = policy_mgr_get_conc_ext_flags(vdev, false);
7898 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
7899 
7900 	return policy_mgr_is_concurrency_allowed(psoc, PM_STA_MODE,
7901 					disabled_link_freq, HW_MODE_20_MHZ,
7902 					conc_ext_flags.value, NULL);
7903 }
7904 
7905 /*
7906  * policy_mgr_re_enable_ml_sta_on_p2p_sap_down() - Handle enable
7907  * link on P2P/SAP/ML_STA vdev UP or channel change
7908  * @psoc: objmgr psoc
7909  * @vdev: vdev which went UP or changed chan
7910  *
7911  * Return: void
7912  */
7913 static void
policy_mgr_handle_sap_cli_go_ml_sta_up_csa(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)7914 policy_mgr_handle_sap_cli_go_ml_sta_up_csa(struct wlan_objmgr_psoc *psoc,
7915 					   struct wlan_objmgr_vdev *vdev)
7916 {
7917 	uint8_t num_ml_sta = 0, num_p2p_sap = 0, num_disabled_ml_sta = 0;
7918 	uint8_t num_affected_link;
7919 	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
7920 	uint8_t p2p_sap_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
7921 	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
7922 	qdf_freq_t p2p_sap_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
7923 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
7924 	struct policy_mgr_psoc_priv_obj *pm_ctx;
7925 	QDF_STATUS status;
7926 
7927 	pm_ctx = policy_mgr_get_context(psoc);
7928 	if (!pm_ctx) {
7929 		policy_mgr_err("Invalid Context");
7930 		return;
7931 	}
7932 
7933 	status = policy_mgr_handle_ml_sta_link_state_allowed(
7934 				psoc, MLO_LINK_FORCE_REASON_CONNECT);
7935 	if (QDF_IS_STATUS_ERROR(status))
7936 		return;
7937 
7938 	/*
7939 	 * eMLSR API policy_mgr_handle_emlsr_sta_concurrency() takes care of
7940 	 * eMLSR concurrencies. Currently, eMLSR STA can't operate with any
7941 	 * cocurrent mode, i.e. one link gets force-disabled when a new
7942 	 * concurrecy is coming up.
7943 	 */
7944 	if (policy_mgr_is_mlo_in_mode_emlsr(psoc, NULL, NULL)) {
7945 		policy_mgr_debug("STA connected in eMLSR mode, don't enable/disable links");
7946 		return;
7947 	}
7948 
7949 	if (QDF_IS_STATUS_SUCCESS(policy_mgr_handle_mcc_ml_sta(psoc, vdev)))
7950 		return;
7951 
7952 	status = policy_mgr_handle_ml_sta_link_concurrency(psoc, vdev);
7953 	if (QDF_IS_STATUS_SUCCESS(status))
7954 		return;
7955 
7956 	policy_mgr_get_ml_sta_and_p2p_cli_go_sap_info(pm_ctx, &num_ml_sta,
7957 						      &num_disabled_ml_sta,
7958 						      ml_sta_vdev_lst,
7959 						      ml_freq_lst, &num_p2p_sap,
7960 						      p2p_sap_vdev_lst,
7961 						      p2p_sap_freq_lst);
7962 
7963 	policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_p2p_sap %d",
7964 			 vdev_id, num_ml_sta, num_disabled_ml_sta, num_p2p_sap);
7965 	if (num_ml_sta < 2 || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
7966 	    num_p2p_sap > MAX_NUMBER_OF_CONC_CONNECTIONS)
7967 		return;
7968 
7969 	num_affected_link = policy_mgr_get_affected_links_for_go_sap_cli(psoc,
7970 						num_ml_sta, ml_sta_vdev_lst,
7971 						ml_freq_lst, num_p2p_sap,
7972 						p2p_sap_vdev_lst,
7973 						p2p_sap_freq_lst);
7974 
7975 	if (!num_affected_link) {
7976 		policy_mgr_debug("vdev %d: no affected link found", vdev_id);
7977 		goto enable_link;
7978 	}
7979 
7980 	if (num_disabled_ml_sta) {
7981 		policy_mgr_debug("As a link is already disabled and affected link present (%d), No action required",
7982 				 num_affected_link);
7983 		return;
7984 	}
7985 
7986 	policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_CONNECT,
7987 				    MLO_LINK_FORCE_MODE_ACTIVE_NUM,
7988 				    num_ml_sta, ml_sta_vdev_lst);
7989 
7990 	return;
7991 enable_link:
7992 
7993 	/*
7994 	 * if no affected link and link can be allowed to enable then renable
7995 	 * the disabled link.
7996 	 */
7997 	if (policy_mgr_sta_ml_link_enable_allowed(psoc, num_disabled_ml_sta,
7998 						  num_ml_sta, ml_freq_lst,
7999 						  ml_sta_vdev_lst))
8000 		policy_mgr_mlo_sta_set_link(psoc,
8001 					    MLO_LINK_FORCE_REASON_DISCONNECT,
8002 					    MLO_LINK_FORCE_MODE_NO_FORCE,
8003 					    num_ml_sta, ml_sta_vdev_lst);
8004 }
8005 
8006 void
policy_mgr_handle_ml_sta_links_on_vdev_up_csa(struct wlan_objmgr_psoc * psoc,enum QDF_OPMODE mode,uint8_t vdev_id)8007 policy_mgr_handle_ml_sta_links_on_vdev_up_csa(struct wlan_objmgr_psoc *psoc,
8008 					      enum QDF_OPMODE mode,
8009 					      uint8_t vdev_id)
8010 {
8011 	struct wlan_objmgr_vdev *vdev;
8012 
8013 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
8014 						    WLAN_POLICY_MGR_ID);
8015 	if (!vdev) {
8016 		policy_mgr_err("vdev %d: invalid vdev", vdev_id);
8017 		return;
8018 	}
8019 
8020 	if (mode == QDF_STA_MODE || mode == QDF_SAP_MODE ||
8021 	    mode == QDF_P2P_CLIENT_MODE || mode == QDF_P2P_GO_MODE)
8022 		policy_mgr_handle_sap_cli_go_ml_sta_up_csa(psoc, vdev);
8023 
8024 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
8025 }
8026 
8027 #define SET_LINK_TIMEOUT 6000
policy_mgr_wait_for_set_link_update(struct wlan_objmgr_psoc * psoc)8028 QDF_STATUS policy_mgr_wait_for_set_link_update(struct wlan_objmgr_psoc *psoc)
8029 {
8030 	struct policy_mgr_psoc_priv_obj *pm_ctx;
8031 	QDF_STATUS status;
8032 
8033 	pm_ctx = policy_mgr_get_context(psoc);
8034 	if (!pm_ctx) {
8035 		policy_mgr_err("Invalid Context");
8036 		return QDF_STATUS_E_INVAL;
8037 	}
8038 
8039 	if (!policy_mgr_get_link_in_progress(pm_ctx)) {
8040 		policy_mgr_err("link is not in progress");
8041 		return QDF_STATUS_E_FAILURE;
8042 	}
8043 
8044 	status =
8045 		qdf_wait_for_event_completion(&pm_ctx->set_link_update_done_evt,
8046 					      SET_LINK_TIMEOUT);
8047 
8048 	if (QDF_IS_STATUS_ERROR(status)) {
8049 		policy_mgr_set_link_in_progress(pm_ctx, false);
8050 		policy_mgr_err("wait for set_link_in_progress failed");
8051 	}
8052 
8053 	return status;
8054 }
8055 
policy_mgr_handle_ml_sta_link_on_traffic_type_change(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)8056 void policy_mgr_handle_ml_sta_link_on_traffic_type_change(
8057 						struct wlan_objmgr_psoc *psoc,
8058 						struct wlan_objmgr_vdev *vdev)
8059 {
8060 	/* Check if any set link is already progress and thus wait */
8061 	policy_mgr_wait_for_set_link_update(psoc);
8062 
8063 	ml_nlink_conn_change_notify(
8064 		psoc, wlan_vdev_get_id(vdev),
8065 		ml_nlink_connection_updated_evt, NULL);
8066 
8067 	/*
8068 	 * Check if traffic type change lead to set link is progress and
8069 	 * thus wait for it to complete.
8070 	 */
8071 	policy_mgr_wait_for_set_link_update(psoc);
8072 }
8073 
8074 static QDF_STATUS
policy_mgr_handle_ml_sta_link_enable_on_sta_down(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)8075 policy_mgr_handle_ml_sta_link_enable_on_sta_down(struct wlan_objmgr_psoc *psoc,
8076 						 struct wlan_objmgr_vdev *vdev)
8077 {
8078 	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0, num_non_ml = 0;
8079 	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
8080 	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
8081 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
8082 	struct policy_mgr_psoc_priv_obj *pm_ctx;
8083 
8084 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
8085 		return QDF_STATUS_E_INVAL;
8086 
8087 	pm_ctx = policy_mgr_get_context(psoc);
8088 	if (!pm_ctx) {
8089 		policy_mgr_err("Invalid Context");
8090 		return QDF_STATUS_E_INVAL;
8091 	}
8092 
8093 	/* Handle only when non-ML STA is going down and ML STA is active */
8094 	policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta,
8095 				   ml_sta_vdev_lst, ml_freq_lst, &num_non_ml,
8096 				   NULL, NULL);
8097 	policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_non_ml: %d",
8098 			 vdev_id, num_ml_sta, num_disabled_ml_sta, num_non_ml);
8099 
8100 	/*
8101 	 * No ML STA is present or sinle link ML is present or
8102 	 * more no.of links are active than supported concurrent connections
8103 	 */
8104 	if (num_ml_sta < 2 || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS)
8105 		return QDF_STATUS_E_INVAL;
8106 
8107 	/* STA+STA cases */
8108 
8109 	/* One ML/non-ML STA is going down and another non ML STA is present */
8110 	if (num_non_ml) {
8111 		policy_mgr_debug("non-ML STA is present");
8112 		return QDF_STATUS_SUCCESS;
8113 	}
8114 
8115 	/*
8116 	 * If no links are disabled or
8117 	 * link can not be allowed to enable then skip checking further.
8118 	 */
8119 	if (!num_disabled_ml_sta ||
8120 	    !policy_mgr_sta_ml_link_enable_allowed(psoc, num_disabled_ml_sta,
8121 						  num_ml_sta, ml_freq_lst,
8122 						  ml_sta_vdev_lst)) {
8123 		if (num_disabled_ml_sta)
8124 			policy_mgr_debug("Not re-enabled due to disallowed concurrency");
8125 		goto done;
8126 	}
8127 
8128 	policy_mgr_mlo_sta_set_link(psoc,
8129 				    MLO_LINK_FORCE_REASON_DISCONNECT,
8130 				    MLO_LINK_FORCE_MODE_NO_FORCE,
8131 				    num_ml_sta, ml_sta_vdev_lst);
8132 
8133 done:
8134 	return QDF_STATUS_SUCCESS;
8135 }
8136 
8137 /*
8138  * policy_mgr_re_enable_ml_sta_on_p2p_sap_sta_down() - Handle enable
8139  * link on P2P/SAP/ML_STA vdev down
8140  * @psoc: objmgr psoc
8141  * @vdev: vdev which went down
8142  *
8143  * Return: void
8144  */
8145 static void
policy_mgr_re_enable_ml_sta_on_p2p_sap_sta_down(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)8146 policy_mgr_re_enable_ml_sta_on_p2p_sap_sta_down(struct wlan_objmgr_psoc *psoc,
8147 						struct wlan_objmgr_vdev *vdev)
8148 {
8149 	uint8_t num_ml_sta = 0, num_p2p_sap = 0, num_disabled_ml_sta = 0;
8150 	uint8_t num_affected_link = 0;
8151 	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
8152 	uint8_t p2p_sap_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
8153 	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
8154 	qdf_freq_t p2p_sap_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
8155 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
8156 	struct policy_mgr_psoc_priv_obj *pm_ctx;
8157 	QDF_STATUS status;
8158 
8159 	status = policy_mgr_handle_ml_sta_link_state_allowed(
8160 				psoc, MLO_LINK_FORCE_REASON_DISCONNECT);
8161 	if (QDF_IS_STATUS_ERROR(status))
8162 		return;
8163 
8164 	status = policy_mgr_handle_ml_sta_link_enable_on_sta_down(psoc, vdev);
8165 	if (QDF_IS_STATUS_SUCCESS(status))
8166 		return;
8167 
8168 	pm_ctx = policy_mgr_get_context(psoc);
8169 	if (!pm_ctx) {
8170 		policy_mgr_err("Invalid Context");
8171 		return;
8172 	}
8173 
8174 	policy_mgr_get_ml_sta_and_p2p_cli_go_sap_info(pm_ctx, &num_ml_sta,
8175 						      &num_disabled_ml_sta,
8176 						      ml_sta_vdev_lst,
8177 						      ml_freq_lst, &num_p2p_sap,
8178 						      p2p_sap_vdev_lst,
8179 						      p2p_sap_freq_lst);
8180 
8181 	policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_p2p_sap %d",
8182 			 vdev_id, num_ml_sta, num_disabled_ml_sta, num_p2p_sap);
8183 
8184 	if (num_ml_sta < 2 || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
8185 	    num_p2p_sap > MAX_NUMBER_OF_CONC_CONNECTIONS)
8186 		return;
8187 
8188 	/* If link can not be allowed to enable then skip checking further. */
8189 	if (!policy_mgr_sta_ml_link_enable_allowed(psoc, num_disabled_ml_sta,
8190 						   num_ml_sta, ml_freq_lst,
8191 						   ml_sta_vdev_lst))
8192 		return;
8193 
8194 	/*
8195 	 * If num_p2p_sap is non zero, ie p2p or sap still present check if
8196 	 * disable link is still required, if not enable the link.
8197 	 *
8198 	 * If num_p2p_sap is 0, ie only ml sta is present, enable the link.
8199 	 */
8200 	if (num_p2p_sap)
8201 		num_affected_link =
8202 			policy_mgr_get_affected_links_for_go_sap_cli(psoc,
8203 						num_ml_sta, ml_sta_vdev_lst,
8204 						ml_freq_lst, num_p2p_sap,
8205 						p2p_sap_vdev_lst,
8206 						p2p_sap_freq_lst);
8207 
8208 	if (num_affected_link)
8209 		policy_mgr_debug("vdev %d: Affected link present, dont reanabe ML link",
8210 				 vdev_id);
8211 	else
8212 		policy_mgr_mlo_sta_set_link(psoc,
8213 					    MLO_LINK_FORCE_REASON_DISCONNECT,
8214 					    MLO_LINK_FORCE_MODE_NO_FORCE,
8215 					    num_ml_sta, ml_sta_vdev_lst);
8216 }
8217 
policy_mgr_handle_ml_sta_links_on_vdev_down(struct wlan_objmgr_psoc * psoc,enum QDF_OPMODE mode,uint8_t vdev_id)8218 void policy_mgr_handle_ml_sta_links_on_vdev_down(struct wlan_objmgr_psoc *psoc,
8219 						 enum QDF_OPMODE mode,
8220 						 uint8_t vdev_id)
8221 {
8222 	struct wlan_objmgr_vdev *vdev;
8223 
8224 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
8225 						    WLAN_POLICY_MGR_ID);
8226 	if (!vdev) {
8227 		policy_mgr_err("vdev %d: invalid vdev", vdev_id);
8228 		return;
8229 	}
8230 
8231 	if (mode == QDF_STA_MODE || mode == QDF_SAP_MODE ||
8232 	    mode == QDF_P2P_CLIENT_MODE || mode == QDF_P2P_GO_MODE)
8233 		policy_mgr_re_enable_ml_sta_on_p2p_sap_sta_down(psoc, vdev);
8234 
8235 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
8236 }
8237 
8238 /**
8239  * policy_mgr_pick_link_vdev_from_inactive_list() - Get inactive vdev
8240  * which can be activated
8241  * @psoc: PSOC object information
8242  * @vdev: vdev object
8243  * @inactive_vdev_num: inactive vdev num in list
8244  * @inactive_vdev_lst: inactive vdev list
8245  * @inactive_freq_lst: inactive vdev frequency list
8246  * @picked_vdev_id: Picked vdev id
8247  * @non_removed_vdev_id: not removed inactive vdev id
8248  *
8249  * If one link is removed and inactivated, pick one of existing inactive
8250  * vdev which can be activated by checking concurrency API.
8251  *
8252  * Return: void
8253  */
8254 static void
policy_mgr_pick_link_vdev_from_inactive_list(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,uint8_t inactive_vdev_num,uint8_t * inactive_vdev_lst,qdf_freq_t * inactive_freq_lst,uint8_t * picked_vdev_id,uint8_t * non_removed_vdev_id)8255 policy_mgr_pick_link_vdev_from_inactive_list(
8256 	struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev,
8257 	uint8_t inactive_vdev_num, uint8_t *inactive_vdev_lst,
8258 	qdf_freq_t *inactive_freq_lst, uint8_t *picked_vdev_id,
8259 	uint8_t *non_removed_vdev_id)
8260 {
8261 	struct policy_mgr_psoc_priv_obj *pm_ctx;
8262 	struct policy_mgr_conc_connection_info
8263 			info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
8264 	uint8_t num_del = 0;
8265 	union conc_ext_flag conc_ext_flags = {0};
8266 	uint8_t i;
8267 
8268 	pm_ctx = policy_mgr_get_context(psoc);
8269 	if (!pm_ctx) {
8270 		policy_mgr_err("Invalid Context");
8271 		return;
8272 	}
8273 
8274 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
8275 	policy_mgr_store_and_del_conn_info_by_vdev_id(
8276 			psoc, wlan_vdev_get_id(vdev),
8277 			info, &num_del);
8278 	/* pick one inactive parnter link and make it active */
8279 	for (i = 0; i < inactive_vdev_num; i++) {
8280 		struct wlan_objmgr_vdev *partner_vdev;
8281 
8282 		if (wlan_get_vdev_link_removed_flag_by_vdev_id(
8283 				psoc, inactive_vdev_lst[i])) {
8284 			policy_mgr_debug("skip removed link vdev %d",
8285 					 inactive_vdev_lst[i]);
8286 			continue;
8287 		}
8288 
8289 		partner_vdev =
8290 		wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
8291 						     inactive_vdev_lst[i],
8292 						     WLAN_POLICY_MGR_ID);
8293 		if (!partner_vdev) {
8294 			policy_mgr_err("invalid partner_vdev %d ",
8295 				       inactive_vdev_lst[i]);
8296 			continue;
8297 		}
8298 		*non_removed_vdev_id = inactive_vdev_lst[i];
8299 
8300 		conc_ext_flags.value =
8301 		policy_mgr_get_conc_ext_flags(partner_vdev, false);
8302 
8303 		if (policy_mgr_is_concurrency_allowed(psoc, PM_STA_MODE,
8304 						      inactive_freq_lst[i],
8305 						      HW_MODE_20_MHZ,
8306 						      conc_ext_flags.value,
8307 						      NULL)) {
8308 			*picked_vdev_id = inactive_vdev_lst[i];
8309 			wlan_objmgr_vdev_release_ref(partner_vdev,
8310 						     WLAN_POLICY_MGR_ID);
8311 			break;
8312 		}
8313 		wlan_objmgr_vdev_release_ref(partner_vdev, WLAN_POLICY_MGR_ID);
8314 	}
8315 	/* Restore the connection info */
8316 	policy_mgr_restore_deleted_conn_info(psoc, info, num_del);
8317 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
8318 }
8319 
8320 QDF_STATUS
policy_mgr_handle_link_removal_on_standby(struct wlan_objmgr_vdev * vdev,struct ml_rv_info * reconfig_info)8321 policy_mgr_handle_link_removal_on_standby(struct wlan_objmgr_vdev *vdev,
8322 					  struct ml_rv_info *reconfig_info)
8323 {
8324 	struct mlo_link_info *link_info;
8325 	uint8_t i, link_id;
8326 	uint32_t removal_link_bitmap = 0;
8327 	QDF_STATUS status;
8328 	struct wlan_objmgr_psoc *psoc;
8329 
8330 	if (!vdev || !vdev->mlo_dev_ctx) {
8331 		policy_mgr_err("invalid vdev or mlo_dev_ctx");
8332 		return QDF_STATUS_E_INVAL;
8333 	}
8334 
8335 	psoc = wlan_vdev_get_psoc(vdev);
8336 	if (!psoc) {
8337 		policy_mgr_err("psoc is null");
8338 		return QDF_STATUS_E_INVAL;
8339 	}
8340 
8341 	for (i = 0; i < reconfig_info->num_links; i++) {
8342 		if (!(reconfig_info->link_info[i].is_ap_removal_timer_p &&
8343 		      reconfig_info->link_info[i].ap_removal_timer))
8344 			continue;
8345 
8346 		link_id = reconfig_info->link_info[i].link_id;
8347 		link_info = mlo_mgr_get_ap_link_by_link_id(vdev->mlo_dev_ctx,
8348 							   link_id);
8349 		if (!link_info) {
8350 			policy_mgr_err("link info null, id %d", link_id);
8351 			return QDF_STATUS_E_NULL_VALUE;
8352 		}
8353 		policy_mgr_debug("AP removal tbtt %d vdev %d link %d flag 0x%x STA MAC " QDF_MAC_ADDR_FMT " BSSID " QDF_MAC_ADDR_FMT,
8354 				 reconfig_info->link_info[i].ap_removal_timer,
8355 				 link_info->vdev_id, link_id,
8356 				 (uint32_t)link_info->link_status_flags,
8357 				 QDF_MAC_ADDR_REF(link_info->link_addr.bytes),
8358 				 QDF_MAC_ADDR_REF(link_info->ap_link_addr.bytes));
8359 
8360 		if (qdf_is_macaddr_zero(&link_info->ap_link_addr))
8361 			continue;
8362 
8363 		if (link_info->vdev_id != WLAN_INVALID_VDEV_ID)
8364 			continue;
8365 
8366 		if (qdf_atomic_test_and_set_bit(LS_F_AP_REMOVAL_BIT,
8367 						&link_info->link_status_flags))
8368 			continue;
8369 
8370 		removal_link_bitmap |= 1 << link_id;
8371 	}
8372 	if (!removal_link_bitmap)
8373 		return QDF_STATUS_SUCCESS;
8374 
8375 	status = policy_mgr_mlo_sta_set_nlink(
8376 			psoc, wlan_vdev_get_id(vdev),
8377 			MLO_LINK_FORCE_REASON_LINK_REMOVAL,
8378 			MLO_LINK_FORCE_MODE_INACTIVE,
8379 			0,
8380 			removal_link_bitmap,
8381 			0,
8382 			0);
8383 	if (status == QDF_STATUS_E_PENDING)
8384 		status = QDF_STATUS_SUCCESS;
8385 	else
8386 		policy_mgr_err("status %d", status);
8387 
8388 	return status;
8389 }
8390 
policy_mgr_handle_link_removal_on_vdev(struct wlan_objmgr_vdev * vdev)8391 void policy_mgr_handle_link_removal_on_vdev(struct wlan_objmgr_vdev *vdev)
8392 {
8393 	struct wlan_objmgr_psoc *psoc;
8394 	struct policy_mgr_psoc_priv_obj *pm_ctx;
8395 	uint32_t i;
8396 	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0;
8397 	uint8_t num_active_ml_sta;
8398 	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
8399 	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
8400 	uint8_t vdev_id = wlan_vdev_get_id(vdev);
8401 	uint8_t non_removal_link_vdev_id = WLAN_INVALID_VDEV_ID;
8402 	uint8_t picked_vdev_id = WLAN_INVALID_VDEV_ID;
8403 	QDF_STATUS status;
8404 
8405 	psoc = wlan_vdev_get_psoc(vdev);
8406 	if (!psoc) {
8407 		policy_mgr_err("Failed to get psoc");
8408 		return;
8409 	}
8410 	pm_ctx = policy_mgr_get_context(psoc);
8411 	if (!pm_ctx) {
8412 		policy_mgr_err("Invalid Context");
8413 		return;
8414 	}
8415 	if (wlan_get_vdev_link_removed_flag_by_vdev_id(psoc, vdev_id)) {
8416 		policy_mgr_debug("removal link vdev %d is removed already",
8417 				 vdev_id);
8418 		return;
8419 	}
8420 
8421 	wlan_connectivity_mlo_reconfig_event(vdev);
8422 
8423 	/* mark link removed for vdev */
8424 	wlan_set_vdev_link_removed_flag_by_vdev_id(psoc, vdev_id,
8425 						   true);
8426 	status = policy_mgr_handle_ml_sta_link_state_allowed(
8427 			psoc, MLO_LINK_FORCE_REASON_LINK_REMOVAL);
8428 	if (QDF_IS_STATUS_ERROR(status)) {
8429 		wlan_set_vdev_link_removed_flag_by_vdev_id(psoc, vdev_id,
8430 							   false);
8431 		return;
8432 	}
8433 
8434 	policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta,
8435 				   ml_sta_vdev_lst, ml_freq_lst,
8436 				   NULL, NULL, NULL);
8437 	if (!num_ml_sta) {
8438 		policy_mgr_debug("unexpected event, no ml sta");
8439 		return;
8440 	}
8441 	if (num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
8442 	    num_disabled_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
8443 	    num_ml_sta <= num_disabled_ml_sta) {
8444 		policy_mgr_debug("unexpected ml sta num %d %d",
8445 				 num_ml_sta, num_disabled_ml_sta);
8446 		return;
8447 	}
8448 	/* Single link FW should handle BTM/disassoc and do roaming.
8449 	 * Host will not send inactive command to FW.
8450 	 */
8451 	if (num_ml_sta < 2) {
8452 		policy_mgr_debug("no op for single link mlo, num_ml_sta %d",
8453 				 num_ml_sta);
8454 		return;
8455 	}
8456 
8457 	policy_mgr_debug("removal link vdev %d num_ml_sta %d num_disabled_ml_sta %d",
8458 			 vdev_id, num_ml_sta, num_disabled_ml_sta);
8459 
8460 	num_active_ml_sta = num_ml_sta;
8461 	if (num_ml_sta >= num_disabled_ml_sta)
8462 		num_active_ml_sta = num_ml_sta - num_disabled_ml_sta;
8463 
8464 	for (i = 0; i < num_active_ml_sta; i++)
8465 		if (ml_sta_vdev_lst[i] == vdev_id)
8466 			break;
8467 
8468 	if (i == num_active_ml_sta) {
8469 		/* no found in active ml list, it must be in inactive list */
8470 		policy_mgr_debug("removal link vdev %d is inactive already",
8471 				 vdev_id);
8472 
8473 		/* send inactive command to fw again with "link removal
8474 		 * reason"
8475 		 */
8476 		policy_mgr_mlo_sta_set_link(
8477 			psoc, MLO_LINK_FORCE_REASON_LINK_REMOVAL,
8478 			MLO_LINK_FORCE_MODE_INACTIVE,
8479 			1, &vdev_id);
8480 		return;
8481 	}
8482 
8483 	/* pick one inactive parnter link and make it active */
8484 	if (num_active_ml_sta < num_ml_sta)
8485 		policy_mgr_pick_link_vdev_from_inactive_list(
8486 				psoc, vdev, num_disabled_ml_sta,
8487 				&ml_sta_vdev_lst[num_active_ml_sta],
8488 				&ml_freq_lst[num_active_ml_sta],
8489 				&picked_vdev_id,
8490 				&non_removal_link_vdev_id);
8491 	if (picked_vdev_id != WLAN_INVALID_VDEV_ID) {
8492 		/* find one inactive link can be active, send it to fw with
8493 		 * the removed link together.
8494 		 */
8495 		policy_mgr_debug("active parnter vdev %d, inactive removal vdev %d",
8496 				 picked_vdev_id, vdev_id);
8497 		policy_mgr_mlo_sta_set_link_ext(
8498 				psoc, MLO_LINK_FORCE_REASON_LINK_REMOVAL,
8499 				MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE,
8500 				1, &picked_vdev_id,
8501 				1, &vdev_id);
8502 		return;
8503 	}
8504 	if (num_active_ml_sta < 2) {
8505 		/* For multi-link MLO, one link is removed and
8506 		 * no find one inactive link can be active:
8507 		 * 1. If at least one left link is not link removed state,
8508 		 * host will trigger roaming.
8509 		 * 2. If all left links are link removed state,
8510 		 * FW will trigger roaming based on BTM or disassoc frame
8511 		 */
8512 		if (non_removal_link_vdev_id != WLAN_INVALID_VDEV_ID) {
8513 			policy_mgr_debug("trigger roaming, non_removal_link_vdev_id %d",
8514 					 non_removal_link_vdev_id);
8515 			policy_mgr_trigger_roam_on_link_removal(vdev);
8516 		}
8517 		return;
8518 	}
8519 	/* If active link number >= 2 and one link is removed, then at least
8520 	 * one link is still active, just send inactived command to fw.
8521 	 */
8522 	policy_mgr_mlo_sta_set_link(psoc, MLO_LINK_FORCE_REASON_LINK_REMOVAL,
8523 				    MLO_LINK_FORCE_MODE_INACTIVE,
8524 				    1, &vdev_id);
8525 }
8526 
8527 /**
8528  * policy_mgr_is_restart_sap_required_with_mlo_sta() - Check SAP required to
8529  * restart for force SCC with MLO STA
8530  * @psoc: PSOC object information
8531  * @sap_vdev_id: sap vdev id
8532  * @sap_ch_freq: sap channel frequency
8533  *
8534  * For MLO STA+SAP case, mlo link maybe in inactive state after connected
8535  * and the hw mode maybe not updated, check MCC/SCC by
8536  * policy_mgr_are_2_freq_on_same_mac may not match MCC/SCC state
8537  * after the link is activated by target later. So to check frequency match
8538  * or not to decide SAP do force SCC or not if MLO STA 2 links are present.
8539  *
8540  * Return: true if SAP is required to force SCC with MLO STA
8541  */
8542 static bool
policy_mgr_is_restart_sap_required_with_mlo_sta(struct wlan_objmgr_psoc * psoc,uint8_t sap_vdev_id,qdf_freq_t sap_ch_freq)8543 policy_mgr_is_restart_sap_required_with_mlo_sta(struct wlan_objmgr_psoc *psoc,
8544 						uint8_t sap_vdev_id,
8545 						qdf_freq_t sap_ch_freq)
8546 {
8547 	struct policy_mgr_psoc_priv_obj *pm_ctx;
8548 	uint32_t i;
8549 	bool same_freq_with_mlo_sta = false;
8550 	bool restart_required = false;
8551 	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0, num_ml_active_sta = 0;
8552 	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
8553 	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
8554 
8555 	pm_ctx = policy_mgr_get_context(psoc);
8556 	if (!pm_ctx) {
8557 		policy_mgr_err("Invalid Context");
8558 		return false;
8559 	}
8560 
8561 	policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta,
8562 				   ml_sta_vdev_lst, ml_freq_lst,
8563 				   NULL, NULL, NULL);
8564 	if (num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS) {
8565 		policy_mgr_debug("unexpected num_ml_sta %d ", num_ml_sta);
8566 		return false;
8567 	}
8568 
8569 	num_ml_active_sta = num_ml_sta;
8570 	if (num_ml_sta >= num_disabled_ml_sta)
8571 		num_ml_active_sta = num_ml_sta - num_disabled_ml_sta;
8572 	for (i = 0; i < num_ml_active_sta; i++) {
8573 		if (ml_freq_lst[i] == sap_ch_freq) {
8574 			same_freq_with_mlo_sta = true;
8575 			break;
8576 		}
8577 	}
8578 
8579 	if (num_ml_active_sta >= 2 && !same_freq_with_mlo_sta) {
8580 		policy_mgr_debug("SAP is not SCC with any of active MLO STA link, restart SAP");
8581 		restart_required = true;
8582 	}
8583 
8584 	return restart_required;
8585 }
8586 
8587 /**
8588  * policy_mgr_is_new_force_allowed() - Check if the new force command is allowed
8589  * @psoc: PSOC object information
8590  * @vdev: ml sta vdev object
8591  * @active_link_bitmap: Active link bitmap from user request
8592  *
8593  * If ML STA associates in 3-link (2.4 GHz + 5 GHz + 6 GHz), Host sends force
8594  * inactive num command between 5 GHz and 6 GHz links to firmware as it's a DBS
8595  * RD. This force has to be in effect at all times but any new force active num
8596  * command request from the userspace (except for 5 GHz + 6 GHz links) should be
8597  * honored. This API checks if the new force command can be allowed.
8598  *
8599  * Return: True if the new force command is allowed, else False
8600  */
8601 static bool
policy_mgr_is_new_force_allowed(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,uint32_t active_link_bitmap)8602 policy_mgr_is_new_force_allowed(struct wlan_objmgr_psoc *psoc,
8603 				struct wlan_objmgr_vdev *vdev,
8604 				uint32_t active_link_bitmap)
8605 {
8606 	uint32_t link_bitmap = 0;
8607 	uint8_t link_num = 0;
8608 	struct set_link_req conc_link_req;
8609 
8610 	qdf_mem_zero(&conc_link_req, sizeof(conc_link_req));
8611 	ml_nlink_get_force_link_request(psoc, vdev, &conc_link_req,
8612 					SET_LINK_FROM_CONCURRENCY);
8613 	/* If force inactive num is present due to MCC link(DBS RD) or
8614 	 * concurrency with legacy intf, don't allow force active if
8615 	 * left inactive link number doesn't meet concurrency
8616 	 * requirement.
8617 	 */
8618 	if (conc_link_req.force_inactive_num_bitmap ||
8619 	    conc_link_req.force_inactive_num) {
8620 		link_bitmap = ~active_link_bitmap &
8621 		conc_link_req.force_inactive_num_bitmap;
8622 		if (!link_bitmap) {
8623 			policy_mgr_err("New force bitmap 0x%x not allowed due to force_inactive_num_bitmap 0x%x",
8624 				       active_link_bitmap,
8625 				       conc_link_req.
8626 				       force_inactive_num_bitmap);
8627 			return false;
8628 		}
8629 		link_num = convert_link_bitmap_to_link_ids(link_bitmap,
8630 							   0, NULL);
8631 		if (link_num < conc_link_req.force_inactive_num) {
8632 			policy_mgr_debug("force inact num exists with %d don't allow act bitmap 0x%x",
8633 					 conc_link_req.force_active_num,
8634 					 active_link_bitmap);
8635 			return false;
8636 		}
8637 	}
8638 	/* If force inactive bitmap is present due to link removal or
8639 	 * concurrency with legacy intf, don't allow force active if
8640 	 * it is conflict with existing concurrency requirement.
8641 	 */
8642 	if (conc_link_req.force_inactive_bitmap) {
8643 		link_bitmap = active_link_bitmap &
8644 			conc_link_req.force_inactive_bitmap;
8645 		if (link_bitmap) {
8646 			policy_mgr_err("New force act bitmap 0x%x not allowed due to conc force inact bitmap 0x%x",
8647 				       active_link_bitmap,
8648 				       conc_link_req.force_inactive_bitmap);
8649 			return false;
8650 		}
8651 	}
8652 
8653 	return true;
8654 }
8655 
policy_mgr_activate_mlo_links_nlink(struct wlan_objmgr_psoc * psoc,uint8_t session_id,uint8_t num_links,struct qdf_mac_addr active_link_addr[2])8656 void policy_mgr_activate_mlo_links_nlink(struct wlan_objmgr_psoc *psoc,
8657 					 uint8_t session_id, uint8_t num_links,
8658 					 struct qdf_mac_addr active_link_addr[2])
8659 {
8660 	uint8_t *link_mac_addr;
8661 	uint32_t link_ctrl_flags;
8662 	enum mlo_link_force_reason reason;
8663 	enum mlo_link_force_mode mode;
8664 	struct wlan_objmgr_vdev *vdev;
8665 	struct mlo_link_info *link_info;
8666 	bool active_link_present = false;
8667 	uint8_t iter, link, active_link_cnt = 0, inactive_link_cnt = 0;
8668 	uint32_t active_link_bitmap = 0;
8669 	uint32_t inactive_link_bitmap = 0;
8670 	struct ml_link_force_state curr = {0};
8671 	bool update_inactive_link = false;
8672 
8673 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id,
8674 						    WLAN_POLICY_MGR_ID);
8675 	if (!vdev) {
8676 		policy_mgr_err("vdev_id: %d vdev not found", session_id);
8677 		return;
8678 	}
8679 
8680 	if (!wlan_cm_is_vdev_connected(vdev)) {
8681 		policy_mgr_err("vdev is not in connected state");
8682 		goto done;
8683 	}
8684 
8685 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
8686 		policy_mgr_err("vdev is not mlo vdev");
8687 		goto done;
8688 	}
8689 
8690 	policy_mgr_debug("Num active links: %d", num_links);
8691 	link_info = &vdev->mlo_dev_ctx->link_ctx->links_info[0];
8692 	for (iter = 0; iter < WLAN_MAX_ML_BSS_LINKS; iter++) {
8693 		if (link_info->link_id == WLAN_INVALID_LINK_ID) {
8694 			link_info++;
8695 			continue;
8696 		}
8697 
8698 		link_mac_addr = &link_info->link_addr.bytes[0];
8699 		policy_mgr_debug("link addr: " QDF_MAC_ADDR_FMT,
8700 				 QDF_MAC_ADDR_REF(link_mac_addr));
8701 
8702 		for (link = 0; link < num_links; link++) {
8703 			policy_mgr_debug("active addr: " QDF_MAC_ADDR_FMT,
8704 			   QDF_MAC_ADDR_REF(&active_link_addr[link].bytes[0]));
8705 			if (!qdf_mem_cmp(link_mac_addr,
8706 					 &active_link_addr[link].bytes[0],
8707 					 QDF_MAC_ADDR_SIZE)) {
8708 				active_link_bitmap |= 1 << link_info->link_id;
8709 				active_link_cnt++;
8710 				active_link_present = true;
8711 				policy_mgr_debug("Link address match");
8712 			}
8713 		}
8714 		if (!active_link_present) {
8715 			inactive_link_bitmap |= 1 << link_info->link_id;
8716 			inactive_link_cnt++;
8717 			policy_mgr_err("No link address match");
8718 		}
8719 		active_link_present = false;
8720 		link_info++;
8721 	}
8722 
8723 	policy_mgr_debug("active link cnt: %d, inactive link cnt: %d",
8724 			 active_link_cnt, inactive_link_cnt);
8725 
8726 	if (!active_link_cnt) {
8727 		goto done;
8728 	} else if (policy_mgr_is_emlsr_sta_concurrency_present(psoc)) {
8729 		policy_mgr_debug("Concurrency exists, cannot enter EMLSR mode");
8730 		goto done;
8731 	} else {
8732 		if (!policy_mgr_is_new_force_allowed(
8733 			psoc, vdev, active_link_bitmap))
8734 			goto done;
8735 
8736 		/* If current force inactive bitmap exists, we have to remove
8737 		 * the new active bitmap from the existing inactive bitmap,
8738 		 * e.g. a link id can't be present in active bitmap and
8739 		 * inactive bitmap at same time, so update inactive bitmap
8740 		 * as well.
8741 		 */
8742 		ml_nlink_get_curr_force_state(psoc, vdev, &curr);
8743 		if (curr.force_inactive_bitmap && !inactive_link_cnt) {
8744 			inactive_link_bitmap = curr.force_inactive_bitmap &
8745 						~active_link_bitmap;
8746 			update_inactive_link = true;
8747 		}
8748 	}
8749 
8750 	/*
8751 	 * If there are both active and inactive vdev count, then issue a
8752 	 * single WMI with force mode MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE,
8753 	 * else if there is only active vdev count, send single WMI for
8754 	 * all active vdevs with force mode MLO_LINK_FORCE_MODE_ACTIVE.
8755 	 */
8756 	if (inactive_link_cnt || update_inactive_link) {
8757 		reason = MLO_LINK_FORCE_REASON_CONNECT;
8758 		mode = MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE;
8759 		link_ctrl_flags = link_ctrl_f_overwrite_active_bitmap |
8760 					link_ctrl_f_overwrite_inactive_bitmap;
8761 	} else {
8762 		reason = MLO_LINK_FORCE_REASON_DISCONNECT;
8763 		mode = MLO_LINK_FORCE_MODE_ACTIVE;
8764 		link_ctrl_flags = link_ctrl_f_overwrite_active_bitmap;
8765 	}
8766 
8767 	policy_mgr_mlo_sta_set_nlink(psoc, wlan_vdev_get_id(vdev),
8768 				     reason, mode, 0,
8769 				     active_link_bitmap, inactive_link_bitmap,
8770 				     link_ctrl_flags);
8771 	if (active_link_bitmap)
8772 		ml_nlink_vendor_command_set_link(
8773 			psoc, session_id,
8774 			LINK_CONTROL_MODE_USER,
8775 			MLO_LINK_FORCE_REASON_CONNECT,
8776 			MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE,
8777 			0, active_link_bitmap,
8778 			inactive_link_bitmap);
8779 
8780 done:
8781 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
8782 }
8783 
policy_mgr_activate_mlo_links(struct wlan_objmgr_psoc * psoc,uint8_t session_id,uint8_t num_links,struct qdf_mac_addr * active_link_addr)8784 void policy_mgr_activate_mlo_links(struct wlan_objmgr_psoc *psoc,
8785 				   uint8_t session_id, uint8_t num_links,
8786 				   struct qdf_mac_addr *active_link_addr)
8787 {
8788 	uint8_t idx, link, active_vdev_cnt = 0, inactive_vdev_cnt = 0;
8789 	uint16_t ml_vdev_cnt = 0;
8790 	struct wlan_objmgr_vdev *tmp_vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {0};
8791 	uint8_t active_vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {0};
8792 	uint8_t inactive_vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {0};
8793 	struct wlan_objmgr_vdev *vdev;
8794 	uint8_t *link_mac_addr;
8795 	bool active_vdev_present = false;
8796 	uint16_t active_link_bitmap = 0;
8797 	uint16_t inactive_link_bitmap = 0;
8798 
8799 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id,
8800 						    WLAN_POLICY_MGR_ID);
8801 	if (!vdev) {
8802 		policy_mgr_err("vdev_id: %d vdev not found", session_id);
8803 		return;
8804 	}
8805 
8806 	if (!wlan_cm_is_vdev_connected(vdev)) {
8807 		policy_mgr_err("vdev is not in connected state");
8808 		goto done;
8809 	}
8810 
8811 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
8812 		policy_mgr_err("vdev is not mlo vdev");
8813 		goto done;
8814 	}
8815 
8816 	mlo_get_ml_vdev_list(vdev, &ml_vdev_cnt, tmp_vdev_lst);
8817 	policy_mgr_debug("Num active links: %d, ML vdev cnt: %d", num_links,
8818 			 ml_vdev_cnt);
8819 	for (idx = 0; idx < ml_vdev_cnt; idx++) {
8820 		link_mac_addr = wlan_vdev_mlme_get_macaddr(tmp_vdev_lst[idx]);
8821 		policy_mgr_debug("link addr: " QDF_MAC_ADDR_FMT,
8822 				 QDF_MAC_ADDR_REF(link_mac_addr));
8823 		for (link = 0; link < num_links; link++) {
8824 			policy_mgr_debug("active addr: " QDF_MAC_ADDR_FMT,
8825 			   QDF_MAC_ADDR_REF(&active_link_addr[link].bytes[0]));
8826 			if (!qdf_mem_cmp(link_mac_addr,
8827 					 &active_link_addr[link].bytes[0],
8828 					 QDF_MAC_ADDR_SIZE)) {
8829 				active_vdev_lst[active_vdev_cnt] =
8830 					wlan_vdev_get_id(tmp_vdev_lst[idx]);
8831 				active_link_bitmap |=
8832 				1 << wlan_vdev_get_link_id(tmp_vdev_lst[idx]);
8833 				active_vdev_cnt++;
8834 				active_vdev_present = true;
8835 				policy_mgr_debug("Link address match");
8836 			}
8837 		}
8838 		if (!active_vdev_present) {
8839 			inactive_vdev_lst[inactive_vdev_cnt] =
8840 					wlan_vdev_get_id(tmp_vdev_lst[idx]);
8841 			inactive_link_bitmap |=
8842 			1 << wlan_vdev_get_link_id(tmp_vdev_lst[idx]);
8843 
8844 			inactive_vdev_cnt++;
8845 			policy_mgr_err("No link address match");
8846 		}
8847 		active_vdev_present = false;
8848 	}
8849 
8850 	policy_mgr_debug("active vdev cnt: %d, inactive vdev cnt: %d",
8851 			 active_vdev_cnt, inactive_vdev_cnt);
8852 
8853 	if (active_vdev_cnt &&
8854 	    policy_mgr_is_emlsr_sta_concurrency_present(psoc)) {
8855 		policy_mgr_debug("Concurrency exists, cannot enter EMLSR mode");
8856 		goto ref_release;
8857 	}
8858 
8859 	/*
8860 	 * If there are both active and inactive vdev count, then issue a
8861 	 * single WMI with force mode MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE,
8862 	 * else if there is only active vdev count, send single WMI for
8863 	 * all active vdevs with force mode MLO_LINK_FORCE_MODE_ACTIVE.
8864 	 */
8865 	if (active_vdev_cnt && inactive_vdev_cnt)
8866 		policy_mgr_mlo_sta_set_link_ext(
8867 					psoc, MLO_LINK_FORCE_REASON_CONNECT,
8868 					MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE,
8869 					active_vdev_cnt, active_vdev_lst,
8870 					inactive_vdev_cnt, inactive_vdev_lst);
8871 	else if (active_vdev_cnt && !inactive_vdev_cnt)
8872 		policy_mgr_mlo_sta_set_link(psoc,
8873 					    MLO_LINK_FORCE_REASON_DISCONNECT,
8874 					    MLO_LINK_FORCE_MODE_ACTIVE,
8875 					    active_vdev_cnt, active_vdev_lst);
8876 	if (active_link_bitmap)
8877 		ml_nlink_vendor_command_set_link(
8878 			psoc, session_id,
8879 			LINK_CONTROL_MODE_USER,
8880 			MLO_LINK_FORCE_REASON_CONNECT,
8881 			MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE,
8882 			0, active_link_bitmap,
8883 			inactive_link_bitmap);
8884 
8885 ref_release:
8886 	for (idx = 0; idx < ml_vdev_cnt; idx++)
8887 		mlo_release_vdev_ref(tmp_vdev_lst[idx]);
8888 done:
8889 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
8890 }
8891 
8892 QDF_STATUS
policy_mgr_update_mlo_links_based_on_linkid(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint8_t num_links,uint8_t * link_id_list,uint32_t * config_state_list)8893 policy_mgr_update_mlo_links_based_on_linkid(struct wlan_objmgr_psoc *psoc,
8894 					    uint8_t vdev_id,
8895 					    uint8_t num_links,
8896 					    uint8_t *link_id_list,
8897 					    uint32_t *config_state_list)
8898 {
8899 	uint8_t idx, link, active_vdev_cnt = 0, inactive_vdev_cnt = 0;
8900 	uint16_t ml_vdev_cnt = 0;
8901 	struct wlan_objmgr_vdev *vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {0};
8902 	uint8_t active_vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {0};
8903 	uint8_t inactive_vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {0};
8904 	struct wlan_objmgr_vdev *vdev;
8905 	uint8_t link_id, num_links_to_disable = 0, num_matched_linkid = 0;
8906 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
8907 	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0, num_non_ml = 0;
8908 	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
8909 	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
8910 	struct policy_mgr_psoc_priv_obj *pm_ctx;
8911 	uint32_t active_link_bitmap = 0;
8912 	uint32_t inactive_link_bitmap = 0;
8913 	bool update_vendor_cmd = false;
8914 
8915 	for (idx = 0; idx < num_links; idx++) {
8916 		if (config_state_list[idx] == 0)
8917 			num_links_to_disable++;
8918 	}
8919 
8920 	if (num_links_to_disable == num_links) {
8921 		policy_mgr_debug("vdev: %d num_links_to_disable: %d", vdev_id,
8922 				 num_links_to_disable);
8923 		return QDF_STATUS_E_FAILURE;
8924 	}
8925 
8926 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
8927 						    WLAN_POLICY_MGR_ID);
8928 	if (!vdev) {
8929 		policy_mgr_err("vdev: %d vdev not found", vdev_id);
8930 		return QDF_STATUS_E_FAILURE;
8931 	}
8932 
8933 	if (!wlan_cm_is_vdev_connected(vdev)) {
8934 		policy_mgr_err("vdev: %d is not in connected state", vdev_id);
8935 		goto release_vdev_ref;
8936 	}
8937 
8938 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
8939 		policy_mgr_err("vdev:%d is not mlo vdev", vdev_id);
8940 		goto release_vdev_ref;
8941 	}
8942 
8943 	pm_ctx = policy_mgr_get_context(psoc);
8944 	if (!pm_ctx) {
8945 		policy_mgr_err("Invalid pm context");
8946 		goto release_vdev_ref;
8947 	}
8948 
8949 	mlo_get_ml_vdev_list(vdev, &ml_vdev_cnt, vdev_lst);
8950 	for (idx = 0; idx < ml_vdev_cnt; idx++) {
8951 		link_id = wlan_vdev_get_link_id(vdev_lst[idx]);
8952 		for (link = 0; link < num_links; link++) {
8953 			if (link_id_list[link] == link_id) {
8954 				num_matched_linkid++;
8955 				policy_mgr_debug("link id:%d match", link_id);
8956 				if (config_state_list[link]) {
8957 					active_vdev_lst[active_vdev_cnt] =
8958 						wlan_vdev_get_id(vdev_lst[idx]);
8959 					active_link_bitmap |= 1 << link_id;
8960 					active_vdev_cnt++;
8961 				} else {
8962 					inactive_vdev_lst[inactive_vdev_cnt] =
8963 						wlan_vdev_get_id(vdev_lst[idx]);
8964 					inactive_link_bitmap |= 1 << link_id;
8965 					inactive_vdev_cnt++;
8966 				}
8967 			}
8968 		}
8969 	}
8970 
8971 	policy_mgr_debug("vdev: %d, active links: %d, ml count: %d, active count: %d, inactive count: %d",
8972 			 vdev_id, num_links, ml_vdev_cnt, active_vdev_cnt,
8973 			 inactive_vdev_cnt);
8974 
8975 	if (num_links != num_matched_linkid) {
8976 		policy_mgr_debug("invalid link id(s), num_matched_linkid: %d",
8977 				 num_matched_linkid);
8978 		goto release_ml_vdev_ref;
8979 	}
8980 
8981 	if (active_vdev_cnt &&
8982 	    policy_mgr_is_emlsr_sta_concurrency_present(psoc)) {
8983 		policy_mgr_debug("vdev: %d emlsr sta conn present", vdev_id);
8984 		if (active_vdev_cnt == 1)
8985 			status = QDF_STATUS_SUCCESS;
8986 		goto release_ml_vdev_ref;
8987 	}
8988 
8989 	policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta,
8990 				   ml_sta_vdev_lst, ml_freq_lst, &num_non_ml,
8991 				   NULL, NULL);
8992 	policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_non_ml: %d",
8993 			 vdev_id, num_ml_sta, num_disabled_ml_sta, num_non_ml);
8994 
8995 	/*
8996 	 * No ML STA is present or sinle link ML is present or
8997 	 * more no.of links are active than supported concurrent connections
8998 	 */
8999 	if (!num_ml_sta || num_ml_sta < 2 ||
9000 	    num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS)
9001 		goto release_ml_vdev_ref;
9002 
9003 	if (!num_disabled_ml_sta) {
9004 		/*
9005 		 * both link are already enabled and received set link req to
9006 		 * enable both again
9007 		 */
9008 		if (active_vdev_cnt && !inactive_vdev_cnt) {
9009 			status = QDF_STATUS_SUCCESS;
9010 			goto release_ml_vdev_ref;
9011 		}
9012 
9013 		/*
9014 		 * both link are already enabled and received set link req
9015 		 * disable one link, disable any
9016 		 */
9017 		if (active_vdev_cnt && inactive_vdev_cnt) {
9018 			status = policy_mgr_mlo_sta_set_link_ext(psoc,
9019 					MLO_LINK_FORCE_REASON_CONNECT,
9020 					MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE,
9021 					active_vdev_cnt, active_vdev_lst,
9022 					inactive_vdev_cnt, inactive_vdev_lst);
9023 			if (status == QDF_STATUS_E_PENDING ||
9024 			    status == QDF_STATUS_SUCCESS)
9025 				update_vendor_cmd = true;
9026 
9027 			goto release_ml_vdev_ref;
9028 		}
9029 	} else {
9030 		/*
9031 		 * one link is enable and one link is disabled, If disabled
9032 		 * link can not be allowed to enable then send status failure
9033 		 * to upper layer.
9034 		 */
9035 		if (active_vdev_cnt &&
9036 		    !policy_mgr_sta_ml_link_enable_allowed(psoc,
9037 							   num_disabled_ml_sta,
9038 							   num_ml_sta,
9039 							   ml_freq_lst,
9040 							   ml_sta_vdev_lst)) {
9041 			policy_mgr_debug("vdev %d: link enable not allowed",
9042 					 vdev_id);
9043 			goto release_ml_vdev_ref;
9044 		}
9045 
9046 		/*
9047 		 * If there are both active and inactive vdev count, then
9048 		 * issue a single WMI with force mode
9049 		 * MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE, else if there is only
9050 		 * active vdev count, send single WMI for all active vdevs
9051 		 * with force mode MLO_LINK_FORCE_MODE_ACTIVE.
9052 		 */
9053 		if (active_vdev_cnt && inactive_vdev_cnt) {
9054 			status = policy_mgr_mlo_sta_set_link_ext(psoc,
9055 					MLO_LINK_FORCE_REASON_CONNECT,
9056 					MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE,
9057 					active_vdev_cnt, active_vdev_lst,
9058 					inactive_vdev_cnt, inactive_vdev_lst);
9059 			if (status == QDF_STATUS_E_PENDING ||
9060 			    status == QDF_STATUS_SUCCESS)
9061 				update_vendor_cmd = true;
9062 		} else if (active_vdev_cnt && !inactive_vdev_cnt) {
9063 			status = policy_mgr_mlo_sta_set_link(psoc,
9064 					MLO_LINK_FORCE_REASON_DISCONNECT,
9065 					MLO_LINK_FORCE_MODE_ACTIVE,
9066 					active_vdev_cnt, active_vdev_lst);
9067 			if (status == QDF_STATUS_E_PENDING ||
9068 			    status == QDF_STATUS_SUCCESS)
9069 				update_vendor_cmd = true;
9070 		}
9071 	}
9072 	if (update_vendor_cmd)
9073 		ml_nlink_vendor_command_set_link(
9074 			psoc, vdev_id,
9075 			LINK_CONTROL_MODE_USER,
9076 			MLO_LINK_FORCE_REASON_CONNECT,
9077 			MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE,
9078 			0, active_link_bitmap,
9079 			inactive_link_bitmap);
9080 
9081 release_ml_vdev_ref:
9082 	for (idx = 0; idx < ml_vdev_cnt; idx++)
9083 		mlo_release_vdev_ref(vdev_lst[idx]);
9084 release_vdev_ref:
9085 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
9086 
9087 	return status;
9088 }
9089 
9090 /**
9091  * policy_mgr_process_mlo_sta_dynamic_force_num_link() - Set links for MLO STA
9092  * @psoc: psoc object
9093  * @reason: Reason for which link is forced
9094  * @mode: Force reason
9095  * @num_mlo_vdev: number of mlo vdev
9096  * @mlo_vdev_lst: MLO STA vdev list
9097  * @force_active_cnt: number of MLO links to operate in active state as per
9098  * user req
9099  *
9100  * User space provides the desired number of MLO links to operate in active
9101  * state at any given time. Host validate request as per current concurrency
9102  * and send SET LINK requests to FW. FW will choose which MLO links should
9103  * operate in the active state.
9104  *
9105  * Return: QDF_STATUS
9106  */
9107 static QDF_STATUS
policy_mgr_process_mlo_sta_dynamic_force_num_link(struct wlan_objmgr_psoc * psoc,enum mlo_link_force_reason reason,enum mlo_link_force_mode mode,uint8_t num_mlo_vdev,uint8_t * mlo_vdev_lst,uint8_t force_active_cnt)9108 policy_mgr_process_mlo_sta_dynamic_force_num_link(struct wlan_objmgr_psoc *psoc,
9109 				enum mlo_link_force_reason reason,
9110 				enum mlo_link_force_mode mode,
9111 				uint8_t num_mlo_vdev, uint8_t *mlo_vdev_lst,
9112 				uint8_t force_active_cnt)
9113 {
9114 	struct mlo_link_set_active_req *req;
9115 	QDF_STATUS status;
9116 	struct policy_mgr_psoc_priv_obj *pm_ctx;
9117 	struct wlan_objmgr_vdev *vdev;
9118 
9119 	if (!num_mlo_vdev) {
9120 		policy_mgr_err("invalid 0 num_mlo_vdev");
9121 		return QDF_STATUS_E_INVAL;
9122 	}
9123 
9124 	pm_ctx = policy_mgr_get_context(psoc);
9125 	if (!pm_ctx) {
9126 		policy_mgr_err("Invalid Context");
9127 		return QDF_STATUS_E_INVAL;
9128 	}
9129 
9130 	req = qdf_mem_malloc(sizeof(*req));
9131 	if (!req)
9132 		return QDF_STATUS_E_NOMEM;
9133 
9134 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, mlo_vdev_lst[0],
9135 						    WLAN_POLICY_MGR_ID);
9136 	if (!vdev) {
9137 		policy_mgr_err("vdev %d: invalid vdev", mlo_vdev_lst[0]);
9138 		qdf_mem_free(req);
9139 		return QDF_STATUS_E_FAILURE;
9140 	}
9141 
9142 	policy_mgr_debug("vdev %d: mode %d num_mlo_vdev %d reason %d",
9143 			 wlan_vdev_get_id(vdev), mode, num_mlo_vdev, reason);
9144 
9145 	/*
9146 	 * TODO: this API has to be merged with policy_mgr_mlo_sta_set_link_ext
9147 	 * as part of 3 link FR change as in caller only we have to decide how
9148 	 * many links to disable/enable for MLO_LINK_FORCE_MODE_ACTIVE_NUM or
9149 	 * MLO_LINK_FORCE_MODE_INACTIVE_NUM scenario
9150 	 */
9151 	req->ctx.vdev = vdev;
9152 	req->param.reason = reason;
9153 	req->param.force_mode = mode;
9154 	req->ctx.set_mlo_link_cb = policy_mgr_handle_link_enable_disable_resp;
9155 	req->ctx.validate_set_mlo_link_cb =
9156 		policy_mgr_validate_set_mlo_link_cb;
9157 	req->ctx.cb_arg = req;
9158 
9159 	/* set MLO vdev bit mask */
9160 	policy_mgr_fill_ml_active_link_vdev_bitmap(req, mlo_vdev_lst,
9161 						   num_mlo_vdev);
9162 
9163 	pm_ctx->active_vdev_bitmap = req->param.vdev_bitmap[0];
9164 	pm_ctx->inactive_vdev_bitmap = req->param.vdev_bitmap[1];
9165 
9166 	req->param.num_link_entry = 1;
9167 	req->param.link_num[0].num_of_link = force_active_cnt;
9168 	req->param.control_flags.dynamic_force_link_num = 1;
9169 
9170 	if (ml_is_nlink_service_supported(psoc)) {
9171 		status =
9172 		policy_mgr_mlo_sta_set_link_by_linkid(psoc, vdev, reason,
9173 						      mode,
9174 						      req->param.link_num[0].
9175 						      num_of_link,
9176 						      num_mlo_vdev,
9177 						      mlo_vdev_lst,
9178 						      0,
9179 						      NULL);
9180 		qdf_mem_free(req);
9181 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
9182 
9183 		if (status != QDF_STATUS_E_PENDING) {
9184 			policy_mgr_err("set_link_by_linkid status %d", status);
9185 			return status;
9186 		}
9187 		return QDF_STATUS_SUCCESS;
9188 	}
9189 
9190 	policy_mgr_set_link_in_progress(pm_ctx, true);
9191 
9192 	status = mlo_ser_set_link_req(req);
9193 	if (QDF_IS_STATUS_ERROR(status)) {
9194 		policy_mgr_err("vdev %d: Failed to set link mode %d num_mlo_vdev %d force_active_cnt: %d, reason %d",
9195 			       wlan_vdev_get_id(vdev), mode, num_mlo_vdev,
9196 			       force_active_cnt,
9197 			       reason);
9198 		qdf_mem_free(req);
9199 		policy_mgr_set_link_in_progress(pm_ctx, false);
9200 	}
9201 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
9202 	return status;
9203 }
9204 
policy_mgr_update_active_mlo_num_links(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint8_t force_active_cnt)9205 QDF_STATUS policy_mgr_update_active_mlo_num_links(struct wlan_objmgr_psoc *psoc,
9206 						  uint8_t vdev_id,
9207 						  uint8_t force_active_cnt)
9208 {
9209 	struct wlan_objmgr_vdev *vdev, *tmp_vdev;
9210 	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0, num_non_ml = 0;
9211 	uint8_t num_enabled_ml_sta = 0, conn_count;
9212 	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
9213 	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
9214 	struct policy_mgr_psoc_priv_obj *pm_ctx;
9215 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
9216 	uint16_t link_bitmap = 0;
9217 	uint8_t i;
9218 
9219 	if (policy_mgr_is_emlsr_sta_concurrency_present(psoc)) {
9220 		policy_mgr_debug("Concurrency exists, cannot enter EMLSR mode");
9221 		return QDF_STATUS_E_FAILURE;
9222 	}
9223 
9224 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
9225 						    WLAN_POLICY_MGR_ID);
9226 	if (!vdev) {
9227 		policy_mgr_err("vdev_id: %d vdev not found", vdev_id);
9228 		return QDF_STATUS_E_FAILURE;
9229 	}
9230 
9231 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
9232 		goto release_vdev_ref;
9233 
9234 	if (!wlan_cm_is_vdev_connected(vdev)) {
9235 		policy_mgr_err("vdev is not in connected state");
9236 		goto release_vdev_ref;
9237 	}
9238 
9239 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
9240 		policy_mgr_err("vdev is not mlo vdev");
9241 		goto release_vdev_ref;
9242 	}
9243 
9244 	pm_ctx = policy_mgr_get_context(psoc);
9245 	if (!pm_ctx) {
9246 		policy_mgr_err("Invalid Context");
9247 		goto release_vdev_ref;
9248 	}
9249 
9250 	conn_count = policy_mgr_get_connection_count(psoc);
9251 	policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta,
9252 				   ml_sta_vdev_lst, ml_freq_lst, &num_non_ml,
9253 				   NULL, NULL);
9254 	policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_non_ml: %d conn cout %d",
9255 			 vdev_id, num_ml_sta, num_disabled_ml_sta, num_non_ml,
9256 			 conn_count);
9257 
9258 	/*
9259 	 * No ML STA is present or more no.of links are active than supported
9260 	 * concurrent connections
9261 	 */
9262 	if (!num_ml_sta || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS)
9263 		goto release_vdev_ref;
9264 
9265 	/*
9266 	 * DUT connected with MLO AP, one link is always active, So if
9267 	 * request comes to make one link is active, host sends set link command
9268 	 * with mode MLO_LINK_FORCE_MODE_ACTIVE_NUM, so that FW should restrict
9269 	 * to only one link and avoid switch from MLSR to MLMR.
9270 	 */
9271 	if (force_active_cnt == 1)
9272 		goto set_link;
9273 
9274 	/*
9275 	 * num_disabled_ml_sta == 0, means 2 link is already active,
9276 	 * In this case send set link command with num link 2 and mode
9277 	 * MLO_LINK_FORCE_MODE_ACTIVE_NUM, so that FW should restrict to only
9278 	 * in MLMR mode (2 link should be active).
9279 	 * If current enabled links are < 2, and there are concurrent
9280 	 * connection present, force active 2 links, which may be
9281 	 * conflict with concurrent rules, reject it.
9282 	 * If the two enabled links are MCC, don't not force active 2 links.
9283 	 */
9284 	num_enabled_ml_sta = num_ml_sta;
9285 	if (num_ml_sta >= num_disabled_ml_sta)
9286 		num_enabled_ml_sta = num_ml_sta - num_disabled_ml_sta;
9287 
9288 	if (force_active_cnt >= 2) {
9289 		if (num_ml_sta < 2) {
9290 			policy_mgr_debug("num_ml_sta %d < 2, can't force active cnt %d",
9291 					 num_ml_sta,
9292 					 force_active_cnt);
9293 			goto release_vdev_ref;
9294 		}
9295 		if (num_enabled_ml_sta < 2 &&
9296 		    conn_count > num_enabled_ml_sta) {
9297 			policy_mgr_debug("enabled link num %d < 2, concurrent conn present %d",
9298 					 num_enabled_ml_sta,
9299 					 conn_count);
9300 			goto release_vdev_ref;
9301 		}
9302 		if (policy_mgr_is_ml_sta_links_in_mcc(
9303 					psoc, ml_freq_lst,
9304 					ml_sta_vdev_lst,
9305 					NULL, num_ml_sta,
9306 					NULL)) {
9307 			policy_mgr_debug("enabled links are mcc, concurrency disallow");
9308 			goto release_vdev_ref;
9309 		}
9310 	}
9311 	if (force_active_cnt == 2 && num_disabled_ml_sta == 0)
9312 		goto set_link;
9313 
9314 	/* Link can not be allowed to enable then skip checking further */
9315 	if (!policy_mgr_sta_ml_link_enable_allowed(psoc, num_disabled_ml_sta,
9316 						   num_ml_sta, ml_freq_lst,
9317 						   ml_sta_vdev_lst)) {
9318 		policy_mgr_debug("vdev %d: link enable not allowed", vdev_id);
9319 		goto release_vdev_ref;
9320 	}
9321 
9322 set_link:
9323 	/*
9324 	 * TODO: In all scenarios wherever host sends
9325 	 * MLO_LINK_FORCE_MODE_ACTIVE_NUM/MLO_LINK_FORCE_MODE_INACTIVE_NUM to
9326 	 * FW, Host need to send MLO_LINK_FORCE_MODE_NO_FORCE to FW.
9327 	 * So instead of two commands for serialization, take care of this in
9328 	 * single serialization active command.
9329 	 */
9330 
9331 	/*
9332 	 * send MLO_LINK_FORCE_MODE_NO_FORCE to FW to clear user mode setting
9333 	 * configured via QCA_WLAN_VENDOR_ATTR_LINK_STATE_CONTROL_MODE in FW
9334 	 */
9335 	status = policy_mgr_mlo_sta_set_link(psoc,
9336 				    MLO_LINK_FORCE_REASON_CONNECT,
9337 				    MLO_LINK_FORCE_MODE_NO_FORCE,
9338 				    num_ml_sta, ml_sta_vdev_lst);
9339 	if (QDF_IS_STATUS_ERROR(status)) {
9340 		policy_mgr_debug("fail to send no force cmd for num_links:%d",
9341 				 num_ml_sta);
9342 		goto release_vdev_ref;
9343 	} else {
9344 		policy_mgr_debug("clear force mode setting for num_links:%d",
9345 				 num_ml_sta);
9346 	}
9347 
9348 	status = policy_mgr_process_mlo_sta_dynamic_force_num_link(psoc,
9349 					     MLO_LINK_FORCE_REASON_CONNECT,
9350 					     MLO_LINK_FORCE_MODE_ACTIVE_NUM,
9351 					     num_ml_sta, ml_sta_vdev_lst,
9352 					     force_active_cnt);
9353 	if (QDF_IS_STATUS_SUCCESS(status)) {
9354 		policy_mgr_debug("vdev %d: link enable allowed", vdev_id);
9355 		for (i = 0; i < num_ml_sta; i++) {
9356 			if (i >= force_active_cnt)
9357 				break;
9358 			tmp_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
9359 				psoc, ml_sta_vdev_lst[i],
9360 				WLAN_POLICY_MGR_ID);
9361 			if (!tmp_vdev) {
9362 				policy_mgr_err("vdev not found for vdev_id %d ",
9363 					       ml_sta_vdev_lst[i]);
9364 				continue;
9365 			}
9366 
9367 			link_bitmap |= 1 << wlan_vdev_get_link_id(tmp_vdev);
9368 			wlan_objmgr_vdev_release_ref(tmp_vdev,
9369 						     WLAN_POLICY_MGR_ID);
9370 		}
9371 		ml_nlink_vendor_command_set_link(
9372 			psoc, vdev_id,
9373 			LINK_CONTROL_MODE_MIXED,
9374 			MLO_LINK_FORCE_REASON_CONNECT,
9375 			MLO_LINK_FORCE_MODE_ACTIVE_NUM,
9376 			force_active_cnt,
9377 			link_bitmap,
9378 			0);
9379 	}
9380 
9381 release_vdev_ref:
9382 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
9383 	return status;
9384 }
9385 
9386 QDF_STATUS
policy_mgr_clear_ml_links_settings_in_fw(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)9387 policy_mgr_clear_ml_links_settings_in_fw(struct wlan_objmgr_psoc *psoc,
9388 					 uint8_t vdev_id)
9389 {
9390 	struct wlan_objmgr_vdev *vdev;
9391 	uint8_t num_ml_sta = 0, num_disabled_ml_sta = 0, num_non_ml = 0;
9392 	uint8_t ml_sta_vdev_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
9393 	qdf_freq_t ml_freq_lst[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
9394 	struct policy_mgr_psoc_priv_obj *pm_ctx;
9395 	uint8_t num_link_to_no_force = 0, num_active_ml_sta = 0;
9396 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
9397 
9398 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
9399 						    WLAN_POLICY_MGR_ID);
9400 	if (!vdev) {
9401 		policy_mgr_err("vdev: %d vdev not found", vdev_id);
9402 		return QDF_STATUS_E_FAILURE;
9403 	}
9404 
9405 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
9406 		goto release_vdev_ref;
9407 
9408 	if (!wlan_cm_is_vdev_connected(vdev)) {
9409 		policy_mgr_err("vdev: %d is not in connected state", vdev_id);
9410 		goto release_vdev_ref;
9411 	}
9412 
9413 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
9414 		policy_mgr_err("vdev: %d is not mlo vdev", vdev_id);
9415 		goto release_vdev_ref;
9416 	}
9417 
9418 	pm_ctx = policy_mgr_get_context(psoc);
9419 	if (!pm_ctx) {
9420 		policy_mgr_err("vdev: %d Invalid Context", vdev_id);
9421 		goto release_vdev_ref;
9422 	}
9423 	/* Clear all user vendor command setting for switching to "default" */
9424 	ml_nlink_vendor_command_set_link(psoc, vdev_id,
9425 					 LINK_CONTROL_MODE_DEFAULT,
9426 					 0, 0, 0, 0, 0);
9427 
9428 	policy_mgr_get_ml_sta_info(pm_ctx, &num_ml_sta, &num_disabled_ml_sta,
9429 				   ml_sta_vdev_lst, ml_freq_lst, &num_non_ml,
9430 				   NULL, NULL);
9431 	policy_mgr_debug("vdev %d: num_ml_sta %d disabled %d num_non_ml: %d",
9432 			 vdev_id, num_ml_sta, num_disabled_ml_sta, num_non_ml);
9433 
9434 	if (!num_ml_sta || num_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS ||
9435 	    num_disabled_ml_sta > MAX_NUMBER_OF_CONC_CONNECTIONS)
9436 		goto release_vdev_ref;
9437 
9438 	num_active_ml_sta = num_ml_sta;
9439 	if (num_ml_sta >= num_disabled_ml_sta)
9440 		num_active_ml_sta = num_ml_sta - num_disabled_ml_sta;
9441 
9442 	num_link_to_no_force += num_active_ml_sta;
9443 
9444 	/* Link can not be allowed to enable then skip checking further */
9445 	if (policy_mgr_sta_ml_link_enable_allowed(psoc, num_disabled_ml_sta,
9446 						  num_ml_sta, ml_freq_lst,
9447 						  ml_sta_vdev_lst)) {
9448 		num_link_to_no_force += num_disabled_ml_sta;
9449 		policy_mgr_debug("Link enable allowed, total num_links: %d",
9450 				 num_link_to_no_force);
9451 	}
9452 
9453 	if (num_link_to_no_force < 1 ||
9454 	    num_link_to_no_force > MAX_NUMBER_OF_CONC_CONNECTIONS) {
9455 		policy_mgr_debug("vdev %d: invalid num_link_to_no_force: %d",
9456 				 vdev_id, num_link_to_no_force);
9457 		goto release_vdev_ref;
9458 	}
9459 
9460 	/*
9461 	 * send WMI_MLO_LINK_SET_ACTIVE_CMDID to clear user mode setting
9462 	 * configured via QCA_WLAN_VENDOR_ATTR_LINK_STATE_CONTROL_MODE in FW
9463 	 */
9464 	status = policy_mgr_mlo_sta_set_link(psoc,
9465 					MLO_LINK_FORCE_REASON_CONNECT,
9466 					MLO_LINK_FORCE_MODE_NO_FORCE,
9467 					num_link_to_no_force,
9468 					ml_sta_vdev_lst);
9469 	if (QDF_IS_STATUS_ERROR(status))
9470 		goto release_vdev_ref;
9471 	else
9472 		policy_mgr_debug("clear user mode setting for num_links:%d",
9473 				 num_link_to_no_force);
9474 
9475 	/*
9476 	 * send WMI_MLO_LINK_SET_ACTIVE_CMDID with value of
9477 	 * num_link as 0 to clear dynamic mode setting configured
9478 	 * via vendor attr LINK_STATE_MIXED_MODE_ACTIVE_NUM_LINKS in FW
9479 	 */
9480 	status = policy_mgr_process_mlo_sta_dynamic_force_num_link(psoc,
9481 				MLO_LINK_FORCE_REASON_CONNECT,
9482 				MLO_LINK_FORCE_MODE_ACTIVE_NUM,
9483 				num_link_to_no_force, ml_sta_vdev_lst, 0);
9484 	if (QDF_IS_STATUS_SUCCESS(status))
9485 		policy_mgr_debug("clear mixed mode setting for num_links:%d",
9486 				 num_link_to_no_force);
9487 release_vdev_ref:
9488 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
9489 	return status;
9490 }
9491 
9492 #else
9493 static bool
policy_mgr_allow_sta_concurrency(struct wlan_objmgr_psoc * psoc,qdf_freq_t freq,uint32_t ext_flags)9494 policy_mgr_allow_sta_concurrency(struct wlan_objmgr_psoc *psoc,
9495 				 qdf_freq_t freq,
9496 				 uint32_t ext_flags)
9497 {
9498 	uint32_t count;
9499 
9500 	count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
9501 							  NULL);
9502 	if (!count)
9503 		return true;
9504 
9505 	if (count >= 2) {
9506 		policy_mgr_rl_debug("Disallow 3rd STA");
9507 		return false;
9508 	}
9509 
9510 	if (!policy_mgr_allow_multiple_sta_connections(psoc)) {
9511 		policy_mgr_rl_debug("Multiple STA connections is not allowed");
9512 		return false;
9513 	}
9514 
9515 	return true;
9516 }
9517 
9518 static bool
policy_mgr_is_restart_sap_required_with_mlo_sta(struct wlan_objmgr_psoc * psoc,uint8_t sap_vdev_id,qdf_freq_t sap_ch_freq)9519 policy_mgr_is_restart_sap_required_with_mlo_sta(struct wlan_objmgr_psoc *psoc,
9520 						uint8_t sap_vdev_id,
9521 						qdf_freq_t sap_ch_freq)
9522 {
9523 	return false;
9524 }
9525 #endif
9526 
9527 #ifdef WLAN_FEATURE_P2P_P2P_STA
policy_mgr_is_p2p_p2p_conc_supported(struct wlan_objmgr_psoc * psoc)9528 bool policy_mgr_is_p2p_p2p_conc_supported(struct wlan_objmgr_psoc *psoc)
9529 {
9530 	return wlan_mlme_get_p2p_p2p_conc_support(psoc);
9531 }
9532 #endif
9533 
9534 /**
9535  * policy_mgr_is_third_conn_sta_p2p_p2p_valid: This API checks the firmware
9536  * capability and allows STA + P2P + P2P combination. It can be in SCC/MCC/DBS
9537  * @psoc: psoc pointer
9538  * @new_conn_mode: third connection mode
9539  *
9540  * Return: true if support else false
9541  */
policy_mgr_is_third_conn_sta_p2p_p2p_valid(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode new_conn_mode)9542 static bool policy_mgr_is_third_conn_sta_p2p_p2p_valid(
9543 					struct wlan_objmgr_psoc *psoc,
9544 					enum policy_mgr_con_mode new_conn_mode)
9545 {
9546 	int num_sta, num_go, num_cli;
9547 
9548 	num_sta = policy_mgr_mode_specific_connection_count(psoc,
9549 							    PM_STA_MODE,
9550 							    NULL);
9551 
9552 	num_go = policy_mgr_mode_specific_connection_count(psoc,
9553 							   PM_P2P_GO_MODE,
9554 							   NULL);
9555 
9556 	num_cli = policy_mgr_mode_specific_connection_count(psoc,
9557 							    PM_P2P_CLIENT_MODE,
9558 							    NULL);
9559 
9560 	if (num_sta + num_go + num_cli != 2)
9561 		return true;
9562 
9563 	/* If STA + P2P + another STA comes up then return true
9564 	 * as this API is only for two port P2P + single STA combo
9565 	 * checks
9566 	 */
9567 	if (num_sta == 1 && new_conn_mode == PM_STA_MODE)
9568 		return true;
9569 
9570 	if ((((PM_STA_MODE == pm_conc_connection_list[0].mode &&
9571 	       PM_P2P_GO_MODE == pm_conc_connection_list[1].mode) ||
9572 	      (PM_P2P_GO_MODE == pm_conc_connection_list[0].mode &&
9573 	       PM_STA_MODE == pm_conc_connection_list[1].mode))
9574 	      ||
9575 	      (PM_P2P_GO_MODE == pm_conc_connection_list[0].mode &&
9576 	       PM_P2P_GO_MODE == pm_conc_connection_list[1].mode)
9577 	      ||
9578 	      ((PM_STA_MODE == pm_conc_connection_list[0].mode &&
9579 		PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode) ||
9580 	       (PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode &&
9581 		PM_STA_MODE == pm_conc_connection_list[1].mode))
9582 	      ||
9583 	      (PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode &&
9584 	       PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode)
9585 	      ||
9586 	      ((PM_P2P_GO_MODE == pm_conc_connection_list[0].mode &&
9587 		PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode) ||
9588 	       (PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode &&
9589 		PM_P2P_GO_MODE == pm_conc_connection_list[1].mode))) &&
9590 	      num_sta <= 1) {
9591 		if ((new_conn_mode == PM_STA_MODE ||
9592 		     new_conn_mode == PM_P2P_CLIENT_MODE ||
9593 		     new_conn_mode == PM_P2P_GO_MODE) &&
9594 		    !policy_mgr_is_p2p_p2p_conc_supported(psoc))
9595 			return false;
9596 	}
9597 
9598 	return true;
9599 }
9600 
policy_mgr_is_sap_go_allowed_with_ll_sap(struct wlan_objmgr_psoc * psoc,qdf_freq_t freq,enum policy_mgr_con_mode mode)9601 static bool policy_mgr_is_sap_go_allowed_with_ll_sap(
9602 					struct wlan_objmgr_psoc *psoc,
9603 					qdf_freq_t freq,
9604 					enum policy_mgr_con_mode mode)
9605 {
9606 	/**
9607 	 * Scenario: When ll SAP(whose profile is set as gaming or
9608 	 * lossless audio) is present on 5GHz channel and SAP/GO
9609 	 * is trying to come up.
9610 	 * Validate the ch_freq of SAP/GO for both DBS and SBS case
9611 	 */
9612 	if ((mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE) &&
9613 	    !policy_mgr_is_ll_sap_concurrency_valid(psoc, freq, mode))
9614 		return false;
9615 
9616 	return true;
9617 }
9618 
policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint32_t ch_freq,enum hw_mode_bandwidth bw,uint32_t ext_flags,struct policy_mgr_pcl_list * pcl)9619 bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc,
9620 				       enum policy_mgr_con_mode mode,
9621 				       uint32_t ch_freq,
9622 				       enum hw_mode_bandwidth bw,
9623 				       uint32_t ext_flags,
9624 				       struct policy_mgr_pcl_list *pcl)
9625 {
9626 	uint32_t num_connections = 0, count = 0, index = 0, i;
9627 	bool status = false, match = false;
9628 	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
9629 	struct policy_mgr_psoc_priv_obj *pm_ctx;
9630 	bool sta_sap_scc_on_dfs_chan;
9631 	bool go_force_scc;
9632 	enum channel_state chan_state;
9633 	bool is_dfs_ch = false;
9634 	struct ch_params ch_params;
9635 
9636 	pm_ctx = policy_mgr_get_context(psoc);
9637 	if (!pm_ctx) {
9638 		policy_mgr_err("Invalid Context");
9639 		return status;
9640 	}
9641 	/* find the current connection state from pm_conc_connection_list*/
9642 	num_connections = policy_mgr_get_connection_count(psoc);
9643 
9644 	if (num_connections && policy_mgr_is_sub_20_mhz_enabled(psoc)) {
9645 		policy_mgr_rl_debug("dont allow concurrency if Sub 20 MHz is enabled");
9646 		return status;
9647 	}
9648 
9649 	if (policy_mgr_max_concurrent_connections_reached(psoc)) {
9650 		policy_mgr_rl_debug("Reached max concurrent connections: %d",
9651 				    pm_ctx->cfg.max_conc_cxns);
9652 		policy_mgr_validate_conn_info(psoc);
9653 		return status;
9654 	}
9655 
9656 	if (ch_freq) {
9657 		if (wlan_reg_is_5ghz_ch_freq(ch_freq)) {
9658 			qdf_mem_zero(&ch_params, sizeof(ch_params));
9659 			ch_params.ch_width = policy_mgr_get_ch_width(bw);
9660 			chan_state =
9661 			wlan_reg_get_5g_bonded_channel_state_for_pwrmode(
9662 					pm_ctx->pdev, ch_freq,
9663 					&ch_params, REG_CURRENT_PWR_MODE);
9664 			if (chan_state == CHANNEL_STATE_DFS)
9665 				is_dfs_ch = true;
9666 		}
9667 		/* don't allow 3rd home channel on same MAC
9668 		 * also check for single mac target which doesn't
9669 		 * support interbad MCC as well
9670 		 */
9671 		if (!policy_mgr_allow_new_home_channel(psoc, mode, ch_freq,
9672 						       num_connections,
9673 						       is_dfs_ch,
9674 						       ext_flags))
9675 			return status;
9676 
9677 		/*
9678 		 * 1) DFS MCC is not yet supported
9679 		 * 2) If you already have STA connection on 5G channel then
9680 		 *    don't allow any other persona to make connection on DFS
9681 		 *    channel because STA 5G + DFS MCC is not allowed.
9682 		 * 3) If STA is on 2G channel and SAP is coming up on
9683 		 *    DFS channel then allow concurrency but make sure it is
9684 		 *    going to DBS and send PCL to firmware indicating that
9685 		 *    don't allow STA to roam to 5G channels.
9686 		 * 4) On a single MAC device, if a SAP/P2PGO is already on a DFS
9687 		 *    channel, don't allow a 2 channel as it will result
9688 		 *    in MCC which is not allowed.
9689 		 */
9690 		if (!policy_mgr_is_5g_channel_allowed(psoc,
9691 			ch_freq, list, PM_P2P_GO_MODE))
9692 			return status;
9693 		if (!policy_mgr_is_5g_channel_allowed(psoc,
9694 			ch_freq, list, PM_SAP_MODE))
9695 			return status;
9696 		if (!policy_mgr_is_6g_channel_allowed(psoc, mode,
9697 						      ch_freq))
9698 			return status;
9699 
9700 		sta_sap_scc_on_dfs_chan =
9701 			policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
9702 		go_force_scc = policy_mgr_go_scc_enforced(psoc);
9703 		if ((mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE) &&
9704 		    (!sta_sap_scc_on_dfs_chan ||
9705 		     !policy_mgr_is_sta_sap_scc(psoc, ch_freq) ||
9706 		     (!go_force_scc && mode == PM_P2P_GO_MODE))) {
9707 			if (is_dfs_ch)
9708 				match = policy_mgr_disallow_mcc(psoc,
9709 								ch_freq);
9710 		}
9711 		if (true == match) {
9712 			policy_mgr_rl_debug("No MCC, SAP/GO about to come up on DFS channel");
9713 			return status;
9714 		}
9715 		if ((policy_mgr_is_hw_dbs_capable(psoc) != true) &&
9716 		    num_connections) {
9717 			if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) {
9718 				if (policy_mgr_is_sap_p2pgo_on_dfs(psoc)) {
9719 					policy_mgr_rl_debug("MCC not allowed: SAP/P2PGO on DFS");
9720 					return status;
9721 				}
9722 			}
9723 		}
9724 	}
9725 
9726 	if (mode == PM_STA_MODE &&
9727 	    !policy_mgr_allow_sta_concurrency(psoc, ch_freq, ext_flags))
9728 		return status;
9729 
9730 	if (!policy_mgr_allow_sap_go_concurrency(psoc, mode, ch_freq,
9731 						 WLAN_INVALID_VDEV_ID)) {
9732 		policy_mgr_rl_debug("This concurrency combination is not allowed");
9733 		return status;
9734 	}
9735 
9736 	/*
9737 	 * don't allow two P2P GO on same band, if fw doesn't
9738 	 * support p2p +p2p concurrency
9739 	 */
9740 	if (ch_freq && mode == PM_P2P_GO_MODE && num_connections &&
9741 	    !policy_mgr_is_p2p_p2p_conc_supported(psoc)) {
9742 		index = 0;
9743 		count = policy_mgr_mode_specific_connection_count(
9744 				psoc, PM_P2P_GO_MODE, list);
9745 		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
9746 		while (index < count) {
9747 			if (WLAN_REG_IS_SAME_BAND_FREQS(
9748 			    ch_freq,
9749 			    pm_conc_connection_list[list[index]].freq)) {
9750 				policy_mgr_rl_debug("Don't allow P2P GO on same band");
9751 				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
9752 				return status;
9753 			}
9754 			index++;
9755 		}
9756 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
9757 	}
9758 
9759 	if (!policy_mgr_allow_wapi_concurrency(pm_ctx)) {
9760 		policy_mgr_rl_debug("Don't allow new conn when wapi security conn existing");
9761 		return status;
9762 	}
9763 
9764 	/* Allow sta+p2p+p2p only if firmware supports the capability */
9765 	if (!policy_mgr_is_third_conn_sta_p2p_p2p_valid(psoc, mode)) {
9766 		policy_mgr_err("Don't allow third connection as GO or GC or STA with old fw");
9767 		return status;
9768 	}
9769 
9770 	/* Validate ll sap + sap/go concurrency */
9771 	if (!policy_mgr_is_sap_go_allowed_with_ll_sap(psoc, ch_freq, mode)) {
9772 		policy_mgr_err("LL SAP concurrency is not valid");
9773 		return status;
9774 	}
9775 
9776 	/*
9777 	 * Don't allow DFS SAP on non-SCC channels if an ML-STA is already
9778 	 * present. PCL list returns the SCC channels and all channels from
9779 	 * other MAC in case of non-ML/single link STA.
9780 	 */
9781 	if (mode == PM_SAP_MODE && pcl &&
9782 	    wlan_reg_is_dfs_for_freq(pm_ctx->pdev, ch_freq)) {
9783 		for (i = 0; i < pcl->pcl_len; i++)
9784 			if (pcl->pcl_list[i] == ch_freq) {
9785 				status = true;
9786 				break;
9787 			}
9788 		if (!status) {
9789 			policy_mgr_err("SAP channel %d Not present in PCL",
9790 				       ch_freq);
9791 			return status;
9792 		}
9793 	}
9794 	status = true;
9795 
9796 	return status;
9797 }
9798 
policy_mgr_allow_concurrency(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint32_t ch_freq,enum hw_mode_bandwidth bw,uint32_t ext_flags,uint8_t vdev_id)9799 bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc,
9800 				  enum policy_mgr_con_mode mode,
9801 				  uint32_t ch_freq,
9802 				  enum hw_mode_bandwidth bw,
9803 				  uint32_t ext_flags, uint8_t vdev_id)
9804 {
9805 	QDF_STATUS status;
9806 	struct policy_mgr_pcl_list pcl;
9807 	bool allowed;
9808 
9809 	qdf_mem_zero(&pcl, sizeof(pcl));
9810 	status = policy_mgr_get_pcl(psoc, mode, pcl.pcl_list, &pcl.pcl_len,
9811 				    pcl.weight_list,
9812 				    QDF_ARRAY_SIZE(pcl.weight_list), vdev_id);
9813 	if (QDF_IS_STATUS_ERROR(status)) {
9814 		policy_mgr_err("disallow connection:%d", status);
9815 		return false;
9816 	}
9817 
9818 	allowed = policy_mgr_is_concurrency_allowed(psoc, mode, ch_freq,
9819 						    bw, ext_flags, &pcl);
9820 
9821 	/* Fourth connection concurrency check */
9822 	if (allowed && policy_mgr_get_connection_count(psoc) == 3)
9823 		allowed = policy_mgr_is_concurrency_allowed_4_port(
9824 				psoc,
9825 				mode,
9826 				ch_freq,
9827 				pcl);
9828 	return allowed;
9829 }
9830 
9831 bool
policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint32_t ch_freq,enum hw_mode_bandwidth bw,uint32_t vdev_id,bool forced,enum sap_csa_reason_code reason)9832 policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc,
9833 				 enum policy_mgr_con_mode mode,
9834 				 uint32_t ch_freq, enum hw_mode_bandwidth bw,
9835 				 uint32_t vdev_id, bool forced,
9836 				 enum sap_csa_reason_code reason)
9837 {
9838 	bool allow = false;
9839 	struct policy_mgr_conc_connection_info
9840 			info[MAX_NUMBER_OF_CONC_CONNECTIONS];
9841 	uint8_t num_cxn_del = 0;
9842 	struct policy_mgr_psoc_priv_obj *pm_ctx;
9843 	uint32_t old_ch_freq, conc_ext_flags;
9844 	QDF_STATUS status;
9845 	struct wlan_objmgr_vdev *vdev;
9846 
9847 	pm_ctx = policy_mgr_get_context(psoc);
9848 	if (!pm_ctx) {
9849 		policy_mgr_err("Invalid Context");
9850 		return allow;
9851 	}
9852 	policy_mgr_debug("check concurrency_csa vdev:%d ch %d bw %d, forced %d, reason %d",
9853 			 vdev_id, ch_freq, bw, forced, reason);
9854 
9855 	status = policy_mgr_get_chan_by_session_id(psoc, vdev_id,
9856 						   &old_ch_freq);
9857 	if (QDF_IS_STATUS_ERROR(status)) {
9858 		policy_mgr_err("Failed to get channel for vdev:%d",
9859 			       vdev_id);
9860 		return allow;
9861 	}
9862 	qdf_mem_zero(info, sizeof(info));
9863 
9864 	/*
9865 	 * Store the connection's parameter and temporarily delete it
9866 	 * from the concurrency table. This way the allow concurrency
9867 	 * check can be used as though a new connection is coming up,
9868 	 * after check, restore the connection to concurrency table.
9869 	 *
9870 	 * In SAP+SAP SCC case, when LTE unsafe event processing,
9871 	 * we should remove the all SAP conn entry on the same ch before
9872 	 * do the concurrency check. Otherwise the left SAP on old channel
9873 	 * will cause the concurrency check failure because of dual beacon
9874 	 * MCC not supported. for the CSA request reason code,
9875 	 * PM_CSA_REASON_UNSAFE_CHANNEL, we remove all the SAP
9876 	 * entry on old channel before do concurrency check.
9877 	 *
9878 	 * The assumption is both SAP should move to the new channel later for
9879 	 * the reason code.
9880 	 */
9881 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
9882 
9883 	if (forced && (reason == CSA_REASON_UNSAFE_CHANNEL ||
9884 		       reason == CSA_REASON_DCS))
9885 		policy_mgr_store_and_del_conn_info_by_chan_and_mode(
9886 			psoc, old_ch_freq, mode, info, &num_cxn_del);
9887 	else
9888 		policy_mgr_store_and_del_conn_info_by_vdev_id(
9889 			psoc, vdev_id, info, &num_cxn_del);
9890 
9891 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
9892 						    WLAN_POLICY_MGR_ID);
9893 	conc_ext_flags = policy_mgr_get_conc_ext_flags(vdev, false);
9894 	allow = policy_mgr_allow_concurrency(psoc, mode, ch_freq,
9895 					     bw, conc_ext_flags, vdev_id);
9896 	if (vdev)
9897 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
9898 
9899 	/* Restore the connection entry */
9900 	if (num_cxn_del > 0)
9901 		policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del);
9902 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
9903 
9904 	if (!allow)
9905 		policy_mgr_err("CSA concurrency check failed");
9906 
9907 	return allow;
9908 }
9909 
9910 /**
9911  * policy_mgr_get_concurrency_mode() - return concurrency mode
9912  * @psoc: PSOC object information
9913  *
9914  * This routine is used to retrieve concurrency mode
9915  *
9916  * Return: uint32_t value of concurrency mask
9917  */
policy_mgr_get_concurrency_mode(struct wlan_objmgr_psoc * psoc)9918 uint32_t policy_mgr_get_concurrency_mode(struct wlan_objmgr_psoc *psoc)
9919 {
9920 	struct policy_mgr_psoc_priv_obj *pm_ctx;
9921 
9922 	pm_ctx = policy_mgr_get_context(psoc);
9923 	if (!pm_ctx) {
9924 		policy_mgr_err("Invalid context");
9925 		return QDF_STA_MASK;
9926 	}
9927 
9928 	policy_mgr_debug("concurrency_mode: 0x%x",
9929 			 pm_ctx->concurrency_mode);
9930 
9931 	return pm_ctx->concurrency_mode;
9932 }
9933 
policy_mgr_set_user_cfg(struct wlan_objmgr_psoc * psoc,struct policy_mgr_user_cfg * user_cfg)9934 QDF_STATUS policy_mgr_set_user_cfg(struct wlan_objmgr_psoc *psoc,
9935 				struct policy_mgr_user_cfg *user_cfg)
9936 {
9937 
9938 	struct policy_mgr_psoc_priv_obj *pm_ctx;
9939 
9940 	pm_ctx = policy_mgr_get_context(psoc);
9941 	if (!pm_ctx) {
9942 		policy_mgr_err("Invalid context");
9943 		return QDF_STATUS_E_FAILURE;
9944 	}
9945 	if (!user_cfg) {
9946 		policy_mgr_err("Invalid User Config");
9947 		return QDF_STATUS_E_FAILURE;
9948 	}
9949 
9950 	pm_ctx->user_cfg = *user_cfg;
9951 	policy_mgr_debug("dbs_selection_plcy 0x%x",
9952 			 pm_ctx->cfg.dbs_selection_plcy);
9953 	policy_mgr_debug("vdev_priority_list 0x%x",
9954 			 pm_ctx->cfg.vdev_priority_list);
9955 	pm_ctx->cur_conc_system_pref = pm_ctx->cfg.sys_pref;
9956 
9957 	return QDF_STATUS_SUCCESS;
9958 }
9959 
policy_mgr_will_freq_lead_to_mcc(struct wlan_objmgr_psoc * psoc,qdf_freq_t freq)9960 bool policy_mgr_will_freq_lead_to_mcc(struct wlan_objmgr_psoc *psoc,
9961 				      qdf_freq_t freq)
9962 {
9963 	bool is_mcc = false;
9964 	uint32_t conn_index;
9965 	struct policy_mgr_psoc_priv_obj *pm_ctx;
9966 
9967 	pm_ctx = policy_mgr_get_context(psoc);
9968 	if (!pm_ctx) {
9969 		policy_mgr_err("Invalid Context");
9970 		return is_mcc;
9971 	}
9972 
9973 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
9974 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
9975 	     conn_index++) {
9976 		if (pm_conc_connection_list[conn_index].in_use &&
9977 		    policy_mgr_2_freq_always_on_same_mac(psoc, freq,
9978 		     pm_conc_connection_list[conn_index].freq)) {
9979 			is_mcc = true;
9980 			break;
9981 		}
9982 	}
9983 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
9984 
9985 	return is_mcc;
9986 }
9987 
9988 /**
9989  * policy_mgr_is_two_connection_mcc() - Check if MCC scenario
9990  * when there are two connections
9991  * @psoc: PSOC object information
9992  *
9993  * If if MCC scenario when there are two connections
9994  *
9995  * Return: true or false
9996  */
policy_mgr_is_two_connection_mcc(struct wlan_objmgr_psoc * psoc)9997 static bool policy_mgr_is_two_connection_mcc(struct wlan_objmgr_psoc *psoc)
9998 {
9999 	return ((pm_conc_connection_list[0].freq !=
10000 		 pm_conc_connection_list[1].freq) &&
10001 		(policy_mgr_are_2_freq_on_same_mac(psoc,
10002 			pm_conc_connection_list[0].freq,
10003 			pm_conc_connection_list[1].freq)) &&
10004 		(pm_conc_connection_list[0].freq <=
10005 		 WLAN_REG_MAX_24GHZ_CHAN_FREQ) &&
10006 		(pm_conc_connection_list[1].freq <=
10007 		 WLAN_REG_MAX_24GHZ_CHAN_FREQ)) ? true : false;
10008 }
10009 
10010 /**
10011  * policy_mgr_is_three_connection_mcc() - Check if MCC scenario
10012  * when there are three connections
10013  *
10014  * If if MCC scenario when there are three connections
10015  *
10016  * Return: true or false
10017  */
policy_mgr_is_three_connection_mcc(void)10018 static bool policy_mgr_is_three_connection_mcc(void)
10019 {
10020 	return (((pm_conc_connection_list[0].freq !=
10021 		  pm_conc_connection_list[1].freq) ||
10022 		 (pm_conc_connection_list[0].freq !=
10023 		  pm_conc_connection_list[2].freq) ||
10024 		 (pm_conc_connection_list[1].freq !=
10025 		  pm_conc_connection_list[2].freq)) &&
10026 		(pm_conc_connection_list[0].freq <=
10027 		 WLAN_REG_MAX_24GHZ_CHAN_FREQ) &&
10028 		(pm_conc_connection_list[1].freq <=
10029 		 WLAN_REG_MAX_24GHZ_CHAN_FREQ) &&
10030 		(pm_conc_connection_list[2].freq <=
10031 		 WLAN_REG_MAX_24GHZ_CHAN_FREQ)) ? true : false;
10032 }
10033 
policy_mgr_get_conc_vdev_on_same_mac(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id,uint8_t mac_id)10034 uint32_t policy_mgr_get_conc_vdev_on_same_mac(struct wlan_objmgr_psoc *psoc,
10035 					      uint32_t vdev_id, uint8_t mac_id)
10036 {
10037 	uint32_t id = WLAN_INVALID_VDEV_ID;
10038 	uint32_t conn_index;
10039 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10040 
10041 	pm_ctx = policy_mgr_get_context(psoc);
10042 	if (!pm_ctx) {
10043 		policy_mgr_err("Invalid Context");
10044 		return id;
10045 	}
10046 
10047 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
10048 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
10049 	     conn_index++) {
10050 		if ((pm_conc_connection_list[conn_index].in_use) &&
10051 		    (pm_conc_connection_list[conn_index].vdev_id != vdev_id) &&
10052 		    (pm_conc_connection_list[conn_index].mac == mac_id)) {
10053 			id = pm_conc_connection_list[conn_index].vdev_id;
10054 			break;
10055 		}
10056 	}
10057 
10058 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
10059 
10060 	return id;
10061 }
10062 
policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc * psoc)10063 bool policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc)
10064 {
10065 	uint32_t num_connections = 0;
10066 	bool is_24G_mcc = false;
10067 
10068 	num_connections = policy_mgr_get_connection_count(psoc);
10069 
10070 	switch (num_connections) {
10071 	case 1:
10072 		break;
10073 	case 2:
10074 		if (policy_mgr_is_two_connection_mcc(psoc))
10075 			is_24G_mcc = true;
10076 		break;
10077 	case 3:
10078 		if (policy_mgr_is_three_connection_mcc())
10079 			is_24G_mcc = true;
10080 		break;
10081 	default:
10082 		policy_mgr_err("unexpected num_connections value %d",
10083 			num_connections);
10084 		break;
10085 	}
10086 
10087 	return is_24G_mcc;
10088 }
10089 
policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint32_t ch_freq)10090 bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc,
10091 				       uint8_t vdev_id, uint32_t ch_freq)
10092 {
10093 	enum policy_mgr_con_mode mode;
10094 	bool ret;
10095 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10096 	struct wlan_objmgr_vdev *vdev;
10097 	uint32_t conc_ext_flags;
10098 
10099 	pm_ctx = policy_mgr_get_context(psoc);
10100 	if (!pm_ctx) {
10101 		policy_mgr_err("Invalid Context");
10102 		return false;
10103 	}
10104 
10105 	if (pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev) {
10106 		mode = pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev(
10107 			psoc, vdev_id);
10108 		if (PM_MAX_NUM_OF_MODE == mode) {
10109 			policy_mgr_err("Invalid mode");
10110 			return false;
10111 		}
10112 	} else
10113 		return false;
10114 
10115 	if (ch_freq == 0) {
10116 		policy_mgr_err("Invalid channel number 0");
10117 		return false;
10118 	}
10119 
10120 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
10121 						    WLAN_POLICY_MGR_ID);
10122 
10123 	/* Take care of 160MHz and 80+80Mhz later */
10124 	conc_ext_flags = policy_mgr_get_conc_ext_flags(vdev, false);
10125 	ret = policy_mgr_allow_concurrency(psoc, mode, ch_freq, HW_MODE_20_MHZ,
10126 					   conc_ext_flags, vdev_id);
10127 	if (vdev)
10128 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
10129 
10130 	if (false == ret) {
10131 		policy_mgr_err("Connection failed due to conc check fail");
10132 		return 0;
10133 	}
10134 
10135 	return true;
10136 }
10137 
10138 /**
10139  * policy_mgr_change_mcc_go_beacon_interval() - Change MCC beacon interval
10140  * @psoc: PSOC object information
10141  * @vdev_id: vdev id
10142  * @dev_mode: device mode
10143  *
10144  * Updates the beacon parameters of the GO in MCC scenario
10145  *
10146  * Return: Success or Failure depending on the overall function behavior
10147  */
policy_mgr_change_mcc_go_beacon_interval(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,enum QDF_OPMODE dev_mode)10148 QDF_STATUS policy_mgr_change_mcc_go_beacon_interval(
10149 		struct wlan_objmgr_psoc *psoc,
10150 		uint8_t vdev_id, enum QDF_OPMODE dev_mode)
10151 {
10152 	QDF_STATUS status;
10153 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10154 
10155 	pm_ctx = policy_mgr_get_context(psoc);
10156 	if (!pm_ctx) {
10157 		policy_mgr_err("Invalid context");
10158 		return QDF_STATUS_E_FAILURE;
10159 	}
10160 
10161 	policy_mgr_debug("UPDATE Beacon Params");
10162 
10163 	if (QDF_SAP_MODE == dev_mode) {
10164 		if (pm_ctx->sme_cbacks.sme_change_mcc_beacon_interval
10165 		    ) {
10166 			status = pm_ctx->sme_cbacks.
10167 				sme_change_mcc_beacon_interval(vdev_id);
10168 			if (status == QDF_STATUS_E_FAILURE) {
10169 				policy_mgr_err("Failed to update Beacon Params");
10170 				return QDF_STATUS_E_FAILURE;
10171 			}
10172 		} else {
10173 			policy_mgr_err("sme_change_mcc_beacon_interval callback is NULL");
10174 			return QDF_STATUS_E_FAILURE;
10175 		}
10176 	}
10177 
10178 	return QDF_STATUS_SUCCESS;
10179 }
10180 
policy_mgr_get_conn_info(uint32_t * len)10181 struct policy_mgr_conc_connection_info *policy_mgr_get_conn_info(uint32_t *len)
10182 {
10183 	struct policy_mgr_conc_connection_info *conn_ptr =
10184 		&pm_conc_connection_list[0];
10185 	*len = MAX_NUMBER_OF_CONC_CONNECTIONS;
10186 
10187 	return conn_ptr;
10188 }
10189 
10190 enum policy_mgr_con_mode
policy_mgr_qdf_opmode_to_pm_con_mode(struct wlan_objmgr_psoc * psoc,enum QDF_OPMODE device_mode,uint8_t vdev_id)10191 policy_mgr_qdf_opmode_to_pm_con_mode(struct wlan_objmgr_psoc *psoc,
10192 				     enum QDF_OPMODE device_mode,
10193 				     uint8_t vdev_id)
10194 {
10195 	enum policy_mgr_con_mode mode = PM_MAX_NUM_OF_MODE;
10196 
10197 	switch (device_mode) {
10198 	case QDF_STA_MODE:
10199 		mode = PM_STA_MODE;
10200 		break;
10201 	case QDF_P2P_CLIENT_MODE:
10202 		mode = PM_P2P_CLIENT_MODE;
10203 		break;
10204 	case QDF_P2P_GO_MODE:
10205 		mode = PM_P2P_GO_MODE;
10206 		break;
10207 	case QDF_SAP_MODE:
10208 #ifdef WLAN_FEATURE_LL_LT_SAP
10209 		if (policy_mgr_is_vdev_ll_lt_sap(psoc, vdev_id))
10210 			mode = PM_LL_LT_SAP_MODE;
10211 		else
10212 #endif
10213 			mode = PM_SAP_MODE;
10214 		break;
10215 	case QDF_NAN_DISC_MODE:
10216 		mode = PM_NAN_DISC_MODE;
10217 		break;
10218 	case QDF_NDI_MODE:
10219 		mode = PM_NDI_MODE;
10220 		break;
10221 	default:
10222 		policy_mgr_debug("Unsupported mode (%d)",
10223 				 device_mode);
10224 	}
10225 
10226 	return mode;
10227 }
10228 
policy_mgr_get_qdf_mode_from_pm(enum policy_mgr_con_mode device_mode)10229 enum QDF_OPMODE policy_mgr_get_qdf_mode_from_pm(
10230 			enum policy_mgr_con_mode device_mode)
10231 {
10232 	enum QDF_OPMODE mode = QDF_MAX_NO_OF_MODE;
10233 
10234 	switch (device_mode) {
10235 	case PM_STA_MODE:
10236 		mode = QDF_STA_MODE;
10237 		break;
10238 	case PM_SAP_MODE:
10239 	case PM_LL_LT_SAP_MODE:
10240 		mode = QDF_SAP_MODE;
10241 		break;
10242 	case PM_P2P_CLIENT_MODE:
10243 		mode = QDF_P2P_CLIENT_MODE;
10244 		break;
10245 	case PM_P2P_GO_MODE:
10246 		mode = QDF_P2P_GO_MODE;
10247 		break;
10248 	case PM_NAN_DISC_MODE:
10249 		mode = QDF_NAN_DISC_MODE;
10250 		break;
10251 	case PM_NDI_MODE:
10252 		mode = QDF_NDI_MODE;
10253 		break;
10254 	default:
10255 		policy_mgr_debug("Unsupported policy mgr mode (%d)",
10256 				 device_mode);
10257 	}
10258 	return mode;
10259 }
10260 
policy_mgr_mode_specific_num_open_sessions(struct wlan_objmgr_psoc * psoc,enum QDF_OPMODE mode,uint8_t * num_sessions)10261 QDF_STATUS policy_mgr_mode_specific_num_open_sessions(
10262 		struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode,
10263 		uint8_t *num_sessions)
10264 {
10265 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10266 
10267 	pm_ctx = policy_mgr_get_context(psoc);
10268 	if (!pm_ctx) {
10269 		policy_mgr_err("Invalid context");
10270 		return QDF_STATUS_E_FAILURE;
10271 	}
10272 
10273 	*num_sessions = pm_ctx->no_of_open_sessions[mode];
10274 	return QDF_STATUS_SUCCESS;
10275 }
10276 
policy_mgr_mode_specific_num_active_sessions(struct wlan_objmgr_psoc * psoc,enum QDF_OPMODE mode,uint8_t * num_sessions)10277 QDF_STATUS policy_mgr_mode_specific_num_active_sessions(
10278 		struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode,
10279 		uint8_t *num_sessions)
10280 {
10281 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10282 
10283 	pm_ctx = policy_mgr_get_context(psoc);
10284 	if (!pm_ctx) {
10285 		policy_mgr_err("Invalid context");
10286 		return QDF_STATUS_E_FAILURE;
10287 	}
10288 
10289 	*num_sessions = pm_ctx->no_of_active_sessions[mode];
10290 	return QDF_STATUS_SUCCESS;
10291 }
10292 
10293 /**
10294  * policy_mgr_concurrent_open_sessions_running() - Checks for
10295  * concurrent open session
10296  * @psoc: PSOC object information
10297  *
10298  * Checks if more than one open session is running for all the allowed modes
10299  * in the driver
10300  *
10301  * Return: True if more than one open session exists, False otherwise
10302  */
policy_mgr_concurrent_open_sessions_running(struct wlan_objmgr_psoc * psoc)10303 bool policy_mgr_concurrent_open_sessions_running(
10304 	struct wlan_objmgr_psoc *psoc)
10305 {
10306 	uint8_t i = 0;
10307 	uint8_t j = 0;
10308 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10309 
10310 	pm_ctx = policy_mgr_get_context(psoc);
10311 	if (!pm_ctx) {
10312 		policy_mgr_err("Invalid context");
10313 		return false;
10314 	}
10315 
10316 	for (i = 0; i < QDF_MAX_NO_OF_MODE; i++)
10317 		j += pm_ctx->no_of_open_sessions[i];
10318 
10319 	return j > 1;
10320 }
10321 
10322 /**
10323  * policy_mgr_concurrent_beaconing_sessions_running() - Checks
10324  * for concurrent beaconing entities
10325  * @psoc: PSOC object information
10326  *
10327  * Checks if multiple beaconing sessions are running i.e., if SAP or GO
10328  * are beaconing together
10329  *
10330  * Return: True if multiple entities are beaconing together, False otherwise
10331  */
policy_mgr_concurrent_beaconing_sessions_running(struct wlan_objmgr_psoc * psoc)10332 bool policy_mgr_concurrent_beaconing_sessions_running(
10333 	struct wlan_objmgr_psoc *psoc)
10334 {
10335 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10336 
10337 	pm_ctx = policy_mgr_get_context(psoc);
10338 	if (!pm_ctx) {
10339 		policy_mgr_err("Invalid context");
10340 		return false;
10341 	}
10342 
10343 	return (pm_ctx->no_of_open_sessions[QDF_SAP_MODE] +
10344 		pm_ctx->no_of_open_sessions[QDF_P2P_GO_MODE]
10345 		> 1) ? true : false;
10346 }
10347 
10348 
policy_mgr_clear_concurrent_session_count(struct wlan_objmgr_psoc * psoc)10349 void policy_mgr_clear_concurrent_session_count(struct wlan_objmgr_psoc *psoc)
10350 {
10351 	uint8_t i = 0;
10352 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10353 
10354 	pm_ctx = policy_mgr_get_context(psoc);
10355 	if (pm_ctx) {
10356 		for (i = 0; i < QDF_MAX_NO_OF_MODE; i++)
10357 			pm_ctx->no_of_active_sessions[i] = 0;
10358 	}
10359 }
10360 
policy_mgr_is_multiple_active_sta_sessions(struct wlan_objmgr_psoc * psoc)10361 bool policy_mgr_is_multiple_active_sta_sessions(struct wlan_objmgr_psoc *psoc)
10362 {
10363 	return policy_mgr_mode_specific_connection_count(
10364 		psoc, PM_STA_MODE, NULL) > 1;
10365 }
10366 
policy_mgr_is_sta_present_on_dfs_channel(struct wlan_objmgr_psoc * psoc,uint8_t * vdev_id,qdf_freq_t * ch_freq,enum hw_mode_bandwidth * ch_width)10367 bool policy_mgr_is_sta_present_on_dfs_channel(struct wlan_objmgr_psoc *psoc,
10368 					      uint8_t *vdev_id,
10369 					      qdf_freq_t *ch_freq,
10370 					      enum hw_mode_bandwidth *ch_width)
10371 {
10372 	struct policy_mgr_conc_connection_info *conn_info;
10373 	bool status = false;
10374 	uint32_t conn_index = 0;
10375 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10376 
10377 	pm_ctx = policy_mgr_get_context(psoc);
10378 	if (!pm_ctx) {
10379 		policy_mgr_err("Invalid Context");
10380 		return false;
10381 	}
10382 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
10383 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
10384 	     conn_index++) {
10385 		conn_info = &pm_conc_connection_list[conn_index];
10386 		if (conn_info->in_use &&
10387 		    (conn_info->mode == PM_STA_MODE ||
10388 		     conn_info->mode == PM_P2P_CLIENT_MODE) &&
10389 		    (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, conn_info->freq) ||
10390 		     (wlan_reg_is_5ghz_ch_freq(conn_info->freq) &&
10391 		      conn_info->bw == HW_MODE_160_MHZ))) {
10392 			*vdev_id = conn_info->vdev_id;
10393 			*ch_freq = pm_conc_connection_list[conn_index].freq;
10394 			*ch_width = conn_info->bw;
10395 			status = true;
10396 			break;
10397 		}
10398 	}
10399 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
10400 
10401 	return status;
10402 }
10403 
policy_mgr_is_sta_present_on_freq(struct wlan_objmgr_psoc * psoc,uint8_t * vdev_id,qdf_freq_t ch_freq,enum hw_mode_bandwidth * ch_width)10404 bool policy_mgr_is_sta_present_on_freq(struct wlan_objmgr_psoc *psoc,
10405 				       uint8_t *vdev_id,
10406 				       qdf_freq_t ch_freq,
10407 				       enum hw_mode_bandwidth *ch_width)
10408 {
10409 	struct policy_mgr_conc_connection_info *conn_info;
10410 	bool status = false;
10411 	uint32_t conn_index = 0;
10412 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10413 
10414 	pm_ctx = policy_mgr_get_context(psoc);
10415 	if (!pm_ctx) {
10416 		policy_mgr_err("Invalid Context");
10417 		return false;
10418 	}
10419 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
10420 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
10421 	     conn_index++) {
10422 		conn_info = &pm_conc_connection_list[conn_index];
10423 		if (conn_info->in_use &&
10424 		    (conn_info->mode == PM_STA_MODE ||
10425 		     conn_info->mode == PM_P2P_CLIENT_MODE) &&
10426 		    ch_freq == conn_info->freq) {
10427 			*vdev_id = conn_info->vdev_id;
10428 			*ch_width = conn_info->bw;
10429 			status = true;
10430 			break;
10431 		}
10432 	}
10433 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
10434 
10435 	return status;
10436 }
10437 
policy_mgr_is_sta_gc_active_on_mac(struct wlan_objmgr_psoc * psoc,uint8_t mac_id)10438 bool policy_mgr_is_sta_gc_active_on_mac(struct wlan_objmgr_psoc *psoc,
10439 					uint8_t mac_id)
10440 {
10441 	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
10442 	uint32_t index, count;
10443 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10444 
10445 	pm_ctx = policy_mgr_get_context(psoc);
10446 	if (!pm_ctx) {
10447 		policy_mgr_err("Invalid Context");
10448 		return false;
10449 	}
10450 
10451 	count = policy_mgr_mode_specific_connection_count(
10452 		psoc, PM_STA_MODE, list);
10453 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
10454 	for (index = 0; index < count; index++) {
10455 		if (mac_id == pm_conc_connection_list[list[index]].mac) {
10456 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
10457 			return true;
10458 		}
10459 	}
10460 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
10461 
10462 	count = policy_mgr_mode_specific_connection_count(
10463 		psoc, PM_P2P_CLIENT_MODE, list);
10464 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
10465 	for (index = 0; index < count; index++) {
10466 		if (mac_id == pm_conc_connection_list[list[index]].mac) {
10467 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
10468 			return true;
10469 		}
10470 	}
10471 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
10472 
10473 	return false;
10474 }
10475 
10476 /**
10477  * policy_mgr_is_sta_active_connection_exists() - Check if a STA
10478  * connection is active
10479  * @psoc: PSOC object information
10480  *
10481  * Checks if there is atleast one active STA connection in the driver
10482  *
10483  * Return: True if an active STA session is present, False otherwise
10484  */
policy_mgr_is_sta_active_connection_exists(struct wlan_objmgr_psoc * psoc)10485 bool policy_mgr_is_sta_active_connection_exists(
10486 	struct wlan_objmgr_psoc *psoc)
10487 {
10488 	return (!policy_mgr_mode_specific_connection_count(
10489 		psoc, PM_STA_MODE, NULL)) ? false : true;
10490 }
10491 
policy_mgr_is_any_nondfs_chnl_present(struct wlan_objmgr_psoc * psoc,uint32_t * ch_freq)10492 bool policy_mgr_is_any_nondfs_chnl_present(struct wlan_objmgr_psoc *psoc,
10493 					   uint32_t *ch_freq)
10494 {
10495 	bool status = false;
10496 	uint32_t conn_index = 0;
10497 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10498 
10499 	pm_ctx = policy_mgr_get_context(psoc);
10500 	if (!pm_ctx) {
10501 		policy_mgr_err("Invalid Context");
10502 		return false;
10503 	}
10504 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
10505 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
10506 			conn_index++) {
10507 		if (pm_conc_connection_list[conn_index].in_use &&
10508 		    !wlan_reg_is_dfs_for_freq(pm_ctx->pdev,
10509 		    pm_conc_connection_list[conn_index].freq)) {
10510 			*ch_freq = pm_conc_connection_list[conn_index].freq;
10511 			status = true;
10512 		}
10513 	}
10514 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
10515 
10516 	return status;
10517 }
10518 
policy_mgr_get_dfs_beaconing_session_id(struct wlan_objmgr_psoc * psoc)10519 uint32_t policy_mgr_get_dfs_beaconing_session_id(
10520 		struct wlan_objmgr_psoc *psoc)
10521 {
10522 	uint32_t session_id = WLAN_UMAC_VDEV_ID_MAX;
10523 	struct policy_mgr_conc_connection_info *conn_info;
10524 	uint32_t conn_index = 0;
10525 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10526 
10527 	pm_ctx = policy_mgr_get_context(psoc);
10528 	if (!pm_ctx) {
10529 		policy_mgr_err("Invalid Context");
10530 		return session_id;
10531 	}
10532 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
10533 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
10534 	     conn_index++) {
10535 		conn_info = &pm_conc_connection_list[conn_index];
10536 		if (conn_info->in_use &&
10537 		    WLAN_REG_IS_5GHZ_CH_FREQ(conn_info->freq) &&
10538 		    (conn_info->ch_flagext & (IEEE80211_CHAN_DFS |
10539 					      IEEE80211_CHAN_DFS_CFREQ2)) &&
10540 		    (conn_info->mode == PM_SAP_MODE ||
10541 		     conn_info->mode == PM_P2P_GO_MODE)) {
10542 			session_id =
10543 				pm_conc_connection_list[conn_index].vdev_id;
10544 			break;
10545 		}
10546 	}
10547 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
10548 
10549 	return session_id;
10550 }
10551 
policy_mgr_is_any_dfs_beaconing_session_present(struct wlan_objmgr_psoc * psoc,qdf_freq_t * ch_freq,enum hw_mode_bandwidth * ch_width)10552 bool policy_mgr_is_any_dfs_beaconing_session_present(
10553 		struct wlan_objmgr_psoc *psoc, qdf_freq_t *ch_freq,
10554 		enum hw_mode_bandwidth *ch_width)
10555 {
10556 	struct policy_mgr_conc_connection_info *conn_info;
10557 	bool status = false;
10558 	uint32_t conn_index = 0;
10559 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10560 
10561 	pm_ctx = policy_mgr_get_context(psoc);
10562 	if (!pm_ctx) {
10563 		policy_mgr_err("Invalid Context");
10564 		return false;
10565 	}
10566 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
10567 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
10568 			conn_index++) {
10569 		conn_info = &pm_conc_connection_list[conn_index];
10570 		if (conn_info->in_use &&
10571 		    (conn_info->mode == PM_SAP_MODE ||
10572 		     conn_info->mode == PM_P2P_GO_MODE) &&
10573 		     (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, conn_info->freq) ||
10574 		      (wlan_reg_is_5ghz_ch_freq(conn_info->freq) &&
10575 		      conn_info->bw == HW_MODE_160_MHZ))) {
10576 			*ch_freq = pm_conc_connection_list[conn_index].freq;
10577 			*ch_width = conn_info->bw;
10578 			status = true;
10579 		}
10580 	}
10581 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
10582 
10583 	return status;
10584 }
10585 
policy_mgr_scan_trim_5g_chnls_for_dfs_ap(struct wlan_objmgr_psoc * psoc,qdf_freq_t * freq)10586 bool policy_mgr_scan_trim_5g_chnls_for_dfs_ap(struct wlan_objmgr_psoc *psoc,
10587 					      qdf_freq_t *freq)
10588 {
10589 	qdf_freq_t dfs_ch_frq = 0;
10590 	qdf_freq_t dfs_sta_frq = 0;
10591 	uint8_t vdev_id;
10592 	enum hw_mode_bandwidth ch_width;
10593 	enum hw_mode_bandwidth ch_sta_width;
10594 	QDF_STATUS status;
10595 	uint8_t  sta_sap_scc_on_dfs_chnl;
10596 
10597 	policy_mgr_is_any_dfs_beaconing_session_present(psoc, &dfs_ch_frq,
10598 							&ch_width);
10599 	if (!dfs_ch_frq)
10600 		return false;
10601 
10602 	*freq = dfs_ch_frq;
10603 
10604 	status = policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc,
10605 						&sta_sap_scc_on_dfs_chnl);
10606 	if (QDF_IS_STATUS_ERROR(status))
10607 		return false;
10608 
10609 	if (policy_mgr_is_sta_present_on_dfs_channel(psoc, &vdev_id,
10610 						     &dfs_sta_frq,
10611 						     &ch_sta_width) &&
10612 	    !policy_mgr_is_hw_dbs_capable(psoc) &&
10613 	    sta_sap_scc_on_dfs_chnl != PM_STA_SAP_ON_DFS_DEFAULT) {
10614 		policymgr_nofl_err("DFS STA present vdev_id %d ch_feq %d ch_width %d",
10615 				   vdev_id, dfs_sta_frq, ch_sta_width);
10616 		return false;
10617 	}
10618 
10619 	/*
10620 	 * 1) if agile & DFS scans are supported
10621 	 * 2) if hardware is DBS capable
10622 	 * 3) if current hw mode is non-dbs
10623 	 * if all above 3 conditions are true then don't skip any
10624 	 * channel from scan list
10625 	 */
10626 	if (policy_mgr_is_hw_dbs_capable(psoc) &&
10627 	    !policy_mgr_is_current_hwmode_dbs(psoc) &&
10628 	    policy_mgr_get_dbs_plus_agile_scan_config(psoc) &&
10629 	    policy_mgr_get_single_mac_scan_with_dfs_config(psoc))
10630 		return false;
10631 
10632 	policy_mgr_debug("scan skip 5g chan due to dfs ap(ch %d / ch_width %d) present",
10633 			 dfs_ch_frq, ch_width);
10634 
10635 	return true;
10636 }
10637 
10638 static void
policy_mgr_fill_trim_chan(struct wlan_objmgr_pdev * pdev,void * object,void * arg)10639 policy_mgr_fill_trim_chan(struct wlan_objmgr_pdev *pdev,
10640 			  void *object, void *arg)
10641 {
10642 	struct wlan_objmgr_vdev *vdev = object;
10643 	struct trim_chan_info *trim_info = arg;
10644 	uint16_t sap_peer_count = 0;
10645 	qdf_freq_t chan_freq;
10646 
10647 	if (wlan_vdev_mlme_get_opmode(vdev) != QDF_SAP_MODE)
10648 		return;
10649 
10650 	if (wlan_vdev_is_up(vdev) != QDF_STATUS_SUCCESS)
10651 		return;
10652 
10653 	sap_peer_count = wlan_vdev_get_peer_count(vdev);
10654 	policy_mgr_debug("vdev %d - peer count %d",
10655 			 wlan_vdev_get_id(vdev), sap_peer_count);
10656 	if (sap_peer_count <= 1)
10657 		return;
10658 
10659 	chan_freq = wlan_get_operation_chan_freq(vdev);
10660 	if (!chan_freq)
10661 		return;
10662 
10663 	if (WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) {
10664 		trim_info->trim |= TRIM_CHANNEL_LIST_5G;
10665 	} else if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) {
10666 		if (trim_info->sap_count != 1)
10667 			return;
10668 
10669 		if ((trim_info->band_capability & BIT(REG_BAND_5G)) ==
10670 		     BIT(REG_BAND_5G))
10671 			return;
10672 
10673 		trim_info->trim |= TRIM_CHANNEL_LIST_24G;
10674 	}
10675 }
10676 
10677 uint16_t
policy_mgr_scan_trim_chnls_for_connected_ap(struct wlan_objmgr_pdev * pdev)10678 policy_mgr_scan_trim_chnls_for_connected_ap(struct wlan_objmgr_pdev *pdev)
10679 {
10680 	struct trim_chan_info trim_info;
10681 	struct wlan_objmgr_psoc *psoc;
10682 	QDF_STATUS status;
10683 
10684 	psoc = wlan_pdev_get_psoc(pdev);
10685 	if (!psoc)
10686 		return TRIM_CHANNEL_LIST_NONE;
10687 
10688 	status = wlan_mlme_get_band_capability(psoc,
10689 					       &trim_info.band_capability);
10690 	if (QDF_IS_STATUS_ERROR(status)) {
10691 		policy_mgr_err("Could not get band capability");
10692 		return TRIM_CHANNEL_LIST_NONE;
10693 	}
10694 
10695 	trim_info.sap_count = policy_mgr_mode_specific_connection_count(psoc,
10696 							PM_SAP_MODE, NULL);
10697 	if (!trim_info.sap_count)
10698 		return TRIM_CHANNEL_LIST_NONE;
10699 
10700 	trim_info.trim = TRIM_CHANNEL_LIST_NONE;
10701 
10702 	wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
10703 					  policy_mgr_fill_trim_chan, &trim_info,
10704 					  0, WLAN_POLICY_MGR_ID);
10705 	policy_mgr_debug("band_capability %d, sap_count %d, trim %d",
10706 			 trim_info.band_capability, trim_info.sap_count,
10707 			 trim_info.trim);
10708 
10709 	return trim_info.trim;
10710 }
10711 
policy_mgr_get_nss_for_vdev(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint8_t * nss_2g,uint8_t * nss_5g)10712 QDF_STATUS policy_mgr_get_nss_for_vdev(struct wlan_objmgr_psoc *psoc,
10713 				enum policy_mgr_con_mode mode,
10714 				uint8_t *nss_2g, uint8_t *nss_5g)
10715 {
10716 	enum QDF_OPMODE dev_mode;
10717 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10718 
10719 	dev_mode = policy_mgr_get_qdf_mode_from_pm(mode);
10720 	if (dev_mode == QDF_MAX_NO_OF_MODE)
10721 		return  QDF_STATUS_E_FAILURE;
10722 	pm_ctx = policy_mgr_get_context(psoc);
10723 	if (!pm_ctx) {
10724 		policy_mgr_err("Invalid Context");
10725 		return QDF_STATUS_E_FAILURE;
10726 	}
10727 
10728 	if (pm_ctx->sme_cbacks.sme_get_nss_for_vdev) {
10729 		pm_ctx->sme_cbacks.sme_get_nss_for_vdev(
10730 			dev_mode, nss_2g, nss_5g);
10731 
10732 	} else {
10733 		policy_mgr_err("sme_get_nss_for_vdev callback is NULL");
10734 		return QDF_STATUS_E_FAILURE;
10735 	}
10736 
10737 	return QDF_STATUS_SUCCESS;
10738 }
10739 
policy_mgr_dump_connection_status_info(struct wlan_objmgr_psoc * psoc)10740 void policy_mgr_dump_connection_status_info(struct wlan_objmgr_psoc *psoc)
10741 {
10742 	uint32_t i;
10743 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10744 
10745 	pm_ctx = policy_mgr_get_context(psoc);
10746 	if (!pm_ctx) {
10747 		policy_mgr_err("Invalid Context");
10748 		return;
10749 	}
10750 
10751 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
10752 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
10753 		if (!pm_conc_connection_list[i].in_use)
10754 			continue;
10755 		policy_mgr_debug("%d: use:%d vdev:%d mode:%d mac:%d freq:%d orig chainmask:%d orig nss:%d bw:%d, ch_flags %0X",
10756 				 i, pm_conc_connection_list[i].in_use,
10757 				 pm_conc_connection_list[i].vdev_id,
10758 				 pm_conc_connection_list[i].mode,
10759 				 pm_conc_connection_list[i].mac,
10760 				 pm_conc_connection_list[i].freq,
10761 				 pm_conc_connection_list[i].chain_mask,
10762 				 pm_conc_connection_list[i].original_nss,
10763 				 pm_conc_connection_list[i].bw,
10764 				 pm_conc_connection_list[i].ch_flagext);
10765 	}
10766 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
10767 
10768 	policy_mgr_dump_curr_freq_range(pm_ctx);
10769 	policy_mgr_validate_conn_info(psoc);
10770 }
10771 
policy_mgr_is_any_mode_active_on_band_along_with_session(struct wlan_objmgr_psoc * psoc,uint8_t session_id,enum policy_mgr_band band)10772 bool policy_mgr_is_any_mode_active_on_band_along_with_session(
10773 						struct wlan_objmgr_psoc *psoc,
10774 						uint8_t session_id,
10775 						enum policy_mgr_band band)
10776 {
10777 	uint32_t i;
10778 	bool status = false;
10779 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10780 
10781 	pm_ctx = policy_mgr_get_context(psoc);
10782 	if (!pm_ctx) {
10783 		policy_mgr_err("Invalid Context");
10784 		status = false;
10785 		goto send_status;
10786 	}
10787 
10788 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
10789 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
10790 		switch (band) {
10791 		case POLICY_MGR_BAND_24:
10792 			if ((pm_conc_connection_list[i].vdev_id != session_id)
10793 			&& (pm_conc_connection_list[i].in_use) &&
10794 			(WLAN_REG_IS_24GHZ_CH_FREQ(
10795 			pm_conc_connection_list[i].freq))) {
10796 				status = true;
10797 				goto release_mutex_and_send_status;
10798 			}
10799 			break;
10800 		case POLICY_MGR_BAND_5:
10801 			if ((pm_conc_connection_list[i].vdev_id != session_id)
10802 			&& (pm_conc_connection_list[i].in_use) &&
10803 			(WLAN_REG_IS_5GHZ_CH_FREQ(
10804 			pm_conc_connection_list[i].freq))) {
10805 				status = true;
10806 				goto release_mutex_and_send_status;
10807 			}
10808 			break;
10809 		default:
10810 			policy_mgr_err("Invalidband option:%d", band);
10811 			status = false;
10812 			goto release_mutex_and_send_status;
10813 		}
10814 	}
10815 release_mutex_and_send_status:
10816 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
10817 send_status:
10818 	return status;
10819 }
10820 
10821 enum phy_ch_width
policy_mgr_get_bw_by_session_id(struct wlan_objmgr_psoc * psoc,uint8_t session_id)10822 policy_mgr_get_bw_by_session_id(struct wlan_objmgr_psoc *psoc,
10823 				uint8_t session_id)
10824 {
10825 	uint32_t i;
10826 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10827 	enum hw_mode_bandwidth bw = HW_MODE_BW_NONE;
10828 
10829 	pm_ctx = policy_mgr_get_context(psoc);
10830 	if (!pm_ctx) {
10831 		policy_mgr_err("Invalid Context");
10832 		return CH_WIDTH_INVALID;
10833 	}
10834 
10835 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
10836 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
10837 		if (pm_conc_connection_list[i].vdev_id == session_id &&
10838 		    pm_conc_connection_list[i].in_use) {
10839 			bw = pm_conc_connection_list[i].bw;
10840 			break;
10841 		}
10842 	}
10843 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
10844 	return policy_mgr_get_ch_width(bw);
10845 }
10846 
policy_mgr_get_chan_by_session_id(struct wlan_objmgr_psoc * psoc,uint8_t session_id,uint32_t * ch_freq)10847 QDF_STATUS policy_mgr_get_chan_by_session_id(struct wlan_objmgr_psoc *psoc,
10848 					     uint8_t session_id,
10849 					     uint32_t *ch_freq)
10850 {
10851 	uint32_t i;
10852 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10853 
10854 	pm_ctx = policy_mgr_get_context(psoc);
10855 	if (!pm_ctx) {
10856 		policy_mgr_err("Invalid Context");
10857 		return QDF_STATUS_E_FAILURE;
10858 	}
10859 
10860 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
10861 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
10862 		if ((pm_conc_connection_list[i].vdev_id == session_id) &&
10863 		    (pm_conc_connection_list[i].in_use)) {
10864 			*ch_freq = pm_conc_connection_list[i].freq;
10865 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
10866 			return QDF_STATUS_SUCCESS;
10867 		}
10868 	}
10869 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
10870 
10871 	return QDF_STATUS_E_FAILURE;
10872 }
10873 
policy_mgr_get_mac_id_by_session_id(struct wlan_objmgr_psoc * psoc,uint8_t session_id,uint8_t * mac_id)10874 QDF_STATUS policy_mgr_get_mac_id_by_session_id(struct wlan_objmgr_psoc *psoc,
10875 					       uint8_t session_id,
10876 					       uint8_t *mac_id)
10877 {
10878 	uint32_t i;
10879 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10880 
10881 	pm_ctx = policy_mgr_get_context(psoc);
10882 	if (!pm_ctx) {
10883 		policy_mgr_err("Invalid Context");
10884 		return QDF_STATUS_E_FAILURE;
10885 	}
10886 
10887 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
10888 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
10889 		if ((pm_conc_connection_list[i].vdev_id == session_id) &&
10890 		    (pm_conc_connection_list[i].in_use)) {
10891 			*mac_id = pm_conc_connection_list[i].mac;
10892 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
10893 			return QDF_STATUS_SUCCESS;
10894 		}
10895 	}
10896 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
10897 
10898 	return QDF_STATUS_E_FAILURE;
10899 }
10900 
policy_mgr_get_sap_go_count_on_mac(struct wlan_objmgr_psoc * psoc,uint32_t * list,uint8_t mac_id)10901 uint32_t policy_mgr_get_sap_go_count_on_mac(struct wlan_objmgr_psoc *psoc,
10902 					    uint32_t *list, uint8_t mac_id)
10903 {
10904 	uint32_t conn_index;
10905 	uint32_t count = 0;
10906 	struct policy_mgr_psoc_priv_obj *pm_ctx;
10907 
10908 	pm_ctx = policy_mgr_get_context(psoc);
10909 	if (!pm_ctx) {
10910 		policy_mgr_err("Invalid Context");
10911 		return count;
10912 	}
10913 
10914 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
10915 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
10916 	     conn_index++) {
10917 		if (pm_conc_connection_list[conn_index].mac == mac_id &&
10918 		    pm_conc_connection_list[conn_index].in_use &&
10919 		    policy_mgr_is_beaconing_mode(
10920 				pm_conc_connection_list[conn_index].mode)) {
10921 			if (list)
10922 				list[count] =
10923 				    pm_conc_connection_list[conn_index].vdev_id;
10924 			count++;
10925 		}
10926 	}
10927 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
10928 
10929 	return count;
10930 }
10931 
policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)10932 uint32_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc,
10933 					      uint8_t vdev_id)
10934 {
10935 	uint8_t mcc_vdev_id;
10936 	QDF_STATUS status;
10937 	uint32_t ch_freq;
10938 
10939 	if (!policy_mgr_is_mcc_with_this_vdev_id(psoc, vdev_id, &mcc_vdev_id)) {
10940 		policy_mgr_debug("No concurrent MCC vdev for id:%d", vdev_id);
10941 		return INVALID_CHANNEL_ID;
10942 	}
10943 
10944 	status = policy_mgr_get_chan_by_session_id(psoc, mcc_vdev_id, &ch_freq);
10945 	if (QDF_IS_STATUS_ERROR(status)) {
10946 		policy_mgr_err("Failed to get channel for MCC vdev:%d",
10947 			       mcc_vdev_id);
10948 		return INVALID_CHANNEL_ID;
10949 	}
10950 
10951 	return ch_freq;
10952 }
10953 
policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev * vdev)10954 bool policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev *vdev)
10955 {
10956 	bool roffchan;
10957 
10958 	if (!vdev) {
10959 		policy_mgr_err("Invalid parameter");
10960 		return false;
10961 	}
10962 
10963 	roffchan = wlan_vdev_mlme_cap_get(vdev, WLAN_VDEV_C_RESTRICT_OFFCHAN);
10964 
10965 	if (roffchan)
10966 		policy_mgr_debug("Restrict offchannel is set");
10967 
10968 	return roffchan;
10969 }
10970 
policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc * psoc,uint32_t ch_freq,bool * ok)10971 QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc,
10972 					  uint32_t ch_freq, bool *ok)
10973 {
10974 	uint32_t cc_count = 0, i;
10975 	uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
10976 	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS];
10977 	struct wlan_objmgr_vdev *vdev;
10978 
10979 	if (!ok) {
10980 		policy_mgr_err("Invalid parameter");
10981 		return QDF_STATUS_E_INVAL;
10982 	}
10983 
10984 	cc_count = policy_mgr_get_sap_mode_info(psoc,
10985 						&op_ch_freq_list[cc_count],
10986 						&vdev_id[cc_count]);
10987 
10988 	if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS)
10989 		cc_count = cc_count +
10990 			   policy_mgr_get_mode_specific_conn_info(
10991 					psoc, &op_ch_freq_list[cc_count],
10992 					&vdev_id[cc_count], PM_P2P_GO_MODE);
10993 
10994 	if (!cc_count) {
10995 		*ok = true;
10996 		return QDF_STATUS_SUCCESS;
10997 	}
10998 
10999 	if (!ch_freq) {
11000 		policy_mgr_err("channel is 0, cc count %d", cc_count);
11001 		return QDF_STATUS_E_INVAL;
11002 	}
11003 
11004 	if (cc_count <= MAX_NUMBER_OF_CONC_CONNECTIONS) {
11005 		for (i = 0; i < cc_count; i++) {
11006 			vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
11007 					psoc, vdev_id[i], WLAN_POLICY_MGR_ID);
11008 			if (!vdev) {
11009 				policy_mgr_err("vdev for vdev_id:%d is NULL",
11010 					       vdev_id[i]);
11011 				return QDF_STATUS_E_INVAL;
11012 			}
11013 
11014 			/**
11015 			 * If channel passed is same as AP/GO operating
11016 			 * channel, return true.
11017 			 *
11018 			 * If channel is different from operating channel but
11019 			 * in same band, return false.
11020 			 *
11021 			 * If operating channel in different band
11022 			 * (DBS capable), return true.
11023 			 *
11024 			 * If operating channel in different band
11025 			 * (not DBS capable), return false.
11026 			 */
11027 			if (policy_mgr_is_dnsc_set(vdev)) {
11028 				if (op_ch_freq_list[i] == ch_freq) {
11029 					*ok = true;
11030 					wlan_objmgr_vdev_release_ref(
11031 							vdev,
11032 							WLAN_POLICY_MGR_ID);
11033 					break;
11034 				} else if (policy_mgr_2_freq_always_on_same_mac(
11035 					   psoc,
11036 					   op_ch_freq_list[i], ch_freq)) {
11037 					*ok = false;
11038 					wlan_objmgr_vdev_release_ref(
11039 					vdev,
11040 					WLAN_POLICY_MGR_ID);
11041 					break;
11042 				} else if (policy_mgr_is_hw_dbs_capable(psoc)) {
11043 					*ok = true;
11044 					wlan_objmgr_vdev_release_ref(
11045 							vdev,
11046 							WLAN_POLICY_MGR_ID);
11047 					break;
11048 				} else {
11049 					*ok = false;
11050 					wlan_objmgr_vdev_release_ref(
11051 							vdev,
11052 							WLAN_POLICY_MGR_ID);
11053 					break;
11054 				}
11055 			} else {
11056 				*ok = true;
11057 			}
11058 			wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
11059 		}
11060 	}
11061 
11062 	return QDF_STATUS_SUCCESS;
11063 }
11064 
policy_mgr_get_hw_dbs_max_bw(struct wlan_objmgr_psoc * psoc,struct dbs_bw * bw_dbs)11065 void policy_mgr_get_hw_dbs_max_bw(struct wlan_objmgr_psoc *psoc,
11066 				  struct dbs_bw *bw_dbs)
11067 {
11068 	uint32_t dbs, sbs, i, param;
11069 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11070 
11071 	pm_ctx = policy_mgr_get_context(psoc);
11072 	if (!pm_ctx) {
11073 		policy_mgr_err("Invalid Context");
11074 		return;
11075 	}
11076 
11077 	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
11078 		param = pm_ctx->hw_mode.hw_mode_list[i];
11079 		dbs = POLICY_MGR_HW_MODE_DBS_MODE_GET(param);
11080 		sbs = POLICY_MGR_HW_MODE_SBS_MODE_GET(param);
11081 
11082 		if (!dbs && !sbs)
11083 			bw_dbs->mac0_bw =
11084 				POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(param);
11085 
11086 		if (dbs) {
11087 			bw_dbs->mac0_bw =
11088 				POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(param);
11089 			bw_dbs->mac1_bw =
11090 				POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(param);
11091 		} else {
11092 			continue;
11093 		}
11094 	}
11095 }
11096 
policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc * psoc,struct dbs_nss * nss_dbs)11097 uint32_t policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc,
11098 				   struct dbs_nss *nss_dbs)
11099 {
11100 	int i, param;
11101 	uint32_t dbs, sbs, tx_chain0, rx_chain0, tx_chain1, rx_chain1;
11102 	uint32_t min_mac0_rf_chains, min_mac1_rf_chains;
11103 	uint32_t max_rf_chains, final_max_rf_chains = HW_MODE_SS_0x0;
11104 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11105 
11106 	pm_ctx = policy_mgr_get_context(psoc);
11107 	if (!pm_ctx) {
11108 		policy_mgr_err("Invalid Context");
11109 		return final_max_rf_chains;
11110 	}
11111 
11112 	nss_dbs->single_mac0_band_cap = 0;
11113 	for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
11114 		param = pm_ctx->hw_mode.hw_mode_list[i];
11115 		dbs = POLICY_MGR_HW_MODE_DBS_MODE_GET(param);
11116 		sbs = POLICY_MGR_HW_MODE_SBS_MODE_GET(param);
11117 
11118 		if (!dbs && !sbs && !nss_dbs->single_mac0_band_cap)
11119 			nss_dbs->single_mac0_band_cap =
11120 				POLICY_MGR_HW_MODE_MAC0_BAND_GET(param);
11121 
11122 		if (dbs) {
11123 			tx_chain0
11124 				= POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param);
11125 			rx_chain0
11126 				= POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param);
11127 
11128 			tx_chain1
11129 				= POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param);
11130 			rx_chain1
11131 				= POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param);
11132 
11133 			min_mac0_rf_chains = QDF_MIN(tx_chain0, rx_chain0);
11134 			min_mac1_rf_chains = QDF_MIN(tx_chain1, rx_chain1);
11135 
11136 			max_rf_chains
11137 			= QDF_MAX(min_mac0_rf_chains, min_mac1_rf_chains);
11138 
11139 			if (final_max_rf_chains < max_rf_chains) {
11140 				final_max_rf_chains
11141 					= (max_rf_chains == 2)
11142 					? HW_MODE_SS_2x2 : HW_MODE_SS_1x1;
11143 
11144 				nss_dbs->mac0_ss
11145 					= (min_mac0_rf_chains == 2)
11146 					? HW_MODE_SS_2x2 : HW_MODE_SS_1x1;
11147 
11148 				nss_dbs->mac1_ss
11149 					= (min_mac1_rf_chains == 2)
11150 					? HW_MODE_SS_2x2 : HW_MODE_SS_1x1;
11151 			}
11152 		} else {
11153 			continue;
11154 		}
11155 	}
11156 
11157 	return final_max_rf_chains;
11158 }
11159 
policy_mgr_is_scan_simultaneous_capable(struct wlan_objmgr_psoc * psoc)11160 bool policy_mgr_is_scan_simultaneous_capable(struct wlan_objmgr_psoc *psoc)
11161 {
11162 	uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
11163 
11164 	policy_mgr_get_dual_mac_feature(psoc, &dual_mac_feature);
11165 	if ((dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) ||
11166 	    (dual_mac_feature == ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN) ||
11167 	    (dual_mac_feature ==
11168 	     ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN) ||
11169 	     !policy_mgr_is_hw_dbs_capable(psoc))
11170 		return false;
11171 
11172 	return true;
11173 }
11174 
policy_mgr_set_cur_conc_system_pref(struct wlan_objmgr_psoc * psoc,uint8_t conc_system_pref)11175 void policy_mgr_set_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc,
11176 		uint8_t conc_system_pref)
11177 {
11178 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11179 
11180 	pm_ctx = policy_mgr_get_context(psoc);
11181 
11182 	if (!pm_ctx) {
11183 		policy_mgr_err("Invalid Context");
11184 		return;
11185 	}
11186 
11187 	policy_mgr_debug("conc_system_pref %hu", conc_system_pref);
11188 	pm_ctx->cur_conc_system_pref = conc_system_pref;
11189 }
11190 
policy_mgr_get_cur_conc_system_pref(struct wlan_objmgr_psoc * psoc)11191 uint8_t policy_mgr_get_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc)
11192 {
11193 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11194 
11195 	pm_ctx = policy_mgr_get_context(psoc);
11196 	if (!pm_ctx) {
11197 		policy_mgr_err("Invalid Context");
11198 		return PM_THROUGHPUT;
11199 	}
11200 
11201 	policy_mgr_debug("conc_system_pref %hu", pm_ctx->cur_conc_system_pref);
11202 	return pm_ctx->cur_conc_system_pref;
11203 }
11204 
policy_mgr_get_updated_scan_and_fw_mode_config(struct wlan_objmgr_psoc * psoc,uint32_t * scan_config,uint32_t * fw_mode_config,uint32_t dual_mac_disable_ini,uint32_t channel_select_logic_conc)11205 QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config(
11206 		struct wlan_objmgr_psoc *psoc, uint32_t *scan_config,
11207 		uint32_t *fw_mode_config, uint32_t dual_mac_disable_ini,
11208 		uint32_t channel_select_logic_conc)
11209 {
11210 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11211 
11212 	pm_ctx = policy_mgr_get_context(psoc);
11213 	if (!pm_ctx) {
11214 		policy_mgr_err("Invalid Context");
11215 		return QDF_STATUS_E_FAILURE;
11216 	}
11217 
11218 	*scan_config = pm_ctx->dual_mac_cfg.cur_scan_config;
11219 	*fw_mode_config = pm_ctx->dual_mac_cfg.cur_fw_mode_config;
11220 	switch (dual_mac_disable_ini) {
11221 	case DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN_WITH_ASYNC_SCAN_OFF:
11222 		policy_mgr_debug("dual_mac_disable_ini:%d async/dbs off",
11223 			dual_mac_disable_ini);
11224 		WMI_DBS_CONC_SCAN_CFG_ASYNC_DBS_SCAN_SET(*scan_config, 0);
11225 		WMI_DBS_FW_MODE_CFG_DBS_FOR_CXN_SET(*fw_mode_config, 0);
11226 		break;
11227 	case DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN:
11228 		policy_mgr_debug("dual_mac_disable_ini:%d dbs_cxn off",
11229 			dual_mac_disable_ini);
11230 		WMI_DBS_FW_MODE_CFG_DBS_FOR_CXN_SET(*fw_mode_config, 0);
11231 		break;
11232 	case ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF:
11233 		policy_mgr_debug("dual_mac_disable_ini:%d async off",
11234 			dual_mac_disable_ini);
11235 		WMI_DBS_CONC_SCAN_CFG_ASYNC_DBS_SCAN_SET(*scan_config, 0);
11236 		break;
11237 	case ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN:
11238 		policy_mgr_debug("dual_mac_disable_ini:%d ",
11239 				 dual_mac_disable_ini);
11240 		WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_SET(*scan_config, 0);
11241 		break;
11242 	default:
11243 		break;
11244 	}
11245 
11246 	WMI_DBS_FW_MODE_CFG_DBS_FOR_STA_PLUS_STA_SET(*fw_mode_config,
11247 		PM_CHANNEL_SELECT_LOGIC_STA_STA_GET(channel_select_logic_conc));
11248 	WMI_DBS_FW_MODE_CFG_DBS_FOR_STA_PLUS_P2P_SET(*fw_mode_config,
11249 		PM_CHANNEL_SELECT_LOGIC_STA_P2P_GET(channel_select_logic_conc));
11250 
11251 	policy_mgr_debug("*scan_config:%x ", *scan_config);
11252 	policy_mgr_debug("*fw_mode_config:%x ", *fw_mode_config);
11253 
11254 	return QDF_STATUS_SUCCESS;
11255 }
11256 
policy_mgr_is_force_scc(struct wlan_objmgr_psoc * psoc)11257 bool policy_mgr_is_force_scc(struct wlan_objmgr_psoc *psoc)
11258 {
11259 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11260 
11261 	pm_ctx = policy_mgr_get_context(psoc);
11262 	if (!pm_ctx) {
11263 		policy_mgr_err("Invalid Context");
11264 		return 0;
11265 	}
11266 
11267 	return ((pm_ctx->cfg.mcc_to_scc_switch ==
11268 		QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION) ||
11269 		(pm_ctx->cfg.mcc_to_scc_switch ==
11270 		QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) ||
11271 		(pm_ctx->cfg.mcc_to_scc_switch ==
11272 		QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) ||
11273 		(pm_ctx->cfg.mcc_to_scc_switch ==
11274 		QDF_MCC_TO_SCC_WITH_PREFERRED_BAND));
11275 }
11276 
policy_mgr_is_sap_allowed_on_dfs_freq(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id,qdf_freq_t ch_freq)11277 bool policy_mgr_is_sap_allowed_on_dfs_freq(struct wlan_objmgr_pdev *pdev,
11278 					   uint8_t vdev_id, qdf_freq_t ch_freq)
11279 {
11280 	struct wlan_objmgr_psoc *psoc;
11281 	uint32_t sta_sap_scc_on_dfs_chan;
11282 	uint32_t sta_cnt, gc_cnt, idx;
11283 	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
11284 	struct wlan_objmgr_vdev *vdev;
11285 
11286 	psoc = wlan_pdev_get_psoc(pdev);
11287 	if (!psoc)
11288 		return false;
11289 
11290 	sta_sap_scc_on_dfs_chan =
11291 		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
11292 	sta_cnt = policy_mgr_get_mode_specific_conn_info(psoc, NULL,
11293 							 vdev_id_list,
11294 							 PM_STA_MODE);
11295 
11296 	if (sta_cnt >= MAX_NUMBER_OF_CONC_CONNECTIONS)
11297 		return false;
11298 
11299 	gc_cnt = policy_mgr_get_mode_specific_conn_info(psoc, NULL,
11300 							&vdev_id_list[sta_cnt],
11301 							PM_P2P_CLIENT_MODE);
11302 
11303 	policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sta_cnt %u, gc_cnt %u",
11304 			 sta_sap_scc_on_dfs_chan, sta_cnt, gc_cnt);
11305 
11306 	/* if sta_sap_scc_on_dfs_chan ini is set, DFS master capability is
11307 	 * assumed disabled in the driver.
11308 	 */
11309 	if ((wlan_reg_get_channel_state_for_pwrmode(
11310 		pdev, ch_freq, REG_CURRENT_PWR_MODE) == CHANNEL_STATE_DFS) &&
11311 	    !sta_cnt && !gc_cnt && sta_sap_scc_on_dfs_chan &&
11312 	    !policy_mgr_get_dfs_master_dynamic_enabled(psoc, vdev_id)) {
11313 		policy_mgr_err("SAP not allowed on DFS channel if no dfs master capability!!");
11314 		return false;
11315 	}
11316 
11317 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
11318 						    vdev_id,
11319 						    WLAN_POLICY_MGR_ID);
11320 	if (!vdev) {
11321 		policy_mgr_err("Invalid vdev");
11322 		return false;
11323 	}
11324 	/* Allow the current CSA to continue if it's already started. This is
11325 	 * possible when SAP CSA started to move to STA channel but STA got
11326 	 * disconnected.
11327 	 */
11328 	if (!wlan_vdev_mlme_is_init_state(vdev) &&
11329 	    !wlan_vdev_is_up_active_state(vdev)) {
11330 		policy_mgr_debug("SAP is not yet UP: vdev %d", vdev_id);
11331 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
11332 		return true;
11333 	}
11334 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
11335 
11336 	/*
11337 	 * Check if any of the concurrent STA/ML-STA link/P2P client are in
11338 	 * disconnecting state and disallow current SAP CSA. Concurrencies
11339 	 * would be re-evaluated upon disconnect completion and SAP would be
11340 	 * moved to right channel.
11341 	 */
11342 	for (idx = 0; idx < sta_cnt + gc_cnt; idx++) {
11343 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
11344 							    vdev_id_list[idx],
11345 							    WLAN_POLICY_MGR_ID);
11346 		if (!vdev) {
11347 			policy_mgr_err("Invalid vdev");
11348 			return false;
11349 		}
11350 		if (wlan_cm_is_vdev_disconnecting(vdev) ||
11351 		    mlo_is_any_link_disconnecting(vdev)) {
11352 			policy_mgr_err("SAP is not allowed to move to DFS channel at this time, vdev %d",
11353 				       vdev_id_list[idx]);
11354 			wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
11355 			return false;
11356 		}
11357 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
11358 	}
11359 
11360 	return true;
11361 }
11362 
11363 bool
policy_mgr_is_sap_go_interface_allowed_on_indoor(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id,qdf_freq_t ch_freq)11364 policy_mgr_is_sap_go_interface_allowed_on_indoor(struct wlan_objmgr_pdev *pdev,
11365 						 uint8_t vdev_id,
11366 						 qdf_freq_t ch_freq)
11367 {
11368 	struct wlan_objmgr_psoc *psoc;
11369 	bool is_scc = false, indoor_support = false;
11370 	enum QDF_OPMODE mode;
11371 
11372 	psoc = wlan_pdev_get_psoc(pdev);
11373 	if (!psoc)
11374 		return true;
11375 
11376 	if (!wlan_reg_is_freq_indoor(pdev, ch_freq))
11377 		return true;
11378 
11379 	is_scc = policy_mgr_is_sta_sap_scc(psoc, ch_freq);
11380 	mode = wlan_get_opmode_from_vdev_id(pdev, vdev_id);
11381 	ucfg_mlme_get_indoor_channel_support(psoc, &indoor_support);
11382 
11383 	/*
11384 	 * Rules for indoor operation:
11385 	 * If gindoor_channel_support is enabled - Allow SAP/GO
11386 	 * If gindoor_channel_support is disabled
11387 	 *      a) Restrict 6 GHz SAP
11388 	 *      b) Restrict standalone 5 GHz SAP
11389 	 *
11390 	 * If p2p_go_on_5ghz_indoor_chan is enabled - Allow GO
11391 	 * with or without concurrency
11392 	 *
11393 	 * If sta_sap_scc_on_indoor_chan is enabled - Allow
11394 	 * SAP/GO with concurrent STA in indoor SCC
11395 	 *
11396 	 * Restrict all other operations on indoor
11397 	 */
11398 
11399 	if (indoor_support)
11400 		return true;
11401 
11402 	if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq)) {
11403 		policy_mgr_rl_debug("SAP operation is not allowed on 6 GHz indoor channel");
11404 		return false;
11405 	}
11406 
11407 	if (mode == QDF_SAP_MODE) {
11408 		if (is_scc &&
11409 		    policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc))
11410 			return true;
11411 		policy_mgr_rl_debug("SAP operation is not allowed on indoor channel");
11412 		return false;
11413 	}
11414 
11415 	if (mode == QDF_P2P_GO_MODE) {
11416 		if (ucfg_p2p_get_indoor_ch_support(psoc) ||
11417 		    (is_scc &&
11418 		    policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc)))
11419 			return true;
11420 		policy_mgr_rl_debug("GO operation is not allowed on indoor channel");
11421 		return false;
11422 	}
11423 
11424 	policy_mgr_rl_debug("SAP operation is not allowed on indoor channel");
11425 	return false;
11426 }
11427 
policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(struct wlan_objmgr_psoc * psoc)11428 bool policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(
11429 		struct wlan_objmgr_psoc *psoc)
11430 {
11431 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11432 	uint8_t sta_sap_scc_on_dfs_chnl = 0;
11433 	bool status = false;
11434 
11435 	pm_ctx = policy_mgr_get_context(psoc);
11436 	if (!pm_ctx) {
11437 		policy_mgr_err("Invalid Context");
11438 		return status;
11439 	}
11440 
11441 	policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc,
11442 					       &sta_sap_scc_on_dfs_chnl);
11443 	if (policy_mgr_is_force_scc(psoc) && sta_sap_scc_on_dfs_chnl)
11444 		status = true;
11445 
11446 	return status;
11447 }
11448 
policy_mgr_is_multi_sap_allowed_on_same_band(struct wlan_objmgr_pdev * pdev,enum policy_mgr_con_mode mode,qdf_freq_t ch_freq)11449 bool policy_mgr_is_multi_sap_allowed_on_same_band(
11450 					struct wlan_objmgr_pdev *pdev,
11451 					enum policy_mgr_con_mode mode,
11452 					qdf_freq_t ch_freq)
11453 {
11454 	struct wlan_objmgr_psoc *psoc;
11455 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11456 	bool multi_sap_allowed_on_same_band;
11457 	QDF_STATUS status;
11458 
11459 	psoc = wlan_pdev_get_psoc(pdev);
11460 	if (!psoc)
11461 		return false;
11462 
11463 	pm_ctx = policy_mgr_get_context(psoc);
11464 	if (!pm_ctx) {
11465 		policy_mgr_err("Invalid Context");
11466 		return false;
11467 	}
11468 
11469 	if (!ch_freq || !policy_mgr_is_sap_mode(mode))
11470 		return true;
11471 
11472 	status = policy_mgr_get_multi_sap_allowed_on_same_band(psoc,
11473 					&multi_sap_allowed_on_same_band);
11474 	if (!QDF_IS_STATUS_SUCCESS(status)) {
11475 		policy_mgr_err("Failed to get multi_sap_allowed_on_same_band");
11476 		/* Allow multi SAPs started on same band by default. */
11477 		multi_sap_allowed_on_same_band = true;
11478 	}
11479 	if (!multi_sap_allowed_on_same_band) {
11480 		uint32_t ap_cnt, index = 0;
11481 		uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
11482 		struct policy_mgr_conc_connection_info *ap_info;
11483 
11484 		ap_cnt = policy_mgr_get_sap_mode_count(psoc, list);
11485 		if (!ap_cnt)
11486 			return true;
11487 
11488 		qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
11489 		while (index < ap_cnt) {
11490 			ap_info = &pm_conc_connection_list[list[index]];
11491 			if (WLAN_REG_IS_SAME_BAND_FREQS(ch_freq,
11492 							ap_info->freq)) {
11493 				policy_mgr_rl_debug("Don't allow SAP on same band");
11494 				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
11495 				return false;
11496 			}
11497 			index++;
11498 		}
11499 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
11500 	}
11501 
11502 	return true;
11503 }
11504 
policy_mgr_is_special_mode_active_5g(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode)11505 bool policy_mgr_is_special_mode_active_5g(struct wlan_objmgr_psoc *psoc,
11506 					  enum policy_mgr_con_mode mode)
11507 {
11508 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11509 	uint32_t conn_index;
11510 	bool ret = false;
11511 
11512 	pm_ctx = policy_mgr_get_context(psoc);
11513 	if (!pm_ctx) {
11514 		policy_mgr_err("Invalid Context");
11515 		return ret;
11516 	}
11517 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
11518 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
11519 	     conn_index++) {
11520 		if (pm_conc_connection_list[conn_index].mode == mode &&
11521 		    pm_conc_connection_list[conn_index].freq >=
11522 					WLAN_REG_MIN_5GHZ_CHAN_FREQ &&
11523 		    pm_conc_connection_list[conn_index].in_use)
11524 			ret = true;
11525 	}
11526 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
11527 
11528 	return ret;
11529 }
11530 
policy_mgr_is_sta_connected_2g(struct wlan_objmgr_psoc * psoc)11531 bool policy_mgr_is_sta_connected_2g(struct wlan_objmgr_psoc *psoc)
11532 {
11533 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11534 	uint32_t conn_index;
11535 	bool ret = false;
11536 
11537 	pm_ctx = policy_mgr_get_context(psoc);
11538 	if (!pm_ctx) {
11539 		policy_mgr_err("Invalid Context");
11540 		return ret;
11541 	}
11542 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
11543 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
11544 	     conn_index++) {
11545 		if (pm_conc_connection_list[conn_index].mode == PM_STA_MODE &&
11546 		    pm_conc_connection_list[conn_index].freq <=
11547 				WLAN_REG_MAX_24GHZ_CHAN_FREQ &&
11548 		    pm_conc_connection_list[conn_index].in_use)
11549 			ret = true;
11550 	}
11551 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
11552 
11553 	return ret;
11554 }
11555 
11556 bool
policy_mgr_is_connected_sta_5g(struct wlan_objmgr_psoc * psoc,qdf_freq_t * freq)11557 policy_mgr_is_connected_sta_5g(struct wlan_objmgr_psoc *psoc, qdf_freq_t *freq)
11558 {
11559 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11560 	uint32_t conn_index;
11561 	bool ret = false;
11562 
11563 	pm_ctx = policy_mgr_get_context(psoc);
11564 	if (!pm_ctx) {
11565 		policy_mgr_err("Invalid Context");
11566 		return ret;
11567 	}
11568 
11569 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
11570 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
11571 	     conn_index++) {
11572 		*freq = pm_conc_connection_list[conn_index].freq;
11573 		if (pm_conc_connection_list[conn_index].mode == PM_STA_MODE &&
11574 		    WLAN_REG_IS_5GHZ_CH_FREQ(*freq) &&
11575 		    pm_conc_connection_list[conn_index].in_use) {
11576 			ret = true;
11577 			break;
11578 		}
11579 	}
11580 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
11581 
11582 	return ret;
11583 }
11584 
policy_mgr_get_connection_info(struct wlan_objmgr_psoc * psoc,struct connection_info * info)11585 uint32_t policy_mgr_get_connection_info(struct wlan_objmgr_psoc *psoc,
11586 					struct connection_info *info)
11587 {
11588 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11589 	uint32_t conn_index, count = 0;
11590 
11591 	pm_ctx = policy_mgr_get_context(psoc);
11592 	if (!pm_ctx) {
11593 		policy_mgr_err("Invalid Context");
11594 		return count;
11595 	}
11596 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
11597 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
11598 	     conn_index++) {
11599 		if (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
11600 			info[count].vdev_id =
11601 				pm_conc_connection_list[conn_index].vdev_id;
11602 			info[count].mac_id =
11603 				pm_conc_connection_list[conn_index].mac;
11604 			info[count].channel = wlan_reg_freq_to_chan(
11605 				pm_ctx->pdev,
11606 				pm_conc_connection_list[conn_index].freq);
11607 			info[count].ch_freq =
11608 				pm_conc_connection_list[conn_index].freq;
11609 			count++;
11610 		}
11611 	}
11612 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
11613 
11614 	return count;
11615 }
11616 
policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint32_t ch_freq,uint32_t vdev_id)11617 bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc,
11618 					 enum policy_mgr_con_mode mode,
11619 					 uint32_t ch_freq,
11620 					 uint32_t vdev_id)
11621 {
11622 	enum policy_mgr_con_mode con_mode;
11623 	int id;
11624 	uint32_t vdev, con_freq;
11625 	bool dbs;
11626 
11627 	if (mode != PM_SAP_MODE && mode != PM_P2P_GO_MODE)
11628 		return true;
11629 	dbs = policy_mgr_is_hw_dbs_capable(psoc);
11630 	for (id = 0; id < MAX_NUMBER_OF_CONC_CONNECTIONS; id++) {
11631 		if (!pm_conc_connection_list[id].in_use)
11632 			continue;
11633 		vdev = pm_conc_connection_list[id].vdev_id;
11634 		if (vdev_id == vdev)
11635 			continue;
11636 		con_mode = pm_conc_connection_list[id].mode;
11637 		if (con_mode != PM_SAP_MODE && con_mode != PM_P2P_GO_MODE)
11638 			continue;
11639 		con_freq = pm_conc_connection_list[id].freq;
11640 
11641 		if (policy_mgr_is_p2p_p2p_conc_supported(psoc) &&
11642 		    (mode == PM_P2P_GO_MODE) && (con_mode == PM_P2P_GO_MODE)) {
11643 			policy_mgr_debug("GO+GO scc is allowed freq = %d ",
11644 					 ch_freq);
11645 			return true;
11646 		}
11647 
11648 		if (policy_mgr_dual_beacon_on_single_mac_mcc_capable(psoc) &&
11649 		    (mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE) &&
11650 		    (con_mode == PM_SAP_MODE || con_mode == PM_P2P_GO_MODE))
11651 			return true;
11652 
11653 		if (policy_mgr_dual_beacon_on_single_mac_scc_capable(psoc) &&
11654 		    (ch_freq == con_freq)) {
11655 			policy_mgr_debug("SCC enabled, 2 AP on same channel, allow 2nd AP");
11656 			return true;
11657 		}
11658 		if (!dbs) {
11659 			policy_mgr_debug("DBS unsupported, mcc and scc unsupported too, don't allow 2nd AP");
11660 			return false;
11661 		}
11662 
11663 		if (policy_mgr_are_2_freq_on_same_mac(psoc, ch_freq,
11664 						      con_freq)) {
11665 			policy_mgr_debug("DBS supported, 2 SAP on same band, reject 2nd AP");
11666 			return false;
11667 		}
11668 	}
11669 
11670 	/* Don't block the second interface */
11671 	return true;
11672 }
11673 
policy_mgr_dual_beacon_on_single_mac_scc_capable(struct wlan_objmgr_psoc * psoc)11674 bool policy_mgr_dual_beacon_on_single_mac_scc_capable(
11675 		struct wlan_objmgr_psoc *psoc)
11676 {
11677 	struct wmi_unified *wmi_handle;
11678 
11679 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
11680 	if (!wmi_handle) {
11681 		policy_mgr_debug("Invalid WMI handle");
11682 		return false;
11683 	}
11684 
11685 	if (wmi_service_enabled(
11686 			wmi_handle,
11687 			wmi_service_dual_beacon_on_single_mac_scc_support)) {
11688 		policy_mgr_debug("Dual beaconing on same channel on single MAC supported");
11689 		return true;
11690 	}
11691 	policy_mgr_debug("Dual beaconing on same channel on single MAC is not supported");
11692 	return false;
11693 }
11694 
policy_mgr_dual_beacon_on_single_mac_mcc_capable(struct wlan_objmgr_psoc * psoc)11695 bool policy_mgr_dual_beacon_on_single_mac_mcc_capable(
11696 		struct wlan_objmgr_psoc *psoc)
11697 {
11698 	struct wmi_unified *wmi_handle;
11699 
11700 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
11701 	if (!wmi_handle) {
11702 		policy_mgr_debug("Invalid WMI handle");
11703 		return false;
11704 	}
11705 
11706 	if (wmi_service_enabled(
11707 			wmi_handle,
11708 			wmi_service_dual_beacon_on_single_mac_mcc_support)) {
11709 		policy_mgr_debug("Dual beaconing on different channel on single MAC supported");
11710 		return true;
11711 	}
11712 	policy_mgr_debug("Dual beaconing on different channel on single MAC is not supported");
11713 	return false;
11714 }
11715 
policy_mgr_sta_sap_scc_on_lte_coex_chan(struct wlan_objmgr_psoc * psoc)11716 bool policy_mgr_sta_sap_scc_on_lte_coex_chan(
11717 	struct wlan_objmgr_psoc *psoc)
11718 {
11719 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11720 	uint8_t scc_lte_coex = 0;
11721 
11722 	pm_ctx = policy_mgr_get_context(psoc);
11723 	if (!pm_ctx) {
11724 		policy_mgr_err("Invalid Context");
11725 		return false;
11726 	}
11727 	policy_mgr_get_sta_sap_scc_lte_coex_chnl(psoc, &scc_lte_coex);
11728 
11729 	return scc_lte_coex;
11730 }
11731 
11732 #if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX)
policy_mgr_init_ap_6ghz_capable(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,enum conn_6ghz_flag ap_6ghz_capable)11733 void policy_mgr_init_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc,
11734 				     uint8_t vdev_id,
11735 				     enum conn_6ghz_flag ap_6ghz_capable)
11736 {
11737 	struct policy_mgr_conc_connection_info *conn_info;
11738 	uint32_t conn_index;
11739 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11740 	enum conn_6ghz_flag conn_6ghz_flag = 0;
11741 
11742 	pm_ctx = policy_mgr_get_context(psoc);
11743 	if (!pm_ctx) {
11744 		policy_mgr_err("Invalid Context");
11745 		return;
11746 	}
11747 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
11748 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
11749 			conn_index++) {
11750 		conn_info = &pm_conc_connection_list[conn_index];
11751 		if (conn_info->in_use &&
11752 		    policy_mgr_is_sap_mode(conn_info->mode) &&
11753 		    vdev_id == conn_info->vdev_id) {
11754 			conn_info->conn_6ghz_flag = ap_6ghz_capable;
11755 			conn_info->conn_6ghz_flag |= CONN_6GHZ_FLAG_VALID;
11756 			conn_6ghz_flag = conn_info->conn_6ghz_flag;
11757 			break;
11758 		}
11759 	}
11760 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
11761 	policy_mgr_debug("vdev %d init conn_6ghz_flag %x new %x",
11762 			 vdev_id, ap_6ghz_capable, conn_6ghz_flag);
11763 }
11764 
policy_mgr_set_ap_6ghz_capable(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,bool set,enum conn_6ghz_flag ap_6ghz_capable)11765 void policy_mgr_set_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc,
11766 				    uint8_t vdev_id,
11767 				    bool set,
11768 				    enum conn_6ghz_flag ap_6ghz_capable)
11769 {
11770 	struct policy_mgr_conc_connection_info *conn_info;
11771 	uint32_t conn_index;
11772 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11773 	enum conn_6ghz_flag conn_6ghz_flag = 0;
11774 
11775 	pm_ctx = policy_mgr_get_context(psoc);
11776 	if (!pm_ctx) {
11777 		policy_mgr_err("Invalid Context");
11778 		return;
11779 	}
11780 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
11781 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
11782 			conn_index++) {
11783 		conn_info = &pm_conc_connection_list[conn_index];
11784 		if (conn_info->in_use &&
11785 		    policy_mgr_is_beaconing_mode(conn_info->mode) &&
11786 		    policy_mgr_is_6ghz_conc_mode_supported(
11787 						psoc, conn_info->mode) &&
11788 		    vdev_id == conn_info->vdev_id) {
11789 			if (set)
11790 				conn_info->conn_6ghz_flag |= ap_6ghz_capable;
11791 			else
11792 				conn_info->conn_6ghz_flag &= ~ap_6ghz_capable;
11793 			conn_info->conn_6ghz_flag |= CONN_6GHZ_FLAG_VALID;
11794 			conn_6ghz_flag = conn_info->conn_6ghz_flag;
11795 			break;
11796 		}
11797 	}
11798 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
11799 	policy_mgr_debug("vdev %d %s conn_6ghz_flag %x new %x",
11800 			 vdev_id, set ? "set" : "clr",
11801 			 ap_6ghz_capable, conn_6ghz_flag);
11802 }
11803 
policy_mgr_get_ap_6ghz_capable(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint32_t * conn_flag)11804 bool policy_mgr_get_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc,
11805 				    uint8_t vdev_id,
11806 				    uint32_t *conn_flag)
11807 {
11808 	struct policy_mgr_conc_connection_info *conn_info;
11809 	uint32_t conn_index;
11810 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11811 	enum conn_6ghz_flag conn_6ghz_flag = 0;
11812 	bool is_6g_allowed = false;
11813 
11814 	if (conn_flag)
11815 		*conn_flag = 0;
11816 	pm_ctx = policy_mgr_get_context(psoc);
11817 	if (!pm_ctx) {
11818 		policy_mgr_err("Invalid Context");
11819 		return false;
11820 	}
11821 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
11822 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
11823 			conn_index++) {
11824 		conn_info = &pm_conc_connection_list[conn_index];
11825 		if (conn_info->in_use &&
11826 		    policy_mgr_is_beaconing_mode(conn_info->mode) &&
11827 		    policy_mgr_is_6ghz_conc_mode_supported(
11828 						psoc, conn_info->mode) &&
11829 		    vdev_id == conn_info->vdev_id) {
11830 			conn_6ghz_flag = conn_info->conn_6ghz_flag;
11831 			break;
11832 		}
11833 	}
11834 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
11835 
11836 	/* If the vdev connection is not active, policy mgr will query legacy
11837 	 * hdd to get sap acs and security information.
11838 	 * The assumption is no legacy client connected for non active
11839 	 * connection.
11840 	 */
11841 	if (!(conn_6ghz_flag & CONN_6GHZ_FLAG_VALID) &&
11842 	    pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable)
11843 		conn_6ghz_flag = pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable(
11844 					psoc, vdev_id) |
11845 					CONN_6GHZ_FLAG_NO_LEGACY_CLIENT;
11846 
11847 	if ((conn_6ghz_flag & CONN_6GHZ_CAPABLE) == CONN_6GHZ_CAPABLE)
11848 		is_6g_allowed = true;
11849 	policy_mgr_debug("vdev %d conn_6ghz_flag %x 6ghz %s", vdev_id,
11850 			 conn_6ghz_flag, is_6g_allowed ? "allowed" : "deny");
11851 	if (conn_flag)
11852 		*conn_flag = conn_6ghz_flag;
11853 
11854 	return is_6g_allowed;
11855 }
11856 #endif
11857 
policy_mgr_is_sta_sap_scc(struct wlan_objmgr_psoc * psoc,uint32_t sap_freq)11858 bool policy_mgr_is_sta_sap_scc(struct wlan_objmgr_psoc *psoc,
11859 			       uint32_t sap_freq)
11860 {
11861 	uint32_t conn_index;
11862 	bool is_scc = false;
11863 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11864 
11865 	pm_ctx = policy_mgr_get_context(psoc);
11866 	if (!pm_ctx) {
11867 		policy_mgr_err("Invalid Context");
11868 		return is_scc;
11869 	}
11870 
11871 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
11872 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
11873 		conn_index++) {
11874 		if (pm_conc_connection_list[conn_index].in_use &&
11875 				(pm_conc_connection_list[conn_index].mode ==
11876 				PM_STA_MODE ||
11877 				pm_conc_connection_list[conn_index].mode ==
11878 				PM_P2P_CLIENT_MODE) && (sap_freq ==
11879 				pm_conc_connection_list[conn_index].freq)) {
11880 			is_scc = true;
11881 			break;
11882 		}
11883 	}
11884 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
11885 
11886 	return is_scc;
11887 }
11888 
policy_mgr_go_scc_enforced(struct wlan_objmgr_psoc * psoc)11889 bool policy_mgr_go_scc_enforced(struct wlan_objmgr_psoc *psoc)
11890 {
11891 	uint32_t mcc_to_scc_switch;
11892 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11893 
11894 	pm_ctx = policy_mgr_get_context(psoc);
11895 	if (!pm_ctx) {
11896 		policy_mgr_err("Invalid Context");
11897 		return false;
11898 	}
11899 	mcc_to_scc_switch = policy_mgr_get_mcc_to_scc_switch_mode(psoc);
11900 	if (mcc_to_scc_switch ==
11901 	    QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION)
11902 		return true;
11903 
11904 	if (pm_ctx->cfg.go_force_scc && policy_mgr_is_force_scc(psoc))
11905 		return true;
11906 
11907 	return false;
11908 }
11909 
11910 uint8_t
policy_mgr_fetch_existing_con_info(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint32_t freq,enum policy_mgr_con_mode * mode,uint32_t * existing_con_freq,enum phy_ch_width * existing_ch_width)11911 policy_mgr_fetch_existing_con_info(struct wlan_objmgr_psoc *psoc,
11912 				   uint8_t vdev_id, uint32_t freq,
11913 				   enum policy_mgr_con_mode *mode,
11914 				   uint32_t *existing_con_freq,
11915 				   enum phy_ch_width *existing_ch_width)
11916 {
11917 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11918 	uint32_t conn_index;
11919 
11920 	pm_ctx = policy_mgr_get_context(psoc);
11921 	if (!pm_ctx) {
11922 		policy_mgr_err("Invalid Context");
11923 		return WLAN_UMAC_VDEV_ID_MAX;
11924 	}
11925 
11926 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
11927 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
11928 	     conn_index++) {
11929 		if ((policy_mgr_is_beaconing_mode(
11930 				pm_conc_connection_list[conn_index].mode) ||
11931 		    pm_conc_connection_list[conn_index].mode ==
11932 		    PM_P2P_CLIENT_MODE ||
11933 		    pm_conc_connection_list[conn_index].mode ==
11934 		    PM_STA_MODE) &&
11935 		    pm_conc_connection_list[conn_index].in_use &&
11936 		    policy_mgr_are_2_freq_on_same_mac(
11937 			psoc, freq, pm_conc_connection_list[conn_index].freq) &&
11938 		    freq != pm_conc_connection_list[conn_index].freq &&
11939 		    vdev_id != pm_conc_connection_list[conn_index].vdev_id) {
11940 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
11941 			policy_mgr_debug(
11942 				"Existing vdev_id for mode %d is %d",
11943 				pm_conc_connection_list[conn_index].mode,
11944 				pm_conc_connection_list[conn_index].vdev_id);
11945 			*mode = pm_conc_connection_list[conn_index].mode;
11946 			*existing_con_freq =
11947 				pm_conc_connection_list[conn_index].freq;
11948 			*existing_ch_width = policy_mgr_get_ch_width(
11949 					pm_conc_connection_list[conn_index].bw);
11950 			return pm_conc_connection_list[conn_index].vdev_id;
11951 		}
11952 	}
11953 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
11954 
11955 	return WLAN_UMAC_VDEV_ID_MAX;
11956 }
11957 
11958 #ifdef WLAN_FEATURE_P2P_P2P_STA
policy_mgr_is_go_scc_strict(struct wlan_objmgr_psoc * psoc)11959 bool policy_mgr_is_go_scc_strict(struct wlan_objmgr_psoc *psoc)
11960 {
11961 	struct policy_mgr_psoc_priv_obj *pm_ctx;
11962 	bool ret = false;
11963 
11964 	pm_ctx = policy_mgr_get_context(psoc);
11965 	if (!pm_ctx) {
11966 		ret = false;
11967 		goto return_val;
11968 	}
11969 	if (pm_ctx->cfg.go_force_scc & GO_FORCE_SCC_STRICT) {
11970 		ret = true;
11971 		goto return_val;
11972 	}
11973 	ret = false;
11974 return_val:
11975 	policy_mgr_debug("ret val is %d", ret);
11976 	return ret;
11977 }
11978 #endif
11979 
policy_mgr_update_nan_vdev_mac_info(struct wlan_objmgr_psoc * psoc,uint8_t nan_vdev_id,uint8_t mac_id)11980 QDF_STATUS policy_mgr_update_nan_vdev_mac_info(struct wlan_objmgr_psoc *psoc,
11981 					       uint8_t nan_vdev_id,
11982 					       uint8_t mac_id)
11983 {
11984 	struct policy_mgr_hw_mode_params hw_mode = {0};
11985 	struct policy_mgr_vdev_mac_map vdev_mac_map = {0};
11986 	QDF_STATUS status;
11987 
11988 	vdev_mac_map.vdev_id = nan_vdev_id;
11989 	vdev_mac_map.mac_id = mac_id;
11990 
11991 	status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
11992 
11993 	if (QDF_IS_STATUS_SUCCESS(status))
11994 		policy_mgr_update_hw_mode_conn_info(psoc, 1, &vdev_mac_map,
11995 						    hw_mode, 0, NULL);
11996 
11997 	return status;
11998 }
11999 
policy_mgr_is_sap_go_on_2g(struct wlan_objmgr_psoc * psoc)12000 bool policy_mgr_is_sap_go_on_2g(struct wlan_objmgr_psoc *psoc)
12001 {
12002 	struct policy_mgr_psoc_priv_obj *pm_ctx;
12003 	uint32_t conn_index;
12004 	bool ret = false;
12005 
12006 	pm_ctx = policy_mgr_get_context(psoc);
12007 	if (!pm_ctx) {
12008 		policy_mgr_err("Invalid Context");
12009 		return ret;
12010 	}
12011 
12012 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
12013 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
12014 		 conn_index++) {
12015 		if ((pm_conc_connection_list[conn_index].mode == PM_SAP_MODE ||
12016 		     pm_conc_connection_list[conn_index].mode == PM_P2P_GO_MODE) &&
12017 			 pm_conc_connection_list[conn_index].freq <=
12018 				WLAN_REG_MAX_24GHZ_CHAN_FREQ &&
12019 			 pm_conc_connection_list[conn_index].in_use)
12020 			ret = true;
12021 	}
12022 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
12023 
12024 	return ret;
12025 }
12026 
12027 static inline bool
policy_mgr_is_chan_eligible_for_sap(struct policy_mgr_psoc_priv_obj * pm_ctx,uint8_t vdev_id,qdf_freq_t freq)12028 policy_mgr_is_chan_eligible_for_sap(struct policy_mgr_psoc_priv_obj *pm_ctx,
12029 				    uint8_t vdev_id, qdf_freq_t freq)
12030 {
12031 	struct wlan_objmgr_vdev *vdev;
12032 	enum channel_state ch_state;
12033 	enum reg_6g_ap_type sta_connected_pwr_type;
12034 	uint32_t ap_power_type_6g = 0;
12035 	bool is_eligible = false;
12036 
12037 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(pm_ctx->psoc, vdev_id,
12038 						    WLAN_POLICY_MGR_ID);
12039 	if (!vdev)
12040 		return false;
12041 
12042 	ch_state = wlan_reg_get_channel_state_for_pwrmode(pm_ctx->pdev,
12043 							  freq,
12044 							  REG_CURRENT_PWR_MODE);
12045 	sta_connected_pwr_type = mlme_get_best_6g_power_type(vdev);
12046 	wlan_reg_get_cur_6g_ap_pwr_type(pm_ctx->pdev, &ap_power_type_6g);
12047 
12048 	/*
12049 	 * If the SAP user configured frequency is 6 GHz,
12050 	 * move the SAP to STA SCC in 6 GHz only if:
12051 	 * a) The channel is PSC
12052 	 * b) The channel supports AP in VLP power type
12053 	 * c) The DUT is configured to operate SAP in VLP only
12054 	 * d) The STA is connected to the 6 GHz AP in
12055 	 *    either VLP or LPI.
12056 	 *    - If the STA is in LPI, then lim_update_tx_power()
12057 	 *	would move the STA to VLP.
12058 	 */
12059 	if (WLAN_REG_IS_6GHZ_PSC_CHAN_FREQ(freq) &&
12060 	    ap_power_type_6g == REG_VERY_LOW_POWER_AP &&
12061 	    ch_state == CHANNEL_STATE_ENABLE &&
12062 	    (sta_connected_pwr_type == REG_VERY_LOW_POWER_AP ||
12063 	     sta_connected_pwr_type == REG_INDOOR_AP))
12064 		is_eligible = true;
12065 
12066 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
12067 	return is_eligible;
12068 }
12069 
policy_mgr_is_restart_sap_required(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,qdf_freq_t freq,tQDF_MCC_TO_SCC_SWITCH_MODE scc_mode)12070 bool policy_mgr_is_restart_sap_required(struct wlan_objmgr_psoc *psoc,
12071 					uint8_t vdev_id,
12072 					qdf_freq_t freq,
12073 					tQDF_MCC_TO_SCC_SWITCH_MODE scc_mode)
12074 {
12075 	uint8_t i;
12076 	bool restart_required = false;
12077 	bool is_sta_p2p_cli;
12078 	bool sap_on_dfs = false;
12079 	struct policy_mgr_psoc_priv_obj *pm_ctx;
12080 	struct policy_mgr_conc_connection_info *connection;
12081 	bool sta_sap_scc_on_dfs_chan, sta_sap_scc_allowed_on_indoor_ch;
12082 	qdf_freq_t user_config_freq;
12083 	bool sap_found = false;
12084 	uint8_t num_mcc_conn = 0;
12085 	uint8_t num_scc_conn = 0;
12086 	uint8_t num_5_or_6_conn = 0;
12087 
12088 	pm_ctx = policy_mgr_get_context(psoc);
12089 	if (!pm_ctx) {
12090 		policy_mgr_err("Invalid psoc");
12091 		return false;
12092 	}
12093 
12094 	if (policy_mgr_is_vdev_ll_lt_sap(psoc, vdev_id)) {
12095 		if (policy_mgr_is_ll_lt_sap_restart_required(psoc))
12096 			return true;
12097 		return false;
12098 	}
12099 
12100 	if (scc_mode == QDF_MCC_TO_SCC_SWITCH_DISABLE) {
12101 		policy_mgr_debug("No scc required");
12102 		return false;
12103 	}
12104 
12105 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
12106 	connection = pm_conc_connection_list;
12107 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
12108 		if (!connection[i].in_use)
12109 			continue;
12110 		if (connection[i].vdev_id == vdev_id) {
12111 			if (WLAN_REG_IS_5GHZ_CH_FREQ(connection[i].freq) &&
12112 			    (connection[i].ch_flagext & (IEEE80211_CHAN_DFS |
12113 					      IEEE80211_CHAN_DFS_CFREQ2)))
12114 				sap_on_dfs = true;
12115 			sap_found = true;
12116 		} else {
12117 			if (connection[i].freq == freq)
12118 				num_scc_conn++;
12119 			else
12120 				num_mcc_conn++;
12121 
12122 			if (!WLAN_REG_IS_24GHZ_CH_FREQ(connection[i].freq))
12123 				num_5_or_6_conn++;
12124 		}
12125 	}
12126 	if (!sap_found) {
12127 		policy_mgr_err("Invalid vdev id: %d", vdev_id);
12128 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
12129 		return false;
12130 	}
12131 	/* Current hw mode is SBS low share. STA 5180, SAP 1 2412,
12132 	 * SAP 2 5745, but SAP 1 is 2G only, can't move to STA 5180,
12133 	 * SAP 2 is SBS with STA, policy_mgr_are_2_freq_on_same_mac
12134 	 * return false for 5745 and 5180 and finally this function
12135 	 * return false, no force SCC on SAP2.
12136 	 * Add mcc conntion count check for SAP2, if SAP 2 channel
12137 	 * is different from all of exsting 2 or more connections, then
12138 	 * try to force SCC on SAP 2.
12139 	 */
12140 	if (num_mcc_conn > 1 && !num_scc_conn) {
12141 		policy_mgr_debug("sap vdev %d has chan %d diff with %d exsting conn",
12142 				 vdev_id, freq, num_mcc_conn);
12143 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
12144 		return true;
12145 	}
12146 	sta_sap_scc_on_dfs_chan =
12147 		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
12148 
12149 	sta_sap_scc_allowed_on_indoor_ch =
12150 		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
12151 
12152 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
12153 		if (!connection[i].in_use)
12154 			continue;
12155 
12156 		if (scc_mode == QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL &&
12157 		    connection[i].mode == PM_P2P_GO_MODE &&
12158 		    connection[i].vdev_id != vdev_id &&
12159 		    policy_mgr_2_freq_always_on_same_mac(psoc, freq,
12160 							 connection[i].freq)) {
12161 			policy_mgr_debug("SAP:%d and GO:%d on same mac. Restart SAP ",
12162 					 freq, connection[i].freq);
12163 			restart_required = true;
12164 			break;
12165 		}
12166 
12167 		is_sta_p2p_cli =
12168 			(connection[i].mode == PM_STA_MODE ||
12169 			 connection[i].mode == PM_P2P_CLIENT_MODE);
12170 		if (!is_sta_p2p_cli)
12171 			continue;
12172 
12173 		if (connection[i].freq != freq &&
12174 		    policy_mgr_are_2_freq_on_same_mac(psoc, freq,
12175 						      connection[i].freq)) {
12176 			policy_mgr_debug("SAP:%d and STA:%d on same mac. Restart SAP ",
12177 					 freq, connection[i].freq);
12178 			restart_required = true;
12179 			break;
12180 		}
12181 		if (connection[i].freq == freq &&
12182 		    !sta_sap_scc_on_dfs_chan && sap_on_dfs) {
12183 			policy_mgr_debug("Move SAP out of DFS ch:%d", freq);
12184 			restart_required = true;
12185 			break;
12186 		}
12187 
12188 		if (connection[i].freq == freq &&
12189 		    !sta_sap_scc_allowed_on_indoor_ch &&
12190 		    wlan_reg_is_freq_indoor(pm_ctx->pdev, connection[i].freq)) {
12191 			policy_mgr_debug("Move SAP out of indoor ch:%d", freq);
12192 			restart_required = true;
12193 			break;
12194 		}
12195 
12196 		/*
12197 		 * Existing connection:
12198 		 * 1. "STA in DFS ch and SoftAP in 2.4 GHz channel, and then
12199 		 * STA moves to 5 GHz non-DFS channel
12200 		 *
12201 		 * 2. "STA in indoor channel and sta_sap_scc_on_indoor_ch
12202 		 * ini is false & SAP has moved to 2.4 GHz channel"
12203 		 * STA moves back to 5 GHZ non indoor/non DFS channel
12204 		 *
12205 		 * Now SAP has to move to STA 5 GHz channel if SAP
12206 		 * was started on 5 GHz channel initially.
12207 		 */
12208 		user_config_freq =
12209 			policy_mgr_get_user_config_sap_freq(psoc, vdev_id);
12210 
12211 		if (connection[i].freq != freq &&
12212 		    WLAN_REG_IS_24GHZ_CH_FREQ(freq) &&
12213 		    WLAN_REG_IS_5GHZ_CH_FREQ(connection[i].freq) &&
12214 		    !wlan_reg_is_dfs_for_freq(pm_ctx->pdev,
12215 					      connection[i].freq) &&
12216 		    WLAN_REG_IS_5GHZ_CH_FREQ(user_config_freq)) {
12217 			policy_mgr_debug("Move SAP from:%d to STA ch:%d  (sap start freq:%d)",
12218 					 freq, connection[i].freq,
12219 					 user_config_freq);
12220 			restart_required = true;
12221 
12222 			if (wlan_reg_is_freq_indoor(pm_ctx->pdev,
12223 						    connection[i].freq) &&
12224 			    !sta_sap_scc_allowed_on_indoor_ch)
12225 				restart_required = false;
12226 			break;
12227 		}
12228 
12229 		/*
12230 		 * SAP has to move away from indoor only channel
12231 		 * when STA moves out of indoor only channel and
12232 		 * SAP standalone support on indoor only
12233 		 * channel ini is disabled
12234 		 **/
12235 		if (connection[i].freq != freq &&
12236 		    WLAN_REG_IS_24GHZ_CH_FREQ(connection[i].freq) &&
12237 		    WLAN_REG_IS_5GHZ_CH_FREQ(freq) &&
12238 		    !policy_mgr_is_sap_go_interface_allowed_on_indoor(
12239 							pm_ctx->pdev,
12240 							vdev_id, freq)) {
12241 			policy_mgr_debug("SAP in indoor freq: sta:%d sap:%d",
12242 					 connection[i].freq, freq);
12243 			restart_required = true;
12244 		}
12245 
12246 		if (scc_mode == QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL &&
12247 		    WLAN_REG_IS_24GHZ_CH_FREQ(freq) && user_config_freq) {
12248 			if (connection[i].freq == freq && !num_5_or_6_conn &&
12249 			    !WLAN_REG_IS_24GHZ_CH_FREQ(user_config_freq)) {
12250 				policy_mgr_debug("SAP move to user configure %d from %d",
12251 						 user_config_freq, freq);
12252 				restart_required = true;
12253 			} else if (connection[i].freq != freq &&
12254 				   WLAN_REG_IS_6GHZ_CHAN_FREQ(user_config_freq) &&
12255 				   policy_mgr_is_chan_eligible_for_sap(pm_ctx,
12256 								       connection[i].vdev_id,
12257 								       connection[i].freq)) {
12258 				policy_mgr_debug("Move SAP to STA 6 GHz channel");
12259 				restart_required = true;
12260 			}
12261 		}
12262 	}
12263 
12264 	if (!restart_required &&
12265 	    policy_mgr_is_restart_sap_required_with_mlo_sta(
12266 					psoc, vdev_id, freq))
12267 		restart_required = true;
12268 
12269 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
12270 
12271 	return restart_required;
12272 }
12273 
policy_mgr_get_roam_enabled_sta_session_id(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)12274 uint8_t policy_mgr_get_roam_enabled_sta_session_id(
12275 					struct wlan_objmgr_psoc *psoc,
12276 					uint8_t vdev_id)
12277 {
12278 	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
12279 	uint32_t index, count;
12280 	struct policy_mgr_psoc_priv_obj *pm_ctx;
12281 	struct wlan_objmgr_vdev *vdev, *assoc_vdev;
12282 
12283 	pm_ctx = policy_mgr_get_context(psoc);
12284 	if (!pm_ctx) {
12285 		policy_mgr_err("Invalid Context");
12286 		return WLAN_UMAC_VDEV_ID_MAX;
12287 	}
12288 
12289 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
12290 						    WLAN_POLICY_MGR_ID);
12291 	if (!vdev) {
12292 		policy_mgr_err("Invalid vdev");
12293 		return WLAN_UMAC_VDEV_ID_MAX;
12294 	}
12295 
12296 	if (wlan_vdev_mlme_is_link_sta_vdev(vdev)) {
12297 		assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev);
12298 		if (assoc_vdev && ucfg_cm_is_vdev_active(assoc_vdev)) {
12299 			policy_mgr_debug("replace link vdev %d with assoc vdev %d",
12300 					 vdev_id, wlan_vdev_get_id(assoc_vdev));
12301 			vdev_id = wlan_vdev_get_id(assoc_vdev);
12302 		}
12303 	}
12304 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
12305 
12306 	count = policy_mgr_mode_specific_connection_count(
12307 		psoc, PM_STA_MODE, list);
12308 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
12309 
12310 	for (index = 0; index < count; index++) {
12311 		if (vdev_id == pm_conc_connection_list[list[index]].vdev_id)
12312 			continue;
12313 		if (MLME_IS_ROAM_INITIALIZED(
12314 			psoc, pm_conc_connection_list[list[index]].vdev_id)) {
12315 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
12316 			return pm_conc_connection_list[list[index]].vdev_id;
12317 		}
12318 	}
12319 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
12320 
12321 	return WLAN_UMAC_VDEV_ID_MAX;
12322 }
12323 
policy_mgr_is_sta_mon_concurrency(struct wlan_objmgr_psoc * psoc)12324 bool policy_mgr_is_sta_mon_concurrency(struct wlan_objmgr_psoc *psoc)
12325 {
12326 	uint32_t conc_mode;
12327 
12328 	if (wlan_mlme_is_sta_mon_conc_supported(psoc)) {
12329 		conc_mode = policy_mgr_get_concurrency_mode(psoc);
12330 		if (conc_mode & QDF_STA_MASK &&
12331 		    conc_mode & QDF_MONITOR_MASK) {
12332 			policy_mgr_err("STA + MON mode is UP");
12333 			return true;
12334 		}
12335 	}
12336 	return false;
12337 }
12338 
policy_mgr_check_mon_concurrency(struct wlan_objmgr_psoc * psoc)12339 QDF_STATUS policy_mgr_check_mon_concurrency(struct wlan_objmgr_psoc *psoc)
12340 {
12341 	uint8_t num_open_session = 0;
12342 
12343 	if (policy_mgr_mode_specific_num_open_sessions(
12344 				psoc,
12345 				QDF_MONITOR_MODE,
12346 				&num_open_session) != QDF_STATUS_SUCCESS)
12347 		return QDF_STATUS_E_INVAL;
12348 
12349 	if (num_open_session) {
12350 		policy_mgr_err("monitor mode already exists, only one is possible");
12351 		return QDF_STATUS_E_BUSY;
12352 	}
12353 
12354 	num_open_session = policy_mgr_get_sap_mode_count(psoc, NULL);
12355 
12356 	if (num_open_session) {
12357 		policy_mgr_err("cannot add monitor mode, due to SAP concurrency");
12358 		return QDF_STATUS_E_INVAL;
12359 	}
12360 
12361 	num_open_session = policy_mgr_mode_specific_connection_count(
12362 					psoc,
12363 					PM_P2P_CLIENT_MODE,
12364 					NULL);
12365 
12366 	if (num_open_session) {
12367 		policy_mgr_err("cannot add monitor mode, due to P2P CLIENT concurrency");
12368 		return QDF_STATUS_E_INVAL;
12369 	}
12370 
12371 	num_open_session = policy_mgr_mode_specific_connection_count(
12372 					psoc,
12373 					PM_P2P_GO_MODE,
12374 					NULL);
12375 
12376 	if (num_open_session) {
12377 		policy_mgr_err("cannot add monitor mode, due to P2P GO concurrency");
12378 		return QDF_STATUS_E_INVAL;
12379 	}
12380 
12381 	num_open_session = policy_mgr_mode_specific_connection_count(
12382 					psoc,
12383 					PM_NAN_DISC_MODE,
12384 					NULL);
12385 
12386 	if (num_open_session) {
12387 		policy_mgr_err("cannot add monitor mode, due to NAN concurrency");
12388 		return QDF_STATUS_E_INVAL;
12389 	}
12390 
12391 	return QDF_STATUS_SUCCESS;
12392 }
12393 
policy_mgr_is_hwmode_offload_enabled(struct wlan_objmgr_psoc * psoc)12394 bool policy_mgr_is_hwmode_offload_enabled(struct wlan_objmgr_psoc *psoc)
12395 {
12396 	struct wmi_unified *wmi_handle;
12397 
12398 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
12399 	if (!wmi_handle) {
12400 		policy_mgr_err("Invalid WMI handle");
12401 		return false;
12402 	}
12403 
12404 	return wmi_service_enabled(wmi_handle,
12405 				   wmi_service_hw_mode_policy_offload_support);
12406 }
12407 
policy_mgr_is_ap_ap_mcc_allow(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_vdev * vdev,uint32_t ch_freq,enum phy_ch_width ch_width,uint8_t * con_vdev_id,uint32_t * con_freq)12408 bool policy_mgr_is_ap_ap_mcc_allow(struct wlan_objmgr_psoc *psoc,
12409 				   struct wlan_objmgr_pdev *pdev,
12410 				   struct wlan_objmgr_vdev *vdev,
12411 				   uint32_t ch_freq,
12412 				   enum phy_ch_width ch_width,
12413 				   uint8_t *con_vdev_id,
12414 				   uint32_t *con_freq)
12415 {
12416 	enum QDF_OPMODE mode;
12417 	enum policy_mgr_con_mode con_mode;
12418 	union conc_ext_flag conc_ext_flags;
12419 	uint32_t cc_count, i, j, ap_index;
12420 	uint32_t op_freq[MAX_NUMBER_OF_CONC_CONNECTIONS * 2];
12421 	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS * 2];
12422 	QDF_STATUS status;
12423 	struct policy_mgr_pcl_list pcl;
12424 
12425 	if (!psoc || !vdev || !pdev) {
12426 		policy_mgr_debug("psoc or vdev or pdev is NULL");
12427 		return false;
12428 	}
12429 
12430 	cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
12431 							  &op_freq[0],
12432 							  &vdev_id[0],
12433 							  PM_SAP_MODE);
12434 	if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS)
12435 		cc_count = cc_count +
12436 				policy_mgr_get_mode_specific_conn_info(
12437 					psoc,
12438 					&op_freq[cc_count],
12439 					&vdev_id[cc_count],
12440 					PM_P2P_GO_MODE);
12441 	if (!cc_count)
12442 		return true;
12443 
12444 	mode = wlan_vdev_mlme_get_opmode(vdev);
12445 	con_mode = policy_mgr_qdf_opmode_to_pm_con_mode(
12446 				psoc, mode, wlan_vdev_get_id(vdev));
12447 	qdf_mem_zero(&pcl, sizeof(pcl));
12448 	status = policy_mgr_get_pcl(psoc, con_mode, pcl.pcl_list, &pcl.pcl_len,
12449 				    pcl.weight_list,
12450 				    QDF_ARRAY_SIZE(pcl.weight_list),
12451 				    wlan_vdev_get_id(vdev));
12452 	if (!pcl.pcl_len)
12453 		return true;
12454 	ap_index = cc_count;
12455 	for (i = 0 ; i < pcl.pcl_len; i++) {
12456 		for (j = 0; j < cc_count; j++) {
12457 			if (op_freq[j] == pcl.pcl_list[i])
12458 				break;
12459 		}
12460 		if (j >= cc_count)
12461 			continue;
12462 		if (ch_freq == op_freq[j]) {
12463 			ap_index = j;
12464 			break;
12465 		}
12466 		if (!policy_mgr_is_hw_dbs_capable(psoc)) {
12467 			ap_index = j;
12468 			break;
12469 		}
12470 		if (wlan_reg_is_same_band_freqs(ch_freq, op_freq[j]) &&
12471 		    !policy_mgr_are_sbs_chan(psoc, ch_freq, op_freq[j])) {
12472 			ap_index = j;
12473 			break;
12474 		}
12475 		if (wlan_reg_is_same_band_freqs(ch_freq, op_freq[j]) &&
12476 		    policy_mgr_get_connection_count(psoc) > 2) {
12477 			ap_index = j;
12478 			break;
12479 		}
12480 	}
12481 	/* If same band MCC SAP/GO not present, return true,
12482 	 * no AP to AP channel override
12483 	 */
12484 	if (ap_index >= cc_count)
12485 		return true;
12486 
12487 	*con_freq = op_freq[ap_index];
12488 	*con_vdev_id = vdev_id[ap_index];
12489 	/*
12490 	 * For 3Vif concurrency we only support SCC in same MAC
12491 	 * in below combination:
12492 	 * 2 beaconing entities with STA in SCC.
12493 	 * 3 beaconing entities in SCC.
12494 	 */
12495 	conc_ext_flags.value = policy_mgr_get_conc_ext_flags(vdev, false);
12496 	if (!policy_mgr_allow_concurrency(
12497 			psoc, con_mode, ch_freq,
12498 			policy_mgr_get_bw(ch_width),
12499 			conc_ext_flags.value,
12500 			wlan_vdev_get_id(vdev))) {
12501 		policy_mgr_debug("AP AP mcc not allowed, try to override 2nd SAP/GO chan");
12502 		return false;
12503 	}
12504 	/* For SCC case & bandwdith > 20, the center frequency have to be
12505 	 * same to avoid target MCC on different center frequency even though
12506 	 * primary channel are same.
12507 	 */
12508 	if (*con_freq == ch_freq && wlan_reg_get_bw_value(ch_width) > 20)
12509 		return false;
12510 
12511 	return true;
12512 }
12513 
policy_mgr_any_other_vdev_on_same_mac_as_freq(struct wlan_objmgr_psoc * psoc,uint32_t freq,uint8_t vdev_id)12514 bool policy_mgr_any_other_vdev_on_same_mac_as_freq(
12515 				struct wlan_objmgr_psoc *psoc,
12516 				uint32_t freq, uint8_t vdev_id)
12517 {
12518 	struct policy_mgr_psoc_priv_obj *pm_ctx;
12519 	uint32_t conn_index = 0;
12520 	bool same_mac = false;
12521 
12522 	pm_ctx = policy_mgr_get_context(psoc);
12523 	if (!pm_ctx) {
12524 		policy_mgr_err("Invalid Context");
12525 		return false;
12526 	}
12527 
12528 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
12529 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
12530 	     conn_index++) {
12531 		if (!pm_conc_connection_list[conn_index].in_use)
12532 			continue;
12533 
12534 		if (pm_conc_connection_list[conn_index].vdev_id == vdev_id)
12535 			continue;
12536 
12537 		if (policy_mgr_are_2_freq_on_same_mac(
12538 				psoc,
12539 				pm_conc_connection_list[conn_index].freq,
12540 				freq)) {
12541 			same_mac = true;
12542 			break;
12543 		}
12544 	}
12545 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
12546 
12547 	return same_mac;
12548 }
12549 
policy_mgr_get_sbs_cfg(struct wlan_objmgr_psoc * psoc,bool * sbs)12550 QDF_STATUS policy_mgr_get_sbs_cfg(struct wlan_objmgr_psoc *psoc, bool *sbs)
12551 {
12552 	struct policy_mgr_psoc_priv_obj *pm_ctx;
12553 
12554 	pm_ctx = policy_mgr_get_context(psoc);
12555 	if (!pm_ctx) {
12556 		policy_mgr_err("pm_ctx is NULL");
12557 		return QDF_STATUS_E_FAILURE;
12558 	}
12559 	*sbs = pm_ctx->cfg.sbs_enable;
12560 
12561 	return QDF_STATUS_SUCCESS;
12562 }
12563 
12564 #ifdef WLAN_FEATURE_SR
policy_mgr_sr_same_mac_conc_enabled(struct wlan_objmgr_psoc * psoc)12565 bool policy_mgr_sr_same_mac_conc_enabled(struct wlan_objmgr_psoc *psoc)
12566 {
12567 	struct wmi_unified *wmi_handle;
12568 	bool sr_conc_enabled;
12569 
12570 	if (!psoc) {
12571 		mlme_err("PSOC is NULL");
12572 		return false;
12573 	}
12574 
12575 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
12576 	if (!wmi_handle) {
12577 		mlme_err("wmi_handle is null");
12578 		return false;
12579 	}
12580 
12581 	sr_conc_enabled = policy_mgr_get_same_mac_conc_sr_status(psoc);
12582 
12583 	return (sr_conc_enabled &&
12584 		wmi_service_enabled(wmi_handle,
12585 				    wmi_service_obss_per_packet_sr_support));
12586 }
12587 #endif
12588 
12589 /**
12590  * _policy_mgr_get_ll_sap_freq()- Function to get LL sap freq if it's present
12591  * for provided type
12592  * @psoc: PSOC object
12593  * @ap_type: low latency ap type
12594  *
12595  * Return: freq if LL SAP otherwise return 0
12596  *
12597  */
_policy_mgr_get_ll_sap_freq(struct wlan_objmgr_psoc * psoc,enum ll_ap_type ap_type)12598 static qdf_freq_t _policy_mgr_get_ll_sap_freq(struct wlan_objmgr_psoc *psoc,
12599 					      enum ll_ap_type ap_type)
12600 {
12601 	struct wlan_objmgr_vdev *sap_vdev;
12602 	struct policy_mgr_psoc_priv_obj *pm_ctx;
12603 	uint32_t conn_idx = 0, vdev_id;
12604 	bool is_ll_sap_present = false;
12605 	qdf_freq_t freq = 0;
12606 	enum host_concurrent_ap_policy profile =
12607 					HOST_CONCURRENT_AP_POLICY_UNSPECIFIED;
12608 
12609 	pm_ctx = policy_mgr_get_context(psoc);
12610 	if (!pm_ctx) {
12611 		policy_mgr_err("pm_ctx is NULL");
12612 		return 0;
12613 	}
12614 
12615 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
12616 	for (conn_idx = 0; conn_idx < MAX_NUMBER_OF_CONC_CONNECTIONS;
12617 	     conn_idx++) {
12618 		if (!(policy_mgr_is_sap_mode(
12619 				pm_conc_connection_list[conn_idx].mode) &&
12620 		      pm_conc_connection_list[conn_idx].in_use))
12621 			continue;
12622 
12623 		vdev_id = pm_conc_connection_list[conn_idx].vdev_id;
12624 		freq = pm_conc_connection_list[conn_idx].freq;
12625 
12626 		sap_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
12627 				psoc,
12628 				vdev_id,
12629 				WLAN_POLICY_MGR_ID);
12630 
12631 		if (!sap_vdev) {
12632 			policy_mgr_err("vdev %d: not a sap vdev", vdev_id);
12633 			continue;
12634 		}
12635 
12636 		profile = wlan_mlme_get_ap_policy(sap_vdev);
12637 		wlan_objmgr_vdev_release_ref(sap_vdev,
12638 					     WLAN_POLICY_MGR_ID);
12639 		switch (ap_type) {
12640 		case LL_AP_TYPE_HT:
12641 			if (profile == HOST_CONCURRENT_AP_POLICY_XR)
12642 				is_ll_sap_present = true;
12643 		break;
12644 		case LL_AP_TYPE_LT:
12645 			if (profile == HOST_CONCURRENT_AP_POLICY_GAMING_AUDIO ||
12646 			    profile ==
12647 			    HOST_CONCURRENT_AP_POLICY_LOSSLESS_AUDIO_STREAMING)
12648 				is_ll_sap_present = true;
12649 		break;
12650 		case LL_AP_TYPE_ANY:
12651 			if (profile == HOST_CONCURRENT_AP_POLICY_GAMING_AUDIO ||
12652 			    profile == HOST_CONCURRENT_AP_POLICY_XR ||
12653 			    profile ==
12654 			    HOST_CONCURRENT_AP_POLICY_LOSSLESS_AUDIO_STREAMING)
12655 				is_ll_sap_present = true;
12656 		break;
12657 		default:
12658 		break;
12659 		}
12660 		if (!is_ll_sap_present)
12661 			continue;
12662 
12663 	       policy_mgr_debug("LL SAP %d present with vdev_id %d and freq %d",
12664 				ap_type, vdev_id, freq);
12665 
12666 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
12667 		return freq;
12668 	}
12669 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
12670 	return 0;
12671 }
12672 
policy_mgr_get_ll_sap_freq(struct wlan_objmgr_psoc * psoc)12673 qdf_freq_t policy_mgr_get_ll_sap_freq(struct wlan_objmgr_psoc *psoc)
12674 {
12675 	return _policy_mgr_get_ll_sap_freq(psoc, LL_AP_TYPE_ANY);
12676 }
12677 
policy_mgr_get_ll_ht_sap_freq(struct wlan_objmgr_psoc * psoc)12678 qdf_freq_t policy_mgr_get_ll_ht_sap_freq(struct wlan_objmgr_psoc *psoc)
12679 {
12680 	return _policy_mgr_get_ll_sap_freq(psoc, LL_AP_TYPE_HT);
12681 }
12682 
policy_mgr_get_ll_lt_sap_freq(struct wlan_objmgr_psoc * psoc)12683 qdf_freq_t policy_mgr_get_ll_lt_sap_freq(struct wlan_objmgr_psoc *psoc)
12684 {
12685 	return _policy_mgr_get_ll_sap_freq(psoc, LL_AP_TYPE_LT);
12686 }
12687 
12688 #ifndef WLAN_FEATURE_LL_LT_SAP
policy_mgr_is_ll_sap_concurrency_valid(struct wlan_objmgr_psoc * psoc,qdf_freq_t freq,enum policy_mgr_con_mode mode)12689 bool policy_mgr_is_ll_sap_concurrency_valid(struct wlan_objmgr_psoc *psoc,
12690 					    qdf_freq_t freq,
12691 					    enum policy_mgr_con_mode mode)
12692 {
12693 	qdf_freq_t ll_sap_freq;
12694 
12695 	ll_sap_freq = policy_mgr_get_ll_sap_freq(psoc);
12696 	if (!ll_sap_freq)
12697 		return true;
12698 
12699 	/*
12700 	 * Scenario: When low latency SAP with 5GHz channel(whose
12701 	 * profile is set as gaming or lossless audio or XR) is present
12702 	 * on SBS/DBS hardware and the other interface like
12703 	 * STA/SAP/GC/GO trying to form connection.
12704 	 * Allow connection on those freq which are mutually exclusive
12705 	 * to LL SAP mac
12706 	 */
12707 
12708 	if (policy_mgr_2_freq_always_on_same_mac(psoc, ll_sap_freq,
12709 						 freq)) {
12710 		policy_mgr_debug("Invalid LL-SAP concurrency for SBS/DBS hw, ll-sap freq %d, conc_freq %d, conc_mode %d",
12711 				 ll_sap_freq, freq, mode);
12712 		return false;
12713 	}
12714 
12715 	return true;
12716 }
12717 #endif
12718 
12719 bool
policy_mgr_update_indoor_concurrency(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint32_t discon_freq,enum indoor_conc_update_type type)12720 policy_mgr_update_indoor_concurrency(struct wlan_objmgr_psoc *psoc,
12721 				     uint8_t vdev_id,
12722 				     uint32_t discon_freq,
12723 				     enum indoor_conc_update_type type)
12724 {
12725 	uint32_t ch_freq;
12726 	enum QDF_OPMODE mode;
12727 	struct policy_mgr_psoc_priv_obj *pm_ctx;
12728 	enum phy_ch_width ch_width = CH_WIDTH_INVALID;
12729 	bool indoor_support = false;
12730 
12731 	pm_ctx = policy_mgr_get_context(psoc);
12732 	if (!pm_ctx) {
12733 		policy_mgr_err("Invalid pm context");
12734 		return false;
12735 	}
12736 
12737 	ucfg_mlme_get_indoor_channel_support(psoc, &indoor_support);
12738 	if (indoor_support ||
12739 	    !policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc))
12740 		return false;
12741 
12742 	mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id);
12743 
12744 	/**
12745 	 * DISCONNECT_WITH_CONCURRENCY update comes after SAP/GO CSA.
12746 	 * Whereas, all other updates come from STA/GC operation.
12747 	 */
12748 	if (type != DISCONNECT_WITH_CONCURRENCY &&
12749 	    (mode != QDF_STA_MODE && mode != QDF_P2P_CLIENT_MODE)) {
12750 		return false;
12751 	} else if (type == DISCONNECT_WITH_CONCURRENCY &&
12752 		 (mode != QDF_SAP_MODE && mode != QDF_P2P_GO_MODE)) {
12753 		return false;
12754 	}
12755 
12756 	switch (type) {
12757 	case CONNECT:
12758 	case SWITCH_WITHOUT_CONCURRENCY:
12759 	case SWITCH_WITH_CONCURRENCY:
12760 		policy_mgr_get_chan_by_session_id(psoc, vdev_id, &ch_freq);
12761 		ch_width = policy_mgr_get_bw_by_session_id(psoc, vdev_id);
12762 		break;
12763 	case DISCONNECT_WITHOUT_CONCURRENCY:
12764 	case DISCONNECT_WITH_CONCURRENCY:
12765 		ch_freq = discon_freq;
12766 		break;
12767 	default:
12768 		return false;
12769 	}
12770 
12771 	if (type != SWITCH_WITHOUT_CONCURRENCY &&
12772 	    !(WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) &&
12773 	    wlan_reg_is_freq_indoor(pm_ctx->pdev, ch_freq))) {
12774 		return false;
12775 	} else if (type == SWITCH_WITHOUT_CONCURRENCY) {
12776 		/* Either the previous frequency or the current
12777 		 * frequency can be indoor. Or both can be indoor.
12778 		 * Therefore, atleast one of the frequency must be
12779 		 * indoor in order to proceed for the update.
12780 		 */
12781 		if (!((WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) &&
12782 		       wlan_reg_is_freq_indoor(pm_ctx->pdev, ch_freq)) ||
12783 		      (WLAN_REG_IS_5GHZ_CH_FREQ(discon_freq) &&
12784 		       wlan_reg_is_freq_indoor(pm_ctx->pdev, discon_freq))))
12785 			return false;
12786 	}
12787 
12788 	switch (type) {
12789 	case CONNECT:
12790 		wlan_reg_modify_indoor_concurrency(pm_ctx->pdev, vdev_id,
12791 						   ch_freq, ch_width, true);
12792 		break;
12793 	case DISCONNECT_WITHOUT_CONCURRENCY:
12794 		wlan_reg_modify_indoor_concurrency(pm_ctx->pdev, vdev_id,
12795 						   0, CH_WIDTH_INVALID, false);
12796 		break;
12797 	case SWITCH_WITHOUT_CONCURRENCY:
12798 		wlan_reg_modify_indoor_concurrency(pm_ctx->pdev, vdev_id, 0,
12799 						   CH_WIDTH_INVALID, false);
12800 		if (wlan_reg_is_freq_indoor(pm_ctx->pdev, ch_freq))
12801 			wlan_reg_modify_indoor_concurrency(pm_ctx->pdev,
12802 							   vdev_id, ch_freq,
12803 							   ch_width, true);
12804 		break;
12805 	case DISCONNECT_WITH_CONCURRENCY:
12806 		/*If there are other sessions, do not change current chan list*/
12807 		if (policy_mgr_get_connection_count_with_ch_freq(ch_freq) > 1)
12808 			return false;
12809 		wlan_reg_modify_indoor_concurrency(pm_ctx->pdev,
12810 						   INVALID_VDEV_ID, ch_freq,
12811 						   CH_WIDTH_INVALID, false);
12812 		break;
12813 	case SWITCH_WITH_CONCURRENCY:
12814 		wlan_reg_modify_indoor_concurrency(pm_ctx->pdev, vdev_id,
12815 						   ch_freq, ch_width, true);
12816 		/*
12817 		 * The previous frequency removal and current channel list
12818 		 * recomputation will happen after SAP CSA
12819 		 */
12820 		return false;
12821 	}
12822 	return true;
12823 }
12824 
policy_mgr_is_conc_sap_present_on_sta_freq(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint32_t ch_freq)12825 bool policy_mgr_is_conc_sap_present_on_sta_freq(struct wlan_objmgr_psoc *psoc,
12826 						enum policy_mgr_con_mode mode,
12827 						uint32_t ch_freq)
12828 {
12829 	struct policy_mgr_psoc_priv_obj *pm_ctx;
12830 	uint8_t i;
12831 	bool sap_go_exists = false;
12832 	enum policy_mgr_con_mode cmode;
12833 
12834 	pm_ctx = policy_mgr_get_context(psoc);
12835 	if (!pm_ctx) {
12836 		policy_mgr_err("Invalid pm context");
12837 		return false;
12838 	}
12839 
12840 	if (mode != PM_STA_MODE && mode != PM_P2P_CLIENT_MODE)
12841 		return false;
12842 
12843 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
12844 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
12845 		cmode = pm_conc_connection_list[i].mode;
12846 		if (pm_conc_connection_list[i].in_use &&
12847 		    ch_freq == pm_conc_connection_list[i].freq &&
12848 		    (cmode == PM_SAP_MODE || cmode == PM_P2P_GO_MODE)) {
12849 			sap_go_exists = true;
12850 			break;
12851 		}
12852 	}
12853 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
12854 
12855 	return sap_go_exists;
12856 }
12857 
policy_mgr_is_sap_mode(enum policy_mgr_con_mode mode)12858 bool policy_mgr_is_sap_mode(enum policy_mgr_con_mode mode)
12859 {
12860 	if (mode == PM_SAP_MODE || mode == PM_LL_LT_SAP_MODE)
12861 		return true;
12862 
12863 	return false;
12864 }
12865 
policy_mgr_is_beaconing_mode(enum policy_mgr_con_mode mode)12866 bool policy_mgr_is_beaconing_mode(enum policy_mgr_con_mode mode)
12867 {
12868 	if (mode == PM_SAP_MODE || mode == PM_LL_LT_SAP_MODE ||
12869 	    mode == PM_P2P_GO_MODE)
12870 		return true;
12871 
12872 	return false;
12873 }
12874 
policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(struct wlan_objmgr_psoc * psoc)12875 bool policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(struct wlan_objmgr_psoc *psoc)
12876 {
12877 	struct policy_mgr_psoc_priv_obj *pm_ctx;
12878 
12879 	pm_ctx = policy_mgr_get_context(psoc);
12880 	if (!pm_ctx) {
12881 		policy_mgr_err("pm_ctx is NULL");
12882 		return 0;
12883 	}
12884 	return pm_ctx->cfg.nan_sap_scc_on_lte_coex_chnl;
12885 }
12886 
12887 QDF_STATUS
policy_mgr_reset_sap_mandatory_channels(struct wlan_objmgr_psoc * psoc)12888 policy_mgr_reset_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc)
12889 {
12890 	struct policy_mgr_psoc_priv_obj *pm_ctx;
12891 
12892 	pm_ctx = policy_mgr_get_context(psoc);
12893 	if (!pm_ctx) {
12894 		policy_mgr_err("Invalid Context");
12895 		return QDF_STATUS_E_FAILURE;
12896 	}
12897 
12898 	pm_ctx->sap_mandatory_channels_len = 0;
12899 	qdf_mem_zero(pm_ctx->sap_mandatory_channels,
12900 		     QDF_ARRAY_SIZE(pm_ctx->sap_mandatory_channels) *
12901 		     sizeof(*pm_ctx->sap_mandatory_channels));
12902 
12903 	return QDF_STATUS_SUCCESS;
12904 }
12905 
policy_mgr_is_freq_on_mac_id(struct policy_mgr_freq_range * freq_range,qdf_freq_t freq,uint8_t mac_id)12906 bool policy_mgr_is_freq_on_mac_id(struct policy_mgr_freq_range *freq_range,
12907 				  qdf_freq_t freq, uint8_t mac_id)
12908 {
12909 	return IS_FREQ_ON_MAC_ID(freq_range, freq, mac_id);
12910 }
12911 
policy_mgr_get_vdev_same_freq_new_conn(struct wlan_objmgr_psoc * psoc,uint32_t new_freq,uint8_t * vdev_id)12912 bool policy_mgr_get_vdev_same_freq_new_conn(struct wlan_objmgr_psoc *psoc,
12913 					    uint32_t new_freq,
12914 					    uint8_t *vdev_id)
12915 {
12916 	struct policy_mgr_psoc_priv_obj *pm_ctx;
12917 	bool match = false;
12918 	uint32_t i;
12919 
12920 	pm_ctx = policy_mgr_get_context(psoc);
12921 	if (qdf_unlikely(!pm_ctx)) {
12922 		policy_mgr_err("Invalid pm_ctx");
12923 		return false;
12924 	}
12925 
12926 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
12927 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
12928 		if (pm_conc_connection_list[i].in_use &&
12929 		    pm_conc_connection_list[i].freq == new_freq) {
12930 			match = true;
12931 			*vdev_id = pm_conc_connection_list[i].vdev_id;
12932 			policy_mgr_debug("new_freq %d matched with vdev_id %d",
12933 					 new_freq, *vdev_id);
12934 			break;
12935 		}
12936 	}
12937 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
12938 
12939 	return match;
12940 }
12941 
policy_mgr_get_vdev_diff_freq_new_conn(struct wlan_objmgr_psoc * psoc,uint32_t new_freq,uint8_t * vdev_id)12942 bool policy_mgr_get_vdev_diff_freq_new_conn(struct wlan_objmgr_psoc *psoc,
12943 					    uint32_t new_freq,
12944 					    uint8_t *vdev_id)
12945 {
12946 	struct policy_mgr_psoc_priv_obj *pm_ctx;
12947 	bool match = false;
12948 	uint32_t i;
12949 
12950 	pm_ctx = policy_mgr_get_context(psoc);
12951 	if (qdf_unlikely(!pm_ctx)) {
12952 		policy_mgr_err("Invalid pm_ctx");
12953 		return false;
12954 	}
12955 
12956 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
12957 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
12958 		if (pm_conc_connection_list[i].in_use &&
12959 		    pm_conc_connection_list[i].freq != new_freq) {
12960 			match = true;
12961 			*vdev_id = pm_conc_connection_list[i].vdev_id;
12962 			policy_mgr_debug("new_freq %d matched with vdev_id %d",
12963 					 new_freq, *vdev_id);
12964 			break;
12965 		}
12966 	}
12967 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
12968 
12969 	return match;
12970 }
12971 
12972 enum hw_mode_bandwidth
policy_mgr_get_connection_max_channel_width(struct wlan_objmgr_psoc * psoc)12973 policy_mgr_get_connection_max_channel_width(struct wlan_objmgr_psoc *psoc)
12974 {
12975 	enum hw_mode_bandwidth bw = HW_MODE_20_MHZ;
12976 	struct policy_mgr_psoc_priv_obj *pm_ctx;
12977 	uint32_t conn_index = 0;
12978 
12979 	pm_ctx = policy_mgr_get_context(psoc);
12980 	if (!pm_ctx) {
12981 		policy_mgr_err("pm_ctx is NULL");
12982 		return HW_MODE_20_MHZ;
12983 	}
12984 
12985 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
12986 
12987 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
12988 	     conn_index++) {
12989 		if (pm_conc_connection_list[conn_index].in_use &&
12990 		    pm_conc_connection_list[conn_index].bw > bw)
12991 			bw = pm_conc_connection_list[conn_index].bw;
12992 	}
12993 
12994 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
12995 
12996 	return bw;
12997 }
12998 
policy_mgr_is_given_freq_5g_low(struct wlan_objmgr_psoc * psoc,qdf_freq_t given_freq)12999 bool policy_mgr_is_given_freq_5g_low(struct wlan_objmgr_psoc *psoc,
13000 				     qdf_freq_t given_freq)
13001 {
13002 	qdf_freq_t sbs_cut_off_freq;
13003 
13004 	sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(psoc);
13005 	if (!sbs_cut_off_freq)
13006 		return false;
13007 
13008 	if (given_freq < sbs_cut_off_freq &&
13009 	    WLAN_REG_IS_5GHZ_CH_FREQ(given_freq))
13010 		return true;
13011 
13012 	return false;
13013 }
13014