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_pcl.c
22 *
23 * WLAN Concurrenct Connection Management APIs
24 *
25 */
26
27 /* Include files */
28
29 #include "wlan_policy_mgr_api.h"
30 #include "wlan_policy_mgr_i.h"
31 #include "qdf_types.h"
32 #include "qdf_trace.h"
33 #include "qdf_str.h"
34 #include "wlan_objmgr_global_obj.h"
35 #include "wlan_utility.h"
36 #include "wlan_mlme_ucfg_api.h"
37 #ifdef WLAN_FEATURE_11BE_MLO
38 #include "wlan_mlo_mgr_cmn.h"
39 #endif
40 #include "wlan_policy_mgr_ll_sap.h"
41 #include "wlan_cm_ucfg_api.h"
42 #include "wlan_cm_roam_api.h"
43 #include "wlan_scan_api.h"
44 #include "wlan_nan_api.h"
45 #include "wlan_mlo_link_force.h"
46
47 /*
48 * first_connection_pcl_table - table which provides PCL for the
49 * very first connection in the system
50 */
51 const enum policy_mgr_pcl_type
52 first_connection_pcl_table[PM_MAX_NUM_OF_MODE]
53 [PM_MAX_CONC_PRIORITY_MODE] = {
54 [PM_STA_MODE] = {PM_NONE, PM_NONE, PM_NONE},
55 [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G },
56 [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G },
57 [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G },
58 [PM_NAN_DISC_MODE] = {PM_5G, PM_5G, PM_5G},
59 [PM_LL_LT_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
60 };
61
62 pm_dbs_pcl_second_connection_table_type
63 *second_connection_pcl_dbs_table;
64
65 enum policy_mgr_pcl_type const
66 (*second_connection_pcl_non_dbs_table)[PM_MAX_ONE_CONNECTION_MODE]
67 [PM_MAX_NUM_OF_MODE][PM_MAX_CONC_PRIORITY_MODE];
68 pm_dbs_pcl_third_connection_table_type
69 *third_connection_pcl_dbs_table;
70 enum policy_mgr_pcl_type const
71 (*third_connection_pcl_non_dbs_table)[PM_MAX_TWO_CONNECTION_MODE]
72 [PM_MAX_NUM_OF_MODE][PM_MAX_CONC_PRIORITY_MODE];
73 policy_mgr_next_action_two_connection_table_type
74 *next_action_two_connection_table;
75 policy_mgr_next_action_three_connection_table_type
76 *next_action_three_connection_table;
77 policy_mgr_next_action_two_connection_table_type
78 *next_action_two_connection_2x2_2g_1x1_5g_table;
79 policy_mgr_next_action_three_connection_table_type
80 *next_action_three_connection_2x2_2g_1x1_5g_table;
81
policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint32_t * pcl_ch,uint32_t * len,uint8_t * pcl_weight,uint32_t weight_len,bool all_matching_cxn_to_del,uint8_t vdev_id)82 QDF_STATUS policy_mgr_get_pcl_for_existing_conn(
83 struct wlan_objmgr_psoc *psoc,
84 enum policy_mgr_con_mode mode,
85 uint32_t *pcl_ch, uint32_t *len,
86 uint8_t *pcl_weight, uint32_t weight_len,
87 bool all_matching_cxn_to_del,
88 uint8_t vdev_id)
89 {
90 struct policy_mgr_conc_connection_info
91 info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
92 uint8_t num_cxn_del = 0;
93
94 QDF_STATUS status = QDF_STATUS_SUCCESS;
95 struct policy_mgr_psoc_priv_obj *pm_ctx;
96
97 policy_mgr_debug("get pcl for existing conn:%d", mode);
98 pm_ctx = policy_mgr_get_context(psoc);
99 if (!pm_ctx) {
100 policy_mgr_err("Invalid Context");
101 return QDF_STATUS_E_FAILURE;
102 }
103
104 *len = 0;
105 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
106 if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) {
107 /* Check, store and temp delete the mode's parameter */
108 policy_mgr_store_and_del_conn_info(psoc, mode,
109 all_matching_cxn_to_del, info, &num_cxn_del);
110 /* Get the PCL */
111 status = policy_mgr_get_pcl(psoc, mode, pcl_ch, len,
112 pcl_weight, weight_len, vdev_id);
113 policy_mgr_debug("Get PCL to FW for mode:%d", mode);
114 /* Restore the connection info */
115 policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del);
116 }
117 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
118
119 return status;
120 }
121
122 #ifdef WLAN_FEATURE_11BE_MLO
123 /**
124 * policy_mgr_get_pcl_concurrent_connetions() - Get concurrent connections
125 * those will affect PCL fetching for the given vdev id
126 * @psoc: PSOC object information
127 * @mode: Connection Mode
128 * @vdev_id: vdev id
129 * @vdev_ids: vdev id list of the concurrent connections
130 * @vdev_ids_size: size of the vdev id list
131 *
132 * Return: number of the concurrent connections
133 */
134 static uint32_t
policy_mgr_get_pcl_concurrent_connetions(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint8_t vdev_id,uint8_t * vdev_ids,uint32_t vdev_ids_size)135 policy_mgr_get_pcl_concurrent_connetions(struct wlan_objmgr_psoc *psoc,
136 enum policy_mgr_con_mode mode,
137 uint8_t vdev_id, uint8_t *vdev_ids,
138 uint32_t vdev_ids_size)
139 {
140 struct wlan_objmgr_vdev *vdev;
141 struct policy_mgr_psoc_priv_obj *pm_ctx;
142 uint32_t num_related = 0;
143 bool is_ml_sta, has_same_band = false;
144 uint8_t vdev_id_with_diff_band = WLAN_INVALID_VDEV_ID;
145 uint8_t num_ml = 0, num_non_ml = 0, ml_vdev_id;
146 uint8_t ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
147 uint8_t non_ml_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
148 uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
149 qdf_freq_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
150 qdf_freq_t freq = 0, ml_freq;
151 int i;
152
153 if (!vdev_ids || !vdev_ids_size) {
154 policy_mgr_err("Invalid parameters");
155 return num_related;
156 }
157
158 if (mode != PM_STA_MODE) {
159 vdev_ids[0] = vdev_id;
160 return 1;
161 }
162
163 pm_ctx = policy_mgr_get_context(psoc);
164 if (!pm_ctx) {
165 policy_mgr_err("Invalid Context");
166 return 0;
167 }
168
169 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
170 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
171 WLAN_POLICY_MGR_ID);
172 if (!vdev) {
173 policy_mgr_err("vdev %d is not present", vdev_id);
174 goto out;
175 }
176
177 if (wlan_vdev_mlme_is_link_sta_vdev(vdev)) {
178 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
179 policy_mgr_debug("ignore ML STA link vdev %d", vdev_id);
180 goto out;
181 }
182
183 is_ml_sta = wlan_vdev_mlme_is_mlo_vdev(vdev);
184 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
185
186 policy_mgr_get_ml_and_non_ml_sta_count(psoc, &num_ml, ml_idx,
187 &num_non_ml, non_ml_idx,
188 freq_list, vdev_id_list);
189 for (i = 0;
190 i < num_non_ml + num_ml && num_related < vdev_ids_size; i++) {
191 if (vdev_id_list[i] == vdev_id) {
192 vdev_ids[num_related++] = vdev_id;
193 freq = freq_list[i];
194 break;
195 }
196 }
197
198 /* No existing connection for the vdev id */
199 if (!freq)
200 goto out;
201
202 for (i = 0; i < num_ml && num_related < vdev_ids_size; i++) {
203 ml_vdev_id = vdev_id_list[ml_idx[i]];
204 if (ml_vdev_id == vdev_id)
205 continue;
206
207 /* If it's ML STA, return vdev ids for all links */
208 if (is_ml_sta) {
209 policy_mgr_debug("vdev_ids[%d]: %d",
210 num_related, ml_vdev_id);
211 vdev_ids[num_related++] = ml_vdev_id;
212 continue;
213 }
214
215 ml_freq = freq_list[ml_idx[i]];
216 if (wlan_reg_is_24ghz_ch_freq(ml_freq) ==
217 wlan_reg_is_24ghz_ch_freq(freq)) {
218 if (policy_mgr_are_sbs_chan(psoc, freq, ml_freq) &&
219 wlan_cm_same_band_sta_allowed(psoc))
220 continue;
221
222 /*
223 * If it's Non-ML STA, and its freq is within the same
224 * band with one of the existing ML link, but can NOT
225 * lead to SBS, return the original vdev id and vdev id
226 * of the ML link within same band.
227 */
228 policy_mgr_debug("vdev_ids[%d]: %d",
229 num_related, ml_vdev_id);
230 vdev_ids[num_related++] = ml_vdev_id;
231 has_same_band = true;
232 break;
233 }
234
235 vdev_id_with_diff_band = ml_vdev_id;
236 }
237
238 /*
239 * If it's Non-ML STA, and ML STA is present but the links are
240 * within different band or (within same band but can lead to SBS and
241 * same band STA is allowed), return original vdev id and vdev id of
242 * any ML link within different band.
243 */
244 if (!has_same_band && vdev_id_with_diff_band != WLAN_INVALID_VDEV_ID) {
245 policy_mgr_debug("vdev_ids[%d]: %d",
246 num_related, vdev_id_with_diff_band);
247
248 if (num_related < vdev_ids_size)
249 vdev_ids[num_related++] = vdev_id_with_diff_band;
250 }
251
252 out:
253 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
254 return num_related;
255 }
256 #else
257 static inline uint32_t
policy_mgr_get_pcl_concurrent_connetions(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint8_t vdev_id,uint8_t * vdev_ids,uint32_t vdev_ids_size)258 policy_mgr_get_pcl_concurrent_connetions(struct wlan_objmgr_psoc *psoc,
259 enum policy_mgr_con_mode mode,
260 uint8_t vdev_id, uint8_t *vdev_ids,
261 uint32_t vdev_ids_size)
262 {
263 if (!vdev_ids || !vdev_ids_size) {
264 policy_mgr_err("Invalid parameters");
265 return 0;
266 }
267
268 vdev_ids[0] = vdev_id;
269 return 1;
270 }
271 #endif
272
policy_mgr_get_pcl_for_vdev_id(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint32_t * pcl_ch,uint32_t * len,uint8_t * pcl_weight,uint32_t weight_len,uint8_t vdev_id)273 QDF_STATUS policy_mgr_get_pcl_for_vdev_id(struct wlan_objmgr_psoc *psoc,
274 enum policy_mgr_con_mode mode,
275 uint32_t *pcl_ch, uint32_t *len,
276 uint8_t *pcl_weight,
277 uint32_t weight_len,
278 uint8_t vdev_id)
279 {
280 struct policy_mgr_conc_connection_info
281 info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
282 QDF_STATUS status = QDF_STATUS_SUCCESS;
283 struct policy_mgr_psoc_priv_obj *pm_ctx;
284 uint8_t ids[MAX_NUMBER_OF_CONC_CONNECTIONS];
285 uint8_t num_del = 0, total_del = 0, id_num = 0;
286 int i;
287
288 policy_mgr_debug("get pcl for existing conn:%d vdev id %d",
289 mode, vdev_id);
290 pm_ctx = policy_mgr_get_context(psoc);
291 if (!pm_ctx) {
292 policy_mgr_err("Invalid Context");
293 return QDF_STATUS_E_FAILURE;
294 }
295
296 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
297 id_num = policy_mgr_get_pcl_concurrent_connetions(psoc, mode,
298 vdev_id, ids,
299 QDF_ARRAY_SIZE(ids));
300 if (!id_num || id_num > MAX_NUMBER_OF_CONC_CONNECTIONS) {
301 status = QDF_STATUS_E_FAILURE;
302 goto out;
303 }
304
305 *len = 0;
306
307 /* Check, store and temp delete the mode's parameter */
308 for (i = 0; i < id_num; i++) {
309 policy_mgr_store_and_del_conn_info_by_vdev_id(psoc,
310 ids[i],
311 &info[i],
312 &num_del);
313 total_del += num_del;
314 }
315
316 /* Get the PCL */
317 status = policy_mgr_get_pcl(psoc, mode, pcl_ch, len,
318 pcl_weight, weight_len, vdev_id);
319 policy_mgr_debug("Get PCL to FW for mode:%d", mode);
320 /* Restore the connection info */
321 policy_mgr_restore_deleted_conn_info(psoc, info, total_del);
322
323 out:
324 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
325
326 return status;
327 }
328
329 QDF_STATUS
policy_mgr_get_pcl_for_scc_in_same_mode(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint32_t * pcl_ch,uint32_t * len,uint8_t * pcl_weight,uint32_t weight_len,uint8_t vdev_id)330 policy_mgr_get_pcl_for_scc_in_same_mode(struct wlan_objmgr_psoc *psoc,
331 enum policy_mgr_con_mode mode,
332 uint32_t *pcl_ch, uint32_t *len,
333 uint8_t *pcl_weight,
334 uint32_t weight_len,
335 uint8_t vdev_id)
336 {
337 struct policy_mgr_psoc_priv_obj *pm_ctx;
338 struct policy_mgr_conc_connection_info
339 info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
340 qdf_freq_t vdev_freq;
341 QDF_STATUS status;
342 uint8_t num_del = 0;
343
344 pm_ctx = policy_mgr_get_context(psoc);
345 if (!pm_ctx) {
346 policy_mgr_err("Invalid Context");
347 return QDF_STATUS_E_FAILURE;
348 }
349
350 status = policy_mgr_get_chan_by_session_id(psoc, vdev_id, &vdev_freq);
351 if (QDF_IS_STATUS_ERROR(status)) {
352 policy_mgr_err("Fail to get channel by vdev id %d", vdev_id);
353 return status;
354 }
355
356 policy_mgr_debug("get pcl for existing conn:%d vdev id %d",
357 mode, vdev_id);
358
359 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
360 policy_mgr_store_and_del_conn_info_by_chan_and_mode(psoc,
361 vdev_freq,
362 mode,
363 info,
364 &num_del);
365 status = policy_mgr_get_pcl(psoc, mode, pcl_ch, len,
366 pcl_weight, weight_len, vdev_id);
367 if (num_del > 0)
368 policy_mgr_restore_deleted_conn_info(psoc, info, num_del);
369 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
370
371 return status;
372 }
373
374 void
polic_mgr_send_pcl_to_fw(struct wlan_objmgr_psoc * psoc,enum QDF_OPMODE mode)375 polic_mgr_send_pcl_to_fw(struct wlan_objmgr_psoc *psoc,
376 enum QDF_OPMODE mode)
377 {
378 uint32_t conn_idx = 0;
379 mac_handle_t mac_handle = cds_get_context(QDF_MODULE_ID_SME);
380 uint8_t vdev_id = WLAN_INVALID_VDEV_ID;
381 struct policy_mgr_psoc_priv_obj *pm_ctx;
382
383 pm_ctx = policy_mgr_get_context(psoc);
384 if (!pm_ctx) {
385 policy_mgr_err("Invalid Context");
386 return;
387 }
388
389 for (conn_idx = 0; conn_idx < MAX_NUMBER_OF_CONC_CONNECTIONS;
390 conn_idx++) {
391 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
392 if (!(pm_conc_connection_list[conn_idx].mode ==
393 PM_STA_MODE &&
394 pm_conc_connection_list[conn_idx].in_use)) {
395 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
396 continue;
397 }
398
399 vdev_id = pm_conc_connection_list[conn_idx].vdev_id;
400 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
401
402 /*
403 * Avoid sending PCL when roaming is in progress. PCL
404 * gets updated to firmware once roaming is done
405 */
406 if (mode == QDF_SAP_MODE &&
407 wlan_cm_roaming_in_progress(pm_ctx->pdev,
408 vdev_id)) {
409 policy_mgr_debug("Roaming is in progress, don't stop RSO for vdev_id: %d",
410 vdev_id);
411 continue;
412 }
413
414 pm_ctx->sme_cbacks.sme_rso_stop_cb(
415 mac_handle, vdev_id,
416 REASON_DRIVER_DISABLED,
417 RSO_SET_PCL);
418
419 policy_mgr_set_pcl_for_existing_combo(pm_ctx->psoc, PM_STA_MODE,
420 vdev_id);
421 pm_ctx->sme_cbacks.sme_rso_start_cb(
422 mac_handle, vdev_id,
423 REASON_DRIVER_ENABLED,
424 RSO_SET_PCL);
425 }
426 }
427
policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc * psoc,enum QDF_OPMODE mode,uint8_t session_id)428 void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc,
429 enum QDF_OPMODE mode,
430 uint8_t session_id)
431 {
432 QDF_STATUS qdf_status;
433 struct policy_mgr_psoc_priv_obj *pm_ctx;
434
435 pm_ctx = policy_mgr_get_context(psoc);
436 if (!pm_ctx) {
437 policy_mgr_err("Invalid Context");
438 return;
439 }
440
441 qdf_status = policy_mgr_decr_active_session(psoc, mode, session_id);
442 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
443 policy_mgr_debug("Invalid active session");
444 return;
445 }
446
447 /*
448 * After the removal of this connection, we need to check if
449 * a STA connection still exists. The reason for this is that
450 * if one or more STA exists, we need to provide the updated
451 * PCL to the FW for cases like LFR.
452 *
453 * Since policy_mgr_get_pcl provides PCL list based on the new
454 * connection that is going to come up, we will find the
455 * existing STA entry, save it and delete it temporarily.
456 * After this we will get PCL as though as new STA connection
457 * is coming up. This will give the exact PCL that needs to be
458 * given to the FW. After setting the PCL, we need to restore
459 * the entry that we have saved before.
460 */
461
462 if ((policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
463 NULL) > 0) &&
464 mode != QDF_STA_MODE)
465 polic_mgr_send_pcl_to_fw(psoc, mode);
466
467 /* do we need to change the HW mode */
468 if (!policy_mgr_is_hw_dbs_capable(psoc))
469 return;
470
471 policy_mgr_check_n_start_opportunistic_timer(psoc);
472 if (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE)
473 ml_nlink_conn_change_notify(
474 psoc, session_id, ml_nlink_ap_stopped_evt, NULL);
475 }
476
477 /**
478 * policy_mgr_update_valid_ch_freq_list() - Update policy manager valid ch list
479 * @pm_ctx: policy manager context data
480 * @reg_ch_list: Regulatory channel list
481 * @is_client: true if caller is a client, false if it is a beaconing entity
482 *
483 * When regulatory component channel list is updated this internal function is
484 * called to update policy manager copy of valid channel list.
485 *
486 * Return: QDF_STATUS_SUCCESS on success other qdf error status code
487 */
488 static void
policy_mgr_update_valid_ch_freq_list(struct policy_mgr_psoc_priv_obj * pm_ctx,struct regulatory_channel * reg_ch_list,bool is_client)489 policy_mgr_update_valid_ch_freq_list(struct policy_mgr_psoc_priv_obj *pm_ctx,
490 struct regulatory_channel *reg_ch_list,
491 bool is_client)
492 {
493 uint32_t i, j = 0, ch_freq;
494 enum channel_state state;
495
496 for (i = 0; i < NUM_CHANNELS; i++) {
497 ch_freq = reg_ch_list[i].center_freq;
498 if (is_client)
499 state = wlan_reg_get_channel_state_for_pwrmode(
500 pm_ctx->pdev, ch_freq,
501 REG_CURRENT_PWR_MODE);
502 else
503 state =
504 wlan_reg_get_channel_state_from_secondary_list_for_freq(
505 pm_ctx->pdev, ch_freq);
506
507 if (state != CHANNEL_STATE_DISABLE &&
508 state != CHANNEL_STATE_INVALID) {
509 pm_ctx->valid_ch_freq_list[j] =
510 reg_ch_list[i].center_freq;
511 j++;
512 }
513 }
514 pm_ctx->valid_ch_freq_list_count = j;
515 }
516
517 #ifdef FEATURE_WLAN_CH_AVOID_EXT
518 void
policy_mgr_set_freq_restriction_mask(struct policy_mgr_psoc_priv_obj * pm_ctx,struct ch_avoid_ind_type * freq_list)519 policy_mgr_set_freq_restriction_mask(struct policy_mgr_psoc_priv_obj *pm_ctx,
520 struct ch_avoid_ind_type *freq_list)
521 {
522 pm_ctx->restriction_mask = freq_list->restriction_mask;
523 }
524
525 uint32_t
policy_mgr_get_freq_restriction_mask(struct policy_mgr_psoc_priv_obj * pm_ctx)526 policy_mgr_get_freq_restriction_mask(struct policy_mgr_psoc_priv_obj *pm_ctx)
527 {
528 return pm_ctx->restriction_mask;
529 }
530 #endif
531
532 void
policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_pdev * pdev,struct regulatory_channel * chan_list,struct avoid_freq_ind_data * avoid_freq_ind,void * arg)533 policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc,
534 struct wlan_objmgr_pdev *pdev,
535 struct regulatory_channel *chan_list,
536 struct avoid_freq_ind_data *avoid_freq_ind,
537 void *arg)
538 {
539 struct policy_mgr_psoc_priv_obj *pm_ctx;
540 uint32_t i;
541 struct ch_avoid_ind_type *freq_list;
542
543 pm_ctx = policy_mgr_get_context(psoc);
544 if (!pm_ctx) {
545 policy_mgr_err("Invalid Context");
546 return;
547 }
548
549 policy_mgr_update_valid_ch_freq_list(pm_ctx, chan_list, false);
550
551 if (!avoid_freq_ind) {
552 policy_mgr_debug("avoid_freq_ind NULL");
553 return;
554 }
555
556 /*
557 * The ch_list buffer can accommodate a maximum of
558 * NUM_CHANNELS and hence the ch_cnt should also not
559 * exceed NUM_CHANNELS.
560 */
561 pm_ctx->unsafe_channel_count = avoid_freq_ind->chan_list.chan_cnt >=
562 NUM_CHANNELS ?
563 NUM_CHANNELS : avoid_freq_ind->chan_list.chan_cnt;
564
565 freq_list = &avoid_freq_ind->freq_list;
566 policy_mgr_set_freq_restriction_mask(pm_ctx, freq_list);
567
568 for (i = 0; i < pm_ctx->unsafe_channel_count; i++)
569 pm_ctx->unsafe_channel_list[i] =
570 avoid_freq_ind->chan_list.chan_freq_list[i];
571
572 policy_mgr_debug("Channel list update, received %d avoided channels",
573 pm_ctx->unsafe_channel_count);
574 }
575
policy_mgr_init_chan_avoidance(struct wlan_objmgr_psoc * psoc,qdf_freq_t * chan_freq_list,uint16_t chan_cnt)576 QDF_STATUS policy_mgr_init_chan_avoidance(struct wlan_objmgr_psoc *psoc,
577 qdf_freq_t *chan_freq_list,
578 uint16_t chan_cnt)
579 {
580 struct policy_mgr_psoc_priv_obj *pm_ctx;
581 uint32_t i;
582
583 pm_ctx = policy_mgr_get_context(psoc);
584 if (!pm_ctx) {
585 policy_mgr_err("Invalid Context");
586 return QDF_STATUS_E_FAILURE;
587 }
588
589 pm_ctx->unsafe_channel_count = chan_cnt >= NUM_CHANNELS ?
590 NUM_CHANNELS : chan_cnt;
591
592 for (i = 0; i < pm_ctx->unsafe_channel_count; i++)
593 pm_ctx->unsafe_channel_list[i] = chan_freq_list[i];
594
595 policy_mgr_debug("Channel list init, received %d avoided channels",
596 pm_ctx->unsafe_channel_count);
597
598 return QDF_STATUS_SUCCESS;
599 }
600
policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc * psoc,uint32_t * pcl_channels,uint32_t * len,uint8_t * weight_list,uint32_t weight_len)601 void policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc *psoc,
602 uint32_t *pcl_channels,
603 uint32_t *len,
604 uint8_t *weight_list,
605 uint32_t weight_len)
606 {
607 uint32_t current_channel_list[NUM_CHANNELS];
608 uint8_t org_weight_list[NUM_CHANNELS];
609 uint8_t is_unsafe = 1;
610 uint8_t i, j;
611 uint32_t safe_channel_count = 0, current_channel_count = 0;
612 struct policy_mgr_psoc_priv_obj *pm_ctx;
613 uint8_t scc_on_lte_coex = 0;
614 uint32_t nan_2g_freq, nan_5g_freq;
615
616 pm_ctx = policy_mgr_get_context(psoc);
617 if (!pm_ctx) {
618 policy_mgr_err("Invalid Context");
619 return;
620 }
621
622 if (len) {
623 current_channel_count = QDF_MIN(*len, NUM_CHANNELS);
624 } else {
625 policy_mgr_err("invalid number of channel length");
626 return;
627 }
628
629 if (!pm_ctx->unsafe_channel_count)
630 return;
631
632 qdf_mem_copy(current_channel_list, pcl_channels,
633 current_channel_count * sizeof(*current_channel_list));
634 qdf_mem_zero(pcl_channels,
635 current_channel_count * sizeof(*pcl_channels));
636
637 qdf_mem_copy(org_weight_list, weight_list, NUM_CHANNELS);
638 qdf_mem_zero(weight_list, weight_len);
639
640 policy_mgr_get_sta_sap_scc_lte_coex_chnl(psoc, &scc_on_lte_coex);
641 nan_2g_freq =
642 policy_mgr_mode_specific_get_channel(pm_ctx->psoc,
643 PM_NAN_DISC_MODE);
644 nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(pm_ctx->psoc);
645
646 for (i = 0; i < current_channel_count; i++) {
647 is_unsafe = 0;
648 for (j = 0; j < pm_ctx->unsafe_channel_count; j++) {
649 if (current_channel_list[i] ==
650 pm_ctx->unsafe_channel_list[j]) {
651 /* Found unsafe channel, update it */
652 is_unsafe = 1;
653 policy_mgr_debug("CH %d is not safe",
654 current_channel_list[i]);
655 break;
656 }
657 }
658 if (is_unsafe && scc_on_lte_coex &&
659 policy_mgr_is_sta_sap_scc(psoc, current_channel_list[i])) {
660 policy_mgr_debug("CH %d unsafe ignored when STA present on it",
661 current_channel_list[i]);
662 is_unsafe = 0;
663 } else if (is_unsafe &&
664 (nan_2g_freq == current_channel_list[i] ||
665 nan_5g_freq == current_channel_list[i]) &&
666 policy_mgr_is_force_scc(pm_ctx->psoc) &&
667 policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(pm_ctx->psoc)) {
668 is_unsafe = 0;
669 }
670
671 if (!is_unsafe) {
672 pcl_channels[safe_channel_count] =
673 current_channel_list[i];
674 if (safe_channel_count < weight_len)
675 weight_list[safe_channel_count] =
676 org_weight_list[i];
677 safe_channel_count++;
678 }
679 }
680 *len = safe_channel_count;
681
682 return;
683 }
684
policy_mgr_modify_pcl_based_on_enabled_channels(struct wlan_objmgr_psoc * psoc,uint32_t * pcl_list_org,uint8_t * weight_list_org,uint32_t * pcl_len_org)685 static QDF_STATUS policy_mgr_modify_pcl_based_on_enabled_channels(
686 struct wlan_objmgr_psoc *psoc,
687 uint32_t *pcl_list_org,
688 uint8_t *weight_list_org,
689 uint32_t *pcl_len_org)
690 {
691 uint32_t i, pcl_len = 0;
692 bool allow_go_scc_on_dfs_chn = false;
693 bool dfs_master_capable = false;
694 uint8_t sta_sap_scc_on_dfs_chnl = 0;
695 QDF_STATUS status = QDF_STATUS_E_FAILURE;
696 struct policy_mgr_psoc_priv_obj *pm_ctx;
697
698 pm_ctx = policy_mgr_get_context(psoc);
699 if (!pm_ctx) {
700 policy_mgr_err("context is NULL");
701 return status;
702 }
703
704 status = ucfg_mlme_get_dfs_master_capability(psoc, &dfs_master_capable);
705 if (QDF_IS_STATUS_ERROR(status)) {
706 policy_mgr_err("failed to get dfs master capable");
707 return status;
708 }
709
710 status = policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc,
711 &sta_sap_scc_on_dfs_chnl);
712 if (QDF_IS_STATUS_ERROR(status)) {
713 policy_mgr_err("failed to get sta_sap_scc_on_dfs_chnl");
714 return status;
715 }
716
717 if (dfs_master_capable && sta_sap_scc_on_dfs_chnl &&
718 pm_ctx->cfg.go_force_scc == GO_FORCE_SCC_STRICT) {
719 allow_go_scc_on_dfs_chn = true;
720 }
721
722 for (i = 0; i < *pcl_len_org; i++) {
723 if ((!wlan_reg_is_passive_or_disable_for_pwrmode(
724 pm_ctx->pdev, pcl_list_org[i],
725 REG_CURRENT_PWR_MODE)) ||
726 (allow_go_scc_on_dfs_chn &&
727 wlan_reg_is_dfs_for_freq(pm_ctx->pdev, pcl_list_org[i]))) {
728 pcl_list_org[pcl_len] = pcl_list_org[i];
729 weight_list_org[pcl_len++] = weight_list_org[i];
730 }
731 }
732 *pcl_len_org = pcl_len;
733
734 return QDF_STATUS_SUCCESS;
735 }
736
policy_mgr_modify_pcl_based_on_dnbs(struct wlan_objmgr_psoc * psoc,uint32_t * pcl_list_org,uint8_t * weight_list_org,uint32_t * pcl_len_org)737 static QDF_STATUS policy_mgr_modify_pcl_based_on_dnbs(
738 struct wlan_objmgr_psoc *psoc,
739 uint32_t *pcl_list_org,
740 uint8_t *weight_list_org,
741 uint32_t *pcl_len_org)
742 {
743 uint32_t i, pcl_len = 0;
744 uint32_t pcl_list[NUM_CHANNELS];
745 uint8_t weight_list[NUM_CHANNELS];
746 bool ok;
747 QDF_STATUS status = QDF_STATUS_E_FAILURE;
748
749 if (*pcl_len_org > NUM_CHANNELS) {
750 policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org);
751 return status;
752 }
753 for (i = 0; i < *pcl_len_org; i++) {
754 status = policy_mgr_is_chan_ok_for_dnbs(psoc, pcl_list_org[i],
755 &ok);
756
757 if (QDF_IS_STATUS_ERROR(status)) {
758 policy_mgr_err("Not able to check DNBS eligibility");
759 return status;
760 }
761 if (ok) {
762 pcl_list[pcl_len] = pcl_list_org[i];
763 weight_list[pcl_len++] = weight_list_org[i];
764 }
765 }
766
767 qdf_mem_zero(pcl_list_org, *pcl_len_org * sizeof(*pcl_list_org));
768 qdf_mem_zero(weight_list_org, *pcl_len_org);
769 qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org));
770 qdf_mem_copy(weight_list_org, weight_list, pcl_len);
771 *pcl_len_org = pcl_len;
772
773 return QDF_STATUS_SUCCESS;
774 }
775
policy_mgr_get_channel(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint32_t * vdev_id)776 uint32_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc,
777 enum policy_mgr_con_mode mode,
778 uint32_t *vdev_id)
779 {
780 uint32_t idx = 0;
781 struct policy_mgr_psoc_priv_obj *pm_ctx;
782
783 pm_ctx = policy_mgr_get_context(psoc);
784 if (!pm_ctx) {
785 policy_mgr_err("Invalid Context");
786 return 0;
787 }
788
789 if (mode >= PM_MAX_NUM_OF_MODE) {
790 policy_mgr_err("incorrect mode");
791 return 0;
792 }
793
794 for (idx = 0; idx < MAX_NUMBER_OF_CONC_CONNECTIONS; idx++) {
795 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
796 if ((pm_conc_connection_list[idx].mode == mode) &&
797 (!vdev_id || (*vdev_id ==
798 pm_conc_connection_list[idx].vdev_id))
799 && pm_conc_connection_list[idx].in_use) {
800 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
801 return pm_conc_connection_list[idx].freq;
802 }
803 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
804 }
805
806 return 0;
807 }
808
policy_mgr_skip_dfs_ch(struct wlan_objmgr_psoc * psoc,bool * skip_dfs_channel)809 QDF_STATUS policy_mgr_skip_dfs_ch(struct wlan_objmgr_psoc *psoc,
810 bool *skip_dfs_channel)
811 {
812 bool sta_sap_scc_on_dfs_chan;
813 bool dfs_master_capable;
814 QDF_STATUS status;
815
816 status = ucfg_mlme_get_dfs_master_capability(psoc,
817 &dfs_master_capable);
818 if (QDF_IS_STATUS_ERROR(status)) {
819 policy_mgr_err("failed to get dfs master capable");
820 return status;
821 }
822
823 *skip_dfs_channel = false;
824 if (!dfs_master_capable) {
825 policy_mgr_debug("skip DFS ch for SAP/Go dfs master cap %d",
826 dfs_master_capable);
827 *skip_dfs_channel = true;
828 return QDF_STATUS_SUCCESS;
829 }
830
831 sta_sap_scc_on_dfs_chan =
832 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
833
834 if (policy_mgr_is_hw_dbs_capable(psoc)) {
835 if ((policy_mgr_is_special_mode_active_5g(psoc,
836 PM_P2P_CLIENT_MODE) ||
837 policy_mgr_is_special_mode_active_5g(psoc, PM_STA_MODE)) &&
838 !sta_sap_scc_on_dfs_chan) {
839 policy_mgr_debug("skip DFS ch from pcl for DBS SAP/Go");
840 *skip_dfs_channel = true;
841 }
842 } else {
843 if ((policy_mgr_mode_specific_connection_count(psoc,
844 PM_STA_MODE,
845 NULL) > 0) &&
846 !sta_sap_scc_on_dfs_chan) {
847 policy_mgr_debug("skip DFS ch from pcl for non-DBS SAP/Go");
848 *skip_dfs_channel = true;
849 }
850 }
851
852 return QDF_STATUS_SUCCESS;
853 }
854
855 /**
856 * policy_mgr_modify_sap_pcl_based_on_dfs() - filter out DFS channel if needed
857 * @psoc: pointer to soc
858 * @pcl_list_org: channel list to filter out
859 * @weight_list_org: weight of channel list
860 * @pcl_len_org: length of channel list
861 *
862 * Return: QDF_STATUS
863 */
policy_mgr_modify_sap_pcl_based_on_dfs(struct wlan_objmgr_psoc * psoc,uint32_t * pcl_list_org,uint8_t * weight_list_org,uint32_t * pcl_len_org)864 static QDF_STATUS policy_mgr_modify_sap_pcl_based_on_dfs(
865 struct wlan_objmgr_psoc *psoc,
866 uint32_t *pcl_list_org,
867 uint8_t *weight_list_org,
868 uint32_t *pcl_len_org)
869 {
870 size_t i, pcl_len = 0;
871 struct policy_mgr_psoc_priv_obj *pm_ctx;
872 bool skip_dfs_channel = false;
873 QDF_STATUS status;
874
875 pm_ctx = policy_mgr_get_context(psoc);
876 if (!pm_ctx) {
877 policy_mgr_err("Invalid Context");
878 return QDF_STATUS_E_FAILURE;
879 }
880 if (*pcl_len_org > NUM_CHANNELS) {
881 policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org);
882 return QDF_STATUS_E_FAILURE;
883 }
884
885 status = policy_mgr_skip_dfs_ch(psoc, &skip_dfs_channel);
886 if (QDF_IS_STATUS_ERROR(status)) {
887 policy_mgr_err("failed to get dfs channel skip info");
888 return status;
889 }
890
891 if (!skip_dfs_channel)
892 return QDF_STATUS_SUCCESS;
893
894 for (i = 0; i < *pcl_len_org; i++) {
895 if (!wlan_reg_is_dfs_in_secondary_list_for_freq(
896 pm_ctx->pdev,
897 pcl_list_org[i])) {
898 pcl_list_org[pcl_len] = pcl_list_org[i];
899 weight_list_org[pcl_len++] = weight_list_org[i];
900 }
901 }
902
903 *pcl_len_org = pcl_len;
904
905 return QDF_STATUS_SUCCESS;
906 }
907
policy_mgr_modify_sap_pcl_based_on_nol(struct wlan_objmgr_psoc * psoc,uint32_t * pcl_list_org,uint8_t * weight_list_org,uint32_t * pcl_len_org)908 static QDF_STATUS policy_mgr_modify_sap_pcl_based_on_nol(
909 struct wlan_objmgr_psoc *psoc,
910 uint32_t *pcl_list_org,
911 uint8_t *weight_list_org,
912 uint32_t *pcl_len_org)
913 {
914 uint32_t i, pcl_len = 0;
915 uint32_t pcl_list[NUM_CHANNELS];
916 uint8_t weight_list[NUM_CHANNELS];
917 struct policy_mgr_psoc_priv_obj *pm_ctx;
918
919 pm_ctx = policy_mgr_get_context(psoc);
920 if (!pm_ctx) {
921 policy_mgr_err("Invalid Context");
922 return QDF_STATUS_E_FAILURE;
923 }
924 if (*pcl_len_org > NUM_CHANNELS) {
925 policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org);
926 return QDF_STATUS_E_FAILURE;
927 }
928
929 for (i = 0; i < *pcl_len_org; i++) {
930 if (!wlan_reg_is_disable_in_secondary_list_for_freq(
931 pm_ctx->pdev, pcl_list_org[i])) {
932 pcl_list[pcl_len] = pcl_list_org[i];
933 weight_list[pcl_len++] = weight_list_org[i];
934 }
935 }
936
937 qdf_mem_zero(pcl_list_org, *pcl_len_org * sizeof(*pcl_list_org));
938 qdf_mem_zero(weight_list_org, *pcl_len_org);
939 qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org));
940 qdf_mem_copy(weight_list_org, weight_list, pcl_len);
941 *pcl_len_org = pcl_len;
942
943 return QDF_STATUS_SUCCESS;
944 }
945
946 static QDF_STATUS
policy_mgr_modify_pcl_based_on_srd(struct wlan_objmgr_psoc * psoc,uint32_t * pcl_list_org,uint8_t * weight_list_org,uint32_t * pcl_len_org)947 policy_mgr_modify_pcl_based_on_srd(struct wlan_objmgr_psoc *psoc,
948 uint32_t *pcl_list_org,
949 uint8_t *weight_list_org,
950 uint32_t *pcl_len_org)
951 {
952 uint32_t i, pcl_len = 0;
953 uint32_t pcl_list[NUM_CHANNELS];
954 uint8_t weight_list[NUM_CHANNELS];
955 struct policy_mgr_psoc_priv_obj *pm_ctx;
956
957 pm_ctx = policy_mgr_get_context(psoc);
958 if (!pm_ctx) {
959 policy_mgr_err("Invalid Context");
960 return QDF_STATUS_E_FAILURE;
961 }
962
963 if (*pcl_len_org > NUM_CHANNELS) {
964 policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org);
965 return QDF_STATUS_E_FAILURE;
966 }
967 for (i = 0; i < *pcl_len_org; i++) {
968 if (wlan_reg_is_etsi_srd_chan_for_freq(
969 pm_ctx->pdev, pcl_list_org[i]))
970 continue;
971 pcl_list[pcl_len] = pcl_list_org[i];
972 weight_list[pcl_len++] = weight_list_org[i];
973 }
974
975 qdf_mem_zero(pcl_list_org, *pcl_len_org * sizeof(*pcl_list_org));
976 qdf_mem_zero(weight_list_org, *pcl_len_org);
977 qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org));
978 qdf_mem_copy(weight_list_org, weight_list, pcl_len);
979 *pcl_len_org = pcl_len;
980
981 return QDF_STATUS_SUCCESS;
982 }
983
984 /**
985 * policy_mgr_modify_pcl_based_on_indoor() - filter out indoor channel if needed
986 * @psoc: pointer to soc
987 * @pcl_list_org: channel list to filter out
988 * @weight_list_org: weight of channel list
989 * @pcl_len_org: length of channel list
990 *
991 * Return: QDF_STATUS
992 */
993 static QDF_STATUS
policy_mgr_modify_pcl_based_on_indoor(struct wlan_objmgr_psoc * psoc,uint32_t * pcl_list_org,uint8_t * weight_list_org,uint32_t * pcl_len_org)994 policy_mgr_modify_pcl_based_on_indoor(struct wlan_objmgr_psoc *psoc,
995 uint32_t *pcl_list_org,
996 uint8_t *weight_list_org,
997 uint32_t *pcl_len_org)
998 {
999 uint32_t i, pcl_len = 0;
1000 uint32_t pcl_list[NUM_CHANNELS];
1001 uint8_t weight_list[NUM_CHANNELS];
1002 struct policy_mgr_psoc_priv_obj *pm_ctx;
1003 bool include_indoor_channel, sta_sap_scc_on_indoor_channel_allowed;
1004 QDF_STATUS status;
1005
1006 pm_ctx = policy_mgr_get_context(psoc);
1007 if (!pm_ctx) {
1008 policy_mgr_err("Invalid Context");
1009 return QDF_STATUS_E_FAILURE;
1010 }
1011
1012 if (*pcl_len_org > NUM_CHANNELS) {
1013 policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org);
1014 return QDF_STATUS_E_FAILURE;
1015 }
1016
1017 status = ucfg_mlme_get_indoor_channel_support(psoc,
1018 &include_indoor_channel);
1019 if (QDF_IS_STATUS_ERROR(status)) {
1020 policy_mgr_err("failed to get indoor channel skip info");
1021 return status;
1022 }
1023
1024 /*
1025 * If STA SAP scc is allowed on indoor channels, and if STA/P2P
1026 * client is present on 5 GHz channel, include indoor channels
1027 */
1028 sta_sap_scc_on_indoor_channel_allowed =
1029 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
1030 if (!include_indoor_channel && sta_sap_scc_on_indoor_channel_allowed &&
1031 (policy_mgr_is_special_mode_active_5g(psoc, PM_P2P_CLIENT_MODE) ||
1032 policy_mgr_is_special_mode_active_5g(psoc, PM_STA_MODE)))
1033 include_indoor_channel = true;
1034
1035 if (include_indoor_channel) {
1036 policy_mgr_debug("Indoor channels allowed. PCL not modified for indoor channels");
1037 return QDF_STATUS_SUCCESS;
1038 }
1039
1040 for (i = 0; i < *pcl_len_org; i++) {
1041 if (wlan_reg_is_freq_indoor_in_secondary_list(pm_ctx->pdev,
1042 pcl_list_org[i])) {
1043 policy_mgr_debug("Remove freq: %d from PCL as it's indoor",
1044 pcl_list_org[i]);
1045 continue;
1046 }
1047 pcl_list[pcl_len] = pcl_list_org[i];
1048 weight_list[pcl_len++] = weight_list_org[i];
1049 }
1050
1051 qdf_mem_zero(pcl_list_org, *pcl_len_org * sizeof(*pcl_list_org));
1052 qdf_mem_zero(weight_list_org, *pcl_len_org);
1053 qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org));
1054 qdf_mem_copy(weight_list_org, weight_list, pcl_len);
1055 *pcl_len_org = pcl_len;
1056
1057 return QDF_STATUS_SUCCESS;
1058 }
1059
1060 /**
1061 * policy_mgr_modify_sap_pcl_for_6G_channels() - filter out the
1062 * 6GHz channels where SCC is not supported.
1063 * @psoc: pointer to soc
1064 * @pcl_list_org: channel list to filter out
1065 * @weight_list_org: weight of channel list
1066 * @pcl_len_org: length of channel list
1067 *
1068 * Return: QDF_STATUS
1069 */
1070 static QDF_STATUS
policy_mgr_modify_sap_pcl_for_6G_channels(struct wlan_objmgr_psoc * psoc,uint32_t * pcl_list_org,uint8_t * weight_list_org,uint32_t * pcl_len_org)1071 policy_mgr_modify_sap_pcl_for_6G_channels(struct wlan_objmgr_psoc *psoc,
1072 uint32_t *pcl_list_org,
1073 uint8_t *weight_list_org,
1074 uint32_t *pcl_len_org)
1075 {
1076 struct policy_mgr_psoc_priv_obj *pm_ctx;
1077 uint32_t pcl_list[NUM_CHANNELS];
1078 uint8_t weight_list[NUM_CHANNELS];
1079 uint32_t vdev_id = 0, pcl_len = 0, i;
1080 struct wlan_objmgr_vdev *vdev;
1081 qdf_freq_t sta_gc_6ghz_freq = 0;
1082 uint32_t ap_pwr_type_6g = 0;
1083 bool indoor_ch_support = false;
1084 bool keep_6ghz_sta_cli_conn;
1085
1086 pm_ctx = policy_mgr_get_context(psoc);
1087 if (!pm_ctx) {
1088 policy_mgr_err("Invalid Context");
1089 return QDF_STATUS_E_FAILURE;
1090 }
1091
1092 if (*pcl_len_org > NUM_CHANNELS) {
1093 policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org);
1094 return QDF_STATUS_E_FAILURE;
1095 }
1096
1097 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1098 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
1099 if ((pm_conc_connection_list[i].mode == PM_STA_MODE ||
1100 pm_conc_connection_list[i].mode == PM_P2P_CLIENT_MODE) &&
1101 pm_conc_connection_list[i].in_use) {
1102 if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(pm_conc_connection_list[i].freq))
1103 continue;
1104 sta_gc_6ghz_freq = pm_conc_connection_list[i].freq;
1105 vdev_id = pm_conc_connection_list[i].vdev_id;
1106 break;
1107 }
1108 }
1109 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1110
1111 if (!sta_gc_6ghz_freq)
1112 return QDF_STATUS_SUCCESS;
1113
1114 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
1115 WLAN_POLICY_MGR_ID);
1116 if (!vdev) {
1117 policy_mgr_err("vdev %d is not present", vdev_id);
1118 return QDF_STATUS_E_FAILURE;
1119 }
1120
1121 /* If STA is present in 6GHz PSC, STA+SAP SCC is allowed
1122 * only for the following combinations:
1123 *
1124 * VLP STA + SAP - Allowed with VLP Power
1125 * LPI STA + SAP - Allowed with VLP power if channel supports VLP.
1126 * LPI STA + SAP - Allowed with LPI power if gindoor_channel_support=1
1127 */
1128 ap_pwr_type_6g = wlan_mlme_get_6g_ap_power_type(vdev);
1129 policy_mgr_debug("STA power type : %d", ap_pwr_type_6g);
1130
1131 ucfg_mlme_get_indoor_channel_support(psoc, &indoor_ch_support);
1132 keep_6ghz_sta_cli_conn = wlan_reg_get_keep_6ghz_sta_cli_connection(
1133 pm_ctx->pdev);
1134 for (i = 0; i < *pcl_len_org; i++) {
1135 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl_list_org[i])) {
1136 if (!WLAN_REG_IS_6GHZ_PSC_CHAN_FREQ(pcl_list_org[i]) ||
1137 keep_6ghz_sta_cli_conn)
1138 continue;
1139 if (ap_pwr_type_6g == REG_VERY_LOW_POWER_AP)
1140 goto add_freq;
1141 else if (ap_pwr_type_6g == REG_INDOOR_AP &&
1142 (!wlan_reg_is_freq_indoor(pm_ctx->pdev,
1143 pcl_list_org[i]) ||
1144 indoor_ch_support))
1145 goto add_freq;
1146 else
1147 continue;
1148 }
1149 add_freq:
1150 pcl_list[pcl_len] = pcl_list_org[i];
1151 weight_list[pcl_len++] = weight_list_org[i];
1152 }
1153
1154 qdf_mem_zero(pcl_list_org, *pcl_len_org * sizeof(*pcl_list_org));
1155 qdf_mem_zero(weight_list_org, *pcl_len_org * sizeof(*weight_list_org));
1156 qdf_mem_copy(pcl_list_org, pcl_list, pcl_len * sizeof(*pcl_list_org));
1157 qdf_mem_copy(weight_list_org, weight_list, pcl_len);
1158 *pcl_len_org = pcl_len;
1159
1160 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
1161 return QDF_STATUS_SUCCESS;
1162 }
1163
1164 /**
1165 * policy_mgr_channel_mcc_with_non_sap() - Helper function to check if channel
1166 * is MCC with exist non-movable connections.
1167 * @psoc: pointer to SOC
1168 * @chan_freq: channel frequency to check
1169 *
1170 * Return: true if is MCC with exist non-movable connections, otherwise false.
1171 */
policy_mgr_channel_mcc_with_non_sap(struct wlan_objmgr_psoc * psoc,qdf_freq_t chan_freq)1172 static bool policy_mgr_channel_mcc_with_non_sap(struct wlan_objmgr_psoc *psoc,
1173 qdf_freq_t chan_freq)
1174 {
1175 uint32_t i, connection_of_2ghz = 0;
1176 qdf_freq_t conc_freq;
1177 bool is_mcc = false, check_only_dbs = false;
1178 struct policy_mgr_psoc_priv_obj *pm_ctx;
1179
1180 pm_ctx = policy_mgr_get_context(psoc);
1181 if (!pm_ctx) {
1182 policy_mgr_err("Invalid Context");
1183 return false;
1184 }
1185
1186 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1187 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
1188 if (pm_conc_connection_list[i].in_use &&
1189 WLAN_REG_IS_24GHZ_CH_FREQ(pm_conc_connection_list[i].freq))
1190 connection_of_2ghz++;
1191 }
1192 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1193
1194 if (connection_of_2ghz >= 2)
1195 check_only_dbs = true;
1196
1197 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1198 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
1199 if (pm_conc_connection_list[i].in_use &&
1200 (pm_conc_connection_list[i].mode == PM_STA_MODE ||
1201 pm_conc_connection_list[i].mode == PM_P2P_CLIENT_MODE ||
1202 pm_conc_connection_list[i].mode == PM_P2P_GO_MODE)) {
1203 conc_freq = pm_conc_connection_list[i].freq;
1204 if (conc_freq != chan_freq &&
1205 ((check_only_dbs &&
1206 policy_mgr_2_freq_same_mac_in_dbs(pm_ctx,
1207 chan_freq,
1208 conc_freq)) ||
1209 policy_mgr_2_freq_always_on_same_mac(psoc,
1210 chan_freq,
1211 conc_freq))) {
1212 is_mcc = true;
1213 break;
1214 }
1215 }
1216 }
1217 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1218
1219 return is_mcc;
1220 }
1221
1222 /**
1223 * policy_mgr_modify_sap_pcl_filter_mcc() - API to filter out MCC channel with
1224 * existing non-SAP connection frequency from SAP PCL list.
1225 * @psoc: pointer to SOC
1226 * @pcl_list_org: channel list to filter out
1227 * @weight_list_org: weight of channel list
1228 * @pcl_len_org: length of channel list
1229 * @mode: Policy manager connection mode
1230 *
1231 * Return: QDF_STATUS
1232 */
1233 static QDF_STATUS
policy_mgr_modify_sap_pcl_filter_mcc(struct wlan_objmgr_psoc * psoc,uint32_t * pcl_list_org,uint8_t * weight_list_org,uint32_t * pcl_len_org,enum policy_mgr_con_mode mode)1234 policy_mgr_modify_sap_pcl_filter_mcc(struct wlan_objmgr_psoc *psoc,
1235 uint32_t *pcl_list_org,
1236 uint8_t *weight_list_org,
1237 uint32_t *pcl_len_org,
1238 enum policy_mgr_con_mode mode)
1239 {
1240 uint32_t i, pcl_len = 0;
1241 struct policy_mgr_psoc_priv_obj *pm_ctx;
1242
1243 if (mode == PM_LL_LT_SAP_MODE)
1244 return QDF_STATUS_SUCCESS;
1245
1246 pm_ctx = policy_mgr_get_context(psoc);
1247 if (!pm_ctx) {
1248 policy_mgr_err("Invalid Context");
1249 return QDF_STATUS_E_FAILURE;
1250 }
1251
1252 if (*pcl_len_org > NUM_CHANNELS) {
1253 policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org);
1254 return QDF_STATUS_E_FAILURE;
1255 }
1256
1257 if (!policy_mgr_is_force_scc(psoc)) {
1258 policy_mgr_debug("force SCC is not prefer, skip!");
1259 return QDF_STATUS_SUCCESS;
1260 }
1261
1262 for (i = 0; i < *pcl_len_org; i++) {
1263 if (policy_mgr_channel_mcc_with_non_sap(psoc, pcl_list_org[i]))
1264 continue;
1265
1266 pcl_list_org[pcl_len] = pcl_list_org[i];
1267 weight_list_org[pcl_len++] = weight_list_org[i];
1268 }
1269
1270 *pcl_len_org = pcl_len;
1271
1272 return QDF_STATUS_SUCCESS;
1273 }
1274
1275 /**
1276 * policy_mgr_modify_sap_go_4th_conc_disallow() - filter out channel that
1277 * is not allowed for 4th sap/go connection
1278 * @psoc: pointer to soc
1279 * @mode: interface mode
1280 * @pcl_list_org: channel list to filter out
1281 * @weight_list_org: weight of channel list
1282 * @pcl_len_org: length of channel list
1283 *
1284 * Return: QDF_STATUS
1285 */
policy_mgr_modify_sap_go_4th_conc_disallow(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint32_t * pcl_list_org,uint8_t * weight_list_org,uint32_t * pcl_len_org)1286 static QDF_STATUS policy_mgr_modify_sap_go_4th_conc_disallow(
1287 struct wlan_objmgr_psoc *psoc,
1288 enum policy_mgr_con_mode mode,
1289 uint32_t *pcl_list_org,
1290 uint8_t *weight_list_org,
1291 uint32_t *pcl_len_org)
1292 {
1293 size_t i, pcl_len = 0;
1294 struct policy_mgr_psoc_priv_obj *pm_ctx;
1295 uint32_t num_connections;
1296
1297 pm_ctx = policy_mgr_get_context(psoc);
1298 if (!pm_ctx) {
1299 policy_mgr_err("Invalid Context");
1300 return QDF_STATUS_E_FAILURE;
1301 }
1302 if (*pcl_len_org > NUM_CHANNELS) {
1303 policy_mgr_err("Invalid PCL List Length %d", *pcl_len_org);
1304 return QDF_STATUS_E_FAILURE;
1305 }
1306 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1307 num_connections = policy_mgr_get_connection_count(psoc);
1308 if (num_connections < 3)
1309 goto end;
1310
1311 for (i = 0; i < *pcl_len_org; i++) {
1312 if (policy_mgr_allow_4th_new_freq(psoc, pcl_list_org[i],
1313 mode, 0)) {
1314 pcl_list_org[pcl_len] = pcl_list_org[i];
1315 weight_list_org[pcl_len++] = weight_list_org[i];
1316 }
1317 }
1318
1319 *pcl_len_org = pcl_len;
1320 end:
1321 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1322
1323 return QDF_STATUS_SUCCESS;
1324 }
1325
policy_mgr_pcl_modification_for_sap(struct wlan_objmgr_psoc * psoc,uint32_t * pcl_channels,uint8_t * pcl_weight,uint32_t * len,uint32_t weight_len,enum policy_mgr_con_mode mode)1326 static QDF_STATUS policy_mgr_pcl_modification_for_sap(
1327 struct wlan_objmgr_psoc *psoc,
1328 uint32_t *pcl_channels, uint8_t *pcl_weight,
1329 uint32_t *len, uint32_t weight_len,
1330 enum policy_mgr_con_mode mode)
1331 {
1332 QDF_STATUS status = QDF_STATUS_E_FAILURE;
1333 struct policy_mgr_psoc_priv_obj *pm_ctx;
1334 bool mandatory_modified_pcl = false;
1335 bool nol_modified_pcl = false;
1336 bool dfs_modified_pcl = false;
1337 bool indoor_modified_pcl = false;
1338 bool passive_modified_pcl = false;
1339 bool band_6ghz_modified_pcl = false;
1340 bool fourth_conc_modified_pcl = false;
1341 bool modified_final_pcl = false;
1342 bool srd_chan_enabled;
1343
1344 pm_ctx = policy_mgr_get_context(psoc);
1345 if (!pm_ctx) {
1346 policy_mgr_err("Invalid context");
1347 return QDF_STATUS_E_FAILURE;
1348 }
1349
1350 /* check the channel avoidance list for beaconing entities */
1351 policy_mgr_update_with_safe_channel_list(psoc, pcl_channels,
1352 len, pcl_weight, weight_len);
1353
1354 if (policy_mgr_is_sap_mandatory_channel_set(psoc)) {
1355 status = policy_mgr_modify_sap_pcl_based_on_mandatory_channel(
1356 psoc, pcl_channels, pcl_weight, len);
1357 if (QDF_IS_STATUS_ERROR(status)) {
1358 policy_mgr_err(
1359 "failed to get mandatory modified pcl for SAP");
1360 return status;
1361 }
1362 mandatory_modified_pcl = true;
1363 }
1364
1365 status = policy_mgr_modify_sap_pcl_based_on_nol(
1366 psoc, pcl_channels, pcl_weight, len);
1367 if (QDF_IS_STATUS_ERROR(status)) {
1368 policy_mgr_err("failed to get nol modified pcl for SAP");
1369 return status;
1370 }
1371 nol_modified_pcl = true;
1372
1373 status = policy_mgr_modify_sap_pcl_based_on_dfs(
1374 psoc, pcl_channels, pcl_weight, len);
1375 if (QDF_IS_STATUS_ERROR(status)) {
1376 policy_mgr_err("failed to get dfs modified pcl for SAP");
1377 return status;
1378 }
1379 dfs_modified_pcl = true;
1380
1381 wlan_mlme_get_srd_master_mode_for_vdev(psoc, QDF_SAP_MODE,
1382 &srd_chan_enabled);
1383
1384 if (!srd_chan_enabled) {
1385 status = policy_mgr_modify_pcl_based_on_srd
1386 (psoc, pcl_channels, pcl_weight, len);
1387 if (QDF_IS_STATUS_ERROR(status)) {
1388 policy_mgr_err("Failed to modify SRD in pcl for SAP");
1389 return status;
1390 }
1391 }
1392
1393 status = policy_mgr_modify_pcl_based_on_indoor(psoc, pcl_channels,
1394 pcl_weight, len);
1395 if (QDF_IS_STATUS_ERROR(status)) {
1396 policy_mgr_err("failed to get indoor modified pcl for SAP");
1397 return status;
1398 }
1399 indoor_modified_pcl = true;
1400
1401 status = policy_mgr_filter_passive_ch(pm_ctx->pdev,
1402 pcl_channels, len);
1403
1404 if (QDF_IS_STATUS_ERROR(status)) {
1405 policy_mgr_err("failed to filter passive channels");
1406 return INVALID_CHANNEL_ID;
1407 }
1408 passive_modified_pcl = true;
1409
1410 status = policy_mgr_modify_sap_pcl_for_6G_channels(psoc,
1411 pcl_channels,
1412 pcl_weight, len);
1413 if (QDF_IS_STATUS_ERROR(status)) {
1414 policy_mgr_err("failed to modify pcl for 6G channels");
1415 return status;
1416 }
1417 band_6ghz_modified_pcl = true;
1418
1419 status = policy_mgr_modify_sap_go_4th_conc_disallow(psoc,
1420 PM_SAP_MODE,
1421 pcl_channels,
1422 pcl_weight, len);
1423 if (QDF_IS_STATUS_ERROR(status)) {
1424 policy_mgr_err("failed to modify pcl for 4th sap channels");
1425 return status;
1426 }
1427 fourth_conc_modified_pcl = true;
1428
1429 status = policy_mgr_modify_sap_pcl_filter_mcc(psoc,
1430 pcl_channels,
1431 pcl_weight, len,
1432 mode);
1433 if (QDF_IS_STATUS_ERROR(status)) {
1434 policy_mgr_err("failed to modify pcl for filter mcc");
1435 return status;
1436 }
1437
1438 modified_final_pcl = true;
1439 policy_mgr_debug("%d %d %d %d %d %d %d %d",
1440 mandatory_modified_pcl,
1441 nol_modified_pcl,
1442 dfs_modified_pcl,
1443 indoor_modified_pcl,
1444 passive_modified_pcl,
1445 band_6ghz_modified_pcl,
1446 fourth_conc_modified_pcl,
1447 modified_final_pcl);
1448
1449 return QDF_STATUS_SUCCESS;
1450 }
1451
policy_mgr_pcl_modification_for_p2p_go(struct wlan_objmgr_psoc * psoc,uint32_t * pcl_channels,uint8_t * pcl_weight,uint32_t * len,uint32_t weight_len)1452 static QDF_STATUS policy_mgr_pcl_modification_for_p2p_go(
1453 struct wlan_objmgr_psoc *psoc,
1454 uint32_t *pcl_channels, uint8_t *pcl_weight,
1455 uint32_t *len, uint32_t weight_len)
1456 {
1457 QDF_STATUS status = QDF_STATUS_E_FAILURE;
1458 bool srd_chan_enabled;
1459
1460 /* check the channel avoidance list for beaconing entities */
1461 policy_mgr_update_with_safe_channel_list(psoc, pcl_channels,
1462 len, pcl_weight, weight_len);
1463
1464 status = policy_mgr_modify_pcl_based_on_enabled_channels(
1465 psoc, pcl_channels, pcl_weight, len);
1466 if (QDF_IS_STATUS_ERROR(status)) {
1467 policy_mgr_err("failed to get modified pcl for GO");
1468 return status;
1469 }
1470
1471 status = policy_mgr_modify_sap_pcl_based_on_dfs(
1472 psoc, pcl_channels, pcl_weight, len);
1473 if (QDF_IS_STATUS_ERROR(status)) {
1474 policy_mgr_err("failed to get dfs modified pcl for GO");
1475 return status;
1476 }
1477
1478 wlan_mlme_get_srd_master_mode_for_vdev(psoc, QDF_P2P_GO_MODE,
1479 &srd_chan_enabled);
1480
1481 if (!srd_chan_enabled) {
1482 status = policy_mgr_modify_pcl_based_on_srd
1483 (psoc, pcl_channels, pcl_weight, len);
1484 if (QDF_IS_STATUS_ERROR(status)) {
1485 policy_mgr_err("Failed to modify SRD in pcl for GO");
1486 return status;
1487 }
1488 }
1489 status = policy_mgr_modify_sap_go_4th_conc_disallow(psoc,
1490 PM_P2P_GO_MODE,
1491 pcl_channels,
1492 pcl_weight, len);
1493 if (QDF_IS_STATUS_ERROR(status)) {
1494 policy_mgr_err("failed to modify pcl for 4th go channels");
1495 return status;
1496 }
1497
1498 return QDF_STATUS_SUCCESS;
1499 }
1500
1501 #ifdef WLAN_FEATURE_LL_LT_SAP
1502 #ifdef WLAN_FEATURE_LL_LT_SAP_6G_SUPPORT
policy_mgr_is_6G_chan_valid_for_ll_sap(qdf_freq_t freq)1503 static bool policy_mgr_is_6G_chan_valid_for_ll_sap(qdf_freq_t freq)
1504 {
1505 if (!wlan_reg_is_6ghz_chan_freq(freq))
1506 return true;
1507
1508 if (wlan_reg_is_6ghz_psc_chan_freq(freq) &&
1509 wlan_reg_is_6ghz_unii5_chan_freq(freq))
1510 return true;
1511
1512 return false;
1513 }
1514 #else
policy_mgr_is_6G_chan_valid_for_ll_sap(qdf_freq_t freq)1515 static inline bool policy_mgr_is_6G_chan_valid_for_ll_sap(qdf_freq_t freq)
1516 {
1517 if (!wlan_reg_is_6ghz_chan_freq(freq))
1518 return true;
1519
1520 return false;
1521 }
1522 #endif
1523
policy_mgr_is_dynamic_sbs_enabled(struct wlan_objmgr_psoc * psoc)1524 static bool policy_mgr_is_dynamic_sbs_enabled(struct wlan_objmgr_psoc *psoc)
1525 {
1526 struct policy_mgr_psoc_priv_obj *pm_ctx;
1527
1528 pm_ctx = policy_mgr_get_context(psoc);
1529 if (!pm_ctx)
1530 return false;
1531
1532 return (policy_mgr_is_hw_sbs_capable(psoc) &&
1533 policy_mgr_can_2ghz_share_low_high_5ghz_sbs(pm_ctx));
1534 }
1535
1536 /**
1537 * policy_mgr_is_sbs_mac0_freq() - Check if the given frequency is
1538 * sbs frequency on mac0 for static sbs case.
1539 * @psoc: psoc pointer
1540 * @freq: Frequency which needs to be checked.
1541 *
1542 * Return: true/false.
1543 */
policy_mgr_is_sbs_mac0_freq(struct wlan_objmgr_psoc * psoc,qdf_freq_t freq)1544 static bool policy_mgr_is_sbs_mac0_freq(struct wlan_objmgr_psoc *psoc,
1545 qdf_freq_t freq)
1546 {
1547 struct policy_mgr_psoc_priv_obj *pm_ctx;
1548 struct policy_mgr_freq_range *freq_range;
1549
1550 if (policy_mgr_is_dynamic_sbs_enabled(psoc))
1551 return false;
1552
1553 pm_ctx = policy_mgr_get_context(psoc);
1554 if (!pm_ctx)
1555 return false;
1556
1557 freq_range = pm_ctx->hw_mode.freq_range_caps[MODE_SBS];
1558
1559 if (policy_mgr_is_freq_on_mac_id(freq_range, freq, 0))
1560 return true;
1561
1562 return false;
1563 }
1564
policy_mgr_pcl_modification_for_ll_lt_sap(struct wlan_objmgr_psoc * psoc,uint32_t * pcl_channels,uint8_t * pcl_weight,uint32_t * len,uint32_t weight_len)1565 static QDF_STATUS policy_mgr_pcl_modification_for_ll_lt_sap(
1566 struct wlan_objmgr_psoc *psoc,
1567 uint32_t *pcl_channels, uint8_t *pcl_weight,
1568 uint32_t *len, uint32_t weight_len)
1569 {
1570 struct policy_mgr_psoc_priv_obj *pm_ctx;
1571 uint32_t pcl_list[NUM_CHANNELS], orig_len = *len;
1572 uint8_t weight_list[NUM_CHANNELS];
1573 uint32_t i, pcl_len = 0;
1574 bool sbs_mac0_modified_pcl = false;
1575
1576 pm_ctx = policy_mgr_get_context(psoc);
1577 if (!pm_ctx) {
1578 policy_mgr_err("pm_ctx is NULL");
1579 return QDF_STATUS_E_FAILURE;
1580 }
1581
1582 policy_mgr_pcl_modification_for_sap(
1583 psoc, pcl_channels, pcl_weight, len, weight_len,
1584 PM_LL_LT_SAP_MODE);
1585
1586 for (i = 0; i < *len; i++) {
1587 /* Remove passive/dfs/6G invalid channel for LL_LT_SAP */
1588 if (wlan_reg_is_24ghz_ch_freq(pcl_channels[i]) ||
1589 wlan_reg_is_passive_for_freq(
1590 pm_ctx->pdev,
1591 pcl_channels[i]) ||
1592 wlan_reg_is_dfs_for_freq(
1593 pm_ctx->pdev,
1594 pcl_channels[i]) ||
1595 !policy_mgr_is_6G_chan_valid_for_ll_sap(pcl_channels[i]))
1596 continue;
1597
1598 /* Remove mac0 frequencies for static SBS case */
1599 if (policy_mgr_is_sbs_mac0_freq(psoc, pcl_channels[i])) {
1600 sbs_mac0_modified_pcl = true;
1601 continue;
1602 }
1603
1604 pcl_list[pcl_len] = pcl_channels[i];
1605 weight_list[pcl_len++] = pcl_weight[i];
1606 }
1607
1608 if (orig_len == pcl_len)
1609 return QDF_STATUS_SUCCESS;
1610
1611 qdf_mem_zero(pcl_channels, *len * sizeof(*pcl_channels));
1612 qdf_mem_zero(pcl_weight, *len);
1613 qdf_mem_copy(pcl_channels, pcl_list, pcl_len * sizeof(*pcl_channels));
1614 qdf_mem_copy(pcl_weight, weight_list, pcl_len);
1615 *len = pcl_len;
1616
1617 policy_mgr_debug("sbs_mac0_modified_pcl %d, PCL after ll sap modification",
1618 sbs_mac0_modified_pcl);
1619 policy_mgr_dump_channel_list(*len, pcl_channels, pcl_weight);
1620
1621 return QDF_STATUS_SUCCESS;
1622 }
1623 #else
1624 static inline QDF_STATUS
policy_mgr_pcl_modification_for_ll_lt_sap(struct wlan_objmgr_psoc * psoc,uint32_t * pcl_channels,uint8_t * pcl_weight,uint32_t * len,uint32_t weight_len)1625 policy_mgr_pcl_modification_for_ll_lt_sap(struct wlan_objmgr_psoc *psoc,
1626 uint32_t *pcl_channels,
1627 uint8_t *pcl_weight,
1628 uint32_t *len, uint32_t weight_len)
1629 {
1630 return QDF_STATUS_SUCCESS;
1631 }
1632 #endif
1633
policy_mgr_mode_specific_modification_on_pcl(struct wlan_objmgr_psoc * psoc,uint32_t * pcl_channels,uint8_t * pcl_weight,uint32_t * len,uint32_t weight_len,enum policy_mgr_con_mode mode)1634 static QDF_STATUS policy_mgr_mode_specific_modification_on_pcl(
1635 struct wlan_objmgr_psoc *psoc,
1636 uint32_t *pcl_channels, uint8_t *pcl_weight,
1637 uint32_t *len, uint32_t weight_len,
1638 enum policy_mgr_con_mode mode)
1639 {
1640 QDF_STATUS status = QDF_STATUS_E_FAILURE;
1641
1642 switch (mode) {
1643 case PM_SAP_MODE:
1644 status = policy_mgr_pcl_modification_for_sap(
1645 psoc, pcl_channels, pcl_weight, len, weight_len, mode);
1646 break;
1647 case PM_P2P_GO_MODE:
1648 status = policy_mgr_pcl_modification_for_p2p_go(
1649 psoc, pcl_channels, pcl_weight, len, weight_len);
1650 break;
1651 case PM_STA_MODE:
1652 case PM_P2P_CLIENT_MODE:
1653 case PM_NAN_DISC_MODE:
1654 status = QDF_STATUS_SUCCESS;
1655 break;
1656 case PM_LL_LT_SAP_MODE:
1657 status = policy_mgr_pcl_modification_for_ll_lt_sap(
1658 psoc, pcl_channels, pcl_weight, len, weight_len);
1659 break;
1660 default:
1661 policy_mgr_err("unexpected mode %d", mode);
1662 break;
1663 }
1664
1665 return status;
1666 }
1667
1668 #ifdef FEATURE_FOURTH_CONNECTION
policy_mgr_get_pcl_4_port(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,enum policy_mgr_conc_priority_mode pref)1669 static enum policy_mgr_pcl_type policy_mgr_get_pcl_4_port(
1670 struct wlan_objmgr_psoc *psoc,
1671 enum policy_mgr_con_mode mode,
1672 enum policy_mgr_conc_priority_mode pref)
1673 {
1674 enum policy_mgr_three_connection_mode fourth_index = 0;
1675 enum policy_mgr_pcl_type pcl;
1676
1677 /* Will be enhanced for other types of 4 port conc (NaN etc.)
1678 * in future.
1679 */
1680 if (!policy_mgr_is_hw_dbs_capable(psoc)) {
1681 policy_mgr_err("Can't find index for 4th port pcl table for non dbs capable");
1682 return PM_MAX_PCL_TYPE;
1683 }
1684
1685 /* SAP and P2P Go have same result in 4th port pcl table */
1686 if (mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE)
1687 mode = PM_SAP_MODE;
1688 else if (mode == PM_P2P_CLIENT_MODE)
1689 mode = PM_STA_MODE;
1690
1691 if (mode != PM_STA_MODE && mode != PM_SAP_MODE &&
1692 mode != PM_NDI_MODE) {
1693 policy_mgr_err("Can't start 4th port if not STA, SAP, NDI");
1694 return PM_MAX_PCL_TYPE;
1695 }
1696
1697 fourth_index =
1698 policy_mgr_get_fourth_connection_pcl_table_index(psoc);
1699 if (PM_MAX_THREE_CONNECTION_MODE == fourth_index) {
1700 policy_mgr_err("Can't find index for 4th port pcl table");
1701 return PM_MAX_PCL_TYPE;
1702 }
1703 policy_mgr_debug("Index for 4th port pcl table: %d", fourth_index);
1704
1705 pcl = fourth_connection_pcl_dbs_sbs_table[fourth_index][mode][pref];
1706
1707 return pcl;
1708 }
1709 #else
policy_mgr_get_pcl_4_port(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,enum policy_mgr_conc_priority_mode pref)1710 static inline enum policy_mgr_pcl_type policy_mgr_get_pcl_4_port(
1711 struct wlan_objmgr_psoc *psoc,
1712 enum policy_mgr_con_mode mode,
1713 enum policy_mgr_conc_priority_mode pref)
1714 {return PM_MAX_PCL_TYPE; }
1715 #endif
1716
policy_mgr_get_pcl(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint32_t * pcl_channels,uint32_t * len,uint8_t * pcl_weight,uint32_t weight_len,uint8_t vdev_id)1717 QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc,
1718 enum policy_mgr_con_mode mode,
1719 uint32_t *pcl_channels, uint32_t *len,
1720 uint8_t *pcl_weight, uint32_t weight_len,
1721 uint8_t vdev_id)
1722 {
1723 QDF_STATUS status = QDF_STATUS_E_FAILURE;
1724 uint32_t num_connections = 0;
1725 enum policy_mgr_conc_priority_mode first_index = 0;
1726 enum policy_mgr_one_connection_mode second_index = 0;
1727 enum policy_mgr_two_connection_mode third_index = 0;
1728 enum policy_mgr_pcl_type pcl = PM_NONE;
1729 enum policy_mgr_conc_priority_mode conc_system_pref = 0;
1730 struct policy_mgr_psoc_priv_obj *pm_ctx;
1731 enum QDF_OPMODE qdf_mode;
1732 uint32_t orig_pcl_len;
1733
1734 pm_ctx = policy_mgr_get_context(psoc);
1735 if (!pm_ctx) {
1736 policy_mgr_err("context is NULL");
1737 return status;
1738 }
1739
1740 if ((mode < 0) || (mode >= PM_MAX_NUM_OF_MODE)) {
1741 policy_mgr_err("Invalid connection mode %d received", mode);
1742 return status;
1743 }
1744
1745 /* find the current connection state from pm_conc_connection_list*/
1746 num_connections = policy_mgr_get_connection_count(psoc);
1747 policy_mgr_debug("connections:%d pref:%d requested mode:%d vdev_id:%d",
1748 num_connections, pm_ctx->cur_conc_system_pref, mode,
1749 vdev_id);
1750
1751 switch (pm_ctx->cur_conc_system_pref) {
1752 case 0:
1753 conc_system_pref = PM_THROUGHPUT;
1754 break;
1755 case 1:
1756 conc_system_pref = PM_POWERSAVE;
1757 break;
1758 case 2:
1759 conc_system_pref = PM_LATENCY;
1760 break;
1761 default:
1762 policy_mgr_err("unknown cur_conc_system_pref value %d",
1763 pm_ctx->cur_conc_system_pref);
1764 break;
1765 }
1766
1767 switch (num_connections) {
1768 case 0:
1769 first_index =
1770 policy_mgr_get_first_connection_pcl_table_index(psoc);
1771 pcl = first_connection_pcl_table[mode][first_index];
1772 break;
1773 case 1:
1774 second_index =
1775 policy_mgr_get_second_connection_pcl_table_index(psoc);
1776 if (PM_MAX_ONE_CONNECTION_MODE == second_index) {
1777 policy_mgr_err("couldn't find index for 2nd connection pcl table");
1778 return status;
1779 }
1780 qdf_mode = policy_mgr_get_qdf_mode_from_pm(mode);
1781 if (qdf_mode == QDF_MAX_NO_OF_MODE)
1782 return status;
1783
1784 if (policy_mgr_is_hw_dbs_capable(psoc) == true &&
1785 policy_mgr_is_dbs_allowed_for_concurrency(
1786 psoc, qdf_mode)) {
1787 pcl = (*second_connection_pcl_dbs_table)
1788 [second_index][mode][conc_system_pref];
1789 } else {
1790 pcl = (*second_connection_pcl_non_dbs_table)
1791 [second_index][mode][conc_system_pref];
1792 }
1793
1794 break;
1795 case 2:
1796 third_index =
1797 policy_mgr_get_third_connection_pcl_table_index(psoc);
1798 if (PM_MAX_TWO_CONNECTION_MODE == third_index) {
1799 policy_mgr_err(
1800 "couldn't find index for 3rd connection pcl table");
1801 return status;
1802 }
1803 if (policy_mgr_is_hw_dbs_capable(psoc) == true) {
1804 pcl = (*third_connection_pcl_dbs_table)
1805 [third_index][mode][conc_system_pref];
1806 } else {
1807 pcl = (*third_connection_pcl_non_dbs_table)
1808 [third_index][mode][conc_system_pref];
1809 }
1810 break;
1811 case 3:
1812 pcl = policy_mgr_get_pcl_4_port(psoc, mode, conc_system_pref);
1813 break;
1814 default:
1815 policy_mgr_err("unexpected num_connections value %d",
1816 num_connections);
1817 break;
1818 }
1819
1820 /* once the PCL enum is obtained find out the exact channel list with
1821 * help from sme_get_cfg_valid_channels
1822 */
1823 status = policy_mgr_get_channel_list(psoc, pcl, mode, pcl_channels,
1824 pcl_weight, weight_len, len);
1825 if (QDF_IS_STATUS_ERROR(status)) {
1826 policy_mgr_err("failed to get channel list:%d", status);
1827 return status;
1828 }
1829
1830 if (!*len) {
1831 policymgr_nofl_debug("Total PCL Chan %d", *len);
1832 return QDF_STATUS_SUCCESS;
1833 }
1834 orig_pcl_len = *len;
1835 policy_mgr_dump_channel_list(*len, pcl_channels, pcl_weight);
1836 policy_mgr_mode_specific_modification_on_pcl(
1837 psoc, pcl_channels, pcl_weight, len, weight_len, mode);
1838
1839 status = policy_mgr_modify_pcl_based_on_dnbs(psoc, pcl_channels,
1840 pcl_weight, len);
1841
1842 if (QDF_IS_STATUS_ERROR(status)) {
1843 policy_mgr_err("failed to get modified pcl based on DNBS");
1844 return status;
1845 }
1846
1847 if (orig_pcl_len != *len) {
1848 policy_mgr_debug("PCL after modification");
1849 policy_mgr_dump_channel_list(*len, pcl_channels, pcl_weight);
1850 }
1851
1852 return QDF_STATUS_SUCCESS;
1853 }
1854
1855 enum policy_mgr_conc_priority_mode
policy_mgr_get_first_connection_pcl_table_index(struct wlan_objmgr_psoc * psoc)1856 policy_mgr_get_first_connection_pcl_table_index(
1857 struct wlan_objmgr_psoc *psoc)
1858 {
1859 struct policy_mgr_psoc_priv_obj *pm_ctx;
1860
1861 pm_ctx = policy_mgr_get_context(psoc);
1862 if (!pm_ctx) {
1863 policy_mgr_err("context is NULL");
1864 return PM_THROUGHPUT;
1865 }
1866
1867 if (pm_ctx->cur_conc_system_pref >= PM_MAX_CONC_PRIORITY_MODE)
1868 return PM_THROUGHPUT;
1869
1870 return pm_ctx->cur_conc_system_pref;
1871 }
1872
1873 enum policy_mgr_one_connection_mode
policy_mgr_get_second_connection_pcl_table_index(struct wlan_objmgr_psoc * psoc)1874 policy_mgr_get_second_connection_pcl_table_index(
1875 struct wlan_objmgr_psoc *psoc)
1876 {
1877 enum policy_mgr_one_connection_mode index = PM_MAX_ONE_CONNECTION_MODE;
1878 struct policy_mgr_psoc_priv_obj *pm_ctx;
1879
1880 pm_ctx = policy_mgr_get_context(psoc);
1881 if (!pm_ctx) {
1882 policy_mgr_err("Invalid Context");
1883 return index;
1884 }
1885
1886 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1887 if (PM_STA_MODE == pm_conc_connection_list[0].mode) {
1888 if (WLAN_REG_IS_24GHZ_CH_FREQ(
1889 pm_conc_connection_list[0].freq)) {
1890 if (POLICY_MGR_ONE_ONE ==
1891 pm_conc_connection_list[0].chain_mask)
1892 index = PM_STA_24_1x1;
1893 else
1894 index = PM_STA_24_2x2;
1895 } else {
1896 if (POLICY_MGR_ONE_ONE ==
1897 pm_conc_connection_list[0].chain_mask)
1898 index = PM_STA_5_1x1;
1899 else
1900 index = PM_STA_5_2x2;
1901 }
1902 } else if (PM_SAP_MODE == pm_conc_connection_list[0].mode) {
1903 if (WLAN_REG_IS_24GHZ_CH_FREQ(
1904 pm_conc_connection_list[0].freq)) {
1905 if (POLICY_MGR_ONE_ONE ==
1906 pm_conc_connection_list[0].chain_mask)
1907 index = PM_SAP_24_1x1;
1908 else
1909 index = PM_SAP_24_2x2;
1910 } else {
1911 if (POLICY_MGR_ONE_ONE ==
1912 pm_conc_connection_list[0].chain_mask)
1913 index = PM_SAP_5_1x1;
1914 else
1915 index = PM_SAP_5_2x2;
1916 }
1917 } else if (PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) {
1918 if (WLAN_REG_IS_24GHZ_CH_FREQ(
1919 pm_conc_connection_list[0].freq)) {
1920 if (POLICY_MGR_ONE_ONE ==
1921 pm_conc_connection_list[0].chain_mask)
1922 index = PM_P2P_CLI_24_1x1;
1923 else
1924 index = PM_P2P_CLI_24_2x2;
1925 } else {
1926 if (POLICY_MGR_ONE_ONE ==
1927 pm_conc_connection_list[0].chain_mask)
1928 index = PM_P2P_CLI_5_1x1;
1929 else
1930 index = PM_P2P_CLI_5_2x2;
1931 }
1932 } else if (PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) {
1933 if (WLAN_REG_IS_24GHZ_CH_FREQ(
1934 pm_conc_connection_list[0].freq)) {
1935 if (POLICY_MGR_ONE_ONE ==
1936 pm_conc_connection_list[0].chain_mask)
1937 index = PM_P2P_GO_24_1x1;
1938 else
1939 index = PM_P2P_GO_24_2x2;
1940 } else {
1941 if (POLICY_MGR_ONE_ONE ==
1942 pm_conc_connection_list[0].chain_mask)
1943 index = PM_P2P_GO_5_1x1;
1944 else
1945 index = PM_P2P_GO_5_2x2;
1946 }
1947 } else if (PM_NAN_DISC_MODE == pm_conc_connection_list[0].mode) {
1948 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
1949 index = PM_NAN_DISC_24_1x1;
1950 else
1951 index = PM_NAN_DISC_24_2x2;
1952 } else if (PM_LL_LT_SAP_MODE == pm_conc_connection_list[0].mode) {
1953 index = PM_LL_LT_SAP_5_2x2;
1954 }
1955
1956 policy_mgr_debug("mode:%d freq:%d chain:%d index:%d",
1957 pm_conc_connection_list[0].mode,
1958 pm_conc_connection_list[0].freq,
1959 pm_conc_connection_list[0].chain_mask, index);
1960
1961 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1962
1963 return index;
1964 }
1965
1966 /*
1967 * policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc() -
1968 * This function checks connection mode is in scc or not and returns
1969 * index value based on mode and prvided index inputs.
1970 *
1971 * @scc_2g_1x1: index of scc_2g_1x1 for provided concurrency
1972 * @scc_2g_2x2: index of scc_2g_2x2 for provided concurrency
1973 * @scc_5g_1x1: index of scc_5g_1x1 for provided concurrency
1974 * @scc_5g_2x2: index of scc_5g_2x2 for provided concurrency
1975 *
1976 * Return: policy_mgr_two_connection_mode index
1977 */
1978 static enum policy_mgr_two_connection_mode
policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(enum policy_mgr_two_connection_mode scc_2g_1x1,enum policy_mgr_two_connection_mode scc_2g_2x2,enum policy_mgr_two_connection_mode scc_5g_1x1,enum policy_mgr_two_connection_mode scc_5g_2x2)1979 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
1980 enum policy_mgr_two_connection_mode scc_2g_1x1,
1981 enum policy_mgr_two_connection_mode scc_2g_2x2,
1982 enum policy_mgr_two_connection_mode scc_5g_1x1,
1983 enum policy_mgr_two_connection_mode scc_5g_2x2)
1984 {
1985 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
1986
1987 if (pm_conc_connection_list[0].freq ==
1988 pm_conc_connection_list[1].freq) {
1989 if (WLAN_REG_IS_24GHZ_CH_FREQ(
1990 pm_conc_connection_list[0].freq)) {
1991 if (POLICY_MGR_ONE_ONE ==
1992 pm_conc_connection_list[0].chain_mask)
1993 index = scc_2g_1x1;
1994 else
1995 index = scc_2g_2x2;
1996 } else {
1997 if (POLICY_MGR_ONE_ONE ==
1998 pm_conc_connection_list[0].chain_mask)
1999 index = scc_5g_1x1;
2000 else
2001 index = scc_5g_2x2;
2002 }
2003 }
2004 return index;
2005 }
2006
2007 /*
2008 * policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc() -
2009 * This function checks connection mode is in mcc or not and returns
2010 * index value based on mode and prvided index inputs.
2011 *
2012 * @mcc_2g_1x1: index of mcc_2g_1x1 for provided concurrency
2013 * @mcc_2g_2x2: index of mcc_2g_2x2 for provided concurrency
2014 * @mcc_5g_1x1: index of mcc_5g_1x1 for provided concurrency
2015 * @mcc_5g_2x2: index of mcc_5g_2x2 for provided concurrency
2016 * @mcc_24_5_1x1: index of mcc_24_5_1x1 for provided concurrency
2017 * @mcc_24_5_2x2: index of mcc_24_5_2x2 for provided concurrency
2018 *
2019 * Return: policy_mgr_two_connection_mode index
2020 */
2021 static enum policy_mgr_two_connection_mode
policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(struct wlan_objmgr_psoc * psoc,enum policy_mgr_two_connection_mode mcc_2g_1x1,enum policy_mgr_two_connection_mode mcc_2g_2x2,enum policy_mgr_two_connection_mode mcc_5g_1x1,enum policy_mgr_two_connection_mode mcc_5g_2x2,enum policy_mgr_two_connection_mode mcc_24_5_1x1,enum policy_mgr_two_connection_mode mcc_24_5_2x2)2022 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(
2023 struct wlan_objmgr_psoc *psoc,
2024 enum policy_mgr_two_connection_mode mcc_2g_1x1,
2025 enum policy_mgr_two_connection_mode mcc_2g_2x2,
2026 enum policy_mgr_two_connection_mode mcc_5g_1x1,
2027 enum policy_mgr_two_connection_mode mcc_5g_2x2,
2028 enum policy_mgr_two_connection_mode mcc_24_5_1x1,
2029 enum policy_mgr_two_connection_mode mcc_24_5_2x2)
2030 {
2031 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
2032
2033 if (policy_mgr_are_2_freq_on_same_mac(psoc,
2034 pm_conc_connection_list[0].freq,
2035 pm_conc_connection_list[1].freq)
2036 ) {
2037 if ((WLAN_REG_IS_24GHZ_CH_FREQ(
2038 pm_conc_connection_list[0].freq)) &&
2039 (WLAN_REG_IS_24GHZ_CH_FREQ(
2040 pm_conc_connection_list[1].freq))) {
2041 if (POLICY_MGR_ONE_ONE ==
2042 pm_conc_connection_list[0].chain_mask)
2043 index = mcc_2g_1x1;
2044 else
2045 index = mcc_2g_2x2;
2046 } else if (!(WLAN_REG_IS_24GHZ_CH_FREQ(
2047 pm_conc_connection_list[0].freq)) &&
2048 !(WLAN_REG_IS_24GHZ_CH_FREQ(
2049 pm_conc_connection_list[1].freq))) {
2050 if (POLICY_MGR_ONE_ONE ==
2051 pm_conc_connection_list[0].chain_mask)
2052 index = mcc_5g_1x1;
2053 else
2054 index = mcc_5g_2x2;
2055 } else {
2056 if (POLICY_MGR_ONE_ONE ==
2057 pm_conc_connection_list[0].chain_mask)
2058 index = mcc_24_5_1x1;
2059 else
2060 index = mcc_24_5_2x2;
2061 }
2062 }
2063 return index;
2064 }
2065
2066 /*
2067 * policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs() -
2068 * This function checks connection mode is in dbs or sbs and returns index
2069 * value based on mode and prvided index inputs.
2070 *
2071 * @sbs_5g_1x1: index of sbs_5g_1x1 for provided concurrency
2072 * @sbs_5g_2x2: index of sbs_5g_2x2 for provided concurrency
2073 * @dbs_1x1: index of dbs_1x1 for provided concurrency
2074 * @dbs_2x2: index of dbs_2x2 for provided concurrency
2075 *
2076 * Return: policy_mgr_two_connection_mode index
2077 */
2078 static enum policy_mgr_two_connection_mode
policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(struct wlan_objmgr_psoc * psoc,enum policy_mgr_two_connection_mode sbs_5g_1x1,enum policy_mgr_two_connection_mode sbs_5g_2x2,enum policy_mgr_two_connection_mode dbs_1x1,enum policy_mgr_two_connection_mode dbs_2x2)2079 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(
2080 struct wlan_objmgr_psoc *psoc,
2081 enum policy_mgr_two_connection_mode sbs_5g_1x1,
2082 enum policy_mgr_two_connection_mode sbs_5g_2x2,
2083 enum policy_mgr_two_connection_mode dbs_1x1,
2084 enum policy_mgr_two_connection_mode dbs_2x2)
2085 {
2086 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
2087
2088 if (!policy_mgr_are_2_freq_on_same_mac(psoc,
2089 pm_conc_connection_list[0].freq,
2090 pm_conc_connection_list[1].freq)
2091 ) {
2092 /* SBS */
2093 if (!(WLAN_REG_IS_24GHZ_CH_FREQ(
2094 pm_conc_connection_list[0].freq)) &&
2095 !(WLAN_REG_IS_24GHZ_CH_FREQ(
2096 pm_conc_connection_list[1].freq))) {
2097 if (POLICY_MGR_ONE_ONE ==
2098 pm_conc_connection_list[0].chain_mask)
2099 index = sbs_5g_1x1;
2100 else
2101 index = sbs_5g_2x2;
2102 } else {
2103 /* DBS */
2104 if (POLICY_MGR_ONE_ONE ==
2105 pm_conc_connection_list[0].chain_mask)
2106 index = dbs_1x1;
2107 else
2108 index = dbs_2x2;
2109 }
2110 }
2111
2112 return index;
2113 }
2114
2115 /*
2116 * policy_mgr_get_3rd_pcl_table_index_for_dbs_with_ml_sta() -
2117 * Get third connection pcl table index when ML STA is present
2118 * @sbs_5g_1x1: index of sbs_5g_1x1 for provided concurrency
2119 * @sbs_5g_2x2: index of sbs_5g_2x2 for provided concurrency
2120 * @dbs_1x1: index of dbs_1x1 for provided concurrency
2121 * @dbs_2x2: index of dbs_2x2 for provided concurrency
2122 *
2123 * This function checks connection mode is in dbs or sbs when two ML STA links
2124 * are active and returns index value based on mode and provided index inputs.
2125 *
2126 * Return: policy_mgr_two_connection_mode index
2127 */
2128 static enum policy_mgr_two_connection_mode
policy_mgr_get_3rd_pcl_table_index_for_dbs_with_ml_sta(struct wlan_objmgr_psoc * psoc,enum policy_mgr_two_connection_mode sbs_5g_1x1,enum policy_mgr_two_connection_mode sbs_5g_2x2,enum policy_mgr_two_connection_mode dbs_1x1,enum policy_mgr_two_connection_mode dbs_2x2)2129 policy_mgr_get_3rd_pcl_table_index_for_dbs_with_ml_sta(
2130 struct wlan_objmgr_psoc *psoc,
2131 enum policy_mgr_two_connection_mode sbs_5g_1x1,
2132 enum policy_mgr_two_connection_mode sbs_5g_2x2,
2133 enum policy_mgr_two_connection_mode dbs_1x1,
2134 enum policy_mgr_two_connection_mode dbs_2x2)
2135 {
2136 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
2137
2138 if (!policy_mgr_2_freq_always_on_same_mac(
2139 psoc,
2140 pm_conc_connection_list[0].freq,
2141 pm_conc_connection_list[1].freq)) {
2142 /* SBS */
2143 if (!(WLAN_REG_IS_24GHZ_CH_FREQ(
2144 pm_conc_connection_list[0].freq)) &&
2145 !(WLAN_REG_IS_24GHZ_CH_FREQ(
2146 pm_conc_connection_list[1].freq))) {
2147 if (POLICY_MGR_ONE_ONE ==
2148 pm_conc_connection_list[0].chain_mask)
2149 index = sbs_5g_1x1;
2150 else
2151 index = sbs_5g_2x2;
2152 } else {
2153 /* DBS */
2154 if (POLICY_MGR_ONE_ONE ==
2155 pm_conc_connection_list[0].chain_mask)
2156 index = dbs_1x1;
2157 else
2158 index = dbs_2x2;
2159 }
2160 }
2161
2162 return index;
2163 }
2164
2165 static enum policy_mgr_two_connection_mode
policy_mgr_get_third_connection_pcl_table_index_cli_sap(struct wlan_objmgr_psoc * psoc)2166 policy_mgr_get_third_connection_pcl_table_index_cli_sap(
2167 struct wlan_objmgr_psoc *psoc)
2168 {
2169 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
2170
2171 index =
2172 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
2173 PM_P2P_CLI_SAP_SCC_24_1x1,
2174 PM_P2P_CLI_SAP_SCC_24_2x2,
2175 PM_P2P_CLI_SAP_SCC_5_1x1,
2176 PM_P2P_CLI_SAP_SCC_5_2x2);
2177 if (index != PM_MAX_TWO_CONNECTION_MODE)
2178 return index;
2179
2180 index =
2181 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
2182 PM_P2P_CLI_SAP_MCC_24_1x1,
2183 PM_P2P_CLI_SAP_MCC_24_2x2,
2184 PM_P2P_CLI_SAP_MCC_5_1x1,
2185 PM_P2P_CLI_SAP_MCC_5_2x2,
2186 PM_P2P_CLI_SAP_MCC_24_5_1x1,
2187 PM_P2P_CLI_SAP_MCC_24_5_2x2);
2188
2189 if (index != PM_MAX_TWO_CONNECTION_MODE)
2190 return index;
2191
2192 index =
2193 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
2194 PM_P2P_CLI_SAP_SBS_5_1x1,
2195 PM_P2P_CLI_SAP_SBS_5_2x2,
2196 PM_P2P_CLI_SAP_DBS_1x1,
2197 PM_P2P_CLI_SAP_DBS_2x2);
2198
2199 return index;
2200 }
2201
2202 static enum policy_mgr_two_connection_mode
policy_mgr_get_third_connection_pcl_table_index_sta_sap(struct wlan_objmgr_psoc * psoc)2203 policy_mgr_get_third_connection_pcl_table_index_sta_sap(
2204 struct wlan_objmgr_psoc *psoc)
2205 {
2206 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
2207
2208 index =
2209 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
2210 PM_STA_SAP_SCC_24_1x1,
2211 PM_STA_SAP_SCC_24_2x2,
2212 PM_STA_SAP_SCC_5_1x1,
2213 PM_STA_SAP_SCC_5_2x2);
2214 if (index != PM_MAX_TWO_CONNECTION_MODE)
2215 return index;
2216
2217 index =
2218 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
2219 PM_STA_SAP_MCC_24_1x1,
2220 PM_STA_SAP_MCC_24_2x2,
2221 PM_STA_SAP_MCC_5_1x1,
2222 PM_STA_SAP_MCC_5_2x2,
2223 PM_STA_SAP_MCC_24_5_1x1,
2224 PM_STA_SAP_MCC_24_5_2x2);
2225
2226 if (index != PM_MAX_TWO_CONNECTION_MODE)
2227 return index;
2228
2229 index =
2230 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
2231 PM_STA_SAP_SBS_5_1x1,
2232 PM_STA_SAP_SBS_5_2x2,
2233 PM_STA_SAP_DBS_1x1,
2234 PM_STA_SAP_DBS_2x2);
2235
2236 return index;
2237 }
2238
2239 static enum policy_mgr_two_connection_mode
policy_mgr_get_third_connection_pcl_table_index_sap_sap(struct wlan_objmgr_psoc * psoc)2240 policy_mgr_get_third_connection_pcl_table_index_sap_sap(
2241 struct wlan_objmgr_psoc *psoc)
2242 {
2243 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
2244
2245 index =
2246 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
2247 PM_SAP_SAP_SCC_24_1x1,
2248 PM_SAP_SAP_SCC_24_2x2,
2249 PM_SAP_SAP_SCC_5_1x1,
2250 PM_SAP_SAP_SCC_5_2x2);
2251 if (index != PM_MAX_TWO_CONNECTION_MODE)
2252 return index;
2253
2254 index =
2255 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
2256 PM_SAP_SAP_MCC_24_1x1,
2257 PM_SAP_SAP_MCC_24_2x2,
2258 PM_SAP_SAP_MCC_5_1x1,
2259 PM_SAP_SAP_MCC_5_2x2,
2260 PM_SAP_SAP_MCC_24_5_1x1,
2261 PM_SAP_SAP_MCC_24_5_2x2);
2262
2263 if (index != PM_MAX_TWO_CONNECTION_MODE)
2264 return index;
2265
2266 index =
2267 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
2268 PM_SAP_SAP_SBS_5_1x1,
2269 PM_SAP_SAP_SBS_5_2x2,
2270 PM_SAP_SAP_DBS_1x1,
2271 PM_SAP_SAP_DBS_2x2);
2272
2273 return index;
2274 }
2275
2276 static enum policy_mgr_two_connection_mode
policy_mgr_get_third_connection_pcl_table_index_sta_go(struct wlan_objmgr_psoc * psoc)2277 policy_mgr_get_third_connection_pcl_table_index_sta_go(
2278 struct wlan_objmgr_psoc *psoc)
2279 {
2280 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
2281
2282 index =
2283 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
2284 PM_STA_P2P_GO_SCC_24_1x1,
2285 PM_STA_P2P_GO_SCC_24_2x2,
2286 PM_STA_P2P_GO_SCC_5_1x1,
2287 PM_STA_P2P_GO_SCC_5_2x2);
2288 if (index != PM_MAX_TWO_CONNECTION_MODE)
2289 return index;
2290
2291 index =
2292 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
2293 PM_STA_P2P_GO_MCC_24_1x1,
2294 PM_STA_P2P_GO_MCC_24_2x2,
2295 PM_STA_P2P_GO_MCC_5_1x1,
2296 PM_STA_P2P_GO_MCC_5_2x2,
2297 PM_STA_P2P_GO_MCC_24_5_1x1,
2298 PM_STA_P2P_GO_MCC_24_5_2x2);
2299
2300 if (index != PM_MAX_TWO_CONNECTION_MODE)
2301 return index;
2302
2303 index =
2304 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
2305 PM_STA_P2P_GO_SBS_5_1x1,
2306 PM_STA_P2P_GO_SBS_5_2x2,
2307 PM_STA_P2P_GO_DBS_1x1,
2308 PM_STA_P2P_GO_DBS_2x2);
2309
2310 return index;
2311 }
2312
2313 static enum policy_mgr_two_connection_mode
policy_mgr_get_third_connection_pcl_table_index_sta_cli(struct wlan_objmgr_psoc * psoc)2314 policy_mgr_get_third_connection_pcl_table_index_sta_cli(
2315 struct wlan_objmgr_psoc *psoc)
2316 {
2317 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
2318
2319 index =
2320 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
2321 PM_STA_P2P_CLI_SCC_24_1x1,
2322 PM_STA_P2P_CLI_SCC_24_2x2,
2323 PM_STA_P2P_CLI_SCC_5_1x1,
2324 PM_STA_P2P_CLI_SCC_5_2x2);
2325 if (index != PM_MAX_TWO_CONNECTION_MODE)
2326 return index;
2327
2328 index =
2329 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
2330 PM_STA_P2P_CLI_MCC_24_1x1,
2331 PM_STA_P2P_CLI_MCC_24_2x2,
2332 PM_STA_P2P_CLI_MCC_5_1x1,
2333 PM_STA_P2P_CLI_MCC_5_2x2,
2334 PM_STA_P2P_CLI_MCC_24_5_1x1,
2335 PM_STA_P2P_CLI_MCC_24_5_2x2);
2336
2337 if (index != PM_MAX_TWO_CONNECTION_MODE)
2338 return index;
2339
2340 index =
2341 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
2342 PM_STA_P2P_CLI_SBS_5_1x1,
2343 PM_STA_P2P_CLI_SBS_5_2x2,
2344 PM_STA_P2P_CLI_DBS_1x1,
2345 PM_STA_P2P_CLI_DBS_2x2);
2346
2347 return index;
2348 }
2349
2350 static enum policy_mgr_two_connection_mode
policy_mgr_get_third_connection_pcl_table_index_go_cli(struct wlan_objmgr_psoc * psoc)2351 policy_mgr_get_third_connection_pcl_table_index_go_cli(
2352 struct wlan_objmgr_psoc *psoc)
2353 {
2354 enum policy_mgr_two_connection_mode index;
2355
2356 index =
2357 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
2358 PM_P2P_GO_P2P_CLI_SCC_24_1x1,
2359 PM_P2P_GO_P2P_CLI_SCC_24_2x2,
2360 PM_P2P_GO_P2P_CLI_SCC_5_1x1,
2361 PM_P2P_GO_P2P_CLI_SCC_5_2x2);
2362 if (index != PM_MAX_TWO_CONNECTION_MODE)
2363 return index;
2364
2365 index =
2366 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
2367 PM_P2P_GO_P2P_CLI_MCC_24_1x1,
2368 PM_P2P_GO_P2P_CLI_MCC_24_2x2,
2369 PM_P2P_GO_P2P_CLI_MCC_5_1x1,
2370 PM_P2P_GO_P2P_CLI_MCC_5_2x2,
2371 PM_P2P_GO_P2P_CLI_MCC_24_5_1x1,
2372 PM_P2P_GO_P2P_CLI_MCC_24_5_2x2);
2373
2374 if (index != PM_MAX_TWO_CONNECTION_MODE)
2375 return index;
2376
2377 index =
2378 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
2379 PM_P2P_GO_P2P_CLI_SBS_5_1x1,
2380 PM_P2P_GO_P2P_CLI_SBS_5_2x2,
2381 PM_P2P_GO_P2P_CLI_DBS_1x1,
2382 PM_P2P_GO_P2P_CLI_DBS_2x2);
2383
2384 return index;
2385 }
2386
2387 static enum policy_mgr_two_connection_mode
policy_mgr_get_third_connection_pcl_table_index_go_sap(struct wlan_objmgr_psoc * psoc)2388 policy_mgr_get_third_connection_pcl_table_index_go_sap(
2389 struct wlan_objmgr_psoc *psoc)
2390 {
2391 enum policy_mgr_two_connection_mode index;
2392
2393 index =
2394 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
2395 PM_P2P_GO_SAP_SCC_24_1x1,
2396 PM_P2P_GO_SAP_SCC_24_2x2,
2397 PM_P2P_GO_SAP_SCC_5_1x1,
2398 PM_P2P_GO_SAP_SCC_5_2x2);
2399 if (index != PM_MAX_TWO_CONNECTION_MODE)
2400 return index;
2401
2402 index =
2403 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
2404 PM_P2P_GO_SAP_MCC_24_1x1,
2405 PM_P2P_GO_SAP_MCC_24_2x2,
2406 PM_P2P_GO_SAP_MCC_5_1x1,
2407 PM_P2P_GO_SAP_MCC_5_2x2,
2408 PM_P2P_GO_SAP_MCC_24_5_1x1,
2409 PM_P2P_GO_SAP_MCC_24_5_2x2);
2410
2411 if (index != PM_MAX_TWO_CONNECTION_MODE)
2412 return index;
2413
2414 index =
2415 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
2416 PM_P2P_GO_SAP_SBS_5_1x1,
2417 PM_P2P_GO_SAP_SBS_5_2x2,
2418 PM_P2P_GO_SAP_DBS_1x1,
2419 PM_P2P_GO_SAP_DBS_2x2);
2420
2421 return index;
2422 }
2423
2424 static enum policy_mgr_two_connection_mode
policy_mgr_get_third_connection_pcl_table_index_sta_sta(struct wlan_objmgr_psoc * psoc)2425 policy_mgr_get_third_connection_pcl_table_index_sta_sta(
2426 struct wlan_objmgr_psoc *psoc)
2427 {
2428 enum policy_mgr_two_connection_mode index;
2429
2430 if (policy_mgr_is_ml_vdev_id(psoc,
2431 pm_conc_connection_list[0].vdev_id) &&
2432 policy_mgr_is_ml_vdev_id(psoc,
2433 pm_conc_connection_list[1].vdev_id)) {
2434 index =
2435 policy_mgr_get_3rd_pcl_table_index_for_dbs_with_ml_sta(
2436 psoc,
2437 PM_STA_STA_SBS_5_1x1,
2438 PM_STA_STA_SBS_5_2x2,
2439 PM_STA_STA_DBS_1x1,
2440 PM_STA_STA_DBS_2x2);
2441 if (index != PM_MAX_TWO_CONNECTION_MODE)
2442 return index;
2443 }
2444 index =
2445 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
2446 PM_STA_STA_SCC_24_1x1,
2447 PM_STA_STA_SCC_24_2x2,
2448 PM_STA_STA_SCC_5_1x1,
2449 PM_STA_STA_SCC_5_2x2);
2450 if (index != PM_MAX_TWO_CONNECTION_MODE)
2451 return index;
2452
2453 index =
2454 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
2455 PM_STA_STA_MCC_24_1x1,
2456 PM_STA_STA_MCC_24_2x2,
2457 PM_STA_STA_MCC_5_1x1,
2458 PM_STA_STA_MCC_5_2x2,
2459 PM_STA_STA_MCC_24_5_1x1,
2460 PM_STA_STA_MCC_24_5_2x2);
2461
2462 if (index != PM_MAX_TWO_CONNECTION_MODE)
2463 return index;
2464
2465 index =
2466 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
2467 PM_STA_STA_SBS_5_1x1,
2468 PM_STA_STA_SBS_5_2x2,
2469 PM_STA_STA_DBS_1x1,
2470 PM_STA_STA_DBS_2x2);
2471
2472 return index;
2473 }
2474
2475 static enum policy_mgr_two_connection_mode
policy_mgr_get_third_connection_pcl_table_index_cli_cli(struct wlan_objmgr_psoc * psoc)2476 policy_mgr_get_third_connection_pcl_table_index_cli_cli(
2477 struct wlan_objmgr_psoc *psoc)
2478 {
2479 enum policy_mgr_two_connection_mode index;
2480
2481 index =
2482 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
2483 PM_P2P_CLI_P2P_CLI_SCC_24_1x1,
2484 PM_P2P_CLI_P2P_CLI_SCC_24_2x2,
2485 PM_P2P_CLI_P2P_CLI_SCC_5_1x1,
2486 PM_P2P_CLI_P2P_CLI_SCC_5_2x2);
2487 if (index != PM_MAX_TWO_CONNECTION_MODE)
2488 return index;
2489
2490 index =
2491 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
2492 PM_P2P_CLI_P2P_CLI_MCC_24_1x1,
2493 PM_P2P_CLI_P2P_CLI_MCC_24_2x2,
2494 PM_P2P_CLI_P2P_CLI_MCC_5_1x1,
2495 PM_P2P_CLI_P2P_CLI_MCC_5_2x2,
2496 PM_P2P_CLI_P2P_CLI_MCC_24_5_1x1,
2497 PM_P2P_CLI_P2P_CLI_MCC_24_5_2x2);
2498
2499 if (index != PM_MAX_TWO_CONNECTION_MODE)
2500 return index;
2501
2502 index =
2503 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
2504 PM_P2P_CLI_P2P_CLI_SBS_5_1x1,
2505 PM_P2P_CLI_P2P_CLI_SBS_5_2x2,
2506 PM_P2P_CLI_P2P_CLI_DBS_1x1,
2507 PM_P2P_CLI_P2P_CLI_DBS_2x2);
2508
2509 return index;
2510 }
2511
2512 static enum policy_mgr_two_connection_mode
policy_mgr_get_third_connection_pcl_table_index_go_go(struct wlan_objmgr_psoc * psoc)2513 policy_mgr_get_third_connection_pcl_table_index_go_go(
2514 struct wlan_objmgr_psoc *psoc)
2515 {
2516 enum policy_mgr_two_connection_mode index;
2517
2518 index =
2519 policy_mgr_check_and_get_third_connection_pcl_table_index_for_scc(
2520 PM_P2P_GO_P2P_GO_SCC_24_1x1,
2521 PM_P2P_GO_P2P_GO_SCC_24_2x2,
2522 PM_P2P_GO_P2P_GO_SCC_5_1x1,
2523 PM_P2P_GO_P2P_GO_SCC_5_2x2);
2524 if (index != PM_MAX_TWO_CONNECTION_MODE)
2525 return index;
2526
2527 index =
2528 policy_mgr_check_and_get_third_connection_pcl_table_index_for_mcc(psoc,
2529 PM_P2P_GO_P2P_GO_MCC_24_1x1,
2530 PM_P2P_GO_P2P_GO_MCC_24_2x2,
2531 PM_P2P_GO_P2P_GO_MCC_5_1x1,
2532 PM_P2P_GO_P2P_GO_MCC_5_2x2,
2533 PM_P2P_GO_P2P_GO_MCC_24_5_1x1,
2534 PM_P2P_GO_P2P_GO_MCC_24_5_2x2);
2535 if (index != PM_MAX_TWO_CONNECTION_MODE)
2536 return index;
2537
2538 index =
2539 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(psoc,
2540 PM_P2P_GO_P2P_GO_SBS_5_1x1,
2541 PM_P2P_GO_P2P_GO_SBS_5_2x2,
2542 PM_P2P_GO_P2P_GO_DBS_1x1,
2543 PM_P2P_GO_P2P_GO_DBS_2x2);
2544 return index;
2545 }
2546
2547 static enum policy_mgr_two_connection_mode
policy_mgr_get_third_connection_pcl_table_index_nan_ndi(struct wlan_objmgr_psoc * psoc)2548 policy_mgr_get_third_connection_pcl_table_index_nan_ndi(
2549 struct wlan_objmgr_psoc *psoc)
2550 {
2551 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
2552 /* SCC */
2553 if (pm_conc_connection_list[0].freq ==
2554 pm_conc_connection_list[1].freq) {
2555 /* Policy mgr only considers NAN Disc ch in 2.4GHz */
2556 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
2557 index = PM_NAN_DISC_NDI_SCC_24_1x1;
2558 else
2559 index = PM_NAN_DISC_NDI_SCC_24_2x2;
2560 /* MCC */
2561 } else if (policy_mgr_are_2_freq_on_same_mac(psoc,
2562 pm_conc_connection_list[0].freq,
2563 pm_conc_connection_list[1].freq)) {
2564 /* Policy mgr only considers NAN Disc ch in 2.4GHz */
2565 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
2566 index = PM_NAN_DISC_NDI_MCC_24_1x1;
2567 else
2568 index = PM_NAN_DISC_NDI_MCC_24_2x2;
2569 /* DBS */
2570 } else {
2571 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
2572 index = PM_NAN_DISC_NDI_DBS_1x1;
2573 else
2574 index = PM_NAN_DISC_NDI_DBS_2x2;
2575 }
2576 return index;
2577 }
2578
2579 static enum policy_mgr_two_connection_mode
policy_mgr_get_third_connection_pcl_table_index_sta_nan(struct wlan_objmgr_psoc * psoc)2580 policy_mgr_get_third_connection_pcl_table_index_sta_nan(
2581 struct wlan_objmgr_psoc *psoc)
2582 {
2583 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
2584 /* SCC */
2585 if (pm_conc_connection_list[0].freq ==
2586 pm_conc_connection_list[1].freq) {
2587 /* Policy mgr only considers NAN Disc ch in 2.4GHz */
2588 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
2589 index = PM_STA_NAN_DISC_SCC_24_1x1;
2590 else
2591 index = PM_STA_NAN_DISC_SCC_24_2x2;
2592 /* MCC */
2593 } else if (policy_mgr_are_2_freq_on_same_mac(psoc,
2594 pm_conc_connection_list[0].freq,
2595 pm_conc_connection_list[1].freq)) {
2596 /* Policy mgr only considers NAN Disc ch in 2.4 GHz */
2597 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
2598 index = PM_STA_NAN_DISC_MCC_24_1x1;
2599 else
2600 index = PM_STA_NAN_DISC_MCC_24_2x2;
2601 /* DBS */
2602 } else {
2603 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
2604 index = PM_STA_NAN_DISC_DBS_1x1;
2605 else
2606 index = PM_STA_NAN_DISC_DBS_2x2;
2607 }
2608 return index;
2609 }
2610
2611 static enum policy_mgr_two_connection_mode
policy_mgr_get_third_connection_pcl_table_index_sap_nan(struct wlan_objmgr_psoc * psoc)2612 policy_mgr_get_third_connection_pcl_table_index_sap_nan(
2613 struct wlan_objmgr_psoc *psoc)
2614 {
2615 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
2616 /* SCC */
2617 if (pm_conc_connection_list[0].freq ==
2618 pm_conc_connection_list[1].freq) {
2619 /* Policy mgr only considers NAN Disc ch in 2.4 GHz */
2620 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
2621 index = PM_SAP_NAN_DISC_SCC_24_1x1;
2622 else
2623 index = PM_SAP_NAN_DISC_SCC_24_2x2;
2624 /* MCC */
2625 } else if (policy_mgr_are_2_freq_on_same_mac(psoc,
2626 pm_conc_connection_list[0].freq,
2627 pm_conc_connection_list[1].freq)) {
2628 /* Policy mgr only considers NAN Disc ch in 2.4GHz */
2629 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
2630 index = PM_SAP_NAN_DISC_MCC_24_1x1;
2631 else
2632 index = PM_SAP_NAN_DISC_MCC_24_2x2;
2633 /* DBS */
2634 } else {
2635 if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask)
2636 index = PM_SAP_NAN_DISC_DBS_1x1;
2637 else
2638 index = PM_SAP_NAN_DISC_DBS_2x2;
2639 }
2640 return index;
2641 }
2642
2643 static enum policy_mgr_two_connection_mode
policy_mgr_get_third_connection_pcl_table_index_sta_ll_lt_sap(struct wlan_objmgr_psoc * psoc)2644 policy_mgr_get_third_connection_pcl_table_index_sta_ll_lt_sap(
2645 struct wlan_objmgr_psoc *psoc)
2646 {
2647 enum policy_mgr_two_connection_mode index;
2648 enum policy_mgr_two_connection_mode sbs_5g_1x1;
2649 enum policy_mgr_two_connection_mode sbs_5g_2x2;
2650 qdf_freq_t sta_freq, sbs_cut_off_freq;
2651
2652 /*
2653 * LL_LT_SAP can not be in SCC so there will not be any scc index.
2654 * With LL_LT_SAP, MCC is possible only on 5 GHz
2655 */
2656 if (policy_mgr_are_2_freq_on_same_mac(
2657 psoc,
2658 pm_conc_connection_list[0].freq,
2659 pm_conc_connection_list[1].freq)) {
2660 if (!(WLAN_REG_IS_24GHZ_CH_FREQ(
2661 pm_conc_connection_list[0].freq)) &&
2662 !(WLAN_REG_IS_24GHZ_CH_FREQ(
2663 pm_conc_connection_list[1].freq))) {
2664 if (POLICY_MGR_ONE_ONE ==
2665 pm_conc_connection_list[0].chain_mask)
2666 index = PM_STA_5_LL_LT_SAP_MCC_1x1;
2667 else
2668 index = PM_STA_5_LL_LT_SAP_MCC_2x2;
2669
2670 return index;
2671 }
2672 }
2673
2674 if (pm_conc_connection_list[0].mode == PM_STA_MODE)
2675 sta_freq = pm_conc_connection_list[0].freq;
2676 else
2677 sta_freq = pm_conc_connection_list[1].freq;
2678
2679 sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(psoc);
2680
2681 if (sta_freq < sbs_cut_off_freq) {
2682 sbs_5g_1x1 = PM_STA_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1;
2683 sbs_5g_2x2 = PM_STA_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2;
2684 } else {
2685 sbs_5g_1x1 = PM_STA_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1;
2686 sbs_5g_2x2 = PM_STA_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2;
2687 }
2688
2689 index =
2690 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(
2691 psoc, sbs_5g_1x1, sbs_5g_2x2,
2692 PM_STA_24_LL_LT_SAP_DBS_1x1,
2693 PM_STA_24_LL_LT_SAP_DBS_2x2);
2694 return index;
2695 }
2696
2697 static enum policy_mgr_two_connection_mode
policy_mgr_get_third_connection_pcl_table_index_sap_ll_lt_sap(struct wlan_objmgr_psoc * psoc)2698 policy_mgr_get_third_connection_pcl_table_index_sap_ll_lt_sap(
2699 struct wlan_objmgr_psoc *psoc)
2700 {
2701 enum policy_mgr_two_connection_mode index;
2702 enum policy_mgr_two_connection_mode sbs_5g_1x1;
2703 enum policy_mgr_two_connection_mode sbs_5g_2x2;
2704 qdf_freq_t sap_freq, sbs_cut_off_freq;
2705
2706 if (pm_conc_connection_list[0].mode == PM_SAP_MODE)
2707 sap_freq = pm_conc_connection_list[0].freq;
2708 else
2709 sap_freq = pm_conc_connection_list[1].freq;
2710
2711 sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(psoc);
2712
2713 if (sap_freq < sbs_cut_off_freq) {
2714 sbs_5g_1x1 = PM_SAP_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1;
2715 sbs_5g_2x2 = PM_SAP_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2;
2716 } else {
2717 sbs_5g_1x1 = PM_SAP_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1;
2718 sbs_5g_2x2 = PM_SAP_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2;
2719 }
2720
2721 /*
2722 * LL_LT_SAP can not be in SCC so there will not be any scc index.
2723 * For LL_LT_SAP + SAP, MCC is not possible, so there will be only
2724 * sbs or dbs index
2725 */
2726
2727 index =
2728 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(
2729 psoc, sbs_5g_1x1, sbs_5g_2x2,
2730 PM_SAP_24_LL_LT_SAP_DBS_1x1,
2731 PM_SAP_24_LL_LT_SAP_DBS_2x2);
2732 return index;
2733 }
2734
2735 static enum policy_mgr_two_connection_mode
policy_mgr_get_third_connection_pcl_table_index_go_ll_lt_sap(struct wlan_objmgr_psoc * psoc)2736 policy_mgr_get_third_connection_pcl_table_index_go_ll_lt_sap(
2737 struct wlan_objmgr_psoc *psoc)
2738 {
2739 enum policy_mgr_two_connection_mode index;
2740 enum policy_mgr_two_connection_mode sbs_5g_1x1;
2741 enum policy_mgr_two_connection_mode sbs_5g_2x2;
2742 qdf_freq_t go_freq, sbs_cut_off_freq;
2743
2744 /*
2745 * LL_LT_SAP can not be in SCC so there will not be any scc index.
2746 * With LL_LT_SAP, MCC is possible only on 5 GHz
2747 */
2748 if (policy_mgr_are_2_freq_on_same_mac(
2749 psoc,
2750 pm_conc_connection_list[0].freq,
2751 pm_conc_connection_list[1].freq)) {
2752 if (!(WLAN_REG_IS_24GHZ_CH_FREQ(
2753 pm_conc_connection_list[0].freq)) &&
2754 !(WLAN_REG_IS_24GHZ_CH_FREQ(
2755 pm_conc_connection_list[1].freq))) {
2756 if (POLICY_MGR_ONE_ONE ==
2757 pm_conc_connection_list[0].chain_mask)
2758 index = PM_P2P_GO_5_LL_LT_SAP_MCC_1x1;
2759 else
2760 index = PM_P2P_GO_5_LL_LT_SAP_MCC_2x2;
2761
2762 return index;
2763 }
2764 }
2765
2766 if (pm_conc_connection_list[0].mode == PM_P2P_GO_MODE)
2767 go_freq = pm_conc_connection_list[0].freq;
2768 else
2769 go_freq = pm_conc_connection_list[1].freq;
2770
2771 sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(psoc);
2772
2773 if (go_freq < sbs_cut_off_freq) {
2774 sbs_5g_1x1 = PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1;
2775 sbs_5g_2x2 = PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2;
2776 } else {
2777 sbs_5g_1x1 = PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1;
2778 sbs_5g_2x2 = PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2;
2779 }
2780
2781 index =
2782 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(
2783 psoc, sbs_5g_1x1, sbs_5g_2x2,
2784 PM_P2P_GO_24_LL_LT_SAP_DBS_1x1,
2785 PM_P2P_GO_24_LL_LT_SAP_DBS_2x2);
2786 return index;
2787 }
2788
2789 static enum policy_mgr_two_connection_mode
policy_mgr_get_third_connection_pcl_table_index_cli_ll_lt_sap(struct wlan_objmgr_psoc * psoc)2790 policy_mgr_get_third_connection_pcl_table_index_cli_ll_lt_sap(
2791 struct wlan_objmgr_psoc *psoc)
2792 {
2793 enum policy_mgr_two_connection_mode index;
2794 enum policy_mgr_two_connection_mode sbs_5g_1x1;
2795 enum policy_mgr_two_connection_mode sbs_5g_2x2;
2796 qdf_freq_t cli_freq, sbs_cut_off_freq;
2797
2798 /*
2799 * LL_LT_SAP can not be in SCC so there will not be any scc index.
2800 * With LL_LT_SAP, MCC is possible only on 5 GHz
2801 */
2802 if (policy_mgr_are_2_freq_on_same_mac(
2803 psoc,
2804 pm_conc_connection_list[0].freq,
2805 pm_conc_connection_list[1].freq)) {
2806 if (!(WLAN_REG_IS_24GHZ_CH_FREQ(
2807 pm_conc_connection_list[0].freq)) &&
2808 !(WLAN_REG_IS_24GHZ_CH_FREQ(
2809 pm_conc_connection_list[1].freq))) {
2810 if (POLICY_MGR_ONE_ONE ==
2811 pm_conc_connection_list[0].chain_mask)
2812 index = PM_P2P_CLI_5_LL_LT_SAP_MCC_1x1;
2813 else
2814 index = PM_P2P_CLI_5_LL_LT_SAP_MCC_2x2;
2815
2816 return index;
2817 }
2818 }
2819
2820 if (pm_conc_connection_list[0].mode == PM_P2P_GO_MODE)
2821 cli_freq = pm_conc_connection_list[0].freq;
2822 else
2823 cli_freq = pm_conc_connection_list[1].freq;
2824
2825 sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(psoc);
2826
2827 if (cli_freq < sbs_cut_off_freq) {
2828 sbs_5g_1x1 = PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_1x1;
2829 sbs_5g_2x2 = PM_P2P_GO_5_LOW_LL_LT_SAP_5_HIGH_SBS_2x2;
2830 } else {
2831 sbs_5g_1x1 = PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_1x1;
2832 sbs_5g_2x2 = PM_P2P_GO_5_HIGH_LL_LT_SAP_5_LOW_SBS_2x2;
2833 }
2834
2835 index =
2836 policy_mgr_check_and_get_third_connection_pcl_table_index_for_dbs(
2837 psoc, sbs_5g_1x1, sbs_5g_2x2,
2838 PM_P2P_CLI_24_LL_LT_SAP_DBS_1x1,
2839 PM_P2P_CLI_24_LL_LT_SAP_DBS_2x2);
2840 return index;
2841 }
2842
2843 enum policy_mgr_two_connection_mode
policy_mgr_get_third_connection_pcl_table_index(struct wlan_objmgr_psoc * psoc)2844 policy_mgr_get_third_connection_pcl_table_index(
2845 struct wlan_objmgr_psoc *psoc)
2846 {
2847 enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE;
2848 struct policy_mgr_psoc_priv_obj *pm_ctx;
2849
2850 pm_ctx = policy_mgr_get_context(psoc);
2851 if (!pm_ctx) {
2852 policy_mgr_err("Invalid Context");
2853 return index;
2854 }
2855
2856 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2857 if (((PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) &&
2858 (PM_SAP_MODE == pm_conc_connection_list[1].mode)) ||
2859 ((PM_SAP_MODE == pm_conc_connection_list[0].mode) &&
2860 (PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode)))
2861 index =
2862 policy_mgr_get_third_connection_pcl_table_index_cli_sap(psoc);
2863 else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) &&
2864 (PM_SAP_MODE == pm_conc_connection_list[1].mode)) ||
2865 ((PM_SAP_MODE == pm_conc_connection_list[0].mode) &&
2866 (PM_STA_MODE == pm_conc_connection_list[1].mode)))
2867 index =
2868 policy_mgr_get_third_connection_pcl_table_index_sta_sap(psoc);
2869 else if ((PM_SAP_MODE == pm_conc_connection_list[0].mode) &&
2870 (PM_SAP_MODE == pm_conc_connection_list[1].mode))
2871 index =
2872 policy_mgr_get_third_connection_pcl_table_index_sap_sap(psoc);
2873 else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) &&
2874 (PM_P2P_GO_MODE == pm_conc_connection_list[1].mode)) ||
2875 ((PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) &&
2876 (PM_STA_MODE == pm_conc_connection_list[1].mode)))
2877 index =
2878 policy_mgr_get_third_connection_pcl_table_index_sta_go(psoc);
2879 else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) &&
2880 (PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode)) ||
2881 ((PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) &&
2882 (PM_STA_MODE == pm_conc_connection_list[1].mode)))
2883 index =
2884 policy_mgr_get_third_connection_pcl_table_index_sta_cli(psoc);
2885 else if (((PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) &&
2886 (PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode)) ||
2887 ((PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) &&
2888 (PM_P2P_GO_MODE == pm_conc_connection_list[1].mode)))
2889 index =
2890 policy_mgr_get_third_connection_pcl_table_index_go_cli(psoc);
2891 else if (((PM_SAP_MODE == pm_conc_connection_list[0].mode) &&
2892 (PM_P2P_GO_MODE == pm_conc_connection_list[1].mode)) ||
2893 ((PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) &&
2894 (PM_SAP_MODE == pm_conc_connection_list[1].mode)))
2895 index =
2896 policy_mgr_get_third_connection_pcl_table_index_go_sap(psoc);
2897 else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) &&
2898 (PM_STA_MODE == pm_conc_connection_list[1].mode)) ||
2899 ((PM_STA_MODE == pm_conc_connection_list[0].mode) &&
2900 (PM_STA_MODE == pm_conc_connection_list[1].mode)))
2901 index =
2902 policy_mgr_get_third_connection_pcl_table_index_sta_sta(psoc);
2903 else if (((PM_NAN_DISC_MODE == pm_conc_connection_list[0].mode) &&
2904 (PM_STA_MODE == pm_conc_connection_list[1].mode)) ||
2905 ((PM_STA_MODE == pm_conc_connection_list[0].mode) &&
2906 (PM_NAN_DISC_MODE == pm_conc_connection_list[1].mode)))
2907 index =
2908 policy_mgr_get_third_connection_pcl_table_index_sta_nan(psoc);
2909 else if (((PM_NAN_DISC_MODE == pm_conc_connection_list[0].mode) &&
2910 (PM_NDI_MODE == pm_conc_connection_list[1].mode)) ||
2911 ((PM_NDI_MODE == pm_conc_connection_list[0].mode) &&
2912 (PM_NAN_DISC_MODE == pm_conc_connection_list[1].mode)))
2913 index =
2914 policy_mgr_get_third_connection_pcl_table_index_nan_ndi(psoc);
2915 else if (((PM_SAP_MODE == pm_conc_connection_list[0].mode) &&
2916 (PM_NAN_DISC_MODE == pm_conc_connection_list[1].mode)) ||
2917 ((PM_NAN_DISC_MODE == pm_conc_connection_list[0].mode) &&
2918 (PM_SAP_MODE == pm_conc_connection_list[1].mode)))
2919 index =
2920 policy_mgr_get_third_connection_pcl_table_index_sap_nan(psoc);
2921 else if ((pm_conc_connection_list[0].mode == PM_P2P_GO_MODE) &&
2922 (pm_conc_connection_list[1].mode == PM_P2P_GO_MODE))
2923 index =
2924 policy_mgr_get_third_connection_pcl_table_index_go_go(psoc);
2925
2926 else if ((pm_conc_connection_list[0].mode == PM_P2P_CLIENT_MODE) &&
2927 (pm_conc_connection_list[1].mode == PM_P2P_CLIENT_MODE))
2928 index =
2929 policy_mgr_get_third_connection_pcl_table_index_cli_cli(psoc);
2930
2931 else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) &&
2932 (PM_LL_LT_SAP_MODE == pm_conc_connection_list[1].mode)) ||
2933 ((PM_LL_LT_SAP_MODE == pm_conc_connection_list[0].mode) &&
2934 (PM_STA_MODE == pm_conc_connection_list[1].mode)))
2935 index = policy_mgr_get_third_connection_pcl_table_index_sta_ll_lt_sap(psoc);
2936
2937 else if (((PM_SAP_MODE == pm_conc_connection_list[0].mode) &&
2938 (PM_LL_LT_SAP_MODE == pm_conc_connection_list[1].mode)) ||
2939 ((PM_LL_LT_SAP_MODE == pm_conc_connection_list[0].mode) &&
2940 (PM_SAP_MODE == pm_conc_connection_list[1].mode)))
2941 index = policy_mgr_get_third_connection_pcl_table_index_sap_ll_lt_sap(psoc);
2942
2943 else if (((PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) &&
2944 (PM_LL_LT_SAP_MODE == pm_conc_connection_list[1].mode)) ||
2945 ((PM_LL_LT_SAP_MODE == pm_conc_connection_list[0].mode) &&
2946 (PM_P2P_GO_MODE == pm_conc_connection_list[1].mode)))
2947 index = policy_mgr_get_third_connection_pcl_table_index_go_ll_lt_sap(psoc);
2948
2949 else if (((PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) &&
2950 (PM_LL_LT_SAP_MODE == pm_conc_connection_list[1].mode)) ||
2951 ((PM_LL_LT_SAP_MODE == pm_conc_connection_list[0].mode) &&
2952 (PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode)))
2953 index = policy_mgr_get_third_connection_pcl_table_index_cli_ll_lt_sap(psoc);
2954
2955 policy_mgr_debug("mode0:%d mode1:%d freq0:%d freq1:%d chain:%d index:%d",
2956 pm_conc_connection_list[0].mode,
2957 pm_conc_connection_list[1].mode,
2958 pm_conc_connection_list[0].freq,
2959 pm_conc_connection_list[1].freq,
2960 pm_conc_connection_list[0].chain_mask, index);
2961
2962 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2963
2964 return index;
2965 }
2966
2967 #ifdef FEATURE_FOURTH_CONNECTION
2968 /**
2969 * policy_mgr_get_index_for_3_given_freq_dbs() - Find the index for next
2970 * connection for given 3 freq in DBS mode
2971 * @pm_ctx: policy manager context
2972 * @index: Index to return for next connection
2973 * @freq1: freq of interface 1
2974 * @freq2: freq of interface 2
2975 * @freq3: freq of interface 3
2976 *
2977 * This function finds the index for next connection for 3 freq in DBS mode.
2978 *
2979 * Return: none
2980 */
2981 static void
policy_mgr_get_index_for_3_given_freq_dbs(struct policy_mgr_psoc_priv_obj * pm_ctx,enum policy_mgr_three_connection_mode * index,qdf_freq_t freq1,qdf_freq_t freq2,qdf_freq_t freq3)2982 policy_mgr_get_index_for_3_given_freq_dbs(
2983 struct policy_mgr_psoc_priv_obj *pm_ctx,
2984 enum policy_mgr_three_connection_mode *index,
2985 qdf_freq_t freq1, qdf_freq_t freq2, qdf_freq_t freq3)
2986 {
2987 /* If all freq are on same band */
2988 if ((WLAN_REG_IS_24GHZ_CH_FREQ(freq1) ==
2989 WLAN_REG_IS_24GHZ_CH_FREQ(freq2) &&
2990 (WLAN_REG_IS_24GHZ_CH_FREQ(freq2) ==
2991 WLAN_REG_IS_24GHZ_CH_FREQ(freq3)))) {
2992 policy_mgr_err("Invalid mode for all freq %d, %d and %d on same band",
2993 freq1, freq2, freq3);
2994 return;
2995 }
2996
2997 /*
2998 * If freq1 and freq2 are on same band and freq3 is on differet band and
2999 * is not sharing mac with any SAP. STA on same band is handled above,
3000 * so both SAP on same band mean STA cannot be on same band. This can
3001 * happen if SBS is not enabled.
3002 */
3003 if (WLAN_REG_IS_24GHZ_CH_FREQ(freq1) ==
3004 WLAN_REG_IS_24GHZ_CH_FREQ(freq2)) {
3005 if (WLAN_REG_IS_24GHZ_CH_FREQ(freq3))
3006 /*
3007 * As all 3 cannot be on same band, so if freq3 is
3008 * 2.4 GHZ mean both freq1 and freq2 are on 5 / 6 GHZ
3009 */
3010 *index = PM_5_SCC_MCC_PLUS_24_DBS;
3011 else
3012 /*
3013 * As all 3 cannot be on same band, so if freq3 is
3014 * 5 / 6 GHZ, mean both freq1 and freq2 are on 2.4 GHZ.
3015 */
3016 *index = PM_24_SCC_MCC_PLUS_5_DBS;
3017 return;
3018 }
3019
3020 /*
3021 * if freq1 and freq 2 are on different band (2 GHZ + 5 GHZ/6 GHZ DBS),
3022 * check with which freq the freq3 will share mac, and return index as
3023 * per it.
3024 */
3025 if (WLAN_REG_IS_24GHZ_CH_FREQ(freq3))
3026 *index = PM_24_SCC_MCC_PLUS_5_DBS;
3027 else
3028 *index = PM_5_SCC_MCC_PLUS_24_DBS;
3029 }
3030
3031 /**
3032 * policy_mgr_get_index_for_3_given_freq_sbs() - Find the index for next
3033 * connection for 3 given freq, in case current HW mode is SBS
3034 * @pm_ctx: policy manager context
3035 * @index: Index to return for next connection
3036 * @freq1: freq of interface 1
3037 * @freq2: freq of interface 2
3038 * @freq3: freq of interface 3
3039 *
3040 * This function finds the index for next
3041 * connection for 3 given freq, in case current HW mode is SBS
3042 *
3043 * Return: none
3044 */
policy_mgr_get_index_for_3_given_freq_sbs(struct policy_mgr_psoc_priv_obj * pm_ctx,enum policy_mgr_three_connection_mode * index,qdf_freq_t freq1,qdf_freq_t freq2,qdf_freq_t freq3)3045 static void policy_mgr_get_index_for_3_given_freq_sbs(
3046 struct policy_mgr_psoc_priv_obj *pm_ctx,
3047 enum policy_mgr_three_connection_mode *index,
3048 qdf_freq_t freq1, qdf_freq_t freq2, qdf_freq_t freq3)
3049 {
3050 qdf_freq_t sbs_cut_off_freq;
3051 qdf_freq_t shared_5_ghz_freq = 0;
3052
3053 /*
3054 * Sanity check: At least 2 of the given freq needs to be creating SBS
3055 * separation for HW mode to be in SBS, if not it shouldn't have
3056 * entered this API.
3057 */
3058 if (!policy_mgr_are_sbs_chan(pm_ctx->psoc, freq1, freq2) &&
3059 !policy_mgr_are_sbs_chan(pm_ctx->psoc, freq2, freq3) &&
3060 !policy_mgr_are_sbs_chan(pm_ctx->psoc, freq3, freq1)) {
3061 policy_mgr_err("freq1 %d, freq2 %d and freq3 %d, none of the 2 connections/3 vdevs are leading to SBS",
3062 freq1, freq2, freq3);
3063 return;
3064 }
3065
3066 sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(pm_ctx->psoc);
3067 if (!sbs_cut_off_freq) {
3068 policy_mgr_err("Invalid cutoff freq");
3069 return;
3070 }
3071
3072 /*
3073 * If dynamic SBS is enabled (2.4 GHZ can share mac with HIGH
3074 * 5GHZ as well as LOW 5 GHZ, but one at a time) and one of the
3075 * freq is 2.4 GHZ, this mean that the new interface can come up on
3076 * 5 GHZ LOW or HIGH and HW mode will move the 2.4 GHZ link to
3077 * the other mac dynamically.
3078 */
3079 if (policy_mgr_can_2ghz_share_low_high_5ghz_sbs(pm_ctx) &&
3080 (WLAN_REG_IS_24GHZ_CH_FREQ(freq1) ||
3081 WLAN_REG_IS_24GHZ_CH_FREQ(freq2) ||
3082 WLAN_REG_IS_24GHZ_CH_FREQ(freq3))) {
3083 *index = PM_24_5_PLUS_5_LOW_N_HIGH_SHARE_SBS;
3084 return;
3085 }
3086 /*
3087 * if freq1 on freq2 same mac, get the 5 / 6 GHZ freq from it check
3088 * and determine shared mac.
3089 */
3090 if (policy_mgr_2_freq_same_mac_in_sbs(pm_ctx, freq1, freq2)) {
3091 /*
3092 * If freq1 is 2.4 GHZ that mean freq2 is 5 / 6 GHZ.
3093 * so take decision using freq2.
3094 */
3095 if (WLAN_REG_IS_24GHZ_CH_FREQ(freq1))
3096 shared_5_ghz_freq = freq2;
3097 else
3098 /* freq1 5 / 6 GHZ, use freq1 */
3099 shared_5_ghz_freq = freq1;
3100 } else if (policy_mgr_2_freq_same_mac_in_sbs(pm_ctx, freq2, freq3)) {
3101 /*
3102 * If freq2 is 2.4 GHZ that mean freq3 is 5 / 6 GHZ.
3103 * so take decision using freq3.
3104 */
3105 if (WLAN_REG_IS_24GHZ_CH_FREQ(freq2))
3106 shared_5_ghz_freq = freq3;
3107 else
3108 /* freq2 5 / 6 GHZ, use freq1 */
3109 shared_5_ghz_freq = freq2;
3110 } else if (policy_mgr_2_freq_same_mac_in_sbs(pm_ctx, freq3, freq1)) {
3111 /*
3112 * If freq1 is 2.4 GHZ that mean freq3 is 5 / 6 GHZ.
3113 * so take decision using freq3.
3114 */
3115 if (WLAN_REG_IS_24GHZ_CH_FREQ(freq1))
3116 shared_5_ghz_freq = freq3;
3117 else
3118 /* freq1 5 / 6 GHZ, use freq1 */
3119 shared_5_ghz_freq = freq1;
3120 }
3121
3122 if (!shared_5_ghz_freq ||
3123 WLAN_REG_IS_24GHZ_CH_FREQ(shared_5_ghz_freq)) {
3124 policy_mgr_err("shared_5_ghz_freq %d is not 5 / 6 GHZ",
3125 shared_5_ghz_freq);
3126 return;
3127 }
3128
3129 /* If shared 5 / 6 GHZ freq is low 5 GHZ, then return high 5 GHZ freq */
3130 if (shared_5_ghz_freq < sbs_cut_off_freq)
3131 *index = PM_MCC_SCC_5G_LOW_PLUS_5_HIGH_SBS;
3132 else
3133 *index = PM_MCC_SCC_5G_HIGH_PLUS_5_LOW_SBS;
3134 }
3135
3136 #ifdef WLAN_FEATURE_11BE_MLO
3137 /**
3138 * policy_mgr_get_index_for_ml_sta_sap_dbs() - Find the index for next
3139 * connection for ML STA + SAP, in case current HW mode is DBS and ML STA is
3140 * 2.4 GHZ + 5 GHZ/6 GHZ OR if SBS is not supported.
3141 * @pm_ctx: policy manager context
3142 * @index: Index to return for next connection
3143 * @sap_freq: SAP freq
3144 * @sta_freq_list: STA freq list
3145 * @ml_sta_idx: ML STA index in freq_list
3146 *
3147 * This function finds the index for next
3148 * connection for ML STA + SAP, in case current HW mode is DBS and ML STA is
3149 * 2.4 GHZ + 5 GHZ/6 GHZ OR if SBS is not supported.
3150 *
3151 * Return: none
3152 */
3153 static void
policy_mgr_get_index_for_ml_sta_sap_dbs(struct policy_mgr_psoc_priv_obj * pm_ctx,enum policy_mgr_three_connection_mode * index,qdf_freq_t sap_freq,qdf_freq_t * sta_freq_list,uint8_t * ml_sta_idx)3154 policy_mgr_get_index_for_ml_sta_sap_dbs(
3155 struct policy_mgr_psoc_priv_obj *pm_ctx,
3156 enum policy_mgr_three_connection_mode *index, qdf_freq_t sap_freq,
3157 qdf_freq_t *sta_freq_list, uint8_t *ml_sta_idx)
3158 {
3159 /* If ML STA and SAP all are on same band */
3160 if ((WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[0]]) ==
3161 WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[1]])) &&
3162 (WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[0]]) ==
3163 WLAN_REG_IS_24GHZ_CH_FREQ(sap_freq))) {
3164 policy_mgr_err("Invalid mode for ML STA %d and %d are on same band as SAP %d",
3165 sta_freq_list[ml_sta_idx[0]],
3166 sta_freq_list[ml_sta_idx[1]], sap_freq);
3167 return;
3168 }
3169
3170 /*
3171 * If ML STA is MCC and SAP is on differet band and is not sharing mac
3172 * with any link. SAP on same band is handled above, so ML STA on same
3173 * band mean SAP cannot be on same band. This can happen if SBS is not
3174 * enabled.
3175 */
3176 if (WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[0]]) ==
3177 WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[1]])) {
3178 if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_freq))
3179 /*
3180 * As all 3 cannot be on same band, so if SAP is 2.4 GHZ
3181 * mean both ML STA are on 5 / 6 GHZ
3182 */
3183 *index = PM_STA_STA_5_SAP_24_DBS;
3184 else
3185 /*
3186 * As all 3 cannot be on same band, so if SAP is
3187 * 5 / 6 GHZ, mean both ML STA are on 2.4 GHZ.
3188 */
3189 policy_mgr_err("Invalid mode for ML STA %d and %d are on 2.4 GHZ, sap freq %d",
3190 sta_freq_list[ml_sta_idx[0]],
3191 sta_freq_list[ml_sta_idx[1]], sap_freq);
3192
3193 return;
3194 }
3195
3196 /*
3197 * if ML STA is 2 GHZ + 5 GHZ/6 GHZ DBS, check with which freq the SAP
3198 * will share mac, and return index as per it.
3199 */
3200 if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_freq))
3201 *index = PM_STA_SAP_24_STA_5_DBS;
3202 else
3203 *index = PM_STA_SAP_5_STA_24_DBS;
3204 }
3205
3206 /**
3207 * policy_mgr_get_index_for_ml_sta_sap_hwmode_sbs() - Find the index for next
3208 * connection for ML STA + SAP, in case current HW mode is SBS but ML STA is
3209 * with 2 GHz + 5/6 GHz.
3210 * @pm_ctx: policy manager context
3211 * @index: Index to return for next connection
3212 * @sap_freq: SAP freq
3213 * @sta_freq_list: STA freq list
3214 * @ml_sta_idx: ML STA index in freq_list
3215 *
3216 * This function finds the index for next connection for ML STA + SAP,
3217 * in case current HW mode is SBS but ML STA is with 2 GHz + 5/6 GHz.
3218 *
3219 * Return: none
3220 */
policy_mgr_get_index_for_ml_sta_sap_hwmode_sbs(struct policy_mgr_psoc_priv_obj * pm_ctx,enum policy_mgr_three_connection_mode * index,qdf_freq_t sap_freq,qdf_freq_t * sta_freq_list,uint8_t * ml_sta_idx)3221 static void policy_mgr_get_index_for_ml_sta_sap_hwmode_sbs(
3222 struct policy_mgr_psoc_priv_obj *pm_ctx,
3223 enum policy_mgr_three_connection_mode *index, qdf_freq_t sap_freq,
3224 qdf_freq_t *sta_freq_list, uint8_t *ml_sta_idx)
3225 {
3226 bool sbs_24_shared_high_support =
3227 policy_mgr_sbs_24_shared_with_high_5(pm_ctx);
3228 bool sbs_24_shared_low_support =
3229 policy_mgr_sbs_24_shared_with_low_5(pm_ctx);
3230 qdf_freq_t sbs_cut_off_freq, ml_sta_5g_freq;
3231 bool ml_sta_5g_low;
3232
3233 /* HW supports sbs but ml sta 2 home channels are not in sbs frequency
3234 * separation by check policy_mgr_are_sbs_chan.
3235 * It means one ml sta is 2.4 GHz, the other is 5/6 GHz.
3236 * The combinations handled by this API:
3237 * 2.4 GHz band | 5 GHz low band | 5/6 GHz high band | PCL list
3238 * ----------------------------------------------------------------------
3239 * ML STA | ML STA+SAP | | 5 GHz High + 2.4 GHz
3240 * ML STA | ML STA+SAP | | 2.4 GHz(nhss)
3241 * ML STA | ML STA | SAP | 5 GHz Low + 2.4 GHz
3242 * ML STA | ML STA | SAP | 2.4 GHz (nhss)
3243 * ML STA | SAP | ML STA | 5 GHz High+ 2.4 GHz
3244 * ML STA | SAP | ML STA | 2.4 GHz (nlss)
3245 * ML STA | | ML STA+SAP | 5 GHz Low + 2.4 GHz
3246 * ML STA | | ML STA+SAP | 2.4 GHz (nlss)
3247 * ML STA+SAP | ML STA | | 5 GHz Low+5 GHz High
3248 * ML STA+SAP | | ML STA | 5 GHz Low+5 GHz High
3249 *
3250 * nhss: no high share supported
3251 * nlss: no low share supported
3252 */
3253
3254 if (!WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[0]]) &&
3255 !WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[1]])) {
3256 policy_mgr_err("unexpected ml sta home freq to handle (%d %d)",
3257 sta_freq_list[ml_sta_idx[0]],
3258 sta_freq_list[ml_sta_idx[1]]);
3259 return;
3260 }
3261 if (!sbs_24_shared_low_support && !sbs_24_shared_high_support) {
3262 policy_mgr_err("unexpected sbs mode: low share %d high share %d",
3263 sbs_24_shared_low_support,
3264 sbs_24_shared_high_support);
3265 return;
3266 }
3267 sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(pm_ctx->psoc);
3268 if (!sbs_cut_off_freq) {
3269 policy_mgr_err("Invalid cutoff freq");
3270 return;
3271 }
3272
3273 if (!WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[0]]))
3274 ml_sta_5g_freq = sta_freq_list[ml_sta_idx[0]];
3275 else
3276 ml_sta_5g_freq = sta_freq_list[ml_sta_idx[1]];
3277 if (ml_sta_5g_freq < sbs_cut_off_freq)
3278 ml_sta_5g_low = true;
3279 else
3280 ml_sta_5g_low = false;
3281
3282 if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_freq)) {
3283 /* pcl 5 GHz Low+5 GHz High - PM_SCC_ON_5_CH_5G */
3284 *index = PM_24_5_PLUS_5_LOW_N_HIGH_SHARE_SBS;
3285 } else if (sap_freq < sbs_cut_off_freq) {
3286 if ((ml_sta_5g_low && sbs_24_shared_high_support) ||
3287 (!ml_sta_5g_low && sbs_24_shared_low_support))
3288 /* pcl 5 GHz High + 2.4 GHz -
3289 * PM_SCC_ON_5G_HIGH_5G_HIGH_PLUS_SHARED_2G
3290 */
3291 *index = PM_STA_24_STA_5_MCC_SAP_5_LOW_SBS;
3292 else
3293 *index = PM_24_5_PLUS_5_LOW_OR_HIGH_SHARE_SBS;
3294 } else {
3295 if ((ml_sta_5g_low && sbs_24_shared_high_support) ||
3296 (!ml_sta_5g_low && sbs_24_shared_low_support))
3297 /* pcl 5 GHz Low + 2.4 GHz -
3298 * PM_SCC_ON_5G_LOW_5G_LOW_PLUS_SHARED_2G
3299 */
3300 *index = PM_STA_24_STA_5_MCC_SAP_5_HIGH_SBS;
3301 else
3302 *index = PM_24_5_PLUS_5_LOW_OR_HIGH_SHARE_SBS;
3303 }
3304 policy_mgr_debug("4th index %d sap freq %d ml sta 5g %d sbs_cut_off_freq %d support high share %d low share %d",
3305 *index, sap_freq, ml_sta_5g_freq, sbs_cut_off_freq,
3306 sbs_24_shared_high_support,
3307 sbs_24_shared_low_support);
3308 }
3309
3310 /**
3311 * policy_mgr_get_index_for_ml_sta_sap_sbs() - Find the index for next
3312 * connection for ML STA + SAP, in case current HW mode is SBS or ML STA is
3313 * with 5 GHZ + 5 GHZ/6 GHZ SBS separation.
3314 * @pm_ctx: policy manager context
3315 * @index: Index to return for next connection
3316 * @sap_freq: SAP freq
3317 * @sta_freq_list: STA freq list
3318 * @ml_sta_idx: ML STA index in freq_list
3319 *
3320 * This function finds the index for next
3321 * connection for ML STA + SAP, in case current HW mode is SBS or ML STA is
3322 * with 5 GHZ + 5 GHZ/6 GHZ SBS separation.
3323 *
3324 * Return: none
3325 */
policy_mgr_get_index_for_ml_sta_sap_sbs(struct policy_mgr_psoc_priv_obj * pm_ctx,enum policy_mgr_three_connection_mode * index,qdf_freq_t sap_freq,qdf_freq_t * sta_freq_list,uint8_t * ml_sta_idx)3326 static void policy_mgr_get_index_for_ml_sta_sap_sbs(
3327 struct policy_mgr_psoc_priv_obj *pm_ctx,
3328 enum policy_mgr_three_connection_mode *index, qdf_freq_t sap_freq,
3329 qdf_freq_t *sta_freq_list, uint8_t *ml_sta_idx)
3330 {
3331 qdf_freq_t sbs_cut_off_freq;
3332 bool can_2ghz_share_low_high_5ghz =
3333 policy_mgr_can_2ghz_share_low_high_5ghz_sbs(pm_ctx);
3334
3335 /*
3336 * Sanity check: At least one of the 3 combo (ML STA OR SAP + one of
3337 * ML STA link) needs to be creating SBS separation for
3338 * HW mode to be in SBS, if not it shouldn't have entered this API.
3339 */
3340 if (!policy_mgr_are_sbs_chan(pm_ctx->psoc, sta_freq_list[ml_sta_idx[0]],
3341 sta_freq_list[ml_sta_idx[1]]) &&
3342 !policy_mgr_are_sbs_chan(pm_ctx->psoc, sap_freq,
3343 sta_freq_list[ml_sta_idx[0]]) &&
3344 !policy_mgr_are_sbs_chan(pm_ctx->psoc, sap_freq,
3345 sta_freq_list[ml_sta_idx[1]])) {
3346 if (policy_mgr_is_current_hwmode_sbs(pm_ctx->psoc)) {
3347 policy_mgr_get_index_for_ml_sta_sap_hwmode_sbs(
3348 pm_ctx, index, sap_freq, sta_freq_list,
3349 ml_sta_idx);
3350 return;
3351 }
3352 policy_mgr_err("SAP freq (%d) and ML STA freq %d and %d, none of the 2 connections/3 vdevs are leading to SBS",
3353 sap_freq,
3354 sta_freq_list[ml_sta_idx[0]],
3355 sta_freq_list[ml_sta_idx[1]]);
3356 return;
3357 }
3358
3359 sbs_cut_off_freq = policy_mgr_get_sbs_cut_off_freq(pm_ctx->psoc);
3360 if (!sbs_cut_off_freq) {
3361 policy_mgr_err("Invalid cutoff freq");
3362 return;
3363 }
3364
3365 if (WLAN_REG_IS_24GHZ_CH_FREQ(sap_freq)) {
3366 /*
3367 * If dynamic SBS is enabled (2.4 GHZ can share mac with HIGH
3368 * 5GHZ as well as LOW 5 GHZ, but one at a time) and SAP is
3369 * 2.4 GHZ, this mean that the new SAP can come up on 5 GHZ LOW
3370 * or HIGH and HW mode will move the 2.4 GHZ SAP to the other
3371 * mac dynamically.
3372 */
3373 if (can_2ghz_share_low_high_5ghz) {
3374 *index = PM_SAP_24_STA_5_STA_5_LOW_N_HIGH_SHARE_SBS;
3375 return;
3376 }
3377 /*
3378 * if SAP is 2.4 GHZ that means both ML STA needs to
3379 * be with 5 GHZ + 5 GHZ/6 GHZ SBS separation. If not, it would
3380 * have failed the sanity check. So Get STA link with
3381 * which SAP freq is sharing mac and select index accordingly
3382 */
3383 if (policy_mgr_2_freq_same_mac_in_sbs(
3384 pm_ctx, sap_freq,
3385 sta_freq_list[ml_sta_idx[0]])) {
3386 /*
3387 * SAP is sharig mac with link ml_sta_idx[0], so check
3388 * if ml_sta_idx[0] is lower 5 GHZ or high 5 GHZ and
3389 * select index
3390 */
3391 if (sta_freq_list[ml_sta_idx[0]] < sbs_cut_off_freq)
3392 *index = PM_STA_5_LOW_SAP_24_MCC_STA_5_HIGH_SBS;
3393 else
3394 *index = PM_STA_5_HIGH_SAP_24_MCC_STA_5_LOW_SBS;
3395 } else {
3396 /*
3397 * SAP is sharig mac with link ml_sta_idx[1], so check
3398 * if ml_sta_idx[1] is lower 5 GHZ or high 5 GHZ and
3399 * select index
3400 */
3401 if (sta_freq_list[ml_sta_idx[1]] < sbs_cut_off_freq)
3402 *index = PM_STA_5_LOW_SAP_24_MCC_STA_5_HIGH_SBS;
3403 else
3404 *index = PM_STA_5_HIGH_SAP_24_MCC_STA_5_LOW_SBS;
3405 }
3406
3407 return;
3408 }
3409
3410 /* SAP freq is 5 GHZ or 6 GHZ and one ML sta is on 2.4 GHZ */
3411 if (WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[0]]) ||
3412 WLAN_REG_IS_24GHZ_CH_FREQ(sta_freq_list[ml_sta_idx[1]])) {
3413 /*
3414 * If dynamic SBS is enabled (2.4 GHZ can share mac with HIGH
3415 * 5GHZ as well as LOW 5 GHZ, but one at a time) and one STA
3416 * link is 2.4 GHZ, this mean that the new SAP can come up on
3417 * 5 GHZ LOW or HIGH and HW mode will move the 2.4 GHZ link to
3418 * the other mac dynamically.
3419 */
3420 if (can_2ghz_share_low_high_5ghz) {
3421 *index = PM_STA_24_SAP_5_STA_5_LOW_N_HIGH_SHARE_SBS;
3422 return;
3423 }
3424 /*
3425 * If (2 GHZ + 5 GHZ/6 GHZ) ML is MCC i.e Both sta links are on
3426 * same mac and SAP is on separate mac. This can happen if SBS
3427 * is not dynamic and is low 5 GHZ shared, with ML STA on 5 GHZ
3428 * low along with SAP 5Ghz high and vice versa. As both links
3429 * of ML STA and sap are on different mac, so set index based
3430 * on sap frequency whether it is in 5 GHZ low band or 5 GHZ
3431 * high Band.
3432 */
3433 if (policy_mgr_2_freq_same_mac_in_sbs(
3434 pm_ctx, sta_freq_list[ml_sta_idx[0]],
3435 sta_freq_list[ml_sta_idx[1]])) {
3436 if (sap_freq < sbs_cut_off_freq)
3437 *index = PM_STA_24_STA_5_HIGH_MCC_SAP_5_LOW_SBS;
3438 else
3439 *index = PM_STA_24_STA_5_LOW_MCC_SAP_5_HIGH_SBS;
3440 } else {
3441 /*
3442 * STA ML is (2 GHZ + 5 GHZ/6 GHZ) select as per the SAP
3443 * freq, as for current mode to be in SBS, SAP will
3444 * share mac with STA 2.4 GHZ Link or will not share
3445 * mac at all (2 GHZ + 5 GHZ/6 GHZ MCC). Other case i.e
3446 * 2 links on 5 GHZ and one STA link on 2 GHZ is DBS and
3447 * sanity check already taken care this at start of the
3448 * func.
3449 */
3450 if (sap_freq < sbs_cut_off_freq)
3451 *index = PM_STA_24_SAP_5_LOW_MCC_STA_5_HIGH_SBS;
3452 else
3453 *index = PM_STA_24_SAP_5_HIGH_MCC_STA_5_LOW_SBS;
3454 }
3455 return;
3456 }
3457 /*
3458 * If (5 GHZ + 5 GHZ/6 GHZ) ML is MCC i.e SAP is not sharing mac
3459 * with any link. This can happen if SBS is not dynamic and is
3460 * low 5 GHZ shared, with ML STA on 5 GHZ low along with SAP 5 GHZ
3461 * high and vice versa. As both ML sta link are on same mac and
3462 * sap is on different mac, so decide whether ML links are sharing
3463 * low 5 GHZ frequency or high 5 GHZ frequency based on sap frequency
3464 */
3465 if (policy_mgr_2_freq_same_mac_in_sbs(
3466 pm_ctx, sta_freq_list[ml_sta_idx[0]],
3467 sta_freq_list[ml_sta_idx[1]])) {
3468 if (sap_freq < sbs_cut_off_freq)
3469 *index = PM_STA_STA_5_HIGH_MCC_SAP_5_LOW_SBS;
3470 else
3471 *index = PM_STA_STA_5_LOW_MCC_SAP_5_HIGH_SBS;
3472 } else {
3473 /*
3474 * STA ML is (5 GHZ + 5 GHZ/6 GHZ SBS/MCC), select as per the
3475 * SAP freq, as for current mode to be in SBS, SAP will share
3476 * mac with the corresponding low/high 5 GHZ
3477 * (5 GHZ + 5 GHZ/6 GHZ SBS) or will not share mac at all
3478 * (5 GHZ +5 GHZ/6 GHZ MCC). Other case sanity already
3479 * taken care at start of the func.
3480 */
3481 if (sap_freq < sbs_cut_off_freq)
3482 *index = PM_STA_SAP_5_LOW_STA_5_HIGH_SBS;
3483 else
3484 *index = PM_STA_SAP_5_HIGH_STA_5_LOW_SBS;
3485 }
3486 }
3487
3488 static void
policy_mgr_get_index_for_ml_sta_sap(struct policy_mgr_psoc_priv_obj * pm_ctx,enum policy_mgr_three_connection_mode * index,qdf_freq_t sap_freq,qdf_freq_t * sta_freq_list,uint8_t * ml_sta_idx)3489 policy_mgr_get_index_for_ml_sta_sap(
3490 struct policy_mgr_psoc_priv_obj *pm_ctx,
3491 enum policy_mgr_three_connection_mode *index,
3492 qdf_freq_t sap_freq, qdf_freq_t *sta_freq_list,
3493 uint8_t *ml_sta_idx)
3494 {
3495 /*
3496 * P2P GO/P2P CLI are treated as SAP to optimize as pcl
3497 * table is same for all three.
3498 */
3499 policy_mgr_debug("channel: sap0: %d, ML STA link0: %d, ML STA link1: %d",
3500 sap_freq, sta_freq_list[ml_sta_idx[0]],
3501 sta_freq_list[ml_sta_idx[1]]);
3502 if (policy_mgr_is_current_hwmode_sbs(pm_ctx->psoc) ||
3503 policy_mgr_are_sbs_chan(pm_ctx->psoc, sta_freq_list[ml_sta_idx[0]],
3504 sta_freq_list[ml_sta_idx[1]])) {
3505 /* if current mode is SBS or the ML STA is 5+5/6Ghz SBS */
3506 policy_mgr_get_index_for_ml_sta_sap_sbs(pm_ctx, index,
3507 sap_freq,
3508 sta_freq_list,
3509 ml_sta_idx);
3510 return;
3511 }
3512 /*
3513 * current HW mode is DBS and ML STA is 2.4 GHZ + 5 GHZ or SBS
3514 * is not enabled
3515 */
3516 policy_mgr_get_index_for_ml_sta_sap_dbs(pm_ctx, index, sap_freq,
3517 sta_freq_list, ml_sta_idx);
3518 }
3519
3520 static void
policy_mgr_get_index_for_ml_sta_sap_sap(struct policy_mgr_psoc_priv_obj * pm_ctx,enum policy_mgr_three_connection_mode * index,qdf_freq_t ml_sta_freq,qdf_freq_t sap_freq_1,qdf_freq_t sap_freq_2)3521 policy_mgr_get_index_for_ml_sta_sap_sap(
3522 struct policy_mgr_psoc_priv_obj *pm_ctx,
3523 enum policy_mgr_three_connection_mode *index,
3524 qdf_freq_t ml_sta_freq, qdf_freq_t sap_freq_1,
3525 qdf_freq_t sap_freq_2)
3526 {
3527 /*
3528 * P2P GO/P2P CLI are treated as SAP to optimize as pcl
3529 * table is same for all three.
3530 */
3531 policy_mgr_debug("channel: ML sta0: %d, SAP0: %d, SAP1: %d",
3532 ml_sta_freq, sap_freq_1, sap_freq_2);
3533 if (policy_mgr_is_current_hwmode_sbs(pm_ctx->psoc))
3534 /* if current mode is SBS */
3535 return policy_mgr_get_index_for_3_given_freq_sbs(pm_ctx, index,
3536 ml_sta_freq, sap_freq_1,
3537 sap_freq_2);
3538
3539 /* current HW mode is DBS */
3540 policy_mgr_get_index_for_3_given_freq_dbs(pm_ctx, index, ml_sta_freq,
3541 sap_freq_1, sap_freq_2);
3542 }
3543
3544 #else /* WLAN_FEATURE_11BE_MLO */
3545
3546 static inline void
policy_mgr_get_index_for_ml_sta_sap(struct policy_mgr_psoc_priv_obj * pm_ctx,enum policy_mgr_three_connection_mode * index,qdf_freq_t sap_freq,qdf_freq_t * sta_freq_list,uint8_t * ml_sta_idx)3547 policy_mgr_get_index_for_ml_sta_sap(
3548 struct policy_mgr_psoc_priv_obj *pm_ctx,
3549 enum policy_mgr_three_connection_mode *index,
3550 qdf_freq_t sap_freq, qdf_freq_t *sta_freq_list,
3551 uint8_t *ml_sta_idx) {}
3552
3553 static inline void
policy_mgr_get_index_for_ml_sta_sap_sap(struct policy_mgr_psoc_priv_obj * pm_ctx,enum policy_mgr_three_connection_mode * index,qdf_freq_t ml_sta_freq,qdf_freq_t sap_freq_1,qdf_freq_t sap_freq_2)3554 policy_mgr_get_index_for_ml_sta_sap_sap(
3555 struct policy_mgr_psoc_priv_obj *pm_ctx,
3556 enum policy_mgr_three_connection_mode *index,
3557 qdf_freq_t ml_sta_freq, qdf_freq_t sap_freq_1,
3558 qdf_freq_t sap_freq_2) {}
3559 #endif /* WLAN_FEATURE_11BE_MLO */
3560
3561 enum policy_mgr_three_connection_mode
policy_mgr_get_fourth_connection_pcl_table_index(struct wlan_objmgr_psoc * psoc)3562 policy_mgr_get_fourth_connection_pcl_table_index(
3563 struct wlan_objmgr_psoc *psoc)
3564 {
3565 enum policy_mgr_three_connection_mode index =
3566 PM_MAX_THREE_CONNECTION_MODE;
3567 struct policy_mgr_psoc_priv_obj *pm_ctx;
3568 uint32_t count_sap = 0;
3569 uint32_t count_sta = 0;
3570 uint32_t count_ndi = 0;
3571 uint32_t count_nan_disc = 0;
3572 uint8_t num_ml_sta = 0, num_non_ml_sta = 0;
3573 uint32_t list_sap[MAX_NUMBER_OF_CONC_CONNECTIONS];
3574 uint32_t list_sta[MAX_NUMBER_OF_CONC_CONNECTIONS];
3575 uint32_t list_ndi[MAX_NUMBER_OF_CONC_CONNECTIONS];
3576 uint32_t list_nan_disc[MAX_NUMBER_OF_CONC_CONNECTIONS];
3577 uint8_t ml_sta_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
3578 uint8_t non_ml_sta_idx[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
3579 qdf_freq_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
3580 uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
3581 qdf_freq_t sap_freq = 0;
3582
3583 pm_ctx = policy_mgr_get_context(psoc);
3584 if (!pm_ctx) {
3585 policy_mgr_err("Invalid Context");
3586 return index;
3587 }
3588
3589 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3590
3591 /* For 4 port concurrency case,
3592 * 1st step: (SAP+STA)(2.4G MAC SCC) + (SAP+STA)(5G MAC SCC)
3593 * 2nd step: (AGO+STA)(2.4G MAC SCC) + (AGO+STA)(5G MAC SCC)
3594 */
3595 count_sap += policy_mgr_mode_specific_connection_count(
3596 psoc, PM_SAP_MODE, &list_sap[count_sap]);
3597 count_sap += policy_mgr_mode_specific_connection_count(
3598 psoc, PM_P2P_GO_MODE, &list_sap[count_sap]);
3599 count_sap += policy_mgr_mode_specific_connection_count(
3600 psoc, PM_P2P_CLIENT_MODE, &list_sap[count_sap]);
3601 count_sta = policy_mgr_mode_specific_connection_count(
3602 psoc, PM_STA_MODE, list_sta);
3603 policy_mgr_get_ml_and_non_ml_sta_count(psoc, &num_ml_sta, ml_sta_idx,
3604 &num_non_ml_sta, non_ml_sta_idx,
3605 freq_list, vdev_id_list);
3606
3607 count_ndi = policy_mgr_mode_specific_connection_count(
3608 psoc, PM_NDI_MODE, list_ndi);
3609 count_nan_disc = policy_mgr_mode_specific_connection_count(
3610 psoc, PM_NAN_DISC_MODE, list_nan_disc);
3611 policy_mgr_debug("sap/go/cli:%d sta:%d ndi:%d nan disc:%d ml_sta:%d",
3612 count_sap, count_sta, count_ndi, count_nan_disc,
3613 num_ml_sta);
3614
3615 if (count_sap == 2 && num_ml_sta == 1) {
3616 policy_mgr_get_index_for_ml_sta_sap_sap(
3617 pm_ctx, &index,
3618 freq_list[ml_sta_idx[0]],
3619 pm_conc_connection_list[list_sap[0]].freq,
3620 pm_conc_connection_list[list_sap[1]].freq);
3621 } else if (count_sap == 2 && count_sta == 1 && !num_ml_sta) {
3622 policy_mgr_debug(
3623 "channel: sap0: %d, sap1: %d, sta0: %d",
3624 pm_conc_connection_list[list_sap[0]].freq,
3625 pm_conc_connection_list[list_sap[1]].freq,
3626 pm_conc_connection_list[list_sta[0]].freq);
3627 if (WLAN_REG_IS_24GHZ_CH_FREQ(
3628 pm_conc_connection_list[list_sap[0]].freq) &&
3629 WLAN_REG_IS_24GHZ_CH_FREQ(
3630 pm_conc_connection_list[list_sta[0]].freq) &&
3631 WLAN_REG_IS_5GHZ_CH_FREQ(
3632 pm_conc_connection_list[list_sap[1]].freq)) {
3633 index = PM_STA_SAP_SCC_24_SAP_5_DBS;
3634 } else if (WLAN_REG_IS_24GHZ_CH_FREQ(
3635 pm_conc_connection_list[list_sap[1]].freq) &&
3636 WLAN_REG_IS_24GHZ_CH_FREQ(
3637 pm_conc_connection_list[list_sta[0]].freq) &&
3638 WLAN_REG_IS_5GHZ_CH_FREQ(
3639 pm_conc_connection_list[list_sap[0]].freq)) {
3640 index = PM_STA_SAP_SCC_24_SAP_5_DBS;
3641 } else if (WLAN_REG_IS_24GHZ_CH_FREQ(
3642 pm_conc_connection_list[list_sap[0]].freq) &&
3643 WLAN_REG_IS_5GHZ_CH_FREQ(
3644 pm_conc_connection_list[list_sta[0]].freq) &&
3645 WLAN_REG_IS_5GHZ_CH_FREQ(
3646 pm_conc_connection_list[list_sap[1]].freq)) {
3647 index = PM_STA_SAP_SCC_5_SAP_24_DBS;
3648 } else if (WLAN_REG_IS_24GHZ_CH_FREQ(
3649 pm_conc_connection_list[list_sap[1]].freq) &&
3650 WLAN_REG_IS_5GHZ_CH_FREQ(
3651 pm_conc_connection_list[list_sta[0]].freq) &&
3652 WLAN_REG_IS_5GHZ_CH_FREQ(
3653 pm_conc_connection_list[list_sap[0]].freq)) {
3654 index = PM_STA_SAP_SCC_5_SAP_24_DBS;
3655 } else {
3656 index = PM_MAX_THREE_CONNECTION_MODE;
3657 }
3658 } else if (num_ml_sta == 2 && count_sap == 1) {
3659 sap_freq = pm_conc_connection_list[list_sap[0]].freq;
3660 policy_mgr_get_index_for_ml_sta_sap(pm_ctx, &index, sap_freq,
3661 freq_list, ml_sta_idx);
3662 } else if (count_sap == 1 && count_sta == 2 && !num_ml_sta) {
3663 policy_mgr_debug(
3664 "channel: sap0: %d, sta0: %d, sta1: %d",
3665 pm_conc_connection_list[list_sap[0]].freq,
3666 pm_conc_connection_list[list_sta[0]].freq,
3667 pm_conc_connection_list[list_sta[1]].freq);
3668 if (WLAN_REG_IS_24GHZ_CH_FREQ(
3669 pm_conc_connection_list[list_sta[0]].freq) &&
3670 WLAN_REG_IS_24GHZ_CH_FREQ(
3671 pm_conc_connection_list[list_sap[0]].freq) &&
3672 WLAN_REG_IS_5GHZ_CH_FREQ(
3673 pm_conc_connection_list[list_sta[1]].freq)) {
3674 index = PM_STA_SAP_24_STA_5_DBS;
3675 } else if (WLAN_REG_IS_24GHZ_CH_FREQ(
3676 pm_conc_connection_list[list_sta[1]].freq) &&
3677 WLAN_REG_IS_24GHZ_CH_FREQ(
3678 pm_conc_connection_list[list_sap[0]].freq) &&
3679 WLAN_REG_IS_5GHZ_CH_FREQ(
3680 pm_conc_connection_list[list_sta[0]].freq)) {
3681 index = PM_STA_SAP_24_STA_5_DBS;
3682 } else if (WLAN_REG_IS_24GHZ_CH_FREQ(
3683 pm_conc_connection_list[list_sta[0]].freq) &&
3684 WLAN_REG_IS_5GHZ_CH_FREQ(
3685 pm_conc_connection_list[list_sap[0]].freq) &&
3686 WLAN_REG_IS_5GHZ_CH_FREQ(
3687 pm_conc_connection_list[list_sta[1]].freq)) {
3688 index = PM_STA_SAP_5_STA_24_DBS;
3689 } else if (WLAN_REG_IS_24GHZ_CH_FREQ(
3690 pm_conc_connection_list[list_sta[1]].freq) &&
3691 WLAN_REG_IS_5GHZ_CH_FREQ(
3692 pm_conc_connection_list[list_sap[0]].freq) &&
3693 WLAN_REG_IS_5GHZ_CH_FREQ(
3694 pm_conc_connection_list[list_sta[0]].freq)) {
3695 index = PM_STA_SAP_5_STA_24_DBS;
3696 } else {
3697 index = PM_MAX_THREE_CONNECTION_MODE;
3698 }
3699 } else if (count_nan_disc == 1 && count_ndi == 1 && count_sap == 1) {
3700 /* Policy mgr only considers NAN Disc ch in 2.4GHz */
3701 if (WLAN_REG_IS_24GHZ_CH_FREQ(
3702 pm_conc_connection_list[list_sap[0]].freq) &&
3703 WLAN_REG_IS_5GHZ_CH_FREQ(
3704 pm_conc_connection_list[list_ndi[0]].freq)) {
3705 index = PM_NAN_DISC_SAP_SCC_24_NDI_5_DBS;
3706 } else if (WLAN_REG_IS_5GHZ_CH_FREQ(
3707 pm_conc_connection_list[list_sap[0]].freq) &&
3708 WLAN_REG_IS_24GHZ_CH_FREQ(
3709 pm_conc_connection_list[list_ndi[0]].freq)) {
3710 index = PM_NAN_DISC_NDI_SCC_24_SAP_5_DBS;
3711 } else if (WLAN_REG_IS_5GHZ_CH_FREQ(
3712 pm_conc_connection_list[list_sap[0]].freq) &&
3713 WLAN_REG_IS_5GHZ_CH_FREQ(
3714 pm_conc_connection_list[list_ndi[0]].freq)) {
3715 index = PM_SAP_NDI_SCC_5_NAN_DISC_24_DBS;
3716 } else {
3717 index = PM_MAX_THREE_CONNECTION_MODE;
3718 }
3719 } else if (count_nan_disc == 1 && count_ndi == 1 && count_sta == 1) {
3720 /* Policy mgr only considers NAN Disc ch in 2.4GHz */
3721 if (WLAN_REG_IS_24GHZ_CH_FREQ(
3722 pm_conc_connection_list[list_sta[0]].freq) &&
3723 WLAN_REG_IS_5GHZ_CH_FREQ(
3724 pm_conc_connection_list[list_ndi[0]].freq)) {
3725 index = PM_NAN_DISC_STA_24_NDI_5_DBS;
3726 } else if (WLAN_REG_IS_5GHZ_CH_FREQ(
3727 pm_conc_connection_list[list_sta[0]].freq) &&
3728 WLAN_REG_IS_24GHZ_CH_FREQ(
3729 pm_conc_connection_list[list_ndi[0]].freq)) {
3730 index = PM_NAN_DISC_NDI_24_STA_5_DBS;
3731 } else if (WLAN_REG_IS_5GHZ_CH_FREQ(
3732 pm_conc_connection_list[list_sta[0]].freq) &&
3733 WLAN_REG_IS_5GHZ_CH_FREQ(
3734 pm_conc_connection_list[list_ndi[0]].freq)) {
3735 index = PM_STA_NDI_5_NAN_DISC_24_DBS;
3736 } else if (WLAN_REG_IS_24GHZ_CH_FREQ(
3737 pm_conc_connection_list[list_sta[0]].freq) &&
3738 WLAN_REG_IS_24GHZ_CH_FREQ(
3739 pm_conc_connection_list[list_ndi[0]].freq)) {
3740 index = PM_STA_NDI_NAN_DISC_24_SMM;
3741 }
3742 } else if (count_nan_disc == 1 && count_ndi == 2) {
3743 /* Policy mgr only considers NAN Disc ch in 2.4GHz */
3744 if (WLAN_REG_IS_24GHZ_CH_FREQ(
3745 pm_conc_connection_list[list_ndi[0]].freq) &&
3746 WLAN_REG_IS_5GHZ_CH_FREQ(
3747 pm_conc_connection_list[list_ndi[1]].freq)) {
3748 index = PM_NAN_DISC_NDI_24_NDI_5_DBS;
3749 } else if (WLAN_REG_IS_5GHZ_CH_FREQ(
3750 pm_conc_connection_list[list_ndi[0]].freq) &&
3751 WLAN_REG_IS_24GHZ_CH_FREQ(
3752 pm_conc_connection_list[list_ndi[0]].freq)) {
3753 index = PM_NAN_DISC_NDI_24_NDI_5_DBS;
3754 } else if (WLAN_REG_IS_5GHZ_CH_FREQ(
3755 pm_conc_connection_list[list_ndi[0]].freq) &&
3756 WLAN_REG_IS_5GHZ_CH_FREQ(
3757 pm_conc_connection_list[list_ndi[0]].freq)) {
3758 index = PM_NDI_NDI_5_NAN_DISC_24_DBS;
3759 } else if (WLAN_REG_IS_24GHZ_CH_FREQ(
3760 pm_conc_connection_list[list_ndi[0]].freq) &&
3761 WLAN_REG_IS_24GHZ_CH_FREQ(
3762 pm_conc_connection_list[list_ndi[0]].freq)) {
3763 index = PM_NDI_NDI_NAN_DISC_24_SMM;
3764 }
3765 } else if (count_sap == 3) {
3766 if (policy_mgr_is_current_hwmode_sbs(psoc))
3767 policy_mgr_get_index_for_3_given_freq_sbs(pm_ctx,
3768 &index,
3769 pm_conc_connection_list[list_sap[0]].freq,
3770 pm_conc_connection_list[list_sap[1]].freq,
3771 pm_conc_connection_list[list_sap[2]].freq);
3772 else if (policy_mgr_is_current_hwmode_dbs(psoc))
3773 policy_mgr_get_index_for_3_given_freq_dbs(pm_ctx,
3774 &index,
3775 pm_conc_connection_list[list_sap[0]].freq,
3776 pm_conc_connection_list[list_sap[1]].freq,
3777 pm_conc_connection_list[list_sap[2]].freq);
3778 }
3779
3780 policy_mgr_debug(
3781 "mode0:%d mode1:%d mode2:%d chan0:%d chan1:%d chan2:%d chain:%d index:%d",
3782 pm_conc_connection_list[0].mode,
3783 pm_conc_connection_list[1].mode,
3784 pm_conc_connection_list[2].mode,
3785 pm_conc_connection_list[0].freq,
3786 pm_conc_connection_list[1].freq,
3787 pm_conc_connection_list[2].freq,
3788 pm_conc_connection_list[0].chain_mask, index);
3789
3790 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
3791
3792 return index;
3793 }
3794 #endif
3795
3796 uint32_t
policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,bool for_existing_conn,uint8_t vdev_id)3797 policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc,
3798 enum policy_mgr_con_mode mode,
3799 bool for_existing_conn,
3800 uint8_t vdev_id)
3801 {
3802 uint32_t pcl_channels[NUM_CHANNELS];
3803 uint8_t pcl_weight[NUM_CHANNELS];
3804 struct policy_mgr_psoc_priv_obj *pm_ctx;
3805
3806 /*
3807 * in worst case if we can't find any channel at all
3808 * then return 2.4G channel, so atleast we won't fall
3809 * under 5G MCC scenario
3810 */
3811 uint32_t i, pcl_len = 0, non_dfs_freq, freq;
3812
3813 pm_ctx = policy_mgr_get_context(psoc);
3814 if (!pm_ctx) {
3815 policy_mgr_err("Invalid Context");
3816 return PM_24_GHZ_CH_FREQ_6;
3817 }
3818
3819 freq = PM_24_GHZ_CH_FREQ_6;
3820 if (true == for_existing_conn) {
3821 /*
3822 * First try to see if there is any non-dfs channel already
3823 * present in current connection table. If yes then return
3824 * that channel
3825 */
3826 if (true == policy_mgr_is_any_nondfs_chnl_present(
3827 psoc, &non_dfs_freq))
3828 return non_dfs_freq;
3829
3830 if (QDF_STATUS_SUCCESS !=
3831 policy_mgr_get_pcl_for_existing_conn(
3832 psoc, mode,
3833 pcl_channels, &pcl_len,
3834 pcl_weight, QDF_ARRAY_SIZE(pcl_weight),
3835 false, vdev_id))
3836 return freq;
3837 } else {
3838 if (QDF_STATUS_SUCCESS != policy_mgr_get_pcl(
3839 psoc, mode, pcl_channels, &pcl_len, pcl_weight,
3840 QDF_ARRAY_SIZE(pcl_weight), vdev_id))
3841 return freq;
3842 }
3843
3844 for (i = 0; i < pcl_len; i++) {
3845 if (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, pcl_channels[i]) ||
3846 !policy_mgr_is_safe_channel(psoc, pcl_channels[i])) {
3847 continue;
3848 } else {
3849 freq = pcl_channels[i];
3850 break;
3851 }
3852 }
3853
3854 return freq;
3855 }
3856
policy_mgr_remove_dsrc_channels(uint32_t * ch_freq_list,uint32_t * num_channels,struct wlan_objmgr_pdev * pdev)3857 static void policy_mgr_remove_dsrc_channels(uint32_t *ch_freq_list,
3858 uint32_t *num_channels,
3859 struct wlan_objmgr_pdev *pdev)
3860 {
3861 uint32_t num_chan_temp = 0;
3862 int i;
3863
3864 for (i = 0; i < *num_channels; i++) {
3865 if (!wlan_reg_is_dsrc_freq(ch_freq_list[i])) {
3866 ch_freq_list[num_chan_temp] = ch_freq_list[i];
3867 num_chan_temp++;
3868 }
3869 }
3870
3871 *num_channels = num_chan_temp;
3872 }
3873
policy_mgr_get_valid_chans_from_range(struct wlan_objmgr_psoc * psoc,uint32_t * ch_freq_list,uint32_t * ch_cnt,enum policy_mgr_con_mode mode)3874 QDF_STATUS policy_mgr_get_valid_chans_from_range(
3875 struct wlan_objmgr_psoc *psoc, uint32_t *ch_freq_list,
3876 uint32_t *ch_cnt, enum policy_mgr_con_mode mode)
3877 {
3878 uint8_t ch_weight_list[NUM_CHANNELS] = {0};
3879 uint32_t ch_weight_len;
3880 QDF_STATUS status = QDF_STATUS_E_FAILURE;
3881 size_t chan_index = 0;
3882
3883 if (!ch_freq_list || !ch_cnt) {
3884 policy_mgr_err("NULL parameters");
3885 return QDF_STATUS_E_FAILURE;
3886 }
3887
3888 for (chan_index = 0; chan_index < *ch_cnt; chan_index++)
3889 ch_weight_list[chan_index] = WEIGHT_OF_GROUP1_PCL_CHANNELS;
3890
3891 ch_weight_len = *ch_cnt;
3892
3893 /* check the channel avoidance list for beaconing entities */
3894 if (policy_mgr_is_beaconing_mode(mode))
3895 policy_mgr_update_with_safe_channel_list(
3896 psoc, ch_freq_list, ch_cnt, ch_weight_list,
3897 ch_weight_len);
3898
3899 status = policy_mgr_mode_specific_modification_on_pcl(
3900 psoc, ch_freq_list, ch_weight_list, ch_cnt,
3901 ch_weight_len, mode);
3902
3903 if (QDF_IS_STATUS_ERROR(status)) {
3904 policy_mgr_err("failed to get modified pcl for mode %d", mode);
3905 return status;
3906 }
3907
3908 status = policy_mgr_modify_pcl_based_on_dnbs(psoc, ch_freq_list,
3909 ch_weight_list, ch_cnt);
3910
3911 if (QDF_IS_STATUS_ERROR(status)) {
3912 policy_mgr_err("failed to get modified pcl based on DNBS");
3913 return status;
3914 }
3915 policy_mgr_dump_channel_list(*ch_cnt, ch_freq_list, ch_weight_list);
3916
3917 return status;
3918 }
3919
policy_mgr_get_valid_chans(struct wlan_objmgr_psoc * psoc,uint32_t * ch_freq_list,uint32_t * list_len)3920 QDF_STATUS policy_mgr_get_valid_chans(struct wlan_objmgr_psoc *psoc,
3921 uint32_t *ch_freq_list,
3922 uint32_t *list_len)
3923 {
3924 struct policy_mgr_psoc_priv_obj *pm_ctx;
3925
3926 *list_len = 0;
3927
3928 pm_ctx = policy_mgr_get_context(psoc);
3929 if (!pm_ctx) {
3930 policy_mgr_err("Invalid Context");
3931 return QDF_STATUS_E_FAILURE;
3932 }
3933 if (!pm_ctx->valid_ch_freq_list_count) {
3934 policy_mgr_err("Invalid PM valid channel list");
3935 return QDF_STATUS_E_INVAL;
3936 }
3937
3938 *list_len = pm_ctx->valid_ch_freq_list_count;
3939 qdf_mem_copy(ch_freq_list, pm_ctx->valid_ch_freq_list,
3940 pm_ctx->valid_ch_freq_list_count *
3941 sizeof(pm_ctx->valid_ch_freq_list[0]));
3942
3943 policy_mgr_remove_dsrc_channels(ch_freq_list, list_len, pm_ctx->pdev);
3944
3945 return QDF_STATUS_SUCCESS;
3946 }
3947
policy_mgr_list_has_24GHz_channel(uint32_t * ch_freq_list,uint32_t list_len)3948 bool policy_mgr_list_has_24GHz_channel(uint32_t *ch_freq_list,
3949 uint32_t list_len)
3950 {
3951 uint32_t i;
3952
3953 for (i = 0; i < list_len; i++) {
3954 if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq_list[i]))
3955 return true;
3956 }
3957
3958 return false;
3959 }
3960
3961 QDF_STATUS
policy_mgr_set_sap_mandatory_channels(struct wlan_objmgr_psoc * psoc,uint32_t * ch_freq_list,uint32_t len)3962 policy_mgr_set_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc,
3963 uint32_t *ch_freq_list, uint32_t len)
3964 {
3965 uint32_t i;
3966 struct policy_mgr_psoc_priv_obj *pm_ctx;
3967
3968 pm_ctx = policy_mgr_get_context(psoc);
3969 if (!pm_ctx) {
3970 policy_mgr_err("Invalid Context");
3971 return QDF_STATUS_E_FAILURE;
3972 }
3973
3974 if (!len) {
3975 policy_mgr_err("No mandatory freq/chan configured");
3976 return QDF_STATUS_E_FAILURE;
3977 }
3978
3979 if (!policy_mgr_list_has_24GHz_channel(ch_freq_list, len)) {
3980 policy_mgr_err("2.4GHz channels missing, this is not expected");
3981 return QDF_STATUS_E_FAILURE;
3982 }
3983
3984 policy_mgr_debug("mandatory chan length:%d",
3985 pm_ctx->sap_mandatory_channels_len);
3986
3987 for (i = 0; i < len; i++) {
3988 pm_ctx->sap_mandatory_channels[i] = ch_freq_list[i];
3989 policy_mgr_debug("chan:%d", pm_ctx->sap_mandatory_channels[i]);
3990 }
3991
3992 pm_ctx->sap_mandatory_channels_len = len;
3993
3994 return QDF_STATUS_SUCCESS;
3995 }
3996
policy_mgr_is_sap_mandatory_channel_set(struct wlan_objmgr_psoc * psoc)3997 bool policy_mgr_is_sap_mandatory_channel_set(struct wlan_objmgr_psoc *psoc)
3998 {
3999 struct policy_mgr_psoc_priv_obj *pm_ctx;
4000
4001 pm_ctx = policy_mgr_get_context(psoc);
4002 if (!pm_ctx) {
4003 policy_mgr_err("Invalid Context");
4004 return false;
4005 }
4006
4007 if (pm_ctx->sap_mandatory_channels_len)
4008 return true;
4009 else
4010 return false;
4011 }
4012
4013 static inline
policy_mgr_is_sta_on_indoor_channel(struct wlan_objmgr_psoc * psoc)4014 uint32_t policy_mgr_is_sta_on_indoor_channel(struct wlan_objmgr_psoc *psoc)
4015 {
4016 struct policy_mgr_psoc_priv_obj *pm_ctx;
4017 uint32_t conn_index;
4018 uint32_t freq = INVALID_CHANNEL_ID;
4019
4020 pm_ctx = policy_mgr_get_context(psoc);
4021 if (!pm_ctx) {
4022 policy_mgr_err("Invalid Context");
4023 return freq;
4024 }
4025 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4026 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
4027 conn_index++) {
4028 if (pm_conc_connection_list[conn_index].mode == PM_STA_MODE &&
4029 wlan_reg_is_freq_indoor(pm_ctx->pdev,
4030 pm_conc_connection_list[conn_index].freq) &&
4031 pm_conc_connection_list[conn_index].in_use) {
4032 freq = pm_conc_connection_list[conn_index].freq;
4033 break;
4034 }
4035 }
4036 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4037
4038 return freq;
4039 }
4040
policy_mgr_modify_sap_pcl_based_on_mandatory_channel(struct wlan_objmgr_psoc * psoc,uint32_t * pcl_list_org,uint8_t * weight_list_org,uint32_t * pcl_len_org)4041 QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel(
4042 struct wlan_objmgr_psoc *psoc, uint32_t *pcl_list_org,
4043 uint8_t *weight_list_org, uint32_t *pcl_len_org)
4044 {
4045 uint32_t i, j, pcl_len = 0;
4046 bool found;
4047 struct policy_mgr_psoc_priv_obj *pm_ctx;
4048 qdf_freq_t dfs_sta_freq = INVALID_CHANNEL_ID;
4049 qdf_freq_t indoor_sta_freq = INVALID_CHANNEL_ID;
4050 qdf_freq_t sta_5GHz_freq = INVALID_CHANNEL_ID;
4051 enum hw_mode_bandwidth sta_ch_width;
4052 uint8_t sta_vdev_id = 0, scc_on_dfs_channel = 0;
4053 bool sta_sap_scc_on_5ghz_channel;
4054 bool scc_on_indoor =
4055 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
4056 uint8_t go_count;
4057 uint32_t go_op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
4058 uint8_t go_vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
4059 uint32_t go_op_ch_freq_5g = 0;
4060
4061 pm_ctx = policy_mgr_get_context(psoc);
4062 if (!pm_ctx) {
4063 policy_mgr_err("Invalid Context");
4064 return QDF_STATUS_E_FAILURE;
4065 }
4066
4067 if (!pm_ctx->sap_mandatory_channels_len)
4068 return QDF_STATUS_SUCCESS;
4069
4070 if (!policy_mgr_list_has_24GHz_channel(pm_ctx->sap_mandatory_channels,
4071 pm_ctx->sap_mandatory_channels_len)) {
4072 policy_mgr_err("fav channel list is missing 2.4GHz channels");
4073 return QDF_STATUS_E_FAILURE;
4074 }
4075
4076
4077 for (i = 0; i < pm_ctx->sap_mandatory_channels_len; i++)
4078 policy_mgr_debug("fav chan:%d",
4079 pm_ctx->sap_mandatory_channels[i]);
4080
4081 if (scc_on_indoor)
4082 indoor_sta_freq = policy_mgr_is_sta_on_indoor_channel(psoc);
4083
4084 policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc, &scc_on_dfs_channel);
4085 if (scc_on_dfs_channel)
4086 policy_mgr_is_sta_present_on_dfs_channel(psoc,
4087 &sta_vdev_id,
4088 &dfs_sta_freq,
4089 &sta_ch_width);
4090 sta_sap_scc_on_5ghz_channel =
4091 policy_mgr_is_connected_sta_5g(psoc, &sta_5GHz_freq);
4092
4093 go_count = policy_mgr_get_mode_specific_conn_info(
4094 psoc, go_op_ch_freq_list,
4095 go_vdev_id_list, PM_P2P_GO_MODE);
4096 if (go_count && !WLAN_REG_IS_24GHZ_CH_FREQ(go_op_ch_freq_list[0])) {
4097 go_op_ch_freq_5g = go_op_ch_freq_list[0];
4098 policy_mgr_debug("go 5/6G present, SAP exclude 5/6G channels");
4099 }
4100
4101 for (i = 0; i < *pcl_len_org; i++) {
4102 found = false;
4103 if (i >= NUM_CHANNELS) {
4104 policy_mgr_debug("index is exceeding NUM_CHANNELS");
4105 break;
4106 }
4107
4108 if (go_op_ch_freq_5g &&
4109 !WLAN_REG_IS_24GHZ_CH_FREQ(pcl_list_org[i]))
4110 continue;
4111
4112 if (scc_on_indoor && policy_mgr_is_force_scc(psoc) &&
4113 pcl_list_org[i] == indoor_sta_freq) {
4114 policy_mgr_debug("indoor chan:%d", pcl_list_org[i]);
4115 found = true;
4116 goto update_pcl;
4117 }
4118
4119 if (scc_on_dfs_channel && policy_mgr_is_force_scc(psoc) &&
4120 pcl_list_org[i] == dfs_sta_freq) {
4121 policy_mgr_debug("dfs chan:%d", pcl_list_org[i]);
4122 found = true;
4123 goto update_pcl;
4124 }
4125
4126 if (sta_sap_scc_on_5ghz_channel &&
4127 policy_mgr_is_force_scc(psoc) &&
4128 pcl_list_org[i] == sta_5GHz_freq) {
4129 policy_mgr_debug("scc chan:%d", pcl_list_org[i]);
4130 found = true;
4131 goto update_pcl;
4132 }
4133
4134 for (j = 0; j < pm_ctx->sap_mandatory_channels_len; j++) {
4135 if (pcl_list_org[i] ==
4136 pm_ctx->sap_mandatory_channels[j]) {
4137 found = true;
4138 break;
4139 }
4140 }
4141
4142 update_pcl:
4143 if (found && (pcl_len < NUM_CHANNELS)) {
4144 pcl_list_org[pcl_len] = pcl_list_org[i];
4145 weight_list_org[pcl_len++] = weight_list_org[i];
4146 }
4147 }
4148 *pcl_len_org = pcl_len;
4149
4150 return QDF_STATUS_SUCCESS;
4151 }
4152
4153 void
policy_mgr_sap_on_non_psc_channel(struct wlan_objmgr_psoc * psoc,qdf_freq_t * intf_ch_freq,uint8_t vdev_id)4154 policy_mgr_sap_on_non_psc_channel(struct wlan_objmgr_psoc *psoc,
4155 qdf_freq_t *intf_ch_freq, uint8_t vdev_id)
4156 {
4157 struct policy_mgr_pcl_list pcl;
4158 struct wlan_objmgr_vdev *vdev;
4159 QDF_STATUS status;
4160 uint32_t i;
4161 uint32_t ap_pwr_type_6g = 0;
4162
4163 if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(*intf_ch_freq))
4164 return;
4165
4166 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
4167 WLAN_POLICY_MGR_ID);
4168
4169 if (!vdev) {
4170 policy_mgr_err("vdev %d is not present", vdev_id);
4171 return;
4172 }
4173
4174 ap_pwr_type_6g = wlan_mlme_get_6g_ap_power_type(vdev);
4175 qdf_mem_zero(&pcl, sizeof(pcl));
4176
4177 /* PCL list is filtered with Non-PSC channels during
4178 * policy_mgr_pcl_modification_for_sap, Reuse same list to check
4179 * if STA is in PSC channel for STA + SAP concurrency during SAP restart
4180 */
4181 status = policy_mgr_get_pcl_for_existing_conn(
4182 psoc, PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len,
4183 pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list),
4184 false, vdev_id);
4185
4186 if (QDF_IS_STATUS_ERROR(status)) {
4187 policy_mgr_err("Unable to get PCL for SAP");
4188 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
4189 return;
4190 }
4191
4192 for (i = 0; i < pcl.pcl_len; i++) {
4193 if ((WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl.pcl_list[i])) &&
4194 pcl.pcl_list[i] == *intf_ch_freq &&
4195 ap_pwr_type_6g == REG_VERY_LOW_POWER_AP) {
4196 policy_mgr_debug("STA is in PSC channel %d in VLP mode, Hence SAP + STA allowed in PSC",
4197 *intf_ch_freq);
4198 *intf_ch_freq = 0;
4199 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
4200 return;
4201 }
4202 }
4203
4204 /* if STA is in Non-PSC Channel + VLP or in non-VLP mode then move
4205 * SAP to 2 GHz from PCL list channels
4206 */
4207 *intf_ch_freq = pcl.pcl_list[0];
4208 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
4209 }
4210
4211 QDF_STATUS
policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc * psoc,uint32_t sap_ch_freq,uint32_t * intf_ch_freq,uint8_t vdev_id)4212 policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc,
4213 uint32_t sap_ch_freq,
4214 uint32_t *intf_ch_freq,
4215 uint8_t vdev_id)
4216 {
4217 struct policy_mgr_psoc_priv_obj *pm_ctx;
4218 QDF_STATUS status;
4219 struct policy_mgr_pcl_list pcl;
4220 uint32_t i;
4221 uint32_t sap_new_freq;
4222 uint8_t mcc_to_scc_switch;
4223 uint8_t sta_count;
4224 qdf_freq_t user_config_freq = 0;
4225 bool sta_sap_scc_on_indoor_channel =
4226 policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
4227
4228 mcc_to_scc_switch =
4229 policy_mgr_get_mcc_to_scc_switch_mode(psoc);
4230
4231 sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
4232 NULL);
4233
4234 if (!sta_count || mcc_to_scc_switch !=
4235 QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL)
4236 return QDF_STATUS_E_FAILURE;
4237
4238 pm_ctx = policy_mgr_get_context(psoc);
4239 if (!pm_ctx) {
4240 policy_mgr_err("Invalid Context");
4241 return QDF_STATUS_E_FAILURE;
4242 }
4243
4244 qdf_mem_zero(&pcl, sizeof(pcl));
4245
4246 status = policy_mgr_get_pcl_for_existing_conn(
4247 psoc, PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len,
4248 pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list),
4249 false, vdev_id);
4250 if (QDF_IS_STATUS_ERROR(status)) {
4251 policy_mgr_err("Unable to get PCL for SAP");
4252 return status;
4253 }
4254
4255 /*
4256 * Get inside below loop if no existing SAP connection and hence a new
4257 * SAP connection might be coming up. pcl.pcl_len can be 0 if no common
4258 * channel between PCL & mandatory channel list as well
4259 */
4260 if (!pcl.pcl_len && !policy_mgr_mode_specific_connection_count(psoc,
4261 PM_SAP_MODE, NULL)) {
4262 policy_mgr_debug("policy_mgr_get_pcl_for_existing_conn returned no pcl");
4263 status = policy_mgr_get_pcl(
4264 psoc, PM_SAP_MODE,
4265 pcl.pcl_list, &pcl.pcl_len,
4266 pcl.weight_list,
4267 QDF_ARRAY_SIZE(pcl.weight_list), vdev_id);
4268 if (QDF_IS_STATUS_ERROR(status)) {
4269 policy_mgr_err("Unable to get PCL for SAP: policy_mgr_get_pcl");
4270 return status;
4271 }
4272 }
4273
4274 status = policy_mgr_modify_sap_pcl_based_on_mandatory_channel(
4275 psoc, pcl.pcl_list,
4276 pcl.weight_list,
4277 &pcl.pcl_len);
4278 if (QDF_IS_STATUS_ERROR(status)) {
4279 policy_mgr_err("Unable to modify SAP PCL");
4280 return status;
4281 }
4282
4283 if (!pcl.pcl_len) {
4284 policy_mgr_err("No common channel between mandatory list & PCL");
4285 return QDF_STATUS_E_FAILURE;
4286 }
4287
4288 /*
4289 * If both freq leads to SBS, and sap_ch_freq is a mandatory freq,
4290 * allow it as they are not interfering.
4291 */
4292 if (policy_mgr_are_sbs_chan(psoc, sap_ch_freq, *intf_ch_freq)) {
4293 for (i = 0; i < pcl.pcl_len; i++) {
4294 if (pcl.pcl_list[i] == sap_ch_freq) {
4295 policy_mgr_debug("As both freq, %d and %d are SBS, allow sap on mandatory freq %d",
4296 sap_ch_freq, *intf_ch_freq,
4297 sap_ch_freq);
4298 *intf_ch_freq = 0;
4299 return QDF_STATUS_SUCCESS;
4300 }
4301 }
4302 }
4303
4304 /*
4305 * If intf_ch_freq is non-2.4Ghz, First try to get a mandatory freq
4306 * which can cause SBS with intf_ch_freq. i.e if STA is in lower 5Ghz,
4307 * allow higher 5Ghz mandatory freq.
4308 */
4309 if (!WLAN_REG_IS_24GHZ_CH_FREQ(*intf_ch_freq)) {
4310 for (i = 0; i < pcl.pcl_len; i++) {
4311 if (policy_mgr_are_sbs_chan(psoc, pcl.pcl_list[i],
4312 *intf_ch_freq)) {
4313 sap_new_freq = pcl.pcl_list[i];
4314 goto update_freq;
4315 }
4316 }
4317 }
4318
4319 sap_new_freq = pcl.pcl_list[0];
4320 /*
4321 * pcl_list carries multiple channel in ML-STA case depending on
4322 * the no.of links connected. Check if intf_ch_freq is carrying
4323 * any frequency from the list and pick it. If intf_ch_freq is not
4324 * present in the list, the frequency present at pcl_list[0] can
4325 * be picked as caller doesn't have any preferred/chosen channel
4326 * as such.
4327 */
4328 for (i = 0; i < pcl.pcl_len; i++) {
4329 if (pcl.pcl_list[i] == *intf_ch_freq) {
4330 sap_new_freq = pcl.pcl_list[i];
4331 break;
4332 }
4333 }
4334
4335 user_config_freq = policy_mgr_get_user_config_sap_freq(psoc, vdev_id);
4336
4337 for (i = 0; i < pcl.pcl_len; i++) {
4338 /* When sta_sap_scc_on_indoor_channel is enabled,
4339 * and if pcl contains SCC channel, then STA must
4340 * exist on the concurrent session. Therefore, choose
4341 * Indoor channel to restart SAP in SCC.
4342 */
4343 if (wlan_reg_is_freq_indoor(pm_ctx->pdev, pcl.pcl_list[i]) &&
4344 !WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl.pcl_list[i]) &&
4345 sta_sap_scc_on_indoor_channel) {
4346 sap_new_freq = pcl.pcl_list[i];
4347 policy_mgr_debug("Choose Indoor channel from PCL list %d sap_new_freq %d",
4348 *intf_ch_freq, sap_new_freq);
4349 goto update_freq;
4350 }
4351
4352 if (user_config_freq && (pcl.pcl_list[i] == user_config_freq)) {
4353 sap_new_freq = pcl.pcl_list[i];
4354 policy_mgr_debug("Prefer starting SAP on user configured channel:%d",
4355 sap_new_freq);
4356 goto update_freq;
4357 }
4358 }
4359
4360 /* If no SBS Try get SCC freq */
4361 if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ch_freq) ||
4362 (WLAN_REG_IS_5GHZ_CH_FREQ(sap_ch_freq) &&
4363 WLAN_REG_IS_5GHZ_CH_FREQ(*intf_ch_freq))) {
4364 for (i = 0; i < pcl.pcl_len; i++) {
4365 if (pcl.pcl_list[i] == *intf_ch_freq) {
4366 sap_new_freq = pcl.pcl_list[i];
4367 break;
4368 }
4369 }
4370 }
4371
4372 update_freq:
4373 *intf_ch_freq = sap_new_freq;
4374 policy_mgr_debug("Mandatory channel:%d org sap ch %d", *intf_ch_freq,
4375 sap_ch_freq);
4376
4377 return QDF_STATUS_SUCCESS;
4378 }
4379
policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc * psoc,struct policy_mgr_pcl_chan_weights * weight,enum policy_mgr_con_mode mode,struct wlan_objmgr_vdev * vdev)4380 QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc,
4381 struct policy_mgr_pcl_chan_weights *weight,
4382 enum policy_mgr_con_mode mode, struct wlan_objmgr_vdev *vdev)
4383 {
4384 uint32_t i, j;
4385 struct policy_mgr_conc_connection_info
4386 info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
4387 uint8_t num_del = 0;
4388 struct policy_mgr_psoc_priv_obj *pm_ctx;
4389 bool strict_follow_pcl = false;
4390
4391 pm_ctx = policy_mgr_get_context(psoc);
4392 if (!pm_ctx) {
4393 policy_mgr_err("Invalid Context");
4394 return QDF_STATUS_E_FAILURE;
4395 }
4396
4397 qdf_mem_set(weight->weighed_valid_list, NUM_CHANNELS,
4398 WEIGHT_OF_DISALLOWED_CHANNELS);
4399 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4400 if ((mode == PM_P2P_GO_MODE || mode == PM_P2P_CLIENT_MODE) ||
4401 (mode == PM_STA_MODE &&
4402 policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
4403 NULL))) {
4404 /*
4405 * Store the STA mode's parameter and temporarily delete it
4406 * from the concurrency table. This way the allow concurrency
4407 * check can be used as though a new connection is coming up,
4408 * allowing to detect the disallowed channels.
4409 */
4410 if (mode == PM_STA_MODE) {
4411 if (policy_mgr_concurrent_sta_on_different_mac(psoc) &&
4412 !wlan_cm_same_band_sta_allowed(psoc) &&
4413 weight->pcl_len) {
4414 policy_mgr_debug("sta follow pcl strictly");
4415 strict_follow_pcl = true;
4416 }
4417 if (vdev)
4418 policy_mgr_store_and_del_conn_info_by_vdev_id(
4419 psoc, wlan_vdev_get_id(vdev),
4420 info, &num_del);
4421 else
4422 policy_mgr_store_and_del_conn_info(psoc,
4423 mode, true,
4424 info,
4425 &num_del);
4426 }
4427 /*
4428 * For two port/three port connection strictly follow
4429 * PCL weight if coming intf is p2p GO/GC and existing
4430 * vdev is SAP/P2PGO/P2PGC.
4431 */
4432 if ((mode == PM_P2P_GO_MODE || mode == PM_P2P_CLIENT_MODE) &&
4433 ((policy_mgr_get_beaconing_mode_count(psoc, NULL)) ||
4434 policy_mgr_mode_specific_connection_count(
4435 psoc, PM_P2P_CLIENT_MODE, NULL)))
4436 strict_follow_pcl = true;
4437
4438 /*
4439 * This is a temporary check and will be removed once ll_lt_sap
4440 * CSA support is added.
4441 */
4442 if (wlan_policy_mgr_get_ll_lt_sap_vdev_id(psoc) !=
4443 WLAN_INVALID_VDEV_ID) {
4444 policy_mgr_debug("LL_LT_SAP present, strict follow PCL");
4445 strict_follow_pcl = true;
4446 }
4447
4448 /*
4449 * There is a small window between releasing the above lock
4450 * and acquiring the same in policy_mgr_allow_concurrency,
4451 * below!
4452 */
4453
4454 for (i = 0; i < weight->saved_num_chan; i++) {
4455 /*
4456 * If channel is not allowed for concurrency, keep pcl
4457 * weight as 0 (WEIGHT_OF_DISALLOWED_CHANNELS)
4458 */
4459 if (!policy_mgr_is_concurrency_allowed
4460 (psoc, mode, weight->saved_chan_list[i],
4461 HW_MODE_20_MHZ,
4462 policy_mgr_get_conc_ext_flags(vdev, false), NULL))
4463 continue;
4464 /*
4465 * Keep weight 0 (WEIGHT_OF_DISALLOWED_CHANNELS) not
4466 * changed for scenarios which require to follow PCL.
4467 */
4468 if (strict_follow_pcl)
4469 continue;
4470 weight->weighed_valid_list[i] =
4471 WEIGHT_OF_NON_PCL_CHANNELS;
4472 }
4473 /* Restore the connection info */
4474 if (mode == PM_STA_MODE)
4475 policy_mgr_restore_deleted_conn_info(psoc, info,
4476 num_del);
4477 }
4478 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4479
4480 for (i = 0; i < weight->saved_num_chan; i++) {
4481 for (j = 0; j < weight->pcl_len; j++) {
4482 if (weight->saved_chan_list[i] == weight->pcl_list[j]) {
4483 weight->weighed_valid_list[i] =
4484 weight->weight_list[j];
4485 break;
4486 }
4487 }
4488 }
4489
4490 return QDF_STATUS_SUCCESS;
4491 }
4492
policy_mgr_mode_specific_get_channel(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode)4493 uint32_t policy_mgr_mode_specific_get_channel(
4494 struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode)
4495 {
4496 uint32_t conn_index;
4497 struct policy_mgr_psoc_priv_obj *pm_ctx;
4498 uint32_t freq = 0;
4499
4500 pm_ctx = policy_mgr_get_context(psoc);
4501 if (!pm_ctx) {
4502 policy_mgr_err("Invalid Context");
4503 return 0;
4504 }
4505 /* provides the channel for the first matching mode type */
4506 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4507 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
4508 conn_index++) {
4509 if ((pm_conc_connection_list[conn_index].mode == mode) &&
4510 pm_conc_connection_list[conn_index].in_use) {
4511 freq = pm_conc_connection_list[conn_index].freq;
4512 break;
4513 }
4514 }
4515 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4516
4517 return freq;
4518 }
4519
policy_mgr_get_connection_count_with_ch_freq(uint32_t ch_freq)4520 uint32_t policy_mgr_get_connection_count_with_ch_freq(uint32_t ch_freq)
4521 {
4522 uint32_t i;
4523 uint32_t count = 0;
4524
4525 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
4526 if (pm_conc_connection_list[i].in_use &&
4527 ch_freq == pm_conc_connection_list[i].freq)
4528 count++;
4529 }
4530
4531 return count;
4532 }
4533
policy_mgr_get_alternate_channel_for_sap(struct wlan_objmgr_psoc * psoc,uint8_t sap_vdev_id,uint32_t sap_ch_freq,enum reg_wifi_band pref_band)4534 uint32_t policy_mgr_get_alternate_channel_for_sap(
4535 struct wlan_objmgr_psoc *psoc, uint8_t sap_vdev_id,
4536 uint32_t sap_ch_freq,
4537 enum reg_wifi_band pref_band)
4538 {
4539 uint32_t pcl_channels[NUM_CHANNELS];
4540 uint8_t pcl_weight[NUM_CHANNELS];
4541 uint32_t ch_freq = 0;
4542 uint32_t pcl_len = 0;
4543 uint32_t first_valid_dfs_5g_freq = 0;
4544 uint32_t first_valid_non_dfs_5g_freq = 0;
4545 uint32_t first_valid_6g_freq = 0;
4546 struct policy_mgr_conc_connection_info info;
4547 uint8_t num_cxn_del = 0;
4548 struct policy_mgr_psoc_priv_obj *pm_ctx;
4549 uint8_t i;
4550 enum policy_mgr_con_mode con_mode;
4551 bool is_6ghz_cap;
4552
4553 pm_ctx = policy_mgr_get_context(psoc);
4554 if (!pm_ctx) {
4555 policy_mgr_err("Invalid Context");
4556 return 0;
4557 }
4558 con_mode = policy_mgr_con_mode_by_vdev_id(psoc, sap_vdev_id);
4559 is_6ghz_cap = policy_mgr_get_ap_6ghz_capable(psoc, sap_vdev_id, NULL);
4560 /*
4561 * Store the connection's parameter and temporarily delete it
4562 * from the concurrency table. This way the get pcl can be used as a
4563 * new connection is coming up, after check, restore the connection to
4564 * concurrency table.
4565 */
4566 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4567 policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, sap_vdev_id,
4568 &info, &num_cxn_del);
4569 if (QDF_STATUS_SUCCESS == policy_mgr_get_pcl(
4570 psoc, con_mode, pcl_channels, &pcl_len,
4571 pcl_weight, QDF_ARRAY_SIZE(pcl_weight), sap_vdev_id)) {
4572 for (i = 0; i < pcl_len; i++) {
4573 /*
4574 * The API is expected to select the channel on the
4575 * other band which is not same as sap's home and
4576 * concurrent interference channel (if present),
4577 * so skip the sap home channel in PCL.
4578 */
4579 if (pcl_channels[i] == sap_ch_freq)
4580 continue;
4581 if (!is_6ghz_cap &&
4582 WLAN_REG_IS_6GHZ_CHAN_FREQ(pcl_channels[i]))
4583 continue;
4584 if (policy_mgr_get_connection_count(psoc) &&
4585 policy_mgr_are_2_freq_on_same_mac(psoc,
4586 sap_ch_freq,
4587 pcl_channels[i]))
4588 continue;
4589 if (policy_mgr_get_connection_count_with_ch_freq(
4590 pcl_channels[i])) {
4591 ch_freq = pcl_channels[i];
4592 break;
4593 } else if (!ch_freq) {
4594 ch_freq = pcl_channels[i];
4595 }
4596 if (!first_valid_non_dfs_5g_freq &&
4597 wlan_reg_is_5ghz_ch_freq(pcl_channels[i])) {
4598 if (!wlan_reg_is_dfs_in_secondary_list_for_freq(
4599 pm_ctx->pdev,
4600 pcl_channels[i])) {
4601 first_valid_non_dfs_5g_freq = pcl_channels[i];
4602 if (pref_band == REG_BAND_5G)
4603 break;
4604 } else if (!first_valid_dfs_5g_freq) {
4605 first_valid_dfs_5g_freq = pcl_channels[i];
4606 }
4607 }
4608 if (!first_valid_6g_freq &&
4609 wlan_reg_is_6ghz_chan_freq(pcl_channels[i])) {
4610 first_valid_6g_freq = pcl_channels[i];
4611 if (pref_band == REG_BAND_6G)
4612 break;
4613 }
4614 }
4615 }
4616
4617 /* Restore the connection entry */
4618 if (num_cxn_del > 0)
4619 policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del);
4620
4621 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4622 if (pref_band == REG_BAND_6G) {
4623 if (first_valid_6g_freq)
4624 ch_freq = first_valid_6g_freq;
4625 else if (first_valid_non_dfs_5g_freq)
4626 ch_freq = first_valid_non_dfs_5g_freq;
4627 else if (first_valid_dfs_5g_freq)
4628 ch_freq = first_valid_dfs_5g_freq;
4629 } else if (pref_band == REG_BAND_5G) {
4630 if (first_valid_non_dfs_5g_freq)
4631 ch_freq = first_valid_non_dfs_5g_freq;
4632 else if (first_valid_dfs_5g_freq)
4633 ch_freq = first_valid_dfs_5g_freq;
4634 }
4635
4636 return ch_freq;
4637 }
4638
4639 /*
4640 * Buffer len size to consider the 4 char freq, 3 char weight, 2 char
4641 * for open close brackets and space and a space, Total 10
4642 */
4643 #define CHAN_WEIGHT_CHAR_LEN 10
4644 #define MAX_CHAN_TO_PRINT 39
4645
policy_mgr_dump_channel_list(uint32_t len,uint32_t * pcl_channels,uint8_t * pcl_weight)4646 bool policy_mgr_dump_channel_list(uint32_t len, uint32_t *pcl_channels,
4647 uint8_t *pcl_weight)
4648 {
4649 uint32_t idx, buff_len, num = 0, count = 0;
4650 char *chan_buff = NULL;
4651
4652 buff_len = (QDF_MIN(len, MAX_CHAN_TO_PRINT) * CHAN_WEIGHT_CHAR_LEN) + 1;
4653 chan_buff = qdf_mem_malloc(buff_len);
4654 if (!chan_buff)
4655 return false;
4656
4657 policymgr_nofl_debug("Total PCL Chan Freq %d", len);
4658 for (idx = 0; (idx < len) && (idx < NUM_CHANNELS); idx++) {
4659 num += qdf_scnprintf(chan_buff + num, buff_len - num,
4660 " %d[%d]", pcl_channels[idx],
4661 pcl_weight[idx]);
4662 count++;
4663 if (count >= MAX_CHAN_TO_PRINT) {
4664 /* Print the MAX_CHAN_TO_PRINT channels */
4665 policymgr_nofl_debug("Freq[weight]:%s",
4666 chan_buff);
4667 count = 0;
4668 num = 0;
4669 }
4670 }
4671 /* Print any pending channels */
4672 if (num)
4673 policymgr_nofl_debug("Freq[weight]:%s", chan_buff);
4674
4675 qdf_mem_free(chan_buff);
4676
4677 return true;
4678 }
4679
policy_mgr_filter_passive_ch(struct wlan_objmgr_pdev * pdev,uint32_t * ch_freq_list,uint32_t * ch_cnt)4680 QDF_STATUS policy_mgr_filter_passive_ch(struct wlan_objmgr_pdev *pdev,
4681 uint32_t *ch_freq_list,
4682 uint32_t *ch_cnt)
4683 {
4684 size_t ch_index;
4685 size_t target_ch_cnt = 0;
4686
4687 if (!pdev || !ch_freq_list || !ch_cnt) {
4688 policy_mgr_err("NULL parameters");
4689 return QDF_STATUS_E_FAULT;
4690 }
4691
4692 for (ch_index = 0; ch_index < *ch_cnt; ch_index++) {
4693 if (wlan_reg_is_passive_for_freq(pdev,
4694 ch_freq_list[ch_index])) {
4695 policy_mgr_debug("Remove freq: %d from list as it's passive",
4696 ch_freq_list[ch_index]);
4697 continue;
4698 }
4699 ch_freq_list[target_ch_cnt++] = ch_freq_list[ch_index];
4700 }
4701
4702 *ch_cnt = target_ch_cnt;
4703
4704 return QDF_STATUS_SUCCESS;
4705 }
4706
policy_mgr_is_3rd_conn_on_same_band_allowed(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,qdf_freq_t ch_freq)4707 bool policy_mgr_is_3rd_conn_on_same_band_allowed(struct wlan_objmgr_psoc *psoc,
4708 enum policy_mgr_con_mode mode,
4709 qdf_freq_t ch_freq)
4710 {
4711 enum policy_mgr_pcl_type pcl = PM_NONE;
4712 enum policy_mgr_conc_priority_mode conc_system_pref = 0;
4713 enum policy_mgr_two_connection_mode third_index = 0;
4714 struct policy_mgr_psoc_priv_obj *pm_ctx;
4715 bool ret = false;
4716
4717 pm_ctx = policy_mgr_get_context(psoc);
4718 if (!pm_ctx) {
4719 policy_mgr_err("context is NULL");
4720 return false;
4721 }
4722
4723 if (pm_conc_connection_list[0].freq != ch_freq ||
4724 pm_conc_connection_list[0].freq !=
4725 pm_conc_connection_list[1].freq) {
4726 policy_mgr_debug("No MCC support in 3vif in same mac: %d %d %d",
4727 pm_conc_connection_list[0].freq,
4728 pm_conc_connection_list[1].freq,
4729 ch_freq);
4730 return false;
4731 }
4732
4733 policy_mgr_debug("pref:%d requested mode:%d",
4734 pm_ctx->cur_conc_system_pref, mode);
4735
4736 switch (pm_ctx->cur_conc_system_pref) {
4737 case 0:
4738 conc_system_pref = PM_THROUGHPUT;
4739 break;
4740 case 1:
4741 conc_system_pref = PM_POWERSAVE;
4742 break;
4743 case 2:
4744 conc_system_pref = PM_LATENCY;
4745 break;
4746 default:
4747 policy_mgr_err("unknown cur_conc_system_pref value %d",
4748 pm_ctx->cur_conc_system_pref);
4749 break;
4750 }
4751
4752 third_index = policy_mgr_get_third_connection_pcl_table_index(psoc);
4753 if (PM_MAX_TWO_CONNECTION_MODE == third_index) {
4754 policy_mgr_err(
4755 "couldn't find index for 3rd connection pcl table");
4756 return false;
4757 }
4758 if (policy_mgr_is_hw_dbs_capable(psoc) == true) {
4759 pcl = (*third_connection_pcl_dbs_table)
4760 [third_index][mode][conc_system_pref];
4761 } else {
4762 pcl = (*third_connection_pcl_non_dbs_table)
4763 [third_index][mode][conc_system_pref];
4764 }
4765
4766 policy_mgr_debug("pcl for third connection mode %s is %d %s",
4767 device_mode_to_string(mode), pcl,
4768 pcl_type_to_string(pcl));
4769 switch (pcl) {
4770 case PM_SCC_CH:
4771 case PM_SCC_CH_24G:
4772 case PM_SCC_CH_5G:
4773 case PM_24G_SCC_CH:
4774 case PM_5G_SCC_CH:
4775 case PM_SCC_ON_5_CH_5G:
4776 case PM_SCC_ON_5_SCC_ON_24_24G:
4777 case PM_SCC_ON_5_SCC_ON_24_5G:
4778 case PM_SCC_ON_5_5G_24G:
4779 case PM_SCC_ON_5_5G_SCC_ON_24G:
4780 case PM_SCC_ON_24_SCC_ON_5_24G:
4781 case PM_SCC_ON_24_SCC_ON_5_5G:
4782 case PM_SCC_ON_24_CH_24G:
4783 case PM_SCC_ON_5_SCC_ON_24:
4784 case PM_SCC_ON_24_SCC_ON_5:
4785 case PM_24G_SCC_CH_SBS_CH:
4786 case PM_24G_SCC_CH_SBS_CH_5G:
4787 case PM_SBS_CH_24G_SCC_CH:
4788 case PM_SBS_CH_SCC_CH_24G:
4789 case PM_SCC_CH_SBS_CH_24G:
4790 case PM_SBS_CH_SCC_CH_5G_24G:
4791 case PM_SCC_CH_MCC_CH_SBS_CH_24G:
4792 case PM_MCC_CH:
4793 case PM_MCC_CH_24G:
4794 case PM_MCC_CH_5G:
4795 case PM_24G_MCC_CH:
4796 case PM_5G_MCC_CH:
4797 case PM_24G_SBS_CH_MCC_CH:
4798 ret = true;
4799 break;
4800 default:
4801 policy_mgr_debug("Not in SCC case");
4802 ret = false;
4803 break;
4804 }
4805 return ret;
4806 }
4807
policy_mgr_is_sta_chan_valid_for_connect_and_roam(struct wlan_objmgr_pdev * pdev,qdf_freq_t freq)4808 bool policy_mgr_is_sta_chan_valid_for_connect_and_roam(
4809 struct wlan_objmgr_pdev *pdev,
4810 qdf_freq_t freq)
4811 {
4812 struct wlan_objmgr_psoc *psoc;
4813 uint32_t sap_count;
4814 bool skip_6g_and_indoor_freq;
4815
4816 psoc = wlan_pdev_get_psoc(pdev);
4817 if (!psoc)
4818 return true;
4819
4820 skip_6g_and_indoor_freq =
4821 wlan_scan_cfg_skip_6g_and_indoor_freq(psoc);
4822 sap_count =
4823 policy_mgr_get_sap_mode_count(psoc, NULL);
4824 /*
4825 * Do not allow STA to connect/roam on 6Ghz or indoor channel for
4826 * non-dbs hardware if SAP is present and skip_6g_and_indoor_freq_scan
4827 * ini is enabled
4828 */
4829 if (skip_6g_and_indoor_freq && sap_count &&
4830 !policy_mgr_is_hw_dbs_capable(psoc) &&
4831 (WLAN_REG_IS_6GHZ_CHAN_FREQ(freq) ||
4832 wlan_reg_is_freq_indoor(pdev, freq)))
4833 return false;
4834
4835 return true;
4836 }
4837
4838 /**
4839 * _policy_mgr_is_vdev_ll_sap() - Check whether any LL SAP is present or not
4840 * for provided ap policy
4841 * @psoc: psoc object
4842 * @vdev_id: vdev id
4843 * @ap_type: LL SAP type
4844 *
4845 * Return: true if it's present otherwise false
4846 */
4847 static bool
_policy_mgr_is_vdev_ll_sap(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id,enum ll_ap_type ap_type)4848 _policy_mgr_is_vdev_ll_sap(struct wlan_objmgr_psoc *psoc,
4849 uint32_t vdev_id, enum ll_ap_type ap_type)
4850 {
4851 struct wlan_objmgr_vdev *vdev;
4852 bool is_ll_sap = false;
4853 enum QDF_OPMODE mode;
4854 struct policy_mgr_psoc_priv_obj *pm_ctx;
4855 enum host_concurrent_ap_policy profile =
4856 HOST_CONCURRENT_AP_POLICY_UNSPECIFIED;
4857
4858 pm_ctx = policy_mgr_get_context(psoc);
4859 if (!pm_ctx) {
4860 policy_mgr_err("Invalid pm_ctx");
4861 return is_ll_sap;
4862 }
4863
4864 mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id);
4865
4866 if (mode != QDF_SAP_MODE)
4867 return is_ll_sap;
4868
4869 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
4870 WLAN_POLICY_MGR_ID);
4871 if (!vdev) {
4872 policy_mgr_err("vdev %d: invalid vdev", vdev_id);
4873 return is_ll_sap;
4874 }
4875
4876 profile = wlan_mlme_get_ap_policy(vdev);
4877 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
4878 switch (ap_type) {
4879 case LL_AP_TYPE_HT:
4880 if (profile == HOST_CONCURRENT_AP_POLICY_XR)
4881 is_ll_sap = true;
4882 break;
4883 case LL_AP_TYPE_LT:
4884 if (profile == HOST_CONCURRENT_AP_POLICY_GAMING_AUDIO ||
4885 profile ==
4886 HOST_CONCURRENT_AP_POLICY_LOSSLESS_AUDIO_STREAMING)
4887 is_ll_sap = true;
4888 break;
4889 case LL_AP_TYPE_ANY:
4890 if (profile == HOST_CONCURRENT_AP_POLICY_GAMING_AUDIO ||
4891 profile ==
4892 HOST_CONCURRENT_AP_POLICY_LOSSLESS_AUDIO_STREAMING ||
4893 profile == HOST_CONCURRENT_AP_POLICY_XR)
4894 is_ll_sap = true;
4895 break;
4896 default:
4897 policy_mgr_err("invalid ap type %d", ap_type);
4898 }
4899 return is_ll_sap;
4900 }
4901
4902 bool
policy_mgr_is_vdev_ll_sap(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id)4903 policy_mgr_is_vdev_ll_sap(struct wlan_objmgr_psoc *psoc,
4904 uint32_t vdev_id)
4905 {
4906 return _policy_mgr_is_vdev_ll_sap(psoc, vdev_id, LL_AP_TYPE_ANY);
4907 }
4908
4909 bool
policy_mgr_is_vdev_ll_ht_sap(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id)4910 policy_mgr_is_vdev_ll_ht_sap(struct wlan_objmgr_psoc *psoc,
4911 uint32_t vdev_id)
4912 {
4913 return _policy_mgr_is_vdev_ll_sap(psoc, vdev_id, LL_AP_TYPE_HT);
4914 }
4915
4916 bool
policy_mgr_is_vdev_ll_lt_sap(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id)4917 policy_mgr_is_vdev_ll_lt_sap(struct wlan_objmgr_psoc *psoc,
4918 uint32_t vdev_id)
4919 {
4920 return _policy_mgr_is_vdev_ll_sap(psoc, vdev_id, LL_AP_TYPE_LT);
4921 }
4922
4923 #ifndef WLAN_FEATURE_LL_LT_SAP
4924 QDF_STATUS
policy_mgr_get_pcl_chlist_for_ll_sap(struct wlan_objmgr_psoc * psoc,uint32_t * len,uint32_t * pcl_channels,uint8_t * pcl_weight)4925 policy_mgr_get_pcl_chlist_for_ll_sap(struct wlan_objmgr_psoc *psoc,
4926 uint32_t *len, uint32_t *pcl_channels,
4927 uint8_t *pcl_weight)
4928 {
4929 struct policy_mgr_psoc_priv_obj *pm_ctx;
4930 uint32_t pcl_len = 0, i, conn_idx = 0;
4931 uint32_t pcl_list[NUM_CHANNELS], total_connection = 0;
4932 uint8_t weight_list[NUM_CHANNELS];
4933 qdf_freq_t freq;
4934
4935 pm_ctx = policy_mgr_get_context(psoc);
4936 if (!pm_ctx) {
4937 policy_mgr_err("pm_ctx is null");
4938 return QDF_STATUS_E_FAILURE;
4939 }
4940
4941 total_connection = policy_mgr_get_connection_count(psoc);
4942 if (!total_connection) {
4943 for (i = 0; i < *len; i++) {
4944 if (WLAN_REG_IS_24GHZ_CH_FREQ(pcl_channels[i]))
4945 continue;
4946
4947 pcl_list[pcl_len] = pcl_channels[i];
4948 weight_list[pcl_len++] = pcl_weight[i];
4949 }
4950 qdf_mem_zero(pcl_channels, *len * sizeof(*pcl_channels));
4951 qdf_mem_copy(pcl_channels, pcl_list,
4952 pcl_len * sizeof(*pcl_channels));
4953 } else {
4954 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4955 for (conn_idx = 0; conn_idx < MAX_NUMBER_OF_CONC_CONNECTIONS;
4956 conn_idx++) {
4957 if (!pm_conc_connection_list[conn_idx].in_use)
4958 continue;
4959
4960 freq = pm_conc_connection_list[conn_idx].freq;
4961
4962 for (i = 0; i < *len; i++) {
4963 if (policy_mgr_2_freq_always_on_same_mac(
4964 psoc,
4965 pcl_channels[i],
4966 freq) ||
4967 WLAN_REG_IS_24GHZ_CH_FREQ(pcl_channels[i]))
4968 continue;
4969 pcl_list[pcl_len] = pcl_channels[i];
4970 weight_list[pcl_len++] = pcl_weight[i];
4971 }
4972 *len = pcl_len;
4973 qdf_mem_zero(pcl_channels,
4974 *len * sizeof(*pcl_channels));
4975 qdf_mem_copy(pcl_channels, pcl_list,
4976 pcl_len * sizeof(*pcl_channels));
4977 }
4978 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4979 }
4980
4981 qdf_mem_zero(pcl_weight, *len * sizeof(*pcl_weight));
4982 qdf_mem_copy(pcl_weight, weight_list, pcl_len);
4983 *len = pcl_len;
4984
4985 return QDF_STATUS_SUCCESS;
4986 }
4987
4988 QDF_STATUS
policy_mgr_get_pcl_ch_for_sap_go_with_ll_sap_present(struct wlan_objmgr_psoc * psoc,uint32_t * len,uint32_t * pcl_channels,uint8_t * pcl_weight)4989 policy_mgr_get_pcl_ch_for_sap_go_with_ll_sap_present(
4990 struct wlan_objmgr_psoc *psoc,
4991 uint32_t *len, uint32_t *pcl_channels,
4992 uint8_t *pcl_weight)
4993 {
4994 struct policy_mgr_psoc_priv_obj *pm_ctx;
4995 uint32_t pcl_len = 0, i, conn_idx = 0;
4996 uint32_t pcl_list[NUM_CHANNELS];
4997 uint8_t weight_list[NUM_CHANNELS];
4998 qdf_freq_t freq;
4999 uint32_t vdev_id;
5000 bool is_ll_sap = 0;
5001
5002 pm_ctx = policy_mgr_get_context(psoc);
5003 if (!pm_ctx) {
5004 policy_mgr_err("pm_ctx is null");
5005 return QDF_STATUS_E_FAILURE;
5006 }
5007
5008 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
5009 for (conn_idx = 0; conn_idx < MAX_NUMBER_OF_CONC_CONNECTIONS;
5010 conn_idx++) {
5011 if (!pm_conc_connection_list[conn_idx].in_use)
5012 continue;
5013
5014 freq = pm_conc_connection_list[conn_idx].freq;
5015 vdev_id = pm_conc_connection_list[conn_idx].vdev_id;
5016 if (!policy_mgr_is_vdev_ll_sap(psoc, vdev_id))
5017 continue;
5018
5019 is_ll_sap = 1;
5020 for (i = 0; i < *len; i++) {
5021 if (policy_mgr_2_freq_always_on_same_mac(
5022 psoc,
5023 pcl_channels[i],
5024 freq))
5025 continue;
5026 pcl_list[pcl_len] = pcl_channels[i];
5027 weight_list[pcl_len++] = pcl_weight[i];
5028 }
5029 *len = pcl_len;
5030 qdf_mem_zero(pcl_channels,
5031 *len * sizeof(*pcl_channels));
5032 qdf_mem_copy(pcl_channels, pcl_list,
5033 pcl_len * sizeof(*pcl_channels));
5034 }
5035 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
5036
5037 if (!is_ll_sap)
5038 return QDF_STATUS_SUCCESS;
5039
5040 qdf_mem_zero(pcl_weight, *len * sizeof(*pcl_weight));
5041 qdf_mem_copy(pcl_weight, weight_list, pcl_len);
5042 *len = pcl_len;
5043
5044 return QDF_STATUS_SUCCESS;
5045 }
5046
5047 QDF_STATUS
policy_mgr_get_pcl_channel_for_ll_sap_concurrency(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id,uint32_t * pcl_channels,uint8_t * pcl_weight,uint32_t * len)5048 policy_mgr_get_pcl_channel_for_ll_sap_concurrency(
5049 struct wlan_objmgr_psoc *psoc,
5050 uint32_t vdev_id,
5051 uint32_t *pcl_channels,
5052 uint8_t *pcl_weight, uint32_t *len)
5053 {
5054 uint32_t orig_len = *len;
5055
5056 if (policy_mgr_is_vdev_ll_sap(psoc, vdev_id)) {
5057 /* Scenario: If there is some existing interface present and
5058 * LL SAP is coming up.
5059 * Filter pcl channel for LL SAP
5060 */
5061 policy_mgr_get_pcl_chlist_for_ll_sap(psoc, len, pcl_channels,
5062 pcl_weight);
5063 } else {
5064 /* Scenario: If there is LL SAP and GO/SAP is coming up.
5065 * Filter pcl channel for GO/SAP
5066 */
5067 policy_mgr_get_pcl_ch_for_sap_go_with_ll_sap_present(
5068 psoc,
5069 len,
5070 pcl_channels,
5071 pcl_weight);
5072 }
5073
5074 if (orig_len != *len) {
5075 policy_mgr_debug("PCL after ll sap modification");
5076 policy_mgr_dump_channel_list(*len, pcl_channels, pcl_weight);
5077 }
5078
5079 return QDF_STATUS_SUCCESS;
5080 }
5081 #endif
5082
5083 #ifdef WLAN_FEATURE_LL_LT_SAP
policy_mgr_get_pcl_ch_list_for_ll_sap(struct wlan_objmgr_psoc * psoc,struct policy_mgr_pcl_list * pcl,uint8_t vdev_id,struct connection_info * info,uint8_t * connection_count)5084 QDF_STATUS policy_mgr_get_pcl_ch_list_for_ll_sap(
5085 struct wlan_objmgr_psoc *psoc,
5086 struct policy_mgr_pcl_list *pcl,
5087 uint8_t vdev_id,
5088 struct connection_info *info,
5089 uint8_t *connection_count)
5090 {
5091 struct policy_mgr_psoc_priv_obj *pm_ctx;
5092 uint8_t num_cxn_del = 0;
5093 struct policy_mgr_conc_connection_info pm_info = {0};
5094 QDF_STATUS status;
5095
5096 pm_ctx = policy_mgr_get_context(psoc);
5097 if (!pm_ctx)
5098 return QDF_STATUS_E_FAILURE;
5099
5100 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
5101
5102 /*
5103 * Scenario: Standalone XPAN is present and CSA happens on
5104 * LL_LT_SAP interface.
5105 * During CSA, it will check the PCL list to get the new freq.
5106 * Since there is already LL_LT_SAP interface entry in PCL index.
5107 * It will lead to LL_LT_SAP + LL_LT_SAP concurrencies. To avoid
5108 * that, delete the existing connection entry from PCL index,
5109 * get the PCL list and restore it back.
5110 */
5111 policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id,
5112 &pm_info, &num_cxn_del);
5113
5114 status = policy_mgr_get_pcl(psoc, PM_LL_LT_SAP_MODE, pcl->pcl_list,
5115 &pcl->pcl_len, pcl->weight_list,
5116 QDF_ARRAY_SIZE(pcl->weight_list),
5117 vdev_id);
5118
5119 /*
5120 * Get existing connection info before updating LL_LT_SAP freq list
5121 * This will help to avoid updation of SCC channel in LL_LT_SAP
5122 * freq list.
5123 */
5124 *connection_count = policy_mgr_get_connection_info(psoc, info);
5125
5126 /* Restore the connection entry */
5127 if (num_cxn_del > 0)
5128 policy_mgr_restore_deleted_conn_info(psoc, &pm_info,
5129 num_cxn_del);
5130
5131 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
5132
5133 return status;
5134 }
5135 #endif
5136