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