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