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