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