xref: /wlan-driver/qcacld-3.0/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
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_action.c
22  *
23  * WLAN Concurrenct Connection Management APIs
24  *
25  */
26 
27 /* Include files */
28 
29 #include "wlan_policy_mgr_api.h"
30 #include "wlan_policy_mgr_i.h"
31 #include "qdf_types.h"
32 #include "qdf_trace.h"
33 #include "wlan_objmgr_global_obj.h"
34 #include "qdf_platform.h"
35 #include "wlan_nan_api.h"
36 #include "nan_ucfg_api.h"
37 #include "wlan_mlme_api.h"
38 #include "sap_api.h"
39 #include "wlan_mlme_api.h"
40 #include "wlan_mlme_ucfg_api.h"
41 #include "target_if.h"
42 #include "wlan_cm_api.h"
43 #include "wlan_mlo_link_force.h"
44 #include "wlan_mlo_mgr_sta.h"
45 #include "wlan_mlo_mgr_link_switch.h"
46 #include "wlan_psoc_mlme_api.h"
47 #include "wlan_policy_mgr_ll_sap.h"
48 
49 enum policy_mgr_conc_next_action (*policy_mgr_get_current_pref_hw_mode_ptr)
50 	(struct wlan_objmgr_psoc *psoc);
51 
52 #define HW_MODE_DUMP_MAX_LEN 100
53 void
policy_mgr_dump_freq_range_n_vdev_map(uint32_t num_vdev_mac_entries,struct policy_mgr_vdev_mac_map * vdev_mac_map,uint32_t num_mac_freq,struct policy_mgr_pdev_mac_freq_map * mac_freq_range)54 policy_mgr_dump_freq_range_n_vdev_map(uint32_t num_vdev_mac_entries,
55 			struct policy_mgr_vdev_mac_map *vdev_mac_map,
56 			uint32_t num_mac_freq,
57 			struct policy_mgr_pdev_mac_freq_map *mac_freq_range)
58 {
59 	char log_str[HW_MODE_DUMP_MAX_LEN] = {0};
60 	uint32_t str_len = HW_MODE_DUMP_MAX_LEN;
61 	uint32_t len = 0;
62 	uint32_t i;
63 
64 	if (mac_freq_range) {
65 		for (i = 0, len = 0; i < num_mac_freq; i++)
66 			len += qdf_scnprintf(log_str + len, str_len - len,
67 					    "mac %d: %d => %d ",
68 					    mac_freq_range[i].mac_id,
69 					    mac_freq_range[i].start_freq,
70 					    mac_freq_range[i].end_freq);
71 		if (num_mac_freq)
72 			policymgr_nofl_debug("Freq range:: %s", log_str);
73 	}
74 
75 	if (!vdev_mac_map || !num_vdev_mac_entries)
76 		return;
77 
78 	for (i = 0, len = 0; i < num_vdev_mac_entries; i++)
79 		len += qdf_scnprintf(log_str + len, str_len - len,
80 				     "vdev %d -> mac %d ",
81 				     vdev_mac_map[i].vdev_id,
82 				     vdev_mac_map[i].mac_id);
83 	policymgr_nofl_debug("Vdev Map:: %s", log_str);
84 }
85 
policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index,uint32_t new_hw_mode_index,uint32_t num_vdev_mac_entries,struct policy_mgr_vdev_mac_map * vdev_mac_map,uint32_t num_mac_freq,struct policy_mgr_pdev_mac_freq_map * mac_freq_range,struct wlan_objmgr_psoc * context)86 void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index,
87 			uint32_t new_hw_mode_index,
88 			uint32_t num_vdev_mac_entries,
89 			struct policy_mgr_vdev_mac_map *vdev_mac_map,
90 			uint32_t num_mac_freq,
91 			struct policy_mgr_pdev_mac_freq_map *mac_freq_range,
92 			struct wlan_objmgr_psoc *context)
93 {
94 	QDF_STATUS status;
95 	struct policy_mgr_hw_mode_params hw_mode;
96 	struct policy_mgr_psoc_priv_obj *pm_ctx;
97 
98 	pm_ctx = policy_mgr_get_context(context);
99 	if (!pm_ctx) {
100 		policy_mgr_err("Invalid context");
101 		return;
102 	}
103 
104 	if (!vdev_mac_map) {
105 		policy_mgr_err("vdev_mac_map is NULL");
106 		return;
107 	}
108 
109 	status = policy_mgr_get_hw_mode_from_idx(context, new_hw_mode_index,
110 						 &hw_mode);
111 	if (QDF_IS_STATUS_ERROR(status)) {
112 		policy_mgr_err("Get HW mode for index %d reason: %d",
113 			       new_hw_mode_index, status);
114 		return;
115 	}
116 
117 	policy_mgr_debug("HW mode: old %d new %d, DBS %d Agile %d SBS %d, MAC0:: SS:Tx %d Rx %d, BW %d band %d, MAC1:: SS:Tx %d Rx %d, BW %d",
118 			 old_hw_mode_index, new_hw_mode_index, hw_mode.dbs_cap,
119 			 hw_mode.agile_dfs_cap, hw_mode.sbs_cap,
120 			 hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss,
121 			 hw_mode.mac0_bw, hw_mode.mac0_band_cap,
122 			 hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss,
123 			 hw_mode.mac1_bw);
124 	policy_mgr_dump_freq_range_n_vdev_map(num_vdev_mac_entries,
125 					      vdev_mac_map, num_mac_freq,
126 					      mac_freq_range);
127 
128 	/* update pm_conc_connection_list */
129 	policy_mgr_update_hw_mode_conn_info(context, num_vdev_mac_entries,
130 					    vdev_mac_map, hw_mode,
131 					    num_mac_freq, mac_freq_range);
132 
133 	if (pm_ctx->mode_change_cb)
134 		pm_ctx->mode_change_cb();
135 
136 	return;
137 }
138 
policy_mgr_check_n_start_opportunistic_timer(struct wlan_objmgr_psoc * psoc)139 QDF_STATUS policy_mgr_check_n_start_opportunistic_timer(
140 		struct wlan_objmgr_psoc *psoc)
141 {
142 	struct policy_mgr_psoc_priv_obj *pm_ctx;
143 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
144 	enum policy_mgr_conn_update_reason reason =
145 				POLICY_MGR_UPDATE_REASON_TIMER_START;
146 
147 	pm_ctx = policy_mgr_get_context(psoc);
148 	if (!pm_ctx) {
149 		policy_mgr_err("PM ctx not valid. Oppurtunistic timer cannot start");
150 		return QDF_STATUS_E_FAILURE;
151 	}
152 	if (policy_mgr_need_opportunistic_upgrade(psoc, &reason)) {
153 	/* let's start the timer */
154 	qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
155 	status = qdf_mc_timer_start(
156 				&pm_ctx->dbs_opportunistic_timer,
157 				DBS_OPPORTUNISTIC_TIME * 1000);
158 	if (!QDF_IS_STATUS_SUCCESS(status))
159 		policy_mgr_err("Failed to start dbs opportunistic timer");
160 	}
161 	return status;
162 }
163 
policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc * psoc,uint32_t session_id,enum hw_mode_ss_config mac0_ss,enum hw_mode_bandwidth mac0_bw,enum hw_mode_ss_config mac1_ss,enum hw_mode_bandwidth mac1_bw,enum hw_mode_mac_band_cap mac0_band_cap,enum hw_mode_dbs_capab dbs,enum hw_mode_agile_dfs_capab dfs,enum hw_mode_sbs_capab sbs,enum policy_mgr_conn_update_reason reason,uint8_t next_action,enum policy_mgr_conc_next_action action,uint32_t request_id)164 QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc,
165 		uint32_t session_id,
166 		enum hw_mode_ss_config mac0_ss,
167 		enum hw_mode_bandwidth mac0_bw,
168 		enum hw_mode_ss_config mac1_ss,
169 		enum hw_mode_bandwidth mac1_bw,
170 		enum hw_mode_mac_band_cap mac0_band_cap,
171 		enum hw_mode_dbs_capab dbs,
172 		enum hw_mode_agile_dfs_capab dfs,
173 		enum hw_mode_sbs_capab sbs,
174 		enum policy_mgr_conn_update_reason reason,
175 		uint8_t next_action, enum policy_mgr_conc_next_action action,
176 		uint32_t request_id)
177 {
178 	int8_t hw_mode_index;
179 	struct policy_mgr_hw_mode msg;
180 	QDF_STATUS status;
181 	struct policy_mgr_psoc_priv_obj *pm_ctx;
182 
183 	pm_ctx = policy_mgr_get_context(psoc);
184 	if (!pm_ctx) {
185 		policy_mgr_err("Invalid context");
186 		return QDF_STATUS_E_FAILURE;
187 	}
188 
189 	if (!pm_ctx->sme_cbacks.sme_pdev_set_hw_mode) {
190 		policy_mgr_debug("NOT supported");
191 		return QDF_STATUS_E_NOSUPPORT;
192 	}
193 
194 	/*
195 	 * if HW is not capable of doing 2x2 or ini config disabled 2x2, don't
196 	 * allow to request FW for 2x2
197 	 */
198 	if ((HW_MODE_SS_2x2 == mac0_ss) && (!pm_ctx->user_cfg.enable2x2)) {
199 		policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac0");
200 		mac0_ss = HW_MODE_SS_1x1;
201 	}
202 	if ((HW_MODE_SS_2x2 == mac1_ss) && (!pm_ctx->user_cfg.enable2x2)) {
203 		policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac1");
204 		mac1_ss = HW_MODE_SS_1x1;
205 	}
206 
207 	hw_mode_index = policy_mgr_get_hw_mode_idx_from_dbs_hw_list(psoc,
208 			mac0_ss, mac0_bw, mac1_ss, mac1_bw, mac0_band_cap,
209 			dbs, dfs, sbs);
210 	if (hw_mode_index < 0) {
211 		policy_mgr_err("Invalid HW mode index obtained");
212 		return QDF_STATUS_E_FAILURE;
213 	}
214 
215 	/* Don't send WMI_PDEV_SET_HW_MODE_CMDID to FW if existing SAP / GO is
216 	 * in CAC-in-progress state. Host is blocking this command as FW is
217 	 * having design limitation and FW don't expect this command when CAC
218 	 * is in progress state.
219 	 */
220 	if (pm_ctx->hdd_cbacks.hdd_is_cac_in_progress &&
221 	    pm_ctx->hdd_cbacks.hdd_is_cac_in_progress() &&
222 	    !policy_mgr_is_hw_dbs_2x2_capable(psoc)) {
223 		policy_mgr_err("SAP CAC_IN_PROGRESS state, drop WMI_PDEV_SET_HW_MODE_CMDID");
224 		return QDF_STATUS_E_FAILURE;
225 	}
226 
227 	msg.hw_mode_index = hw_mode_index;
228 	msg.set_hw_mode_cb = (void *)policy_mgr_pdev_set_hw_mode_cb;
229 	msg.reason = reason;
230 	msg.session_id = session_id;
231 	msg.next_action = next_action;
232 	msg.action = action;
233 	msg.context = psoc;
234 	msg.request_id = request_id;
235 
236 	policy_mgr_debug("set hw mode to sme: hw_mode_index: %d session:%d reason:%d action %d request_id %d",
237 			 msg.hw_mode_index, msg.session_id, msg.reason, action,
238 			 msg.request_id);
239 
240 	status = pm_ctx->sme_cbacks.sme_pdev_set_hw_mode(msg);
241 	if (status != QDF_STATUS_SUCCESS) {
242 		policy_mgr_err("Failed to set hw mode to SME");
243 		return status;
244 	}
245 
246 	return QDF_STATUS_SUCCESS;
247 }
248 
249 /**
250  * policy_mgr_get_sap_bw() - get current SAP bandwidth
251  * @psoc: Pointer to psoc
252  * @bw: Buffer to update the bandwidth
253  *
254  * Get the current SAP bandwidth. This API supports only single SAP
255  * concurrencies and doesn't cover multi SAP(e.g. SAP+SAP).
256  *
257  * return : QDF_STATUS
258  */
259 static QDF_STATUS
policy_mgr_get_sap_bw(struct wlan_objmgr_psoc * psoc,enum phy_ch_width * bw)260 policy_mgr_get_sap_bw(struct wlan_objmgr_psoc *psoc, enum phy_ch_width *bw)
261 {
262 	uint32_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
263 	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
264 	struct wlan_objmgr_vdev *vdev;
265 
266 	if (policy_mgr_get_mode_specific_conn_info(psoc, &freq_list[0],
267 						   &vdev_id_list[0],
268 						   PM_SAP_MODE) != 1 ||
269 	    !WLAN_REG_IS_6GHZ_CHAN_FREQ(freq_list[0]))
270 		return QDF_STATUS_E_NOSUPPORT;
271 
272 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id_list[0],
273 						    WLAN_POLICY_MGR_ID);
274 	if (!vdev) {
275 		policy_mgr_err("vdev %d is NULL", vdev_id_list[0]);
276 		return QDF_STATUS_E_INVAL;
277 	}
278 
279 	*bw = wlan_mlme_get_ap_oper_ch_width(vdev);
280 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
281 
282 	return QDF_STATUS_SUCCESS;
283 }
284 
285 /**
286  * policy_mgr_get_sap_ch_width_update_action() - get SAP ch_width update action
287  * @psoc: Pointer to psoc
288  * @vdev_id: Vdev id of the caller
289  * @ch_freq: channel frequency of new connection
290  * @next_action: next action to happen in order to update bandwidth
291  * @reason: Bandwidth upgrade/downgrade reason
292  *
293  * Check if current operating SAP needs a downgrade to 160MHz or an upgrade
294  * to 320MHz based on the new connection.
295  *
296  * return : None
297  */
298 static void
policy_mgr_get_sap_ch_width_update_action(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,qdf_freq_t ch_freq,enum policy_mgr_conc_next_action * next_action,enum policy_mgr_conn_update_reason * reason)299 policy_mgr_get_sap_ch_width_update_action(struct wlan_objmgr_psoc *psoc,
300 				uint8_t vdev_id, qdf_freq_t ch_freq,
301 				enum policy_mgr_conc_next_action *next_action,
302 				enum policy_mgr_conn_update_reason *reason)
303 {
304 	enum phy_ch_width cur_bw;
305 	qdf_freq_t freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
306 	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
307 	bool eht_capab = false;
308 
309 	/*
310 	 * Stop any running opportunistic timer as it will be started after
311 	 * decision if required.
312 	 */
313 	policy_mgr_stop_opportunistic_timer(psoc);
314 	if (QDF_IS_STATUS_ERROR(wlan_psoc_mlme_get_11be_capab(psoc,
315 							      &eht_capab)) ||
316 	    !eht_capab ||
317 	    QDF_IS_STATUS_ERROR(policy_mgr_get_sap_bw(psoc, &cur_bw)) ||
318 	    cur_bw < CH_WIDTH_160MHZ)
319 		return;
320 
321 	policy_mgr_get_mode_specific_conn_info(psoc, &freq_list[0],
322 					       &vdev_id_list[0], PM_SAP_MODE);
323 	if (cur_bw == CH_WIDTH_320MHZ && ch_freq &&
324 	    policy_mgr_is_conn_lead_to_dbs_sbs(psoc, vdev_id, ch_freq))
325 		*next_action = PM_DOWNGRADE_BW;
326 	else if (cur_bw == CH_WIDTH_160MHZ &&
327 		 !ch_freq &&
328 		 !policy_mgr_is_conn_lead_to_dbs_sbs(psoc,
329 					vdev_id_list[0], freq_list[0]) &&
330 		 (reason &&
331 		  (*reason == POLICY_MGR_UPDATE_REASON_TIMER_START ||
332 		   *reason == POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC)))
333 		*next_action = PM_UPGRADE_BW;
334 }
335 
policy_mgr_need_opportunistic_upgrade(struct wlan_objmgr_psoc * psoc,enum policy_mgr_conn_update_reason * reason)336 enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade(
337 		struct wlan_objmgr_psoc *psoc,
338 		enum policy_mgr_conn_update_reason *reason)
339 {
340 	uint32_t conn_index;
341 	enum policy_mgr_conc_next_action upgrade = PM_NOP;
342 	enum policy_mgr_conc_next_action preferred_dbs_action;
343 	uint8_t mac = 0;
344 	struct policy_mgr_hw_mode_params hw_mode;
345 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
346 	struct policy_mgr_psoc_priv_obj *pm_ctx;
347 
348 	if (policy_mgr_is_hwmode_offload_enabled(psoc)) {
349 		policy_mgr_get_sap_ch_width_update_action(psoc,
350 							  WLAN_INVALID_VDEV_ID,
351 							  0, &upgrade,
352 							  reason);
353 		return upgrade;
354 	}
355 
356 	pm_ctx = policy_mgr_get_context(psoc);
357 	if (!pm_ctx) {
358 		policy_mgr_err("Invalid Context");
359 		goto exit;
360 	}
361 
362 	if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
363 		policy_mgr_rl_debug("driver isn't dbs capable, no further action needed");
364 		goto exit;
365 	}
366 
367 	status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
368 	if (!QDF_IS_STATUS_SUCCESS(status)) {
369 		policy_mgr_err("policy_mgr_get_current_hw_mode failed");
370 		goto exit;
371 	}
372 	if (!hw_mode.dbs_cap) {
373 		policy_mgr_debug("current HW mode is non-DBS capable");
374 		goto exit;
375 	}
376 
377 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
378 	/* Are both mac's still in use */
379 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
380 		conn_index++) {
381 		policy_mgr_debug("index:%d mac:%d in_use:%d chan:%d org_nss:%d",
382 			conn_index,
383 			pm_conc_connection_list[conn_index].mac,
384 			pm_conc_connection_list[conn_index].in_use,
385 			pm_conc_connection_list[conn_index].freq,
386 			pm_conc_connection_list[conn_index].original_nss);
387 		if ((pm_conc_connection_list[conn_index].mac == 0) &&
388 			pm_conc_connection_list[conn_index].in_use) {
389 			mac |= POLICY_MGR_MAC0;
390 			if (POLICY_MGR_MAC0_AND_MAC1 == mac) {
391 				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
392 				goto done;
393 			}
394 		} else if ((pm_conc_connection_list[conn_index].mac == 1) &&
395 			pm_conc_connection_list[conn_index].in_use) {
396 			mac |= POLICY_MGR_MAC1;
397 			if (policy_mgr_is_hw_dbs_required_for_band(
398 					psoc, HW_MODE_MAC_BAND_2G) &&
399 			    WLAN_REG_IS_24GHZ_CH_FREQ(
400 				pm_conc_connection_list[conn_index].freq)) {
401 				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
402 				policy_mgr_debug("2X2 DBS capable with 2.4 GHZ connection");
403 				goto done;
404 			}
405 			if (POLICY_MGR_MAC0_AND_MAC1 == mac) {
406 				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
407 				goto done;
408 			}
409 		}
410 	}
411 	/* Let's request for single MAC mode */
412 	upgrade = PM_SINGLE_MAC;
413 	if (reason)
414 		*reason = POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC;
415 	/* Is there any connection had an initial connection with 2x2 */
416 	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
417 		conn_index++) {
418 		if ((pm_conc_connection_list[conn_index].original_nss == 2) &&
419 			pm_conc_connection_list[conn_index].in_use) {
420 			upgrade = PM_SINGLE_MAC_UPGRADE;
421 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
422 			goto done;
423 		}
424 	}
425 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
426 
427 done:
428 	if (upgrade == PM_NOP && hw_mode.dbs_cap &&
429 	    policy_mgr_is_2x2_1x1_dbs_capable(psoc)) {
430 		preferred_dbs_action =
431 			policy_mgr_get_preferred_dbs_action_table(
432 					psoc, INVALID_VDEV_ID, 0, 0);
433 		if (hw_mode.action_type == PM_DBS1 &&
434 		    preferred_dbs_action == PM_DBS2) {
435 			upgrade = PM_DBS2_DOWNGRADE;
436 			if (reason)
437 				*reason =
438 				POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE;
439 		} else if (hw_mode.action_type == PM_DBS2 &&
440 		    preferred_dbs_action == PM_DBS1) {
441 			upgrade = PM_DBS1_DOWNGRADE;
442 			if (reason)
443 				*reason =
444 				POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE;
445 		}
446 	}
447 exit:
448 	return upgrade;
449 }
450 
policy_mgr_update_connection_info(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id)451 QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc,
452 					uint32_t vdev_id)
453 {
454 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
455 	uint32_t conn_index = 0, ch_freq, cur_freq;
456 	bool found = false;
457 	struct policy_mgr_vdev_entry_info conn_table_entry;
458 	enum policy_mgr_chain_mode chain_mask = POLICY_MGR_ONE_ONE;
459 	uint8_t nss_2g, nss_5g;
460 	enum policy_mgr_con_mode mode;
461 	uint32_t nss = 0;
462 	struct policy_mgr_psoc_priv_obj *pm_ctx;
463 
464 	pm_ctx = policy_mgr_get_context(psoc);
465 	if (!pm_ctx) {
466 		policy_mgr_err("Invalid Context");
467 		return status;
468 	}
469 
470 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
471 	while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
472 		if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
473 			/* debug msg */
474 			found = true;
475 			break;
476 		}
477 		conn_index++;
478 	}
479 
480 	if (!found) {
481 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
482 		/* err msg */
483 		policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list",
484 			vdev_id);
485 		return QDF_STATUS_NOT_INITIALIZED;
486 	}
487 	if (pm_ctx->wma_cbacks.wma_get_connection_info) {
488 		status = pm_ctx->wma_cbacks.wma_get_connection_info(
489 				vdev_id, &conn_table_entry);
490 		if (QDF_STATUS_SUCCESS != status) {
491 			qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
492 			policy_mgr_err("can't find vdev_id %d in connection table",
493 			vdev_id);
494 			return status;
495 		}
496 	} else {
497 		qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
498 		policy_mgr_err("wma_get_connection_info is NULL");
499 		return QDF_STATUS_E_FAILURE;
500 	}
501 
502 	cur_freq = pm_conc_connection_list[conn_index].freq;
503 
504 	mode = policy_mgr_qdf_opmode_to_pm_con_mode(
505 					psoc,
506 					wlan_get_opmode_from_vdev_id(
507 								pm_ctx->pdev,
508 								vdev_id),
509 					vdev_id);
510 
511 	ch_freq = conn_table_entry.mhz;
512 	status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g);
513 	if (QDF_IS_STATUS_SUCCESS(status)) {
514 		if ((WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) && nss_2g > 1) ||
515 		    (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && nss_5g > 1))
516 			chain_mask = POLICY_MGR_TWO_TWO;
517 		else
518 			chain_mask = POLICY_MGR_ONE_ONE;
519 		nss = (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) ? nss_2g : nss_5g;
520 	} else {
521 		policy_mgr_err("Error in getting nss");
522 	}
523 
524 	policy_mgr_debug("update PM connection table for vdev:%d", vdev_id);
525 
526 	/* add the entry */
527 	policy_mgr_update_conc_list(
528 			psoc, conn_index, mode, ch_freq,
529 			policy_mgr_get_bw(conn_table_entry.chan_width),
530 			conn_table_entry.mac_id, chain_mask,
531 			nss, vdev_id, true, true, conn_table_entry.ch_flagext);
532 	policy_mgr_dump_current_concurrency(psoc);
533 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
534 
535 	/* do we need to change the HW mode */
536 	policy_mgr_check_n_start_opportunistic_timer(psoc);
537 
538 	if (policy_mgr_is_conc_sap_present_on_sta_freq(psoc, mode, cur_freq) &&
539 	    policy_mgr_update_indoor_concurrency(psoc, vdev_id, 0,
540 						 SWITCH_WITH_CONCURRENCY))
541 		wlan_reg_recompute_current_chan_list(psoc, pm_ctx->pdev);
542 	else if (policy_mgr_update_indoor_concurrency(psoc, vdev_id, cur_freq,
543 						SWITCH_WITHOUT_CONCURRENCY))
544 		wlan_reg_recompute_current_chan_list(psoc, pm_ctx->pdev);
545 	else if (wlan_reg_get_keep_6ghz_sta_cli_connection(pm_ctx->pdev) &&
546 		 (mode == PM_STA_MODE || mode == PM_P2P_CLIENT_MODE))
547 		wlan_reg_recompute_current_chan_list(psoc, pm_ctx->pdev);
548 
549 	ml_nlink_conn_change_notify(
550 		psoc, vdev_id, ml_nlink_connection_updated_evt, NULL);
551 
552 	return QDF_STATUS_SUCCESS;
553 }
554 
policy_mgr_update_and_wait_for_connection_update(struct wlan_objmgr_psoc * psoc,uint8_t session_id,uint32_t ch_freq,enum policy_mgr_conn_update_reason reason)555 QDF_STATUS policy_mgr_update_and_wait_for_connection_update(
556 		struct wlan_objmgr_psoc *psoc,
557 		uint8_t session_id,
558 		uint32_t ch_freq,
559 		enum policy_mgr_conn_update_reason reason)
560 {
561 	QDF_STATUS status;
562 
563 	policy_mgr_debug("session:%d ch_freq:%d reason:%d",
564 			 session_id, ch_freq, reason);
565 
566 	status = policy_mgr_reset_connection_update(psoc);
567 	if (QDF_IS_STATUS_ERROR(status))
568 		policy_mgr_err("clearing event failed");
569 
570 	status = policy_mgr_current_connections_update(
571 			psoc, session_id, ch_freq, reason,
572 			POLICY_MGR_DEF_REQ_ID);
573 	if (QDF_STATUS_E_FAILURE == status) {
574 		policy_mgr_err("connections update failed");
575 		return QDF_STATUS_E_FAILURE;
576 	}
577 
578 	/* Wait only when status is success */
579 	if (QDF_IS_STATUS_SUCCESS(status)) {
580 		status = policy_mgr_wait_for_connection_update(psoc);
581 		if (QDF_IS_STATUS_ERROR(status)) {
582 			policy_mgr_err("qdf wait for event failed");
583 			return QDF_STATUS_E_FAILURE;
584 		}
585 	}
586 
587 	return QDF_STATUS_SUCCESS;
588 }
589 
policy_mgr_is_dbs_allowed_for_concurrency(struct wlan_objmgr_psoc * psoc,enum QDF_OPMODE new_conn_mode)590 bool policy_mgr_is_dbs_allowed_for_concurrency(
591 		struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE new_conn_mode)
592 {
593 	struct policy_mgr_psoc_priv_obj *pm_ctx;
594 	uint32_t count, dbs_for_sta_sta, dbs_for_sta_p2p;
595 	bool ret = true;
596 	uint32_t ch_sel_plcy;
597 
598 	pm_ctx = policy_mgr_get_context(psoc);
599 	if (!pm_ctx) {
600 		policy_mgr_err("Invalid context");
601 		return ret;
602 	}
603 
604 	count = policy_mgr_get_connection_count(psoc);
605 
606 	if (count != 1 || new_conn_mode == QDF_MAX_NO_OF_MODE)
607 		return ret;
608 
609 	ch_sel_plcy = pm_ctx->cfg.chnl_select_plcy;
610 	dbs_for_sta_sta = PM_CHANNEL_SELECT_LOGIC_STA_STA_GET(ch_sel_plcy);
611 	dbs_for_sta_p2p = PM_CHANNEL_SELECT_LOGIC_STA_P2P_GET(ch_sel_plcy);
612 
613 	switch (pm_conc_connection_list[0].mode) {
614 	case PM_STA_MODE:
615 		switch (new_conn_mode) {
616 		case QDF_STA_MODE:
617 			if (!dbs_for_sta_sta)
618 				return false;
619 			break;
620 		case QDF_P2P_DEVICE_MODE:
621 		case QDF_P2P_CLIENT_MODE:
622 		case QDF_P2P_GO_MODE:
623 			if (!dbs_for_sta_p2p)
624 				return false;
625 			break;
626 		default:
627 			break;
628 		}
629 		break;
630 	case PM_P2P_CLIENT_MODE:
631 	case PM_P2P_GO_MODE:
632 		switch (new_conn_mode) {
633 		case QDF_STA_MODE:
634 			if (!dbs_for_sta_p2p)
635 				return false;
636 			break;
637 		default:
638 			break;
639 		}
640 		break;
641 	case PM_NAN_DISC_MODE:
642 		switch (new_conn_mode) {
643 		case QDF_STA_MODE:
644 		case QDF_SAP_MODE:
645 		case QDF_NDI_MODE:
646 			return true;
647 		default:
648 			return false;
649 		}
650 		break;
651 	default:
652 		break;
653 	}
654 
655 	return ret;
656 }
657 
policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc * psoc,uint32_t ch_freq)658 bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc,
659 				     uint32_t ch_freq)
660 {
661 	uint8_t i;
662 	struct policy_mgr_psoc_priv_obj *pm_ctx;
663 
664 	pm_ctx = policy_mgr_get_context(psoc);
665 	if (!pm_ctx) {
666 		policy_mgr_err("Invalid Context");
667 		return false;
668 	}
669 
670 	/*
671 	 * check given channel freq against already existing connections'
672 	 * channel freqs. if they differ then channels are in different bands
673 	 */
674 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
675 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
676 		if (pm_conc_connection_list[i].in_use)
677 			if (!WLAN_REG_IS_SAME_BAND_FREQS(
678 			    ch_freq, pm_conc_connection_list[i].freq)) {
679 				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
680 				policy_mgr_debug("channel is in diff band");
681 				return true;
682 			}
683 	}
684 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
685 
686 	return false;
687 }
688 
policy_mgr_is_hwmode_set_for_given_chnl(struct wlan_objmgr_psoc * psoc,uint32_t ch_freq)689 bool policy_mgr_is_hwmode_set_for_given_chnl(struct wlan_objmgr_psoc *psoc,
690 					     uint32_t ch_freq)
691 {
692 	enum policy_mgr_band band;
693 	bool is_hwmode_dbs, dbs_required_for_2g;
694 
695 	if (policy_mgr_is_hwmode_offload_enabled(psoc))
696 		return true;
697 
698 	if (policy_mgr_is_hw_dbs_capable(psoc) == false)
699 		return true;
700 
701 	if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))
702 		band = POLICY_MGR_BAND_24;
703 	else
704 		band = POLICY_MGR_BAND_5;
705 
706 	is_hwmode_dbs = policy_mgr_is_current_hwmode_dbs(psoc);
707 	dbs_required_for_2g = policy_mgr_is_hw_dbs_required_for_band(
708 					psoc, HW_MODE_MAC_BAND_2G);
709 	/*
710 	 * If HW supports 2x2 chains in DBS HW mode and if DBS HW mode is not
711 	 * yet set then this is the right time to block the connection.
712 	 */
713 	if (band == POLICY_MGR_BAND_24 && dbs_required_for_2g &&
714 	    !is_hwmode_dbs) {
715 		policy_mgr_err("HW mode is not yet in DBS!!!!!");
716 		return false;
717 	}
718 
719 	return true;
720 }
721 
722 /**
723  * policy_mgr_pri_id_to_con_mode() - convert policy_mgr_pri_id to
724  * policy_mgr_con_mode
725  * @pri_id: policy_mgr_pri_id
726  *
727  * The help function converts policy_mgr_pri_id type to  policy_mgr_con_mode
728  * type.
729  *
730  * Return: policy_mgr_con_mode type.
731  */
732 static
policy_mgr_pri_id_to_con_mode(enum policy_mgr_pri_id pri_id)733 enum policy_mgr_con_mode policy_mgr_pri_id_to_con_mode(
734 	enum policy_mgr_pri_id pri_id)
735 {
736 	switch (pri_id) {
737 	case PM_STA_PRI_ID:
738 		return PM_STA_MODE;
739 	case PM_SAP_PRI_ID:
740 		return PM_SAP_MODE;
741 	case PM_P2P_GO_PRI_ID:
742 		return PM_P2P_GO_MODE;
743 	case PM_P2P_CLI_PRI_ID:
744 		return PM_P2P_CLIENT_MODE;
745 	default:
746 		return PM_MAX_NUM_OF_MODE;
747 	}
748 }
749 
750 enum policy_mgr_conc_next_action
policy_mgr_get_preferred_dbs_action_table(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id,uint32_t ch_freq,enum policy_mgr_conn_update_reason reason)751 policy_mgr_get_preferred_dbs_action_table(
752 	struct wlan_objmgr_psoc *psoc,
753 	uint32_t vdev_id,
754 	uint32_t ch_freq,
755 	enum policy_mgr_conn_update_reason reason)
756 {
757 	struct policy_mgr_psoc_priv_obj *pm_ctx;
758 	enum policy_mgr_con_mode pri_conn_mode = PM_MAX_NUM_OF_MODE;
759 	enum policy_mgr_con_mode new_conn_mode = PM_MAX_NUM_OF_MODE;
760 	enum QDF_OPMODE new_conn_op_mode = QDF_MAX_NO_OF_MODE;
761 	bool band_pref_5g = true;
762 	bool vdev_priority_enabled = false;
763 	bool dbs_2x2_5g_1x1_2g_supported;
764 	bool dbs_2x2_2g_1x1_5g_supported;
765 	uint32_t vdev_pri_list, vdev_pri_id;
766 	uint32_t ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
767 	uint8_t vdev_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
768 	uint32_t vdev_count = 0;
769 	uint32_t i;
770 	bool found;
771 
772 	pm_ctx = policy_mgr_get_context(psoc);
773 	if (!pm_ctx) {
774 		policy_mgr_err("Invalid context");
775 		return PM_NOP;
776 	}
777 	dbs_2x2_5g_1x1_2g_supported =
778 		policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc);
779 	dbs_2x2_2g_1x1_5g_supported =
780 		policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc);
781 	policy_mgr_debug("target support DBS1 %d DBS2 %d",
782 			 dbs_2x2_5g_1x1_2g_supported,
783 			 dbs_2x2_2g_1x1_5g_supported);
784 	/*
785 	 * If both DBS1 and DBS2 not supported, this should be Legacy Single
786 	 * DBS mode HW. The policy_mgr_psoc_enable has setup the correct
787 	 * action tables.
788 	 */
789 	if (!dbs_2x2_5g_1x1_2g_supported && !dbs_2x2_2g_1x1_5g_supported)
790 		return PM_NOP;
791 	if (!dbs_2x2_5g_1x1_2g_supported) {
792 		band_pref_5g = false;
793 		policy_mgr_debug("target only supports DBS2!");
794 		goto DONE;
795 	}
796 	if (!dbs_2x2_2g_1x1_5g_supported) {
797 		policy_mgr_debug("target only supports DBS1!");
798 		goto DONE;
799 	}
800 	if (PM_GET_BAND_PREFERRED(pm_ctx->cfg.dbs_selection_plcy) == 1)
801 		band_pref_5g = false;
802 
803 	if (PM_GET_VDEV_PRIORITY_ENABLED(
804 	    pm_ctx->cfg.dbs_selection_plcy) == 1 &&
805 	    pm_ctx->cfg.vdev_priority_list)
806 		vdev_priority_enabled = true;
807 
808 	if (!vdev_priority_enabled)
809 		goto DONE;
810 
811 	if (vdev_id != INVALID_VDEV_ID && ch_freq) {
812 		if (pm_ctx->hdd_cbacks.hdd_get_device_mode)
813 			new_conn_op_mode = pm_ctx->hdd_cbacks.
814 					hdd_get_device_mode(vdev_id);
815 
816 		new_conn_mode =
817 			policy_mgr_qdf_opmode_to_pm_con_mode(psoc,
818 							     new_conn_op_mode,
819 							     vdev_id);
820 		if (new_conn_mode == PM_MAX_NUM_OF_MODE)
821 			policy_mgr_debug("new vdev %d op_mode %d freq %d reason %d: not prioritized",
822 					 vdev_id, new_conn_op_mode,
823 					 ch_freq, reason);
824 		else
825 			policy_mgr_debug("new vdev %d op_mode %d freq %d : reason %d",
826 					 vdev_id, new_conn_op_mode, ch_freq,
827 					 reason);
828 	}
829 	vdev_pri_list = pm_ctx->cfg.vdev_priority_list;
830 	while (vdev_pri_list) {
831 		vdev_pri_id = vdev_pri_list & 0xF;
832 		pri_conn_mode = policy_mgr_pri_id_to_con_mode(vdev_pri_id);
833 		if (pri_conn_mode == PM_MAX_NUM_OF_MODE) {
834 			policy_mgr_debug("vdev_pri_id %d prioritization not supported",
835 					 vdev_pri_id);
836 			goto NEXT;
837 		}
838 		vdev_count = policy_mgr_get_mode_specific_conn_info(
839 				psoc, ch_freq_list, vdev_list, pri_conn_mode);
840 		/**
841 		 * Take care of duplication case, the vdev id may
842 		 * exist in the conn list already with old chan.
843 		 * Replace with new chan before make decision.
844 		 */
845 		found = false;
846 		for (i = 0; i < vdev_count; i++) {
847 			policy_mgr_debug("[%d] vdev %d chan %d conn_mode %d",
848 					 i, vdev_list[i], ch_freq_list[i],
849 					 pri_conn_mode);
850 
851 			if (new_conn_mode == pri_conn_mode &&
852 			    vdev_list[i] == vdev_id) {
853 				ch_freq_list[i] = ch_freq;
854 				found = true;
855 			}
856 		}
857 		/**
858 		 * The new coming vdev should be added to the list to
859 		 * make decision if it is prioritized.
860 		 */
861 		if (!found && new_conn_mode == pri_conn_mode) {
862 			ch_freq_list[vdev_count] = ch_freq;
863 			vdev_list[vdev_count++] = vdev_id;
864 		}
865 		/**
866 		 * if more than one vdev has same priority, keep "band_pref_5g"
867 		 * value as default band preference setting.
868 		 */
869 		if (vdev_count > 1)
870 			break;
871 		/**
872 		 * select the only active vdev (or new coming vdev) chan as
873 		 * preferred band.
874 		 */
875 		if (vdev_count > 0) {
876 			band_pref_5g =
877 				WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq_list[0]);
878 			break;
879 		}
880 NEXT:
881 		vdev_pri_list >>= 4;
882 	}
883 DONE:
884 	policy_mgr_debug("band_pref_5g %d", band_pref_5g);
885 	if (band_pref_5g)
886 		return PM_DBS1;
887 	else
888 		return PM_DBS2;
889 }
890 
891 /**
892  * policy_mgr_get_second_conn_action_table() - get second conn action table
893  * @psoc: Pointer to psoc
894  * @vdev_id: vdev Id
895  * @ch_freq: channel frequency of vdev.
896  * @reason: reason of request
897  *
898  * Get the action table based on current HW Caps and INI user preference.
899  * This function will be called by policy_mgr_current_connections_update during
900  * DBS action decision.
901  *
902  * return : action table address
903  */
904 static policy_mgr_next_action_two_connection_table_type *
policy_mgr_get_second_conn_action_table(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id,uint32_t ch_freq,enum policy_mgr_conn_update_reason reason)905 policy_mgr_get_second_conn_action_table(
906 	struct wlan_objmgr_psoc *psoc,
907 	uint32_t vdev_id,
908 	uint32_t ch_freq,
909 	enum policy_mgr_conn_update_reason reason)
910 {
911 	enum policy_mgr_conc_next_action preferred_action;
912 
913 	if (!policy_mgr_is_2x2_1x1_dbs_capable(psoc))
914 		return next_action_two_connection_table;
915 
916 	preferred_action = policy_mgr_get_preferred_dbs_action_table(
917 				psoc, vdev_id, ch_freq, reason);
918 	switch (preferred_action) {
919 	case PM_DBS2:
920 		return next_action_two_connection_2x2_2g_1x1_5g_table;
921 	default:
922 		return next_action_two_connection_table;
923 	}
924 }
925 
926 /**
927  * policy_mgr_get_third_conn_action_table() - get third connection action table
928  * @psoc: Pointer to psoc
929  * @vdev_id: vdev Id
930  * @ch_freq: channel frequency of vdev.
931  * @reason: reason of request
932  *
933  * Get the action table based on current HW Caps and INI user preference.
934  * This function will be called by policy_mgr_current_connections_update during
935  * DBS action decision.
936  *
937  * return : action table address
938  */
939 static policy_mgr_next_action_three_connection_table_type *
policy_mgr_get_third_conn_action_table(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id,uint32_t ch_freq,enum policy_mgr_conn_update_reason reason)940 policy_mgr_get_third_conn_action_table(
941 	struct wlan_objmgr_psoc *psoc,
942 	uint32_t vdev_id,
943 	uint32_t ch_freq,
944 	enum policy_mgr_conn_update_reason reason)
945 {
946 	enum policy_mgr_conc_next_action preferred_action;
947 
948 	if (!policy_mgr_is_2x2_1x1_dbs_capable(psoc))
949 		return next_action_three_connection_table;
950 
951 	preferred_action = policy_mgr_get_preferred_dbs_action_table(
952 				psoc, vdev_id, ch_freq, reason);
953 	switch (preferred_action) {
954 	case PM_DBS2:
955 		return next_action_three_connection_2x2_2g_1x1_5g_table;
956 	default:
957 		return next_action_three_connection_table;
958 	}
959 }
960 
961 bool
policy_mgr_is_conn_lead_to_dbs_sbs(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,qdf_freq_t freq)962 policy_mgr_is_conn_lead_to_dbs_sbs(struct wlan_objmgr_psoc *psoc,
963 				   uint8_t vdev_id, qdf_freq_t freq)
964 {
965 	struct connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
966 	uint32_t connection_count, i;
967 
968 	connection_count = policy_mgr_get_connection_info(psoc, info);
969 	for (i = 0; i < connection_count; i++) {
970 		/* Ignore the vdev id for which freq is passed */
971 		if (vdev_id == info[i].vdev_id)
972 			continue;
973 		if (!policy_mgr_2_freq_always_on_same_mac(psoc, freq,
974 							  info[i].ch_freq))
975 			return true;
976 	}
977 	return false;
978 }
979 
980 static QDF_STATUS
policy_mgr_get_next_action(struct wlan_objmgr_psoc * psoc,uint32_t session_id,uint32_t ch_freq,enum policy_mgr_conn_update_reason reason,enum policy_mgr_conc_next_action * next_action)981 policy_mgr_get_next_action(struct wlan_objmgr_psoc *psoc,
982 			   uint32_t session_id,
983 			   uint32_t ch_freq,
984 			   enum policy_mgr_conn_update_reason reason,
985 			   enum policy_mgr_conc_next_action *next_action)
986 {
987 	uint32_t num_connections = 0;
988 	enum policy_mgr_one_connection_mode second_index = 0;
989 	enum policy_mgr_two_connection_mode third_index = 0;
990 	policy_mgr_next_action_two_connection_table_type *second_conn_table;
991 	policy_mgr_next_action_three_connection_table_type *third_conn_table;
992 	enum policy_mgr_band band;
993 	struct policy_mgr_psoc_priv_obj *pm_ctx;
994 	enum QDF_OPMODE new_conn_mode = QDF_MAX_NO_OF_MODE;
995 
996 	if (!next_action) {
997 		policy_mgr_err("next_action is NULL");
998 		return QDF_STATUS_E_FAILURE;
999 	}
1000 
1001 	if (policy_mgr_is_hwmode_offload_enabled(psoc)) {
1002 		*next_action = PM_NOP;
1003 		policy_mgr_get_sap_ch_width_update_action(psoc, session_id,
1004 							  ch_freq,
1005 							  next_action, &reason);
1006 		return QDF_STATUS_SUCCESS;
1007 	}
1008 
1009 	pm_ctx = policy_mgr_get_context(psoc);
1010 	if (!pm_ctx) {
1011 		policy_mgr_err("Invalid context");
1012 		return QDF_STATUS_E_FAILURE;
1013 	}
1014 
1015 	if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))
1016 		band = POLICY_MGR_BAND_24;
1017 	else
1018 		band = POLICY_MGR_BAND_5;
1019 
1020 	num_connections = policy_mgr_get_connection_count(psoc);
1021 
1022 	policy_mgr_debug("num_connections=%d freq=%d",
1023 			 num_connections, ch_freq);
1024 
1025 	switch (num_connections) {
1026 	case 0:
1027 		if (band == POLICY_MGR_BAND_24)
1028 			if (policy_mgr_is_hw_dbs_required_for_band(
1029 					psoc, HW_MODE_MAC_BAND_2G))
1030 				*next_action = PM_DBS;
1031 			else
1032 				*next_action = PM_NOP;
1033 		else
1034 			*next_action = PM_NOP;
1035 		break;
1036 	case 1:
1037 		second_index =
1038 			policy_mgr_get_second_connection_pcl_table_index(psoc);
1039 		if (PM_MAX_ONE_CONNECTION_MODE == second_index) {
1040 			policy_mgr_err(
1041 			"couldn't find index for 2nd connection next action table");
1042 			return QDF_STATUS_E_FAILURE;
1043 		}
1044 		second_conn_table = policy_mgr_get_second_conn_action_table(
1045 			psoc, session_id, ch_freq, reason);
1046 		*next_action = (*second_conn_table)[second_index][band];
1047 		break;
1048 	case 2:
1049 		third_index =
1050 			policy_mgr_get_third_connection_pcl_table_index(psoc);
1051 		if (PM_MAX_TWO_CONNECTION_MODE == third_index) {
1052 			policy_mgr_err(
1053 			"couldn't find index for 3rd connection next action table");
1054 			return QDF_STATUS_E_FAILURE;
1055 		}
1056 		third_conn_table = policy_mgr_get_third_conn_action_table(
1057 			psoc, session_id, ch_freq, reason);
1058 		*next_action = (*third_conn_table)[third_index][band];
1059 		break;
1060 	default:
1061 		policy_mgr_err("unexpected num_connections value %d",
1062 			num_connections);
1063 		break;
1064 	}
1065 
1066 	/*
1067 	 * There is no adapter associated with NAN Discovery, hence skip the
1068 	 * HDD callback and fill separately.
1069 	 */
1070 	if (reason == POLICY_MGR_UPDATE_REASON_NAN_DISCOVERY)
1071 		new_conn_mode = QDF_NAN_DISC_MODE;
1072 	else if (pm_ctx->hdd_cbacks.hdd_get_device_mode)
1073 		new_conn_mode = pm_ctx->hdd_cbacks.
1074 					hdd_get_device_mode(session_id);
1075 
1076 	/*
1077 	 * Based on channel_select_logic_conc ini, hw mode is set
1078 	 * when second connection is about to come up that results
1079 	 * in STA+STA and STA+P2P concurrency.
1080 	 * 1) If MCC is set and if current hw mode is dbs, hw mode
1081 	 *  should be set to single mac for above concurrency.
1082 	 * 2) If MCC is set and if current hw mode is not dbs, hw
1083 	 *  mode change is not required.
1084 	 */
1085 	if (policy_mgr_is_current_hwmode_dbs(psoc) &&
1086 		!policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode))
1087 		*next_action = PM_SINGLE_MAC;
1088 	else if (!policy_mgr_is_current_hwmode_dbs(psoc) &&
1089 		!policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode))
1090 		*next_action = PM_NOP;
1091 
1092 	policy_mgr_debug("idx2=%d idx3=%d next_action=%d, band=%d reason=%d session_id=%d",
1093 			 second_index, third_index, *next_action, band,
1094 			 reason, session_id);
1095 
1096 	return QDF_STATUS_SUCCESS;
1097 }
1098 
1099 static bool
policy_mgr_is_hw_mode_change_required(struct wlan_objmgr_psoc * psoc,uint32_t ch_freq,uint8_t vdev_id)1100 policy_mgr_is_hw_mode_change_required(struct wlan_objmgr_psoc *psoc,
1101 				      uint32_t ch_freq, uint8_t vdev_id)
1102 {
1103 	if (policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G)) {
1104 		if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))
1105 			return true;
1106 	} else {
1107 		if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) &&
1108 		    policy_mgr_is_any_mode_active_on_band_along_with_session
1109 			(psoc, vdev_id, POLICY_MGR_BAND_5))
1110 			return true;
1111 
1112 		if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) &&
1113 		    policy_mgr_is_any_mode_active_on_band_along_with_session
1114 			(psoc, vdev_id, POLICY_MGR_BAND_24))
1115 			return true;
1116 	}
1117 
1118 	return false;
1119 }
1120 
1121 static bool
policy_mgr_is_ch_width_downgrade_required(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,struct scan_cache_entry * entry,qdf_list_t * scan_list)1122 policy_mgr_is_ch_width_downgrade_required(struct wlan_objmgr_psoc *psoc,
1123 					  uint8_t vdev_id,
1124 					  struct scan_cache_entry *entry,
1125 					  qdf_list_t *scan_list)
1126 
1127 {
1128 	if (policy_mgr_is_conn_lead_to_dbs_sbs(psoc, vdev_id,
1129 					       entry->channel.chan_freq) ||
1130 	    wlan_cm_bss_mlo_type(psoc, entry, scan_list))
1131 		return true;
1132 
1133 	return false;
1134 }
1135 
1136 static uint32_t
policy_mgr_check_for_hw_mode_change(struct wlan_objmgr_psoc * psoc,qdf_list_t * scan_list,uint8_t vdev_id)1137 policy_mgr_check_for_hw_mode_change(struct wlan_objmgr_psoc *psoc,
1138 				    qdf_list_t *scan_list, uint8_t vdev_id)
1139 {
1140 
1141 	struct scan_cache_node *scan_node = NULL;
1142 	qdf_list_node_t *cur_node = NULL, *next_node = NULL;
1143 	uint32_t ch_freq = 0;
1144 	struct scan_cache_entry *entry;
1145 	bool eht_capab =  false, check_sap_bw_downgrade = false;
1146 	enum phy_ch_width cur_bw = CH_WIDTH_INVALID;
1147 	struct wlan_objmgr_vdev *vdev;
1148 
1149 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
1150 						    WLAN_POLICY_MGR_ID);
1151 	if (!vdev)
1152 		goto end;
1153 
1154 	if (policy_mgr_is_hwmode_offload_enabled(psoc)) {
1155 		/*
1156 		 * Stop any running opportunistic timer as it will be started
1157 		 * after decision if required.
1158 		 */
1159 		policy_mgr_stop_opportunistic_timer(psoc);
1160 		wlan_psoc_mlme_get_11be_capab(psoc, &eht_capab);
1161 		if (eht_capab &&
1162 		    QDF_IS_STATUS_SUCCESS(policy_mgr_get_sap_bw(psoc,
1163 								&cur_bw)) &&
1164 						cur_bw == CH_WIDTH_320MHZ &&
1165 		    !mlo_mgr_is_link_switch_in_progress(vdev))
1166 			check_sap_bw_downgrade = true;
1167 		else
1168 			goto end;
1169 	}
1170 
1171 	if (!scan_list || !qdf_list_size(scan_list)) {
1172 		policy_mgr_debug("Scan list is NULL or No BSSIDs present");
1173 		goto end;
1174 	}
1175 
1176 	if (!policy_mgr_is_hw_dbs_capable(psoc)) {
1177 		policy_mgr_debug("Driver isn't DBS capable");
1178 		goto end;
1179 	}
1180 
1181 	if (check_sap_bw_downgrade)
1182 		goto ch_width_update;
1183 
1184 	if (!policy_mgr_is_dbs_allowed_for_concurrency(psoc, QDF_STA_MODE)) {
1185 		policy_mgr_debug("DBS not allowed for concurrency combo");
1186 		goto end;
1187 	}
1188 
1189 	if (!policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
1190 	    !policy_mgr_is_hw_dbs_required_for_band(psoc,
1191 						    HW_MODE_MAC_BAND_2G) &&
1192 	    !policy_mgr_get_connection_count(psoc)) {
1193 		policy_mgr_debug("1x1 DBS with no existing connection, HW mode change not required");
1194 		goto end;
1195 	}
1196 
1197 ch_width_update:
1198 	qdf_list_peek_front(scan_list, &cur_node);
1199 
1200 	while (cur_node) {
1201 		qdf_list_peek_next(scan_list, cur_node, &next_node);
1202 
1203 		scan_node = qdf_container_of(cur_node, struct scan_cache_node,
1204 					     node);
1205 		entry = scan_node->entry;
1206 		ch_freq = entry->channel.chan_freq;
1207 
1208 		if (policy_mgr_is_hw_mode_change_required(psoc, ch_freq,
1209 							  vdev_id) ||
1210 		    policy_mgr_is_ch_width_downgrade_required(psoc, vdev_id,
1211 							      entry,
1212 							      scan_list)) {
1213 			policy_mgr_debug("Scan list has BSS of freq %d hw mode/SAP ch_width:%d update required",
1214 					 ch_freq, cur_bw);
1215 			break;
1216 		}
1217 
1218 		ch_freq = 0;
1219 		cur_node = next_node;
1220 		next_node = NULL;
1221 	}
1222 
1223 end:
1224 	if (vdev)
1225 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
1226 
1227 	return ch_freq;
1228 }
1229 
1230 QDF_STATUS
policy_mgr_change_hw_mode_sta_connect(struct wlan_objmgr_psoc * psoc,qdf_list_t * scan_list,uint8_t vdev_id,uint32_t connect_id)1231 policy_mgr_change_hw_mode_sta_connect(struct wlan_objmgr_psoc *psoc,
1232 				      qdf_list_t *scan_list, uint8_t vdev_id,
1233 				      uint32_t connect_id)
1234 {
1235 	QDF_STATUS status;
1236 	uint32_t ch_freq;
1237 
1238 	ch_freq = policy_mgr_check_for_hw_mode_change(psoc, scan_list, vdev_id);
1239 	if (!ch_freq)
1240 		return QDF_STATUS_E_ALREADY;
1241 
1242 	status = policy_mgr_current_connections_update(psoc, vdev_id, ch_freq,
1243 			POLICY_MGR_UPDATE_REASON_STA_CONNECT, connect_id);
1244 
1245 	/*
1246 	 * If status is success then the callback of policy mgr hw mode change
1247 	 * would be called.
1248 	 * If status is no support then the DUT is already in required HW mode.
1249 	 */
1250 
1251 	if (status == QDF_STATUS_E_FAILURE)
1252 		policy_mgr_err("Hw mode change failed");
1253 	else if (status == QDF_STATUS_E_NOSUPPORT)
1254 		status = QDF_STATUS_E_ALREADY;
1255 
1256 	return status;
1257 }
1258 
1259 QDF_STATUS
policy_mgr_current_connections_update(struct wlan_objmgr_psoc * psoc,uint32_t session_id,uint32_t ch_freq,enum policy_mgr_conn_update_reason reason,uint32_t request_id)1260 policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc,
1261 				      uint32_t session_id, uint32_t ch_freq,
1262 				      enum policy_mgr_conn_update_reason
1263 				      reason, uint32_t request_id)
1264 {
1265 	enum policy_mgr_conc_next_action next_action = PM_NOP;
1266 	QDF_STATUS status;
1267 
1268 	if (!policy_mgr_is_hw_dbs_capable(psoc)) {
1269 		policy_mgr_rl_debug("driver isn't dbs capable, no further action needed");
1270 		return QDF_STATUS_E_NOSUPPORT;
1271 	}
1272 
1273 	status = policy_mgr_get_next_action(psoc, session_id, ch_freq, reason,
1274 					    &next_action);
1275 	if (QDF_IS_STATUS_ERROR(status))
1276 		return status;
1277 
1278 	if (PM_NOP != next_action)
1279 		status = policy_mgr_next_actions(psoc, session_id,
1280 						next_action, reason,
1281 						request_id);
1282 	else
1283 		status = QDF_STATUS_E_NOSUPPORT;
1284 
1285 	policy_mgr_debug("next_action %d reason=%d session_id=%d request_id %x",
1286 			 next_action, reason, session_id, request_id);
1287 
1288 	return status;
1289 }
1290 
1291 /**
1292  * policy_mgr_dbs1_dbs2_need_action() - whether more actions are needed
1293  *                                      in DBS1 and DBS2 hw mode
1294  * @psoc: psoc object
1295  * @action: action type
1296  * @hw_mode: hardware mode
1297  *
1298  * The function checks further action are needed or not for DBS1 and DBS2.
1299  *
1300  * Return: true if more action are needed, otherwise
1301  *         return false
1302  */
1303 static bool
policy_mgr_dbs1_dbs2_need_action(struct wlan_objmgr_psoc * psoc,enum policy_mgr_conc_next_action action,struct policy_mgr_hw_mode_params * hw_mode)1304 policy_mgr_dbs1_dbs2_need_action(struct wlan_objmgr_psoc *psoc,
1305 				 enum policy_mgr_conc_next_action action,
1306 				 struct policy_mgr_hw_mode_params *hw_mode)
1307 {
1308 	if (policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc) ||
1309 	    policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc)) {
1310 		policy_mgr_debug("curr dbs action %d new action %d",
1311 				 hw_mode->action_type, action);
1312 		if (hw_mode->action_type == PM_DBS1 &&
1313 		    ((action == PM_DBS1 ||
1314 		    action == PM_DBS1_DOWNGRADE))) {
1315 			policy_mgr_debug("driver is already in DBS_5G_2x2_24G_1x1 (%d), no further action %d needed",
1316 					 hw_mode->action_type, action);
1317 			return false;
1318 		} else if (hw_mode->action_type == PM_DBS2 &&
1319 			   ((action == PM_DBS2 ||
1320 			   action == PM_DBS2_DOWNGRADE))) {
1321 			policy_mgr_debug("driver is already in DBS_24G_2x2_5G_1x1 (%d), no further action %d needed",
1322 					 hw_mode->action_type, action);
1323 			return false;
1324 		}
1325 	}
1326 
1327 	return true;
1328 }
1329 
1330 QDF_STATUS
policy_mgr_validate_dbs_switch(struct wlan_objmgr_psoc * psoc,enum policy_mgr_conc_next_action action)1331 policy_mgr_validate_dbs_switch(struct wlan_objmgr_psoc *psoc,
1332 			       enum policy_mgr_conc_next_action action)
1333 {
1334 	QDF_STATUS status;
1335 	struct policy_mgr_hw_mode_params hw_mode;
1336 
1337 	/* check for the current HW index to see if really need any action */
1338 	status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
1339 	if (!QDF_IS_STATUS_SUCCESS(status)) {
1340 		policy_mgr_err("policy_mgr_get_current_hw_mode failed");
1341 		return status;
1342 	}
1343 
1344 	if ((action == PM_SBS) || (action == PM_SBS_DOWNGRADE)) {
1345 		if (!policy_mgr_is_hw_sbs_capable(psoc)) {
1346 			/* No action */
1347 			policy_mgr_notice("firmware is not sbs capable");
1348 			return QDF_STATUS_E_NOSUPPORT;
1349 		}
1350 		/* current mode is already SBS nothing to be
1351 		 * done
1352 		 */
1353 		if (hw_mode.sbs_cap) {
1354 			policy_mgr_notice("current mode is already SBS");
1355 			return QDF_STATUS_E_ALREADY;
1356 		}
1357 		return QDF_STATUS_SUCCESS;
1358 	}
1359 
1360 	if (!hw_mode.dbs_cap) {
1361 		if (action == PM_SINGLE_MAC ||
1362 		    action == PM_SINGLE_MAC_UPGRADE) {
1363 			policy_mgr_notice("current mode is already single MAC");
1364 			return QDF_STATUS_E_ALREADY;
1365 		} else {
1366 			return QDF_STATUS_SUCCESS;
1367 		}
1368 	}
1369 	/**
1370 	 * If already in DBS, no need to request DBS again (HL, Napier).
1371 	 * For dual DBS HW, in case DBS1 -> DBS2 or DBS2 -> DBS1
1372 	 * switching, we need to check the current DBS mode is same as
1373 	 * requested or not.
1374 	 */
1375 	if (policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc) ||
1376 	    policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc)) {
1377 		if (!policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode))
1378 			return QDF_STATUS_E_ALREADY;
1379 	} else if ((action == PM_DBS_DOWNGRADE) || (action == PM_DBS) ||
1380 		   (action == PM_DBS_UPGRADE)) {
1381 		policy_mgr_debug("driver is already in %s mode, no further action needed",
1382 				 (hw_mode.dbs_cap) ? "dbs" : "non dbs");
1383 		return QDF_STATUS_E_ALREADY;
1384 	}
1385 	return QDF_STATUS_SUCCESS;
1386 }
1387 
1388 /**
1389  * policy_mgr_validate_unsupported_action() - unsupported action validation
1390  * @psoc: psoc object
1391  * @action: action type
1392  *
1393  * The help function checks the Action supported by HW or not.
1394  *
1395  * Return: QDF_STATUS_SUCCESS if supported by HW, otherwise
1396  *         return QDF_STATUS_E_NOSUPPORT
1397  */
policy_mgr_validate_unsupported_action(struct wlan_objmgr_psoc * psoc,enum policy_mgr_conc_next_action action)1398 static QDF_STATUS policy_mgr_validate_unsupported_action
1399 		(struct wlan_objmgr_psoc *psoc,
1400 		 enum policy_mgr_conc_next_action action)
1401 {
1402 	if (action == PM_SBS || action == PM_SBS_DOWNGRADE) {
1403 		if (!policy_mgr_is_hw_sbs_capable(psoc)) {
1404 			/* No action */
1405 			policy_mgr_notice("firmware is not sbs capable");
1406 			return QDF_STATUS_E_NOSUPPORT;
1407 		}
1408 	}
1409 
1410 	return QDF_STATUS_SUCCESS;
1411 }
1412 
policy_mgr_next_actions(struct wlan_objmgr_psoc * psoc,uint32_t session_id,enum policy_mgr_conc_next_action action,enum policy_mgr_conn_update_reason reason,uint32_t request_id)1413 QDF_STATUS policy_mgr_next_actions(
1414 		struct wlan_objmgr_psoc *psoc,
1415 		uint32_t session_id,
1416 		enum policy_mgr_conc_next_action action,
1417 		enum policy_mgr_conn_update_reason reason,
1418 		uint32_t request_id)
1419 {
1420 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1421 	struct dbs_nss nss_dbs = {0};
1422 	struct dbs_bw bw_dbs = {0};
1423 	struct policy_mgr_hw_mode_params hw_mode;
1424 	enum policy_mgr_conc_next_action next_action;
1425 	bool is_sbs_supported;
1426 	enum hw_mode_sbs_capab sbs_capab;
1427 
1428 	if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
1429 		policy_mgr_rl_debug("driver isn't dbs capable, no further action needed");
1430 		return QDF_STATUS_E_NOSUPPORT;
1431 	}
1432 	status = policy_mgr_validate_unsupported_action(psoc, action);
1433 	if (!QDF_IS_STATUS_SUCCESS(status))
1434 		return status;
1435 	/* check for the current HW index to see if really need any action */
1436 	status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
1437 	if (!QDF_IS_STATUS_SUCCESS(status)) {
1438 		policy_mgr_err("policy_mgr_get_current_hw_mode failed");
1439 		return status;
1440 	}
1441 
1442 	switch (action) {
1443 	case PM_DBS_DOWNGRADE:
1444 		/*
1445 		* check if we have a beaconing entity that is using 2x2. If yes,
1446 		* update the beacon template & notify FW. Once FW confirms
1447 		*  beacon updated, send down the HW mode change req
1448 		*/
1449 		status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
1450 					PM_DBS, reason, session_id, request_id);
1451 		break;
1452 	case PM_DBS:
1453 		(void)policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs);
1454 		policy_mgr_get_hw_dbs_max_bw(psoc, &bw_dbs);
1455 		is_sbs_supported = policy_mgr_is_hw_sbs_capable(psoc);
1456 		sbs_capab = is_sbs_supported ? HW_MODE_SBS : HW_MODE_SBS_NONE;
1457 		status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1458 						     nss_dbs.mac0_ss,
1459 						     bw_dbs.mac0_bw,
1460 						     nss_dbs.mac1_ss,
1461 						     bw_dbs.mac1_bw,
1462 						     HW_MODE_MAC_BAND_NONE,
1463 						     HW_MODE_DBS,
1464 						     HW_MODE_AGILE_DFS_NONE,
1465 						     sbs_capab,
1466 						     reason, PM_NOP, PM_DBS,
1467 						     request_id);
1468 		break;
1469 	case PM_SINGLE_MAC_UPGRADE:
1470 		/*
1471 		 * change the HW mode first before the NSS upgrade
1472 		 */
1473 		status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1474 						HW_MODE_SS_2x2,
1475 						HW_MODE_80_MHZ,
1476 						HW_MODE_SS_0x0, HW_MODE_BW_NONE,
1477 						HW_MODE_MAC_BAND_NONE,
1478 						HW_MODE_DBS_NONE,
1479 						HW_MODE_AGILE_DFS_NONE,
1480 						HW_MODE_SBS_NONE,
1481 						reason, PM_UPGRADE,
1482 						PM_SINGLE_MAC_UPGRADE,
1483 						request_id);
1484 		break;
1485 	case PM_SINGLE_MAC:
1486 		status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1487 						HW_MODE_SS_2x2,
1488 						HW_MODE_80_MHZ,
1489 						HW_MODE_SS_0x0, HW_MODE_BW_NONE,
1490 						HW_MODE_MAC_BAND_NONE,
1491 						HW_MODE_DBS_NONE,
1492 						HW_MODE_AGILE_DFS_NONE,
1493 						HW_MODE_SBS_NONE,
1494 						reason, PM_NOP, PM_SINGLE_MAC,
1495 						request_id);
1496 		break;
1497 	case PM_DBS_UPGRADE:
1498 		status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1499 						HW_MODE_SS_2x2,
1500 						HW_MODE_80_MHZ,
1501 						HW_MODE_SS_2x2, HW_MODE_80_MHZ,
1502 						HW_MODE_MAC_BAND_NONE,
1503 						HW_MODE_DBS,
1504 						HW_MODE_AGILE_DFS_NONE,
1505 						HW_MODE_SBS_NONE,
1506 						reason, PM_UPGRADE,
1507 						PM_DBS_UPGRADE, request_id);
1508 		break;
1509 	case PM_SBS_DOWNGRADE:
1510 		status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
1511 					PM_SBS, reason, session_id, request_id);
1512 		break;
1513 	case PM_SBS:
1514 		status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1515 						HW_MODE_SS_1x1,
1516 						HW_MODE_80_MHZ,
1517 						HW_MODE_SS_1x1, HW_MODE_80_MHZ,
1518 						HW_MODE_MAC_BAND_NONE,
1519 						HW_MODE_DBS,
1520 						HW_MODE_AGILE_DFS_NONE,
1521 						HW_MODE_SBS,
1522 						reason, PM_NOP, PM_SBS,
1523 						request_id);
1524 		break;
1525 	case PM_DOWNGRADE:
1526 		/*
1527 		 * check if we have a beaconing entity that advertised 2x2
1528 		 * initially. If yes, update the beacon template & notify FW.
1529 		 */
1530 		status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_1,
1531 					PM_NOP, POLICY_MGR_ANY, reason,
1532 					session_id, request_id);
1533 		break;
1534 	case PM_UPGRADE:
1535 		/*
1536 		 * check if we have a beaconing entity that advertised 2x2
1537 		 * initially. If yes, update the beacon template & notify FW.
1538 		 */
1539 		status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_2,
1540 					PM_NOP, POLICY_MGR_ANY, reason,
1541 					session_id, request_id);
1542 		break;
1543 	case PM_DBS1_DOWNGRADE:
1544 		if (policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode))
1545 			status = policy_mgr_complete_action(psoc,
1546 							    POLICY_MGR_RX_NSS_1,
1547 							    PM_DBS1, reason,
1548 							    session_id,
1549 							    request_id);
1550 		else
1551 			status = QDF_STATUS_E_ALREADY;
1552 		break;
1553 	case PM_DBS2_DOWNGRADE:
1554 		if (policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode))
1555 			status = policy_mgr_complete_action(psoc,
1556 							    POLICY_MGR_RX_NSS_1,
1557 							    PM_DBS2, reason,
1558 							    session_id,
1559 							    request_id);
1560 		else
1561 			status = QDF_STATUS_E_ALREADY;
1562 		break;
1563 	case PM_DBS1:
1564 		/*
1565 		 * PM_DBS1 (2x2 5G + 1x1 2G) will support 5G 2x2. If previous
1566 		 * mode is DBS, that should be 2x2 2G + 1x1 5G mode and
1567 		 * the 5G band was downgraded to 1x1. So, we need to
1568 		 * upgrade 5G vdevs after hw mode change.
1569 		 */
1570 		if (policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode)) {
1571 			if (hw_mode.dbs_cap)
1572 				next_action = PM_UPGRADE_5G;
1573 			else
1574 				next_action = PM_NOP;
1575 			status = policy_mgr_pdev_set_hw_mode(
1576 					psoc, session_id,
1577 					HW_MODE_SS_2x2,
1578 					HW_MODE_80_MHZ,
1579 					HW_MODE_SS_1x1, HW_MODE_40_MHZ,
1580 					HW_MODE_MAC_BAND_5G,
1581 					HW_MODE_DBS,
1582 					HW_MODE_AGILE_DFS_NONE,
1583 					HW_MODE_SBS_NONE,
1584 					reason, next_action, PM_DBS1,
1585 					request_id);
1586 		} else {
1587 			status = QDF_STATUS_E_ALREADY;
1588 		}
1589 		break;
1590 	case PM_DBS2:
1591 		/*
1592 		 * PM_DBS2 (2x2 2G + 1x1 5G) will support 2G 2x2. If previous
1593 		 * mode is DBS, that should be 2x2 5G + 1x1 2G mode and
1594 		 * the 2G band was downgraded to 1x1. So, we need to
1595 		 * upgrade 5G vdevs after hw mode change.
1596 		 */
1597 		if (policy_mgr_dbs1_dbs2_need_action(psoc, action, &hw_mode)) {
1598 			if (hw_mode.dbs_cap)
1599 				next_action = PM_UPGRADE_2G;
1600 			else
1601 				next_action = PM_NOP;
1602 			status = policy_mgr_pdev_set_hw_mode(
1603 						psoc, session_id,
1604 						HW_MODE_SS_2x2,
1605 						HW_MODE_40_MHZ,
1606 						HW_MODE_SS_1x1, HW_MODE_40_MHZ,
1607 						HW_MODE_MAC_BAND_2G,
1608 						HW_MODE_DBS,
1609 						HW_MODE_AGILE_DFS_NONE,
1610 						HW_MODE_SBS_NONE,
1611 						reason, next_action, PM_DBS2,
1612 						request_id);
1613 		} else {
1614 			status = QDF_STATUS_E_ALREADY;
1615 		}
1616 		break;
1617 	case PM_UPGRADE_5G:
1618 		status = policy_mgr_nss_update(
1619 					psoc, POLICY_MGR_RX_NSS_2,
1620 					PM_NOP, POLICY_MGR_BAND_5, reason,
1621 					session_id, request_id);
1622 		break;
1623 	case PM_UPGRADE_2G:
1624 		status = policy_mgr_nss_update(
1625 					psoc, POLICY_MGR_RX_NSS_2,
1626 					PM_NOP, POLICY_MGR_BAND_24, reason,
1627 					session_id, request_id);
1628 		break;
1629 	case PM_DOWNGRADE_BW:
1630 	case PM_UPGRADE_BW:
1631 		policy_mgr_sap_ch_width_update(psoc, action, reason,
1632 					       session_id, request_id);
1633 		break;
1634 	default:
1635 		policy_mgr_err("unexpected action value %d", action);
1636 		status = QDF_STATUS_E_FAILURE;
1637 		break;
1638 	}
1639 
1640 	return status;
1641 }
1642 
1643 QDF_STATUS
policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint32_t ch_freq,enum policy_mgr_conn_update_reason reason,uint32_t request_id)1644 policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc,
1645 				 uint8_t vdev_id, uint32_t ch_freq,
1646 				 enum policy_mgr_conn_update_reason reason,
1647 				 uint32_t request_id)
1648 {
1649 	QDF_STATUS status;
1650 	uint8_t num_cxn_del = 0;
1651 	struct policy_mgr_conc_connection_info info = {0};
1652 
1653 	policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id,
1654 						      &info, &num_cxn_del);
1655 
1656 	if (!policy_mgr_check_for_session_conc(psoc, vdev_id, ch_freq)) {
1657 		policy_mgr_err("Conc not allowed for the vdev %d", vdev_id);
1658 		return QDF_STATUS_E_FAILURE;
1659 	}
1660 
1661 	status = policy_mgr_reset_connection_update(psoc);
1662 	if (!QDF_IS_STATUS_SUCCESS(status))
1663 		policy_mgr_err("clearing event failed");
1664 
1665 	status = policy_mgr_current_connections_update(psoc, vdev_id,
1666 						       ch_freq, reason,
1667 						       request_id);
1668 	if (QDF_STATUS_E_FAILURE == status)
1669 		policy_mgr_err("connections update failed");
1670 
1671 	if (num_cxn_del > 0)
1672 		policy_mgr_restore_deleted_conn_info(psoc, &info,
1673 						     num_cxn_del);
1674 
1675 	return status;
1676 }
1677 
1678 enum policy_mgr_con_mode
policy_mgr_con_mode_by_vdev_id(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)1679 policy_mgr_con_mode_by_vdev_id(struct wlan_objmgr_psoc *psoc,
1680 			       uint8_t vdev_id)
1681 {
1682 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1683 	enum policy_mgr_con_mode mode = PM_MAX_NUM_OF_MODE;
1684 	enum QDF_OPMODE op_mode;
1685 
1686 	pm_ctx = policy_mgr_get_context(psoc);
1687 	if (!pm_ctx) {
1688 		policy_mgr_err("Invalid Context");
1689 		return mode;
1690 	}
1691 
1692 	op_mode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id);
1693 	return policy_mgr_qdf_opmode_to_pm_con_mode(psoc, op_mode, vdev_id);
1694 }
1695 
1696 #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
1697 qdf_freq_t
policy_mgr_get_user_config_sap_freq(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)1698 policy_mgr_get_user_config_sap_freq(struct wlan_objmgr_psoc *psoc,
1699 				    uint8_t vdev_id)
1700 {
1701 	struct wlan_objmgr_vdev *vdev;
1702 	qdf_freq_t freq;
1703 
1704 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
1705 						    WLAN_POLICY_MGR_ID);
1706 	if (!vdev) {
1707 		policy_mgr_err("vdev is NULL");
1708 		return 0;
1709 	}
1710 	freq = wlan_get_sap_user_config_freq(vdev);
1711 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
1712 
1713 	return freq;
1714 }
1715 
1716 /**
1717  * policy_mgr_is_sap_go_existed() - Check if restart SAP/Go exist
1718  * @psoc: PSOC object data
1719  *
1720  * To simplify, if SAP/P2P Go exist, they may need switch channel for
1721  * forcing scc with sta or band capability change.
1722  * Restart: true or false
1723  */
policy_mgr_is_sap_go_existed(struct wlan_objmgr_psoc * psoc)1724 static bool policy_mgr_is_sap_go_existed(struct wlan_objmgr_psoc *psoc)
1725 {
1726 	uint32_t ap_present, go_present;
1727 
1728 	ap_present = policy_mgr_get_sap_mode_count(psoc, NULL);
1729 	if (ap_present)
1730 		return true;
1731 
1732 	go_present = policy_mgr_mode_specific_connection_count(
1733 				psoc, PM_P2P_GO_MODE, NULL);
1734 	if (go_present)
1735 		return true;
1736 
1737 	return false;
1738 }
1739 
1740 #ifdef FEATURE_WLAN_CH_AVOID_EXT
policy_mgr_is_safe_channel(struct wlan_objmgr_psoc * psoc,uint32_t ch_freq)1741 bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc,
1742 				uint32_t ch_freq)
1743 {
1744 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1745 	bool is_safe = true;
1746 	uint8_t j;
1747 	unsigned long restriction_mask;
1748 
1749 	pm_ctx = policy_mgr_get_context(psoc);
1750 	if (!pm_ctx) {
1751 		policy_mgr_err("Invalid context");
1752 		return is_safe;
1753 	}
1754 
1755 	if (pm_ctx->unsafe_channel_count == 0)
1756 		return is_safe;
1757 
1758 	restriction_mask =
1759 		(unsigned long)policy_mgr_get_freq_restriction_mask(pm_ctx);
1760 	for (j = 0; j < pm_ctx->unsafe_channel_count; j++) {
1761 		if ((ch_freq == pm_ctx->unsafe_channel_list[j]) &&
1762 		    (qdf_test_bit(QDF_SAP_MODE, &restriction_mask) ||
1763 		     !wlan_mlme_get_coex_unsafe_chan_nb_user_prefer_for_sap(
1764 								     psoc))) {
1765 			is_safe = false;
1766 			policy_mgr_warn("Freq %d is not safe, restriction mask %lu", ch_freq, restriction_mask);
1767 			break;
1768 		}
1769 	}
1770 
1771 	return is_safe;
1772 }
1773 
policy_mgr_restrict_sap_on_unsafe_chan(struct wlan_objmgr_psoc * psoc)1774 bool policy_mgr_restrict_sap_on_unsafe_chan(struct wlan_objmgr_psoc *psoc)
1775 {
1776 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1777 	unsigned long restriction_mask;
1778 
1779 	pm_ctx = policy_mgr_get_context(psoc);
1780 	if (!pm_ctx) {
1781 		policy_mgr_err("Invalid context");
1782 		return false;
1783 	}
1784 
1785 	restriction_mask =
1786 		(unsigned long)policy_mgr_get_freq_restriction_mask(pm_ctx);
1787 	return qdf_test_bit(QDF_SAP_MODE, &restriction_mask);
1788 }
1789 #else
policy_mgr_is_safe_channel(struct wlan_objmgr_psoc * psoc,uint32_t ch_freq)1790 bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc,
1791 				uint32_t ch_freq)
1792 {
1793 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1794 	bool is_safe = true;
1795 	uint8_t j;
1796 
1797 	pm_ctx = policy_mgr_get_context(psoc);
1798 	if (!pm_ctx) {
1799 		policy_mgr_err("Invalid context");
1800 		return is_safe;
1801 	}
1802 
1803 	if (pm_ctx->unsafe_channel_count == 0)
1804 		return is_safe;
1805 
1806 	for (j = 0; j < pm_ctx->unsafe_channel_count; j++) {
1807 		if (ch_freq == pm_ctx->unsafe_channel_list[j]) {
1808 			is_safe = false;
1809 			policy_mgr_warn("Freq %d is not safe", ch_freq);
1810 			break;
1811 		}
1812 	}
1813 
1814 	return is_safe;
1815 }
1816 #endif
1817 
policy_mgr_is_sap_freq_allowed(struct wlan_objmgr_psoc * psoc,enum QDF_OPMODE opmode,uint32_t sap_freq)1818 bool policy_mgr_is_sap_freq_allowed(struct wlan_objmgr_psoc *psoc,
1819 				    enum QDF_OPMODE opmode,
1820 				    uint32_t sap_freq)
1821 {
1822 	uint32_t nan_2g_freq, nan_5g_freq;
1823 
1824 	/*
1825 	 * Ignore safe channel validation when the mode is P2P_GO and user
1826 	 * configures the corresponding bit in ini coex_unsafe_chan_nb_user_prefer.
1827 	 */
1828 	if ((opmode == QDF_P2P_GO_MODE &&
1829 	     wlan_mlme_get_coex_unsafe_chan_nb_user_prefer_for_p2p_go(psoc)) ||
1830 	    policy_mgr_is_safe_channel(psoc, sap_freq))
1831 		return true;
1832 
1833 	/*
1834 	 * Return true if it's STA+SAP SCC and
1835 	 * STA+SAP SCC on LTE coex channel is allowed.
1836 	 */
1837 	if (policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) &&
1838 	    policy_mgr_is_sta_sap_scc(psoc, sap_freq)) {
1839 		policy_mgr_debug("unsafe freq %d for sap is allowed", sap_freq);
1840 		return true;
1841 	}
1842 
1843 	nan_2g_freq =
1844 		policy_mgr_mode_specific_get_channel(psoc, PM_NAN_DISC_MODE);
1845 	nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(psoc);
1846 
1847 	if ((WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, sap_freq) ||
1848 	     WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, sap_freq)) &&
1849 	    policy_mgr_is_force_scc(psoc) &&
1850 	    policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(psoc)) {
1851 		policy_mgr_debug("NAN+SAP SCC on unsafe freq %d is allowed",
1852 				  sap_freq);
1853 		return true;
1854 	}
1855 
1856 	return false;
1857 }
1858 
policy_mgr_is_sap_restart_required_after_sta_disconnect(struct wlan_objmgr_psoc * psoc,uint32_t sap_vdev_id,uint32_t * intf_ch_freq,bool is_acs_mode)1859 bool policy_mgr_is_sap_restart_required_after_sta_disconnect(
1860 			struct wlan_objmgr_psoc *psoc,
1861 			uint32_t sap_vdev_id, uint32_t *intf_ch_freq,
1862 			bool is_acs_mode)
1863 {
1864 	struct policy_mgr_psoc_priv_obj *pm_ctx;
1865 	uint32_t curr_sap_freq = 0, new_sap_freq = 0;
1866 	bool sta_sap_scc_on_dfs_chan =
1867 		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
1868 	bool sta_sap_scc_on_lte_coex_chan =
1869 		policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc);
1870 	uint8_t sta_sap_scc_on_dfs_chnl_config_value = 0;
1871 	uint32_t cc_count, i, go_index_start, pcl_len = 0;
1872 	uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS * 2];
1873 	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS * 2];
1874 	enum policy_mgr_con_mode mode;
1875 	uint32_t pcl_channels[NUM_CHANNELS + 1];
1876 	uint8_t pcl_weight[NUM_CHANNELS + 1];
1877 	struct policy_mgr_conc_connection_info info = {0};
1878 	uint8_t num_cxn_del = 0;
1879 	QDF_STATUS status;
1880 	uint32_t sta_gc_present = 0;
1881 	qdf_freq_t user_config_freq = 0;
1882 	enum reg_wifi_band user_band, op_band;
1883 
1884 	if (intf_ch_freq)
1885 		*intf_ch_freq = 0;
1886 
1887 	pm_ctx = policy_mgr_get_context(psoc);
1888 	if (!pm_ctx) {
1889 		policy_mgr_err("Invalid pm context");
1890 		return false;
1891 	}
1892 
1893 	policy_mgr_get_sta_sap_scc_on_dfs_chnl(psoc, &sta_sap_scc_on_dfs_chnl_config_value);
1894 
1895 	if (!policy_mgr_is_hw_dbs_capable(psoc))
1896 		if (policy_mgr_get_connection_count(psoc) > 1)
1897 			return false;
1898 
1899 	cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
1900 							  &op_ch_freq_list[0],
1901 							  &vdev_id[0],
1902 							  PM_SAP_MODE);
1903 	go_index_start = cc_count;
1904 	if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS)
1905 		cc_count += policy_mgr_get_mode_specific_conn_info(
1906 					psoc, &op_ch_freq_list[cc_count],
1907 					&vdev_id[cc_count], PM_P2P_GO_MODE);
1908 
1909 	sta_gc_present =
1910 		policy_mgr_mode_specific_connection_count(psoc,
1911 							  PM_STA_MODE, NULL) +
1912 		policy_mgr_mode_specific_connection_count(psoc,
1913 							  PM_P2P_CLIENT_MODE,
1914 							  NULL);
1915 
1916 	for (i = 0 ; i < cc_count; i++) {
1917 		if (sap_vdev_id != INVALID_VDEV_ID &&
1918 		    sap_vdev_id != vdev_id[i])
1919 			continue;
1920 
1921 		sap_vdev_id = vdev_id[i];
1922 		user_config_freq =
1923 			policy_mgr_get_user_config_sap_freq(psoc, sap_vdev_id);
1924 
1925 		if (policy_mgr_is_any_mode_active_on_band_along_with_session(
1926 				psoc,  vdev_id[i],
1927 				WLAN_REG_IS_24GHZ_CH_FREQ(op_ch_freq_list[i]) ?
1928 				POLICY_MGR_BAND_24 : POLICY_MGR_BAND_5))
1929 			continue;
1930 
1931 		if (sta_sap_scc_on_dfs_chan &&
1932 		    (sta_sap_scc_on_dfs_chnl_config_value != 2) &&
1933 		     wlan_reg_is_dfs_for_freq(pm_ctx->pdev,
1934 					      op_ch_freq_list[i]) &&
1935 		     pm_ctx->last_disconn_sta_freq == op_ch_freq_list[i]) {
1936 			curr_sap_freq = op_ch_freq_list[i];
1937 			policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sta_sap_scc_on_dfs_chnl_config_value %u, dfs sap_ch_freq %u",
1938 					 sta_sap_scc_on_dfs_chan,
1939 					 sta_sap_scc_on_dfs_chnl_config_value,
1940 					 curr_sap_freq);
1941 			break;
1942 		}
1943 
1944 		if ((is_acs_mode ||
1945 		     policy_mgr_restrict_sap_on_unsafe_chan(psoc)) &&
1946 		    sta_sap_scc_on_lte_coex_chan &&
1947 		    !policy_mgr_is_safe_channel(psoc, op_ch_freq_list[i]) &&
1948 		    pm_ctx->last_disconn_sta_freq == op_ch_freq_list[i]) {
1949 			curr_sap_freq = op_ch_freq_list[i];
1950 			policy_mgr_debug("sta_sap_scc_on_lte_coex_chan %u unsafe sap_ch_freq %u",
1951 					 sta_sap_scc_on_lte_coex_chan,
1952 					 curr_sap_freq);
1953 			break;
1954 		}
1955 		/* When STA+SAP SCC is allowed on indoor channel,
1956 		 * Restart the SAP when :
1957 		 * 1. The user configured SAP frequency is not
1958 		 * the same as current freq. (or)
1959 		 * 2. The frequency is not allowed in the indoor
1960 		 * channel.
1961 		 */
1962 		if (pm_ctx->last_disconn_sta_freq == op_ch_freq_list[i] &&
1963 		    !policy_mgr_is_sap_go_interface_allowed_on_indoor(
1964 							pm_ctx->pdev,
1965 							sap_vdev_id,
1966 							op_ch_freq_list[i])) {
1967 			curr_sap_freq = op_ch_freq_list[i];
1968 			policy_mgr_debug("indoor sap_ch_freq %u",
1969 					 curr_sap_freq);
1970 			break;
1971 		}
1972 
1973 		/*
1974 		 * STA got disconnected & SAP has previously moved to 2.4 GHz
1975 		 * due to concurrency, then move SAP back to user configured
1976 		 * frequency if the user configured band is better than
1977 		 * the current operating band.
1978 		 */
1979 		op_band = wlan_reg_freq_to_band(op_ch_freq_list[i]);
1980 		user_band = wlan_reg_freq_to_band(user_config_freq);
1981 
1982 		if (!sta_gc_present && user_config_freq &&
1983 		    op_band < user_band) {
1984 			curr_sap_freq = op_ch_freq_list[i];
1985 			policy_mgr_debug("Move sap to user configured freq: %d",
1986 					 user_config_freq);
1987 			break;
1988 		}
1989 	}
1990 
1991 	if (!curr_sap_freq) {
1992 		policy_mgr_debug("SAP restart is not required");
1993 		return false;
1994 	}
1995 
1996 	mode = i >= go_index_start ? PM_P2P_GO_MODE : PM_SAP_MODE;
1997 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1998 	policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, sap_vdev_id,
1999 						      &info, &num_cxn_del);
2000 
2001 	/* Add the user config ch as first condidate */
2002 	pcl_channels[0] = user_config_freq;
2003 	pcl_weight[0] = 0;
2004 	status = policy_mgr_get_pcl(psoc, mode, &pcl_channels[1], &pcl_len,
2005 				    &pcl_weight[1],
2006 				    QDF_ARRAY_SIZE(pcl_weight) - 1,
2007 				    sap_vdev_id);
2008 	if (status == QDF_STATUS_SUCCESS)
2009 		pcl_len++;
2010 	else
2011 		pcl_len = 1;
2012 
2013 
2014 	for (i = 0; i < pcl_len; i++) {
2015 		if (pcl_channels[i] == curr_sap_freq)
2016 			continue;
2017 
2018 		if (!policy_mgr_is_safe_channel(psoc, pcl_channels[i]) ||
2019 		    wlan_reg_is_dfs_for_freq(pm_ctx->pdev, pcl_channels[i]))
2020 			continue;
2021 
2022 		/* SAP moved to 2.4 GHz, due to STA on DFS or Indoor where
2023 		 * concurrency is not allowed, now that there is no
2024 		 * STA/GC in 5 GHz band, move 2.4 GHz SAP to 5 GHz band if SAP
2025 		 * was initially started on 5 GHz band.
2026 		 * Checking again here as pcl_channels[0] could be
2027 		 * on indoor which is not removed in policy_mgr_get_pcl
2028 		 */
2029 		if (!sta_gc_present &&
2030 		    !policy_mgr_is_sap_go_interface_allowed_on_indoor(
2031 							pm_ctx->pdev,
2032 							sap_vdev_id,
2033 							pcl_channels[i])) {
2034 			policy_mgr_debug("Do not allow SAP on indoor frequency, STA is absent");
2035 			continue;
2036 		}
2037 
2038 		new_sap_freq = pcl_channels[i];
2039 		break;
2040 	}
2041 
2042 	/* Restore the connection entry */
2043 	if (num_cxn_del > 0)
2044 		policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del);
2045 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2046 
2047 	if (new_sap_freq == 0 || curr_sap_freq == new_sap_freq)
2048 		return false;
2049 	if (!intf_ch_freq)
2050 		return true;
2051 
2052 	*intf_ch_freq = new_sap_freq;
2053 	policy_mgr_debug("Standalone SAP(vdev_id %d) will be moved to channel %u",
2054 			 sap_vdev_id, *intf_ch_freq);
2055 
2056 	return true;
2057 }
2058 
2059 /**
2060  * policy_mgr_is_nan_sap_unsafe_ch_scc_allowed() - Check if NAN+SAP SCC is
2061  *                                               allowed in LTE COEX unsafe ch
2062  * @pm_ctx: policy_mgr_psoc_priv_obj policy mgr context
2063  * @ch_freq: Channel frequency to check
2064  *
2065  * Return: True if allowed else false
2066  */
2067 static bool
policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(struct policy_mgr_psoc_priv_obj * pm_ctx,uint32_t ch_freq)2068 policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(struct policy_mgr_psoc_priv_obj
2069 					    *pm_ctx, uint32_t ch_freq)
2070 {
2071 	if (policy_mgr_is_safe_channel(pm_ctx->psoc, ch_freq) ||
2072 	    pm_ctx->cfg.nan_sap_scc_on_lte_coex_chnl)
2073 		return true;
2074 
2075 	return false;
2076 }
2077 
2078 /**
2079  * policy_mgr_nan_disable_work() - qdf defer function wrapper for NAN disable
2080  * @data: qdf_work data
2081  *
2082  * Return: None
2083  */
policy_mgr_nan_disable_work(void * data)2084 static void policy_mgr_nan_disable_work(void *data)
2085 {
2086 	struct wlan_objmgr_psoc *psoc = data;
2087 
2088 	ucfg_nan_disable_concurrency(psoc);
2089 }
2090 
policy_mgr_nan_sap_scc_on_unsafe_ch_chk(struct wlan_objmgr_psoc * psoc,uint32_t sap_freq)2091 bool policy_mgr_nan_sap_scc_on_unsafe_ch_chk(struct wlan_objmgr_psoc *psoc,
2092 					     uint32_t sap_freq)
2093 {
2094 	uint32_t nan_2g_freq, nan_5g_freq;
2095 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2096 
2097 	pm_ctx = policy_mgr_get_context(psoc);
2098 	if (!pm_ctx) {
2099 		policy_mgr_err("Invalid Context");
2100 		return false;
2101 	}
2102 
2103 	nan_2g_freq = policy_mgr_mode_specific_get_channel(psoc,
2104 							   PM_NAN_DISC_MODE);
2105 	if (nan_2g_freq == 0) {
2106 		policy_mgr_debug("No NAN+SAP SCC");
2107 		return false;
2108 	}
2109 	nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(psoc);
2110 
2111 	policy_mgr_debug("Freq SAP: %d NAN: %d %d", sap_freq,
2112 			 nan_2g_freq, nan_5g_freq);
2113 	if (WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, sap_freq)) {
2114 		if (policy_mgr_is_force_scc(pm_ctx->psoc) &&
2115 		    policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(pm_ctx,
2116 								nan_2g_freq))
2117 			return true;
2118 	} else if (WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, sap_freq)) {
2119 		if (policy_mgr_is_force_scc(pm_ctx->psoc) &&
2120 		    policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(pm_ctx,
2121 								nan_5g_freq))
2122 			return true;
2123 	} else {
2124 		/*
2125 		 * NAN + SAP in different bands. Continue to check for
2126 		 * SAP in unsafe channel
2127 		 */
2128 		return false;
2129 	}
2130 	policy_mgr_info("NAN+SAP unsafe ch SCC not allowed. Disabling NAN");
2131 	/* change context to worker since this is executed in sched thread ctx*/
2132 	qdf_create_work(0, &pm_ctx->nan_sap_conc_work,
2133 			policy_mgr_nan_disable_work, psoc);
2134 	qdf_sched_work(0, &pm_ctx->nan_sap_conc_work);
2135 
2136 	return false;
2137 }
2138 
2139 bool
policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc * psoc,enum policy_mgr_con_mode mode,uint32_t ch_freq)2140 policy_mgr_nan_sap_pre_enable_conc_check(struct wlan_objmgr_psoc *psoc,
2141 					 enum policy_mgr_con_mode mode,
2142 					 uint32_t ch_freq)
2143 {
2144 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2145 	uint32_t sap_freq, nan_2g_freq, nan_5g_freq;
2146 
2147 	pm_ctx = policy_mgr_get_context(psoc);
2148 	if (!pm_ctx) {
2149 		policy_mgr_err("Invalid Context");
2150 		return false;
2151 	}
2152 
2153 	if (!policy_mgr_is_sap_mode(mode) || mode == PM_NAN_DISC_MODE) {
2154 		policy_mgr_debug("Not NAN or SAP mode");
2155 		return true;
2156 	}
2157 
2158 	if (!ch_freq) {
2159 		policy_mgr_err("Invalid channel");
2160 		return false;
2161 	}
2162 
2163 	if (!wlan_nan_get_sap_conc_support(pm_ctx->psoc)) {
2164 		policy_mgr_debug("NAN+SAP not supported in fw");
2165 		/* Reject NAN as SAP is of high priority */
2166 		if (mode == PM_NAN_DISC_MODE)
2167 			return false;
2168 		/* Before SAP start disable NAN */
2169 		ucfg_nan_disable_concurrency(pm_ctx->psoc);
2170 		return true;
2171 	}
2172 
2173 	if (mode == PM_NAN_DISC_MODE) {
2174 		sap_freq = policy_mgr_mode_specific_get_channel(pm_ctx->psoc,
2175 								PM_SAP_MODE);
2176 		policy_mgr_debug("FREQ SAP: %d NAN: %d", sap_freq, ch_freq);
2177 		if (!sap_freq) {
2178 			sap_freq = policy_mgr_mode_specific_get_channel(
2179 							pm_ctx->psoc,
2180 							PM_LL_LT_SAP_MODE);
2181 			policy_mgr_debug("FREQ LL_LT_SAP: %d NAN: %d",
2182 					 sap_freq, ch_freq);
2183 		}
2184 		if (ucfg_is_nan_dbs_supported(pm_ctx->psoc) &&
2185 		    !WLAN_REG_IS_SAME_BAND_FREQS(sap_freq, ch_freq))
2186 			return true;
2187 
2188 		if (sap_freq == ch_freq) {
2189 			policy_mgr_debug("NAN+SAP SCC");
2190 			return true;
2191 		}
2192 
2193 		if (!policy_mgr_is_force_scc(pm_ctx->psoc)) {
2194 			policy_mgr_debug("SAP force SCC disabled");
2195 			return false;
2196 		}
2197 		if (!policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(
2198 						pm_ctx, ch_freq)) {
2199 			policy_mgr_debug("NAN+SAP unsafe ch SCC disabled");
2200 			return false;
2201 		}
2202 		if (pm_ctx->hdd_cbacks.hdd_is_cac_in_progress &&
2203 		    pm_ctx->hdd_cbacks.hdd_is_cac_in_progress()) {
2204 			policy_mgr_debug("DFS CAC in progress, reject NAN enable");
2205 			return false;
2206 		}
2207 	} else if (policy_mgr_is_sap_mode(mode)) {
2208 		nan_2g_freq =
2209 			policy_mgr_mode_specific_get_channel(pm_ctx->psoc,
2210 							     PM_NAN_DISC_MODE);
2211 		nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(pm_ctx->psoc);
2212 		policy_mgr_debug("SAP CH: %d NAN Ch: %d %d", ch_freq,
2213 				 nan_2g_freq, nan_5g_freq);
2214 		if (ucfg_is_nan_conc_control_supported(pm_ctx->psoc) &&
2215 		    !ucfg_is_nan_dbs_supported(pm_ctx->psoc) &&
2216 		    !WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, ch_freq)) {
2217 			if (!policy_mgr_is_force_scc(pm_ctx->psoc)) {
2218 				policy_mgr_debug("NAN and SAP are in different bands but SAP force SCC disabled");
2219 				ucfg_nan_disable_concurrency(pm_ctx->psoc);
2220 				return true;
2221 			}
2222 		} else if (WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, ch_freq) ||
2223 			   WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, ch_freq)) {
2224 			if (ch_freq == nan_2g_freq || ch_freq == nan_5g_freq) {
2225 				policy_mgr_debug("NAN+SAP SCC");
2226 				return true;
2227 			}
2228 			if (!policy_mgr_is_force_scc(pm_ctx->psoc)) {
2229 				policy_mgr_debug("SAP force SCC disabled");
2230 				ucfg_nan_disable_concurrency(pm_ctx->psoc);
2231 				return true;
2232 			}
2233 			if ((WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) &&
2234 			     !policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(
2235 			     pm_ctx, nan_5g_freq)) ||
2236 			    (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) &&
2237 			     !policy_mgr_is_nan_sap_unsafe_ch_scc_allowed(
2238 			     pm_ctx, nan_2g_freq))) {
2239 				policy_mgr_debug("NAN+SAP unsafe ch SCC disabled");
2240 				ucfg_nan_disable_concurrency(pm_ctx->psoc);
2241 				return true;
2242 			}
2243 		}
2244 	}
2245 	return true;
2246 }
2247 
2248 QDF_STATUS
policy_mgr_nan_sap_post_enable_conc_check(struct wlan_objmgr_psoc * psoc)2249 policy_mgr_nan_sap_post_enable_conc_check(struct wlan_objmgr_psoc *psoc)
2250 {
2251 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2252 	struct policy_mgr_conc_connection_info *sap_info = NULL;
2253 	uint8_t i;
2254 	qdf_freq_t nan_freq_2g, nan_freq_5g;
2255 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2256 
2257 	pm_ctx = policy_mgr_get_context(psoc);
2258 	if (!pm_ctx) {
2259 		policy_mgr_err("Invalid pm context");
2260 		return QDF_STATUS_E_INVAL;
2261 	}
2262 
2263 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2264 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
2265 		if (policy_mgr_is_sap_mode(pm_conc_connection_list[i].mode) &&
2266 		    pm_conc_connection_list[i].in_use) {
2267 			sap_info = &pm_conc_connection_list[i];
2268 			break;
2269 		}
2270 	}
2271 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2272 
2273 	if (!sap_info)
2274 		goto end;
2275 	if (sap_info->freq == 0)
2276 		goto end;
2277 	nan_freq_2g = policy_mgr_mode_specific_get_channel(psoc,
2278 							   PM_NAN_DISC_MODE);
2279 	nan_freq_5g = wlan_nan_get_disc_5g_ch_freq(psoc);
2280 	if (sap_info->freq == nan_freq_2g || sap_info->freq == nan_freq_5g) {
2281 		policy_mgr_debug("NAN and SAP already in SCC");
2282 		goto end;
2283 	}
2284 	if (nan_freq_2g == 0)
2285 		goto end;
2286 
2287 	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
2288 	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
2289 		policy_mgr_debug("channel switch is already in progress");
2290 		return status;
2291 	}
2292 
2293 	if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason)
2294 		pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(psoc,
2295 					sap_info->vdev_id,
2296 					CSA_REASON_CONCURRENT_NAN_EVENT);
2297 
2298 	/* SAP should be moved to 2g NAN channel on non-DBS platforms */
2299 	if (!ucfg_is_nan_dbs_supported(pm_ctx->psoc) ||
2300 	    WLAN_REG_IS_24GHZ_CH_FREQ(sap_info->freq)) {
2301 		policy_mgr_debug("Force SCC for NAN+SAP Ch freq: %d",
2302 				 nan_freq_2g);
2303 		status =
2304 		policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id,
2305 						       nan_freq_2g,
2306 						       policy_mgr_get_ch_width(
2307 						       sap_info->bw),
2308 						       true);
2309 		if (status == QDF_STATUS_SUCCESS)
2310 			status = QDF_STATUS_E_PENDING;
2311 	} else if (nan_freq_5g && WLAN_REG_IS_5GHZ_CH_FREQ(sap_info->freq)) {
2312 		policy_mgr_debug("Force SCC for NAN+SAP Ch freq: %d",
2313 				 nan_freq_5g);
2314 		status =
2315 		policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id,
2316 						       nan_freq_5g,
2317 						       policy_mgr_get_ch_width(
2318 						       sap_info->bw),
2319 						       true);
2320 		if (status == QDF_STATUS_SUCCESS)
2321 			status = QDF_STATUS_E_PENDING;
2322 	}
2323 
2324 end:
2325 	pm_ctx->sta_ap_intf_check_work_info->nan_force_scc_in_progress = false;
2326 
2327 	return status;
2328 }
2329 
policy_mgr_nan_sap_post_disable_conc_check(struct wlan_objmgr_psoc * psoc)2330 void policy_mgr_nan_sap_post_disable_conc_check(struct wlan_objmgr_psoc *psoc)
2331 {
2332 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2333 	struct policy_mgr_conc_connection_info *sap_info = NULL;
2334 	uint32_t sap_freq = 0, i;
2335 	QDF_STATUS status;
2336 	uint32_t user_config_freq;
2337 	uint8_t band_mask = 0;
2338 	uint8_t chn_idx, num_chan;
2339 	struct regulatory_channel *channel_list;
2340 
2341 	pm_ctx = policy_mgr_get_context(psoc);
2342 	if (!pm_ctx) {
2343 		policy_mgr_err("Invalid pm context");
2344 		return;
2345 	}
2346 
2347 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
2348 		if (pm_conc_connection_list[i].mode == PM_SAP_MODE &&
2349 		    pm_conc_connection_list[i].in_use) {
2350 			sap_info = &pm_conc_connection_list[i];
2351 			sap_freq = sap_info->freq;
2352 			break;
2353 		}
2354 	}
2355 	if (sap_freq == 0 || policy_mgr_is_safe_channel(psoc, sap_freq))
2356 		return;
2357 
2358 	user_config_freq = policy_mgr_get_user_config_sap_freq(
2359 						psoc, sap_info->vdev_id);
2360 
2361 	sap_freq = policy_mgr_get_nondfs_preferred_channel(psoc, PM_SAP_MODE,
2362 							   false,
2363 							   sap_info->vdev_id);
2364 	policy_mgr_debug("User/ACS orig Freq: %d New SAP Freq: %d",
2365 			 user_config_freq, sap_freq);
2366 
2367 	if (wlan_reg_is_enable_in_secondary_list_for_freq(pm_ctx->pdev,
2368 							  user_config_freq) &&
2369 	    policy_mgr_is_safe_channel(psoc, user_config_freq)) {
2370 		policy_mgr_debug("Give preference to user config freq");
2371 		sap_freq = user_config_freq;
2372 	} else {
2373 		channel_list = qdf_mem_malloc(
2374 					sizeof(struct regulatory_channel) *
2375 					       NUM_CHANNELS);
2376 		if (!channel_list)
2377 			return;
2378 
2379 		band_mask |= BIT(wlan_reg_freq_to_band(user_config_freq));
2380 		num_chan = wlan_reg_get_band_channel_list_for_pwrmode(
2381 						pm_ctx->pdev,
2382 						band_mask,
2383 						channel_list,
2384 						REG_CURRENT_PWR_MODE);
2385 		for (chn_idx = 0; chn_idx < num_chan; chn_idx++) {
2386 			if (wlan_reg_is_enable_in_secondary_list_for_freq(
2387 					pm_ctx->pdev,
2388 					channel_list[chn_idx].center_freq) &&
2389 			    policy_mgr_is_safe_channel(
2390 					psoc,
2391 					channel_list[chn_idx].center_freq)) {
2392 				policy_mgr_debug("Prefer user config band freq %d",
2393 						 channel_list[chn_idx].center_freq);
2394 				sap_freq = channel_list[chn_idx].center_freq;
2395 			}
2396 		}
2397 		qdf_mem_free(channel_list);
2398 	}
2399 
2400 	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
2401 	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
2402 		policy_mgr_debug("wait as channel switch is already in progress");
2403 		status = qdf_wait_single_event(
2404 					&pm_ctx->channel_switch_complete_evt,
2405 					CHANNEL_SWITCH_COMPLETE_TIMEOUT);
2406 		if (QDF_IS_STATUS_ERROR(status))
2407 			policy_mgr_err("wait for event failed, still continue with channel switch");
2408 	}
2409 
2410 	if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason)
2411 		pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(
2412 				psoc, sap_info->vdev_id,
2413 				CSA_REASON_CONCURRENT_NAN_EVENT);
2414 
2415 	policy_mgr_change_sap_channel_with_csa(psoc, sap_info->vdev_id,
2416 					       sap_freq,
2417 					       policy_mgr_get_ch_width(
2418 					       sap_info->bw), true);
2419 }
2420 
policy_mgr_check_sap_restart(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)2421 void policy_mgr_check_sap_restart(struct wlan_objmgr_psoc *psoc,
2422 				  uint8_t vdev_id)
2423 {
2424 	QDF_STATUS status;
2425 	uint32_t ch_freq;
2426 	struct policy_mgr_psoc_priv_obj *pm_ctx = NULL;
2427 
2428 	if (!psoc) {
2429 		policy_mgr_err("Invalid psoc");
2430 		return;
2431 	}
2432 	pm_ctx = policy_mgr_get_context(psoc);
2433 	if (!pm_ctx) {
2434 		policy_mgr_err("Invalid context");
2435 		return;
2436 	}
2437 
2438 	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
2439 	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
2440 		policy_mgr_debug("channel switch is already in progress");
2441 		return;
2442 	}
2443 
2444 	/*
2445 	 * Restart should be handled by sap_fsm_validate_and_change_channel(),
2446 	 * after SAP starts.
2447 	 */
2448 	if (pm_ctx->hdd_cbacks.hdd_is_cac_in_progress &&
2449 	    pm_ctx->hdd_cbacks.hdd_is_cac_in_progress()) {
2450 		policy_mgr_debug("DFS CAC in progress, do not restart SAP");
2451 		return;
2452 	}
2453 
2454 	if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) {
2455 		policy_mgr_err("SAP restart get channel callback in NULL");
2456 		goto end;
2457 	}
2458 	status =
2459 		pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart(psoc,
2460 								      vdev_id,
2461 								      &ch_freq);
2462 	if (status == QDF_STATUS_SUCCESS)
2463 		policy_mgr_debug("SAP vdev id %d switch to new ch freq: %d",
2464 				 vdev_id, ch_freq);
2465 
2466 end:
2467 	pm_ctx->last_disconn_sta_freq = 0;
2468 }
2469 
2470 /**
2471  * policy_mgr_handle_sap_plus_go_force_scc() - Do SAP/GO force SCC
2472  * @psoc: soc object
2473  *
2474  * This function will check SAP/GO channel state and select channel
2475  * to avoid MCC, then do channel change on the second interface.
2476  *
2477  * Return: QDF_STATUS_SUCCESS if successfully handle the SAP/GO
2478  * force SCC.
2479  */
2480 static QDF_STATUS
policy_mgr_handle_sap_plus_go_force_scc(struct wlan_objmgr_psoc * psoc)2481 policy_mgr_handle_sap_plus_go_force_scc(struct wlan_objmgr_psoc *psoc)
2482 {
2483 	QDF_STATUS status = QDF_STATUS_E_INVAL;
2484 	uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
2485 	enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE;
2486 	enum policy_mgr_con_mode vdev_con_mode;
2487 	uint32_t existing_ch_freq, chan_freq, intf_ch_freq;
2488 	enum phy_ch_width existing_ch_width;
2489 	uint8_t vdev_id;
2490 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2491 	struct sta_ap_intf_check_work_ctx *work_info;
2492 	struct ch_params ch_params = {0};
2493 	enum QDF_OPMODE opmode;
2494 
2495 	pm_ctx = policy_mgr_get_context(psoc);
2496 	if (!pm_ctx) {
2497 		policy_mgr_err("Invalid Context");
2498 		return status;
2499 	}
2500 
2501 	work_info = pm_ctx->sta_ap_intf_check_work_info;
2502 	if (!work_info) {
2503 		policy_mgr_err("invalid work info");
2504 		return status;
2505 	}
2506 	if (work_info->sap_plus_go_force_scc.reason == CSA_REASON_UNKNOWN)
2507 		return status;
2508 
2509 	vdev_id = work_info->sap_plus_go_force_scc.initiator_vdev_id;
2510 	chan_freq = wlan_get_operation_chan_freq_vdev_id(pm_ctx->pdev, vdev_id);
2511 	opmode = wlan_get_opmode_from_vdev_id(pm_ctx->pdev, vdev_id);
2512 	vdev_con_mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, opmode,
2513 							     vdev_id);
2514 
2515 	existing_vdev_id =
2516 		policy_mgr_fetch_existing_con_info(
2517 				psoc,
2518 				vdev_id,
2519 				chan_freq,
2520 				&existing_vdev_mode,
2521 				&existing_ch_freq, &existing_ch_width);
2522 	policy_mgr_debug("initiator vdev %d mode %d freq %d, existing vdev %d mode %d freq %d reason %d",
2523 			 vdev_id, vdev_con_mode, chan_freq, existing_vdev_id,
2524 			 existing_vdev_mode, existing_ch_freq,
2525 			 work_info->sap_plus_go_force_scc.reason);
2526 
2527 	if (existing_vdev_id == WLAN_UMAC_VDEV_ID_MAX)
2528 		goto force_scc_done;
2529 
2530 	if (!((vdev_con_mode == PM_P2P_GO_MODE &&
2531 	       existing_vdev_mode == PM_SAP_MODE) ||
2532 	      (vdev_con_mode == PM_SAP_MODE &&
2533 	       existing_vdev_mode == PM_P2P_GO_MODE)))
2534 		goto force_scc_done;
2535 
2536 	if (!pm_ctx->hdd_cbacks.wlan_check_cc_intf_cb)
2537 		goto force_scc_done;
2538 
2539 	intf_ch_freq = 0;
2540 	status = pm_ctx->hdd_cbacks.wlan_check_cc_intf_cb(psoc,
2541 							  existing_vdev_id,
2542 							  &intf_ch_freq);
2543 	policy_mgr_debug("vdev %d freq %d intf %d status %d",
2544 			 existing_vdev_id, existing_ch_freq,
2545 			 intf_ch_freq, status);
2546 	if (QDF_IS_STATUS_ERROR(status))
2547 		goto force_scc_done;
2548 	if (!intf_ch_freq || intf_ch_freq == existing_ch_freq)
2549 		goto force_scc_done;
2550 
2551 	ch_params.ch_width = existing_ch_width;
2552 	if (pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params) {
2553 		status = pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params(
2554 			psoc, existing_vdev_id, intf_ch_freq, &ch_params);
2555 		if (QDF_IS_STATUS_ERROR(status))
2556 			policy_mgr_debug("no candidate valid bw for vdev %d intf %d",
2557 					 existing_vdev_id, intf_ch_freq);
2558 	}
2559 
2560 	status = policy_mgr_valid_sap_conc_channel_check(
2561 		    psoc, &intf_ch_freq, existing_ch_freq, existing_vdev_id,
2562 		    &ch_params);
2563 	if (QDF_IS_STATUS_ERROR(status)) {
2564 		policy_mgr_err("warning no candidate freq for vdev %d freq %d intf %d",
2565 			       existing_vdev_id, existing_ch_freq,
2566 			       intf_ch_freq);
2567 		goto force_scc_done;
2568 	}
2569 
2570 	if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason)
2571 		pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(
2572 				psoc, existing_vdev_id,
2573 				work_info->sap_plus_go_force_scc.reason);
2574 
2575 	status = policy_mgr_change_sap_channel_with_csa(
2576 			psoc, existing_vdev_id, intf_ch_freq,
2577 			ch_params.ch_width, true);
2578 	if (QDF_IS_STATUS_ERROR(status)) {
2579 		policy_mgr_err("warning sap/go vdev %d freq %d intf %d csa failed",
2580 			       existing_vdev_id, existing_ch_freq,
2581 			       intf_ch_freq);
2582 	}
2583 
2584 force_scc_done:
2585 	work_info->sap_plus_go_force_scc.reason = CSA_REASON_UNKNOWN;
2586 	work_info->sap_plus_go_force_scc.initiator_vdev_id =
2587 					WLAN_UMAC_VDEV_ID_MAX;
2588 	work_info->sap_plus_go_force_scc.responder_vdev_id =
2589 					WLAN_UMAC_VDEV_ID_MAX;
2590 
2591 	return status;
2592 }
2593 
2594 QDF_STATUS
policy_mgr_check_sap_go_force_scc(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,enum sap_csa_reason_code reason_code)2595 policy_mgr_check_sap_go_force_scc(struct wlan_objmgr_psoc *psoc,
2596 				  struct wlan_objmgr_vdev *vdev,
2597 				  enum sap_csa_reason_code reason_code)
2598 {
2599 	uint8_t existing_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
2600 	enum policy_mgr_con_mode existing_vdev_mode = PM_MAX_NUM_OF_MODE;
2601 	enum policy_mgr_con_mode vdev_con_mode;
2602 	uint32_t con_freq, chan_freq;
2603 	enum phy_ch_width ch_width;
2604 	uint8_t vdev_id;
2605 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2606 	struct sta_ap_intf_check_work_ctx *work_info;
2607 	enum QDF_OPMODE opmode;
2608 
2609 	if (reason_code != CSA_REASON_GO_BSS_STARTED &&
2610 	    reason_code != CSA_REASON_USER_INITIATED)
2611 		return QDF_STATUS_SUCCESS;
2612 
2613 	pm_ctx = policy_mgr_get_context(psoc);
2614 	if (!pm_ctx) {
2615 		policy_mgr_err("Invalid Context");
2616 		return QDF_STATUS_E_INVAL;
2617 	}
2618 	if (pm_ctx->cfg.mcc_to_scc_switch ==
2619 		QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL)
2620 		return QDF_STATUS_SUCCESS;
2621 
2622 	if (!vdev) {
2623 		policy_mgr_err("vdev is null");
2624 		return QDF_STATUS_E_INVAL;
2625 	}
2626 	vdev_id = wlan_vdev_get_id(vdev);
2627 	opmode = wlan_vdev_mlme_get_opmode(vdev);
2628 	work_info = pm_ctx->sta_ap_intf_check_work_info;
2629 	if (!work_info) {
2630 		policy_mgr_err("invalid work info");
2631 		return QDF_STATUS_E_INVAL;
2632 	}
2633 
2634 	chan_freq = wlan_get_operation_chan_freq(vdev);
2635 	vdev_con_mode = policy_mgr_qdf_opmode_to_pm_con_mode(psoc, opmode,
2636 							     vdev_id);
2637 
2638 	existing_vdev_id =
2639 		policy_mgr_fetch_existing_con_info(psoc,
2640 						   vdev_id,
2641 						   chan_freq,
2642 						   &existing_vdev_mode,
2643 						   &con_freq, &ch_width);
2644 	if (existing_vdev_id == WLAN_UMAC_VDEV_ID_MAX)
2645 		return QDF_STATUS_SUCCESS;
2646 
2647 	if (!((vdev_con_mode == PM_P2P_GO_MODE &&
2648 	       existing_vdev_mode == PM_SAP_MODE) ||
2649 	      (vdev_con_mode == PM_SAP_MODE &&
2650 	       existing_vdev_mode == PM_P2P_GO_MODE)))
2651 		return QDF_STATUS_SUCCESS;
2652 
2653 	work_info->sap_plus_go_force_scc.reason = reason_code;
2654 	work_info->sap_plus_go_force_scc.initiator_vdev_id = vdev_id;
2655 	work_info->sap_plus_go_force_scc.responder_vdev_id = existing_vdev_id;
2656 
2657 	policy_mgr_debug("initiator vdev %d freq %d, existing vdev %d freq %d reason %d",
2658 			 vdev_id, chan_freq, existing_vdev_id,
2659 			 con_freq, reason_code);
2660 
2661 	if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
2662 				    WAIT_BEFORE_GO_FORCESCC_RESTART))
2663 		policy_mgr_debug("change interface request already queued");
2664 
2665 	return QDF_STATUS_E_PENDING;
2666 }
2667 
2668 /**
2669  * policy_mgr_is_any_conn_in_transition() - Check if any STA/CLI
2670  * connection is disconnecting or roaming state
2671  * @psoc: PSOC object information
2672  *
2673  * This function will check connection table and find any STA/CLI
2674  * in transition state such as disconnecting, link switch or roaming.
2675  *
2676  * Return: true if there is one STA/CLI in transition state.
2677  */
2678 static bool
policy_mgr_is_any_conn_in_transition(struct wlan_objmgr_psoc * psoc)2679 policy_mgr_is_any_conn_in_transition(struct wlan_objmgr_psoc *psoc)
2680 {
2681 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2682 	uint32_t i;
2683 	struct policy_mgr_conc_connection_info *conn_info;
2684 	struct wlan_objmgr_vdev *vdev;
2685 	bool non_connected = false;
2686 	bool in_link_switch = false;
2687 	uint8_t vdev_id;
2688 
2689 	pm_ctx = policy_mgr_get_context(psoc);
2690 	if (!pm_ctx) {
2691 		policy_mgr_err("Invalid pm context");
2692 		return false;
2693 	}
2694 
2695 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2696 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
2697 		conn_info = &pm_conc_connection_list[i];
2698 		if (!(conn_info->in_use &&
2699 		      (conn_info->mode == PM_STA_MODE ||
2700 		       conn_info->mode == PM_P2P_CLIENT_MODE)))
2701 			continue;
2702 		vdev_id = conn_info->vdev_id;
2703 		vdev = wlan_objmgr_get_vdev_by_id_from_pdev(
2704 				pm_ctx->pdev, vdev_id, WLAN_POLICY_MGR_ID);
2705 		if (!vdev) {
2706 			policy_mgr_err("vdev %d: not found", vdev_id);
2707 			continue;
2708 		}
2709 
2710 		non_connected = !wlan_cm_is_vdev_connected(vdev);
2711 
2712 		if (mlo_is_mld_sta(vdev) &&
2713 		    mlo_mgr_is_link_switch_in_progress(vdev))
2714 			in_link_switch = true;
2715 
2716 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
2717 		if (non_connected) {
2718 			policy_mgr_debug("vdev %d: is in transition state",
2719 					 vdev_id);
2720 			break;
2721 		}
2722 		if (in_link_switch) {
2723 			policy_mgr_debug("vdev %d: sta mld is in link switch state",
2724 					 vdev_id);
2725 			break;
2726 		}
2727 	}
2728 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2729 
2730 	return non_connected || in_link_switch;
2731 }
2732 
__policy_mgr_check_sta_ap_concurrent_ch_intf(struct policy_mgr_psoc_priv_obj * pm_ctx)2733 static void __policy_mgr_check_sta_ap_concurrent_ch_intf(
2734 				struct policy_mgr_psoc_priv_obj *pm_ctx)
2735 {
2736 	uint32_t mcc_to_scc_switch, cc_count = 0, i;
2737 	QDF_STATUS status;
2738 	uint32_t ch_freq;
2739 	uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS];
2740 	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS];
2741 	struct sta_ap_intf_check_work_ctx *work_info;
2742 
2743 	if (!pm_ctx) {
2744 		policy_mgr_err("Invalid context");
2745 		return;
2746 	}
2747 	work_info = pm_ctx->sta_ap_intf_check_work_info;
2748 
2749 	if (work_info->nan_force_scc_in_progress) {
2750 		policy_mgr_nan_sap_post_enable_conc_check(pm_ctx->psoc);
2751 		return;
2752 	}
2753 	/*
2754 	 * Check if force scc is required for GO + GO case. vdev id will be
2755 	 * valid in case of GO+GO force scc only. So, for valid vdev id move
2756 	 * first GO to newly formed GO channel.
2757 	 */
2758 	policy_mgr_debug("p2p go vdev id: %d csa reason: %d",
2759 			 work_info->go_plus_go_force_scc.vdev_id,
2760 			 work_info->sap_plus_go_force_scc.reason);
2761 	if (pm_ctx->sta_ap_intf_check_work_info->go_plus_go_force_scc.vdev_id <
2762 	    WLAN_UMAC_VDEV_ID_MAX) {
2763 		policy_mgr_do_go_plus_go_force_scc(
2764 			pm_ctx->psoc, work_info->go_plus_go_force_scc.vdev_id,
2765 			work_info->go_plus_go_force_scc.ch_freq,
2766 			work_info->go_plus_go_force_scc.ch_width);
2767 		work_info->go_plus_go_force_scc.vdev_id = WLAN_UMAC_VDEV_ID_MAX;
2768 		goto end;
2769 	}
2770 	/*
2771 	 * Check if force scc is required for GO + SAP case.
2772 	 */
2773 	if (pm_ctx->sta_ap_intf_check_work_info->sap_plus_go_force_scc.reason !=
2774 	    CSA_REASON_UNKNOWN) {
2775 		status = policy_mgr_handle_sap_plus_go_force_scc(pm_ctx->psoc);
2776 		goto end;
2777 	}
2778 
2779 	mcc_to_scc_switch =
2780 		policy_mgr_get_mcc_to_scc_switch_mode(pm_ctx->psoc);
2781 
2782 	policy_mgr_debug("Concurrent open sessions running: %d",
2783 			 policy_mgr_concurrent_open_sessions_running(pm_ctx->psoc));
2784 
2785 	if (!policy_mgr_is_sap_go_existed(pm_ctx->psoc))
2786 		goto end;
2787 
2788 	cc_count = policy_mgr_get_sap_mode_info(pm_ctx->psoc,
2789 						&op_ch_freq_list[cc_count],
2790 						&vdev_id[cc_count]);
2791 
2792 	policy_mgr_debug("Number of concurrent SAP: %d", cc_count);
2793 	if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS)
2794 		cc_count = cc_count +
2795 				policy_mgr_get_mode_specific_conn_info(
2796 					pm_ctx->psoc, &op_ch_freq_list[cc_count],
2797 					&vdev_id[cc_count], PM_P2P_GO_MODE);
2798 	policy_mgr_debug("Number of beaconing entities (SAP + GO):%d",
2799 							cc_count);
2800 	if (!cc_count) {
2801 		policy_mgr_err("Could not retrieve SAP/GO operating channel&vdevid");
2802 		goto end;
2803 	}
2804 
2805 	/* When any STA/CLI is transition state, such as roaming or
2806 	 * disconnecting, skip force scc for this time.
2807 	 */
2808 	if (policy_mgr_is_any_conn_in_transition(pm_ctx->psoc)) {
2809 		policy_mgr_debug("defer sap conc check to a later time due to another sta/cli dicon/roam pending");
2810 		qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
2811 				       SAP_CONC_CHECK_DEFER_TIMEOUT_MS);
2812 		goto end;
2813 	}
2814 
2815 	if (policy_mgr_is_ap_start_in_progress(pm_ctx->psoc)) {
2816 		policy_mgr_debug("defer sap conc check to a later time due to another sap/go start pending");
2817 		qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
2818 				       SAP_CONC_CHECK_DEFER_TIMEOUT_MS);
2819 		goto end;
2820 	}
2821 	if (policy_mgr_is_set_link_in_progress(pm_ctx->psoc)) {
2822 		policy_mgr_debug("defer sap conc check to a later time due to ml sta set link in progress");
2823 		qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
2824 				       SAP_CONC_CHECK_DEFER_TIMEOUT_MS);
2825 		goto end;
2826 	}
2827 
2828 	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
2829 	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
2830 		policy_mgr_debug("wait as channel switch is already in progress");
2831 		status = qdf_wait_single_event(
2832 					&pm_ctx->channel_switch_complete_evt,
2833 					CHANNEL_SWITCH_COMPLETE_TIMEOUT);
2834 		if (QDF_IS_STATUS_ERROR(status))
2835 			policy_mgr_err("wait for event failed, still continue with channel switch");
2836 	}
2837 
2838 	if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) {
2839 		policy_mgr_err("SAP restart get channel callback in NULL");
2840 		goto end;
2841 	}
2842 	if (cc_count <= MAX_NUMBER_OF_CONC_CONNECTIONS)
2843 		for (i = 0; i < cc_count; i++) {
2844 			status = pm_ctx->hdd_cbacks.
2845 				wlan_hdd_get_channel_for_sap_restart
2846 					(pm_ctx->psoc, vdev_id[i], &ch_freq);
2847 			if (status == QDF_STATUS_SUCCESS) {
2848 				policy_mgr_debug("SAP vdev id %d restarts, old ch freq :%d new ch freq: %d",
2849 						 vdev_id[i],
2850 						 op_ch_freq_list[i], ch_freq);
2851 				break;
2852 			}
2853 		}
2854 
2855 end:
2856 	pm_ctx->last_disconn_sta_freq = 0;
2857 }
2858 
policy_mgr_check_sta_ap_concurrent_ch_intf(void * data)2859 void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data)
2860 {
2861 	struct qdf_op_sync *op_sync;
2862 	struct policy_mgr_psoc_priv_obj *pm_ctx = data;
2863 	int ret;
2864 
2865 	if (!pm_ctx) {
2866 		policy_mgr_err("Invalid context");
2867 		return;
2868 	}
2869 
2870 	ret = qdf_op_protect(&op_sync);
2871 	if (ret) {
2872 		if (ret == -EAGAIN) {
2873 			if (qdf_is_driver_unloading() ||
2874 			    qdf_is_recovering() ||
2875 			    qdf_is_driver_state_module_stop()) {
2876 				policy_mgr_debug("driver not ready");
2877 				return;
2878 			}
2879 
2880 			if (!pm_ctx->sta_ap_intf_check_work_info)
2881 				return;
2882 
2883 			pm_ctx->work_fail_count++;
2884 			policy_mgr_debug("qdf_op start fail, ret %d, work_fail_count %d",
2885 					 ret, pm_ctx->work_fail_count);
2886 			if (pm_ctx->work_fail_count > 1) {
2887 				pm_ctx->work_fail_count = 0;
2888 				return;
2889 			}
2890 			qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
2891 					       SAP_CONC_CHECK_DEFER_TIMEOUT_MS);
2892 		}
2893 		return;
2894 	}
2895 	pm_ctx->work_fail_count = 0;
2896 	__policy_mgr_check_sta_ap_concurrent_ch_intf(data);
2897 
2898 	qdf_op_unprotect(op_sync);
2899 }
2900 
policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc * psoc,uint32_t sta_ch_freq)2901 static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc,
2902 						uint32_t sta_ch_freq)
2903 {
2904 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2905 	bool sta_sap_scc_on_dfs_chan, sta_sap_scc_on_indoor_channel;
2906 
2907 	pm_ctx = policy_mgr_get_context(psoc);
2908 	if (!pm_ctx) {
2909 		policy_mgr_err("Invalid context");
2910 		return false;
2911 	}
2912 
2913 	sta_sap_scc_on_dfs_chan =
2914 		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
2915 	if (wlan_reg_is_dfs_for_freq(pm_ctx->pdev, sta_ch_freq) &&
2916 	    sta_sap_scc_on_dfs_chan) {
2917 		policy_mgr_debug("STA, SAP SCC is allowed on DFS chan %u",
2918 				 sta_ch_freq);
2919 		return true;
2920 	}
2921 
2922 	sta_sap_scc_on_indoor_channel =
2923 		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
2924 	if (wlan_reg_is_freq_indoor(pm_ctx->pdev, sta_ch_freq) &&
2925 	    sta_sap_scc_on_indoor_channel) {
2926 		policy_mgr_debug("STA, SAP SCC is allowed on indoor chan %u",
2927 				 sta_ch_freq);
2928 		return true;
2929 	}
2930 
2931 	if ((wlan_reg_is_dfs_for_freq(pm_ctx->pdev, sta_ch_freq) &&
2932 	     !sta_sap_scc_on_dfs_chan) ||
2933 	    wlan_reg_is_passive_or_disable_for_pwrmode(
2934 	    pm_ctx->pdev, sta_ch_freq, REG_CURRENT_PWR_MODE) ||
2935 	    (wlan_reg_is_freq_indoor(pm_ctx->pdev, sta_ch_freq) &&
2936 	     !sta_sap_scc_on_indoor_channel) ||
2937 	    (!policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) &&
2938 	     !policy_mgr_is_safe_channel(psoc, sta_ch_freq))) {
2939 		if (policy_mgr_is_hw_dbs_capable(psoc))
2940 			return true;
2941 		else
2942 			return false;
2943 	}
2944 	else
2945 		return true;
2946 }
2947 
policy_mgr_get_srd_enable_for_vdev(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)2948 static bool policy_mgr_get_srd_enable_for_vdev(
2949 				struct wlan_objmgr_psoc *psoc,
2950 				uint8_t vdev_id)
2951 {
2952 	struct wlan_objmgr_vdev *vdev;
2953 	enum QDF_OPMODE vdev_opmode;
2954 	bool enable_srd_channel = false;
2955 
2956 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
2957 						    WLAN_POLICY_MGR_ID);
2958 	if (!vdev) {
2959 		policy_mgr_err("vdev is NULL");
2960 		return false;
2961 	}
2962 
2963 	vdev_opmode = wlan_vdev_mlme_get_opmode(vdev);
2964 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
2965 
2966 	wlan_mlme_get_srd_master_mode_for_vdev(psoc, vdev_opmode,
2967 					       &enable_srd_channel);
2968 	return enable_srd_channel;
2969 }
2970 
2971 QDF_STATUS
policy_mgr_valid_sap_conc_channel_check(struct wlan_objmgr_psoc * psoc,uint32_t * con_ch_freq,uint32_t sap_ch_freq,uint8_t sap_vdev_id,struct ch_params * ch_params)2972 policy_mgr_valid_sap_conc_channel_check(struct wlan_objmgr_psoc *psoc,
2973 					uint32_t *con_ch_freq,
2974 					uint32_t sap_ch_freq,
2975 					uint8_t sap_vdev_id,
2976 					struct ch_params *ch_params)
2977 {
2978 	struct policy_mgr_psoc_priv_obj *pm_ctx;
2979 	uint32_t ch_freq = *con_ch_freq;
2980 	bool find_alternate = false;
2981 	enum phy_ch_width old_ch_width;
2982 	bool sta_sap_scc_on_dfs_chan, sta_sap_scc_on_indoor_channel;
2983 	bool is_dfs;
2984 	bool is_6ghz_cap;
2985 	bool is_sta_sap_scc;
2986 	enum policy_mgr_con_mode con_mode;
2987 	uint32_t nan_2g_freq, nan_5g_freq;
2988 
2989 	pm_ctx = policy_mgr_get_context(psoc);
2990 	if (!pm_ctx) {
2991 		policy_mgr_err("Invalid context");
2992 		return QDF_STATUS_E_FAILURE;
2993 	}
2994 	/*
2995 	 * If force SCC is set, Check if conc channel is DFS
2996 	 * or passive or part of LTE avoided channel list.
2997 	 * In that case move SAP to other band if DBS is supported,
2998 	 * return otherwise
2999 	 */
3000 	if (!policy_mgr_is_force_scc(psoc))
3001 		return QDF_STATUS_SUCCESS;
3002 
3003 	/*
3004 	 * If interference is 0, it could be STA/SAP SCC,
3005 	 * check further if SAP can start on STA home channel or
3006 	 * select other band channel if not.
3007 	 */
3008 	if (!ch_freq) {
3009 		if (!policy_mgr_any_other_vdev_on_same_mac_as_freq(psoc,
3010 								   sap_ch_freq,
3011 								   sap_vdev_id))
3012 			return QDF_STATUS_SUCCESS;
3013 
3014 		ch_freq = sap_ch_freq;
3015 	}
3016 
3017 	if (!ch_freq)
3018 		return QDF_STATUS_SUCCESS;
3019 
3020 	con_mode = policy_mgr_con_mode_by_vdev_id(psoc, sap_vdev_id);
3021 
3022 	is_sta_sap_scc = policy_mgr_is_sta_sap_scc(psoc, ch_freq);
3023 
3024 	nan_2g_freq =
3025 		policy_mgr_mode_specific_get_channel(psoc, PM_NAN_DISC_MODE);
3026 	nan_5g_freq = wlan_nan_get_disc_5g_ch_freq(psoc);
3027 
3028 	sta_sap_scc_on_dfs_chan =
3029 		policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
3030 
3031 	sta_sap_scc_on_indoor_channel =
3032 		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(psoc);
3033 	old_ch_width = ch_params->ch_width;
3034 	if (pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params)
3035 		pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params(
3036 			psoc, sap_vdev_id, ch_freq, ch_params);
3037 
3038 	is_dfs = wlan_mlme_check_chan_param_has_dfs(
3039 			pm_ctx->pdev, ch_params, ch_freq);
3040 	is_6ghz_cap = policy_mgr_get_ap_6ghz_capable(psoc, sap_vdev_id, NULL);
3041 
3042 	if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) && is_dfs &&
3043 	    !sta_sap_scc_on_dfs_chan && is_sta_sap_scc) {
3044 		find_alternate = true;
3045 		policymgr_nofl_debug("sap not capable of DFS SCC on con ch_freq %d",
3046 				     ch_freq);
3047 	} else if (wlan_reg_is_disable_for_pwrmode(pm_ctx->pdev, ch_freq,
3048 						   REG_CURRENT_PWR_MODE)) {
3049 		find_alternate = true;
3050 		policymgr_nofl_debug("sap not capable on disabled con ch_freq %d",
3051 				     ch_freq);
3052 	} else if (con_mode == PM_P2P_GO_MODE &&
3053 		   wlan_reg_is_passive_or_disable_for_pwrmode(
3054 						pm_ctx->pdev,
3055 						ch_freq,
3056 						REG_CURRENT_PWR_MODE) &&
3057 		   !(policy_mgr_is_go_scc_strict(psoc) &&
3058 		     (!is_sta_sap_scc || sta_sap_scc_on_dfs_chan))) {
3059 		find_alternate = true;
3060 		policymgr_nofl_debug("Go not capable on dfs/disabled con ch_freq %d",
3061 				     ch_freq);
3062 	} else if (!policy_mgr_is_safe_channel(psoc, ch_freq) &&
3063 		   !(policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) &&
3064 		     is_sta_sap_scc) &&
3065 		   !(policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(psoc) &&
3066 		    (WLAN_REG_IS_SAME_BAND_FREQS(nan_2g_freq, ch_freq) ||
3067 		     WLAN_REG_IS_SAME_BAND_FREQS(nan_5g_freq, ch_freq)))) {
3068 		find_alternate = true;
3069 		policymgr_nofl_debug("sap not capable unsafe con ch_freq %d",
3070 				     ch_freq);
3071 	} else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq) &&
3072 		   !WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ch_freq) &&
3073 		   !is_6ghz_cap) {
3074 		policymgr_nofl_debug("sap not capable on 6GHZ con ch_freq %d",
3075 				     ch_freq);
3076 		find_alternate = true;
3077 	} else if (wlan_reg_is_etsi_srd_chan_for_freq(pm_ctx->pdev,
3078 						      ch_freq) &&
3079 		   !policy_mgr_get_srd_enable_for_vdev(psoc, sap_vdev_id)) {
3080 		find_alternate = true;
3081 		policymgr_nofl_debug("sap not capable on SRD con ch_freq %d",
3082 				     ch_freq);
3083 	} else if (!policy_mgr_is_sap_go_interface_allowed_on_indoor(
3084 							pm_ctx->pdev,
3085 							sap_vdev_id, ch_freq)) {
3086 		policymgr_nofl_debug("sap not capable on indoor con ch_freq %d is_sta_sap_scc:%d",
3087 				     ch_freq, is_sta_sap_scc);
3088 		find_alternate = true;
3089 	}
3090 
3091 	if (find_alternate) {
3092 		if (policy_mgr_is_hw_dbs_capable(psoc)) {
3093 			ch_freq = policy_mgr_get_alternate_channel_for_sap(
3094 						psoc, sap_vdev_id, sap_ch_freq,
3095 						REG_BAND_UNKNOWN);
3096 			policymgr_nofl_debug("selected alternate ch %d",
3097 					     ch_freq);
3098 			if (!ch_freq) {
3099 				policymgr_nofl_debug("Sap can't have concurrency on %d in dbs hw",
3100 						     *con_ch_freq);
3101 				return QDF_STATUS_E_FAILURE;
3102 			}
3103 		} else {
3104 			/* MCC not supported for non-DBS chip*/
3105 			ch_freq = 0;
3106 			if (con_mode == PM_SAP_MODE) {
3107 				policymgr_nofl_debug("MCC situation in non-dbs hw STA freq %d SAP freq %d not supported",
3108 						     *con_ch_freq, sap_ch_freq);
3109 				return QDF_STATUS_E_FAILURE;
3110 			} else {
3111 				policymgr_nofl_debug("MCC situation in non-dbs hw STA freq %d GO freq %d SCC not supported",
3112 						     *con_ch_freq, sap_ch_freq);
3113 			}
3114 		}
3115 	}
3116 
3117 	if (ch_freq != sap_ch_freq || old_ch_width != ch_params->ch_width) {
3118 		*con_ch_freq = ch_freq;
3119 		policymgr_nofl_debug("sap conc result con freq %d bw %d org freq %d bw %d",
3120 				     ch_freq, ch_params->ch_width, sap_ch_freq,
3121 				     old_ch_width);
3122 	}
3123 
3124 	if (*con_ch_freq &&
3125 	    pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params)
3126 		pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params(
3127 			psoc, sap_vdev_id, ch_freq, ch_params);
3128 
3129 	return QDF_STATUS_SUCCESS;
3130 }
3131 
policy_mgr_check_concurrent_intf_and_restart_sap(struct wlan_objmgr_psoc * psoc,bool is_acs_mode)3132 void policy_mgr_check_concurrent_intf_and_restart_sap(
3133 		struct wlan_objmgr_psoc *psoc, bool is_acs_mode)
3134 {
3135 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3136 	uint32_t mcc_to_scc_switch;
3137 	uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
3138 	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
3139 	uint32_t cc_count = 0;
3140 	uint32_t timeout_ms = 0;
3141 	bool restart_sap = false;
3142 	uint32_t sap_freq;
3143 	/*
3144 	 * if no sta, sap/p2p go may need switch channel for band
3145 	 * capability change.
3146 	 * If sta exist, sap/p2p go may need switch channel to force scc
3147 	 */
3148 	bool sta_check = false, gc_check = false;
3149 
3150 	pm_ctx = policy_mgr_get_context(psoc);
3151 	if (!pm_ctx) {
3152 		policy_mgr_err("Invalid context");
3153 		return;
3154 	}
3155 	if (!pm_ctx->sta_ap_intf_check_work_info) {
3156 		policy_mgr_err("Invalid sta_ap_intf_check_work_info");
3157 		return;
3158 	}
3159 	if (!policy_mgr_is_sap_go_existed(psoc)) {
3160 		policy_mgr_debug(
3161 			"No action taken at check_concurrent_intf_and_restart_sap");
3162 		return;
3163 	}
3164 
3165 	if (policy_mgr_is_ll_lt_sap_restart_required(psoc)) {
3166 		restart_sap = true;
3167 		goto sap_restart;
3168 	}
3169 
3170 	/*
3171 	 * If STA+SAP sessions are on DFS channel and STA+SAP SCC is
3172 	 * enabled on DFS channel then move the SAP out of DFS channel
3173 	 * as soon as STA gets disconnect.
3174 	 * If STA+SAP sessions are on unsafe channel and STA+SAP SCC is
3175 	 * enabled on unsafe channel then move the SAP to safe channel
3176 	 * as soon as STA disconnected.
3177 	 */
3178 	if (policy_mgr_is_sap_restart_required_after_sta_disconnect(
3179 			psoc, INVALID_VDEV_ID, &sap_freq, is_acs_mode)) {
3180 		policy_mgr_debug("move the SAP to configured channel %u",
3181 				 sap_freq);
3182 		restart_sap = true;
3183 		goto sap_restart;
3184 	}
3185 
3186 	/*
3187 	 * This is to check the cases where STA got disconnected or
3188 	 * sta is present on some valid channel where SAP evaluation/restart
3189 	 * might be needed.
3190 	 * force SCC with STA+STA+SAP will need some additional logic
3191 	 */
3192 	cc_count = policy_mgr_get_mode_specific_conn_info(
3193 				psoc, &op_ch_freq_list[cc_count],
3194 				&vdev_id[cc_count], PM_STA_MODE);
3195 
3196 	sta_check = !cc_count ||
3197 		    policy_mgr_valid_sta_channel_check(psoc, op_ch_freq_list[0]);
3198 
3199 	cc_count = 0;
3200 	cc_count = policy_mgr_get_mode_specific_conn_info(
3201 				psoc, &op_ch_freq_list[cc_count],
3202 				&vdev_id[cc_count], PM_P2P_CLIENT_MODE);
3203 
3204 	gc_check = !!cc_count;
3205 
3206 	mcc_to_scc_switch =
3207 		policy_mgr_get_mcc_to_scc_switch_mode(psoc);
3208 	policy_mgr_debug("MCC to SCC switch: %d chan: %d sta_check: %d, gc_check: %d",
3209 			 mcc_to_scc_switch, op_ch_freq_list[0],
3210 			 sta_check, gc_check);
3211 
3212 	cc_count = 0;
3213 	cc_count = policy_mgr_get_mode_specific_conn_info(
3214 				psoc, &op_ch_freq_list[cc_count],
3215 				&vdev_id[cc_count], PM_SAP_MODE);
3216 
3217 	/* SAP + SAP case needs additional handling */
3218 	if (cc_count == 1 && !is_acs_mode &&
3219 	    target_psoc_get_sap_coex_fixed_chan_cap(
3220 			wlan_psoc_get_tgt_if_handle(psoc)) &&
3221 	    !policy_mgr_is_safe_channel(psoc, op_ch_freq_list[0])) {
3222 		policy_mgr_debug("Avoid channel switch as it's allowed to operate on unsafe channel: %d",
3223 				 op_ch_freq_list[0]);
3224 		return;
3225 	}
3226 
3227 sap_restart:
3228 	/*
3229 	 * If sta_sap_scc_on_dfs_chan is true then standalone SAP is not
3230 	 * allowed on DFS channel. SAP is allowed on DFS channel only when STA
3231 	 * is already connected on that channel.
3232 	 * In following condition restart_sap will be true if
3233 	 * sta_sap_scc_on_dfs_chan is true and SAP is on DFS channel.
3234 	 * This scenario can come if STA+SAP are operating on DFS channel and
3235 	 * STA gets disconnected.
3236 	 */
3237 	if (restart_sap ||
3238 	    ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) &&
3239 	    (sta_check || gc_check))) {
3240 		if (!pm_ctx->sta_ap_intf_check_work_info) {
3241 			policy_mgr_err("invalid sta_ap_intf_check_work_info");
3242 			return;
3243 		}
3244 
3245 		policy_mgr_debug("Checking for Concurrent Change interference");
3246 
3247 		if (policy_mgr_mode_specific_connection_count(
3248 					psoc, PM_P2P_GO_MODE, NULL))
3249 			timeout_ms = MAX_NOA_TIME;
3250 
3251 		if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
3252 					    timeout_ms)) {
3253 			policy_mgr_debug("change interface request already queued");
3254 			return;
3255 		}
3256 	}
3257 }
3258 
policy_mgr_check_bw_with_unsafe_chan_freq(struct wlan_objmgr_psoc * psoc,qdf_freq_t center_freq,enum phy_ch_width ch_width)3259 bool policy_mgr_check_bw_with_unsafe_chan_freq(struct wlan_objmgr_psoc *psoc,
3260 					       qdf_freq_t center_freq,
3261 					       enum phy_ch_width ch_width)
3262 {
3263 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3264 	uint32_t freq_start, freq_end, bw, i, unsafe_chan_freq;
3265 
3266 	pm_ctx = policy_mgr_get_context(psoc);
3267 	if (!pm_ctx) {
3268 		policy_mgr_err("Invalid Context");
3269 		return true;
3270 	}
3271 
3272 	if (ch_width <= CH_WIDTH_20MHZ || !center_freq)
3273 		return true;
3274 
3275 	if (!pm_ctx->unsafe_channel_count)
3276 		return true;
3277 
3278 	bw = wlan_reg_get_bw_value(ch_width);
3279 	freq_start = center_freq - bw / 2;
3280 	freq_end = center_freq + bw / 2;
3281 
3282 	for (i = 0; i < pm_ctx->unsafe_channel_count; i++) {
3283 		unsafe_chan_freq = pm_ctx->unsafe_channel_list[i];
3284 		if (unsafe_chan_freq > freq_start &&
3285 		    unsafe_chan_freq < freq_end) {
3286 			policy_mgr_debug("unsafe ch freq %d is in range %d-%d",
3287 					 unsafe_chan_freq,
3288 					 freq_start,
3289 					 freq_end);
3290 			return false;
3291 		}
3292 	}
3293 	return true;
3294 }
3295 
3296 /**
3297  * policy_mgr_change_sap_channel_with_csa() - Move SAP channel using (E)CSA
3298  * @psoc: PSOC object information
3299  * @vdev_id: Vdev id
3300  * @ch_freq: Channel to change
3301  * @ch_width: channel width to change
3302  * @forced: Force to switch channel, ignore SCC/MCC check
3303  *
3304  * Invoke the callback function to change SAP channel using (E)CSA
3305  *
3306  * Return: QDF_STATUS_SUCCESS for success
3307  */
3308 QDF_STATUS
policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint32_t ch_freq,uint32_t ch_width,bool forced)3309 policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc,
3310 				       uint8_t vdev_id, uint32_t ch_freq,
3311 				       uint32_t ch_width, bool forced)
3312 {
3313 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3314 	struct ch_params ch_params = {0};
3315 	qdf_freq_t center_freq;
3316 	QDF_STATUS status;
3317 
3318 	pm_ctx = policy_mgr_get_context(psoc);
3319 	if (!pm_ctx) {
3320 		policy_mgr_err("Invalid context");
3321 		return QDF_STATUS_E_INVAL;
3322 	}
3323 	if (pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params) {
3324 		ch_params.ch_width = ch_width;
3325 		status = pm_ctx->hdd_cbacks.wlan_get_ap_prefer_conc_ch_params(
3326 			psoc, vdev_id, ch_freq, &ch_params);
3327 		if (QDF_IS_STATUS_SUCCESS(status) &&
3328 		    ch_width > ch_params.ch_width)
3329 			ch_width = ch_params.ch_width;
3330 	}
3331 
3332 	if (ch_params.mhz_freq_seg1)
3333 		center_freq = ch_params.mhz_freq_seg1;
3334 	else
3335 		center_freq = ch_params.mhz_freq_seg0;
3336 
3337 	if (!policy_mgr_check_bw_with_unsafe_chan_freq(psoc,
3338 						       center_freq,
3339 						       ch_width)) {
3340 		policy_mgr_info("SAP bw shrink to 20M for unsafe");
3341 		ch_width = CH_WIDTH_20MHZ;
3342 	}
3343 
3344 	if (pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb) {
3345 		policy_mgr_info("SAP change change without restart");
3346 		status = pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb(psoc,
3347 								       vdev_id,
3348 								       ch_freq,
3349 								       ch_width,
3350 								       forced);
3351 	} else {
3352 		status = QDF_STATUS_E_INVAL;
3353 	}
3354 
3355 	return status;
3356 }
3357 #endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */
3358 
3359 QDF_STATUS
policy_mgr_sta_sap_dfs_scc_conc_check(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,struct csa_offload_params * csa_event)3360 policy_mgr_sta_sap_dfs_scc_conc_check(struct wlan_objmgr_psoc *psoc,
3361 				      uint8_t vdev_id,
3362 				      struct csa_offload_params *csa_event)
3363 {
3364 	uint8_t concur_vdev_id, i;
3365 	bool move_sap_go_first;
3366 	enum hw_mode_bandwidth bw;
3367 	qdf_freq_t cur_freq, new_freq;
3368 	struct wlan_objmgr_vdev *vdev, *conc_vdev;
3369 	struct wlan_objmgr_pdev *pdev;
3370 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3371 	enum policy_mgr_con_mode cur_mode;
3372 	enum policy_mgr_con_mode concur_mode = PM_MAX_NUM_OF_MODE;
3373 
3374 	pm_ctx = policy_mgr_get_context(psoc);
3375 	if (!pm_ctx) {
3376 		policy_mgr_err("Invalid context");
3377 		return QDF_STATUS_E_INVAL;
3378 	}
3379 	if (!csa_event) {
3380 		policy_mgr_err("CSA IE Received event is NULL");
3381 		return QDF_STATUS_E_INVAL;
3382 	}
3383 
3384 	policy_mgr_get_dfs_sta_sap_go_scc_movement(psoc, &move_sap_go_first);
3385 	if (!move_sap_go_first) {
3386 		policy_mgr_err("g_move_sap_go_1st_on_dfs_sta_csa is disabled");
3387 		return QDF_STATUS_E_NOSUPPORT;
3388 	}
3389 
3390 	cur_mode = policy_mgr_get_mode_by_vdev_id(psoc, vdev_id);
3391 	if (cur_mode != PM_STA_MODE) {
3392 		policy_mgr_err("CSA received on non-STA connection");
3393 		return QDF_STATUS_E_INVAL;
3394 	}
3395 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
3396 						    WLAN_POLICY_MGR_ID);
3397 	if (!vdev) {
3398 		policy_mgr_err("vdev is NULL");
3399 		return QDF_STATUS_E_INVAL;
3400 	}
3401 	pdev = wlan_vdev_get_pdev(vdev);
3402 	cur_freq = wlan_get_operation_chan_freq_vdev_id(pdev, vdev_id);
3403 
3404 	if (!wlan_reg_is_dfs_for_freq(pdev, cur_freq) &&
3405 	    !wlan_reg_is_freq_indoor(pdev, cur_freq)) {
3406 		policy_mgr_err("SAP / GO operating channel is non-DFS");
3407 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
3408 		return QDF_STATUS_E_INVAL;
3409 	}
3410 
3411 	/* Check if there is any SAP / GO operating on the same channel or not
3412 	 * If yes, then get the current bandwidth and vdev_id of concurrent SAP
3413 	 * or GO and trigger channel switch to new channel received in CSA on
3414 	 * STA interface. If this new channel is DFS then trigger channel
3415 	 * switch to non-DFS channel. Once STA moves to this new channel and
3416 	 * when it receives very first beacon, it will then enforce SCC again
3417 	 */
3418 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
3419 		if (pm_conc_connection_list[i].in_use &&
3420 		    pm_conc_connection_list[i].freq == cur_freq &&
3421 		    pm_conc_connection_list[i].vdev_id != vdev_id &&
3422 		    (pm_conc_connection_list[i].mode == PM_P2P_GO_MODE ||
3423 		     pm_conc_connection_list[i].mode == PM_SAP_MODE)) {
3424 			concur_mode = pm_conc_connection_list[i].mode;
3425 			bw = pm_conc_connection_list[i].bw;
3426 			concur_vdev_id = pm_conc_connection_list[i].vdev_id;
3427 			break;
3428 		}
3429 	}
3430 
3431 	/* If there is no concurrent SAP / GO, then return */
3432 	if (concur_mode == PM_MAX_NUM_OF_MODE) {
3433 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
3434 		return QDF_STATUS_E_INVAL;
3435 	}
3436 
3437 	conc_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, concur_vdev_id,
3438 							 WLAN_POLICY_MGR_ID);
3439 	if (!conc_vdev) {
3440 		policy_mgr_err("conc_vdev is NULL");
3441 		wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
3442 		return QDF_STATUS_E_INVAL;
3443 	}
3444 	wlan_vdev_mlme_set_sap_go_move_before_sta(conc_vdev, true);
3445 	wlan_vdev_mlme_set_sap_go_move_before_sta(vdev, true);
3446 	wlan_objmgr_vdev_release_ref(conc_vdev, WLAN_POLICY_MGR_ID);
3447 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
3448 
3449 	/*Change the CSA count*/
3450 	if (pm_ctx->sme_cbacks.sme_change_sap_csa_count)
3451 		/* Total 4 CSA frames are allowed so that GO / SAP
3452 		 * will move to new channel within 500ms
3453 		 */
3454 		pm_ctx->sme_cbacks.sme_change_sap_csa_count(4);
3455 	new_freq = csa_event->csa_chan_freq;
3456 
3457 	/* If the new channel is DFS or indoor, then select another channel
3458 	 * and switch the SAP / GO to avoid CAC. This will resume traffic on
3459 	 * SAP / GO interface immediately. Once STA moves to this new channel
3460 	 * and receives the very first beacon, then it will enforece SCC
3461 	 */
3462 	if (wlan_reg_is_dfs_for_freq(pdev, new_freq) ||
3463 	    wlan_reg_is_freq_indoor(pdev, new_freq)) {
3464 		if (wlan_reg_is_24ghz_ch_freq(new_freq)) {
3465 			new_freq = wlan_reg_min_24ghz_chan_freq();
3466 		} else if (wlan_reg_is_5ghz_ch_freq(new_freq)) {
3467 			new_freq = wlan_reg_min_5ghz_chan_freq();
3468 			/* if none of the 5G channel is non-DFS */
3469 			if (wlan_reg_is_dfs_for_freq(pdev, new_freq) ||
3470 			    wlan_reg_is_freq_indoor(pdev, new_freq))
3471 				new_freq = policy_mgr_get_nondfs_preferred_channel(psoc,
3472 										   concur_mode,
3473 										   true,
3474 										   concur_vdev_id);
3475 		} else {
3476 			new_freq = wlan_reg_min_6ghz_chan_freq();
3477 		}
3478 	}
3479 	policy_mgr_debug("Restart vdev: %u on freq: %u",
3480 			 concur_vdev_id, new_freq);
3481 
3482 	return policy_mgr_change_sap_channel_with_csa(psoc, concur_vdev_id,
3483 						      new_freq, bw, true);
3484 }
3485 
policy_mgr_sta_sap_dfs_enforce_scc(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)3486 void policy_mgr_sta_sap_dfs_enforce_scc(struct wlan_objmgr_psoc *psoc,
3487 					uint8_t vdev_id)
3488 {
3489 	bool is_sap_go_moved_before_sta, move_sap_go_first;
3490 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3491 	struct wlan_objmgr_vdev *vdev;
3492 	struct wlan_objmgr_pdev *pdev;
3493 	enum policy_mgr_con_mode cur_mode;
3494 
3495 	pm_ctx = policy_mgr_get_context(psoc);
3496 	if (!pm_ctx) {
3497 		policy_mgr_err("Invalid context");
3498 		return;
3499 	}
3500 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
3501 						    WLAN_POLICY_MGR_ID);
3502 	if (!vdev) {
3503 		policy_mgr_err("vdev is NULL");
3504 		return;
3505 	}
3506 	is_sap_go_moved_before_sta =
3507 			wlan_vdev_mlme_is_sap_go_move_before_sta(vdev);
3508 	pdev = wlan_vdev_get_pdev(vdev);
3509 	wlan_vdev_mlme_set_sap_go_move_before_sta(vdev, false);
3510 	wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
3511 
3512 	policy_mgr_get_dfs_sta_sap_go_scc_movement(psoc, &move_sap_go_first);
3513 	if (!is_sap_go_moved_before_sta || !move_sap_go_first) {
3514 		policy_mgr_debug("SAP / GO moved before STA: %u INI g_move_sap_go_1st_on_dfs_sta_csa: %u",
3515 				 is_sap_go_moved_before_sta, move_sap_go_first);
3516 		return;
3517 	}
3518 
3519 	cur_mode = policy_mgr_get_mode_by_vdev_id(psoc, vdev_id);
3520 	if (cur_mode != PM_STA_MODE) {
3521 		policy_mgr_err("CSA received on non-STA connection");
3522 		return;
3523 	}
3524 
3525 	policy_mgr_debug("Enforce SCC");
3526 	policy_mgr_check_concurrent_intf_and_restart_sap(psoc, false);
3527 }
3528 
3529 #ifdef WLAN_FEATURE_P2P_P2P_STA
policy_mgr_do_go_plus_go_force_scc(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint32_t ch_freq,uint32_t ch_width)3530 void policy_mgr_do_go_plus_go_force_scc(struct wlan_objmgr_psoc *psoc,
3531 					uint8_t vdev_id, uint32_t ch_freq,
3532 					uint32_t ch_width)
3533 {
3534 	uint8_t total_connection;
3535 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3536 
3537 	pm_ctx = policy_mgr_get_context(psoc);
3538 	if (!pm_ctx) {
3539 		policy_mgr_err("Invalid Context");
3540 		return;
3541 	}
3542 
3543 	total_connection = policy_mgr_mode_specific_connection_count(
3544 						psoc, PM_P2P_GO_MODE, NULL);
3545 
3546 	policy_mgr_debug("Total p2p go connection %d", total_connection);
3547 
3548 	/* If any p2p disconnected, don't do csa */
3549 	if (total_connection > 1) {
3550 		if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason)
3551 			pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(
3552 				psoc, vdev_id,
3553 				CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL);
3554 
3555 		policy_mgr_change_sap_channel_with_csa(psoc, vdev_id,
3556 						       ch_freq, ch_width, true);
3557 	}
3558 }
3559 
policy_mgr_process_forcescc_for_go(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint32_t ch_freq,uint32_t ch_width,enum policy_mgr_con_mode mode)3560 void policy_mgr_process_forcescc_for_go(struct wlan_objmgr_psoc *psoc,
3561 					uint8_t vdev_id, uint32_t ch_freq,
3562 					uint32_t ch_width,
3563 					enum policy_mgr_con_mode mode)
3564 {
3565 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3566 	struct sta_ap_intf_check_work_ctx *work_info;
3567 
3568 	pm_ctx = policy_mgr_get_context(psoc);
3569 	if (!pm_ctx) {
3570 		policy_mgr_err("Invalid Context");
3571 		return;
3572 	}
3573 	if (!pm_ctx->sta_ap_intf_check_work_info) {
3574 		policy_mgr_err("invalid work info");
3575 		return;
3576 	}
3577 	work_info = pm_ctx->sta_ap_intf_check_work_info;
3578 	if (mode == PM_P2P_GO_MODE) {
3579 		work_info->go_plus_go_force_scc.vdev_id = vdev_id;
3580 		work_info->go_plus_go_force_scc.ch_freq = ch_freq;
3581 		work_info->go_plus_go_force_scc.ch_width = ch_width;
3582 	}
3583 
3584 	if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work,
3585 				    WAIT_BEFORE_GO_FORCESCC_RESTART))
3586 		policy_mgr_debug("change interface request already queued");
3587 }
3588 #endif
3589 
policy_mgr_is_chan_switch_in_progress(struct wlan_objmgr_psoc * psoc)3590 bool policy_mgr_is_chan_switch_in_progress(struct wlan_objmgr_psoc *psoc)
3591 {
3592 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3593 
3594 	pm_ctx = policy_mgr_get_context(psoc);
3595 	if (!pm_ctx) {
3596 		policy_mgr_err("Invalid pm context");
3597 		return false;
3598 	}
3599 	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
3600 	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
3601 		policy_mgr_debug("channel switch is in progress");
3602 		return true;
3603 	}
3604 
3605 	return false;
3606 }
3607 
policy_mgr_wait_chan_switch_complete_evt(struct wlan_objmgr_psoc * psoc)3608 QDF_STATUS policy_mgr_wait_chan_switch_complete_evt(
3609 		struct wlan_objmgr_psoc *psoc)
3610 {
3611 	QDF_STATUS status;
3612 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3613 
3614 	pm_ctx = policy_mgr_get_context(psoc);
3615 
3616 	if (!pm_ctx) {
3617 		policy_mgr_err("Invalid context");
3618 		return QDF_STATUS_E_FAILURE;
3619 	}
3620 
3621 	status = qdf_wait_single_event(
3622 				&pm_ctx->channel_switch_complete_evt,
3623 				CHANNEL_SWITCH_COMPLETE_TIMEOUT);
3624 	if (QDF_IS_STATUS_ERROR(status))
3625 		policy_mgr_err("wait for event failed, still continue with channel switch");
3626 
3627 	return status;
3628 }
3629 
__policy_mgr_is_ap_start_in_progress(struct wlan_objmgr_pdev * pdev,void * object,void * arg)3630 static void __policy_mgr_is_ap_start_in_progress(struct wlan_objmgr_pdev *pdev,
3631 						 void *object, void *arg)
3632 {
3633 	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
3634 	uint32_t *ap_starting_vdev_id = (uint32_t *)arg;
3635 	enum wlan_serialization_cmd_type cmd_type;
3636 	enum QDF_OPMODE op_mode;
3637 
3638 	if (!vdev || !ap_starting_vdev_id)
3639 		return;
3640 	if (*ap_starting_vdev_id != WLAN_INVALID_VDEV_ID)
3641 		return;
3642 	op_mode = wlan_vdev_mlme_get_opmode(vdev);
3643 	if (op_mode != QDF_SAP_MODE && op_mode != QDF_P2P_GO_MODE &&
3644 	    op_mode != QDF_NDI_MODE)
3645 		return;
3646 	/* Check AP start is present in active and pending queue or not */
3647 	cmd_type = wlan_serialization_get_vdev_active_cmd_type(vdev);
3648 	if (cmd_type == WLAN_SER_CMD_VDEV_START_BSS ||
3649 	    wlan_ser_is_non_scan_cmd_type_in_vdev_queue(
3650 			vdev, WLAN_SER_CMD_VDEV_START_BSS)) {
3651 		*ap_starting_vdev_id = wlan_vdev_get_id(vdev);
3652 		policy_mgr_debug("vdev %d op mode %d start bss is pending",
3653 				 *ap_starting_vdev_id, op_mode);
3654 	}
3655 }
3656 
policy_mgr_is_ap_start_in_progress(struct wlan_objmgr_psoc * psoc)3657 bool policy_mgr_is_ap_start_in_progress(struct wlan_objmgr_psoc *psoc)
3658 {
3659 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3660 	uint32_t ap_starting_vdev_id = WLAN_INVALID_VDEV_ID;
3661 
3662 	pm_ctx = policy_mgr_get_context(psoc);
3663 	if (!pm_ctx) {
3664 		policy_mgr_err("Invalid pm context");
3665 		return false;
3666 	}
3667 
3668 	wlan_objmgr_pdev_iterate_obj_list(pm_ctx->pdev, WLAN_VDEV_OP,
3669 					  __policy_mgr_is_ap_start_in_progress,
3670 					  &ap_starting_vdev_id, 0,
3671 					  WLAN_POLICY_MGR_ID);
3672 
3673 	return ap_starting_vdev_id != WLAN_INVALID_VDEV_ID;
3674 }
3675 
policy_mgr_process_force_scc_for_nan(struct wlan_objmgr_psoc * psoc)3676 void policy_mgr_process_force_scc_for_nan(struct wlan_objmgr_psoc *psoc)
3677 {
3678 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3679 
3680 	pm_ctx = policy_mgr_get_context(psoc);
3681 	if (!pm_ctx) {
3682 		policy_mgr_err("Invalid Context");
3683 		return;
3684 	}
3685 	if (!pm_ctx->sta_ap_intf_check_work_info) {
3686 		policy_mgr_err("invalid work info");
3687 		return;
3688 	}
3689 
3690 	pm_ctx->sta_ap_intf_check_work_info->nan_force_scc_in_progress = true;
3691 
3692 	if (!qdf_delayed_work_start(&pm_ctx->sta_ap_intf_check_work, 0))
3693 		policy_mgr_debug("change interface request already queued");
3694 }
3695 
policy_mgr_wait_for_connection_update(struct wlan_objmgr_psoc * psoc)3696 QDF_STATUS policy_mgr_wait_for_connection_update(struct wlan_objmgr_psoc *psoc)
3697 {
3698 	QDF_STATUS status;
3699 	struct policy_mgr_psoc_priv_obj *policy_mgr_context;
3700 
3701 	policy_mgr_context = policy_mgr_get_context(psoc);
3702 	if (!policy_mgr_context) {
3703 		policy_mgr_err("Invalid context");
3704 		return QDF_STATUS_E_FAILURE;
3705 	}
3706 
3707 	status = qdf_wait_single_event(
3708 			&policy_mgr_context->connection_update_done_evt,
3709 			CONNECTION_UPDATE_TIMEOUT);
3710 
3711 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3712 		policy_mgr_err("wait for event failed");
3713 		return QDF_STATUS_E_FAILURE;
3714 	}
3715 
3716 	return QDF_STATUS_SUCCESS;
3717 }
3718 
policy_mgr_reset_connection_update(struct wlan_objmgr_psoc * psoc)3719 QDF_STATUS policy_mgr_reset_connection_update(struct wlan_objmgr_psoc *psoc)
3720 {
3721 	QDF_STATUS status;
3722 	struct policy_mgr_psoc_priv_obj *policy_mgr_context;
3723 
3724 	policy_mgr_context = policy_mgr_get_context(psoc);
3725 	if (!policy_mgr_context) {
3726 		policy_mgr_err("Invalid context");
3727 		return QDF_STATUS_E_FAILURE;
3728 	}
3729 
3730 	status = qdf_event_reset(
3731 		&policy_mgr_context->connection_update_done_evt);
3732 
3733 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3734 		policy_mgr_err("clear event failed");
3735 		return QDF_STATUS_E_FAILURE;
3736 	}
3737 
3738 	return QDF_STATUS_SUCCESS;
3739 }
3740 
policy_mgr_reset_hw_mode_change(struct wlan_objmgr_psoc * psoc)3741 void policy_mgr_reset_hw_mode_change(struct wlan_objmgr_psoc *psoc)
3742 {
3743 	policy_mgr_err("Clear hw mode change and connection update evt");
3744 	policy_mgr_set_hw_mode_change_in_progress(
3745 			psoc, POLICY_MGR_HW_MODE_NOT_IN_PROGRESS);
3746 	policy_mgr_reset_connection_update(psoc);
3747 }
3748 
policy_mgr_set_connection_update(struct wlan_objmgr_psoc * psoc)3749 QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc)
3750 {
3751 	QDF_STATUS status;
3752 	struct policy_mgr_psoc_priv_obj *policy_mgr_context;
3753 
3754 	policy_mgr_context = policy_mgr_get_context(psoc);
3755 	if (!policy_mgr_context) {
3756 		policy_mgr_err("Invalid context");
3757 		return QDF_STATUS_E_FAILURE;
3758 	}
3759 
3760 	status = qdf_event_set(&policy_mgr_context->connection_update_done_evt);
3761 
3762 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3763 		policy_mgr_err("set event failed");
3764 		return QDF_STATUS_E_FAILURE;
3765 	}
3766 
3767 	return QDF_STATUS_SUCCESS;
3768 }
3769 
policy_mgr_set_chan_switch_complete_evt(struct wlan_objmgr_psoc * psoc)3770 QDF_STATUS policy_mgr_set_chan_switch_complete_evt(
3771 		struct wlan_objmgr_psoc *psoc)
3772 {
3773 	QDF_STATUS status;
3774 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3775 
3776 	pm_ctx = policy_mgr_get_context(psoc);
3777 
3778 	if (!pm_ctx) {
3779 		policy_mgr_err("Invalid context");
3780 		return QDF_STATUS_E_FAILURE;
3781 	}
3782 
3783 	/*
3784 	 * Set channel_switch_complete_evt only if no vdev has channel switch
3785 	 * in progress.
3786 	 */
3787 	if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress &&
3788 	    pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) {
3789 		policy_mgr_info("Not all channel switch completed");
3790 		return QDF_STATUS_SUCCESS;
3791 	}
3792 
3793 	status = qdf_event_set_all(&pm_ctx->channel_switch_complete_evt);
3794 
3795 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3796 		policy_mgr_err("set event failed");
3797 		return QDF_STATUS_E_FAILURE;
3798 	}
3799 
3800 	return QDF_STATUS_SUCCESS;
3801 }
3802 
policy_mgr_reset_chan_switch_complete_evt(struct wlan_objmgr_psoc * psoc)3803 QDF_STATUS policy_mgr_reset_chan_switch_complete_evt(
3804 		struct wlan_objmgr_psoc *psoc)
3805 {
3806 	QDF_STATUS status;
3807 	struct policy_mgr_psoc_priv_obj *policy_mgr_context;
3808 
3809 	policy_mgr_context = policy_mgr_get_context(psoc);
3810 
3811 	if (!policy_mgr_context) {
3812 		policy_mgr_err("Invalid context");
3813 		return QDF_STATUS_E_FAILURE;
3814 	}
3815 	status = qdf_event_reset(
3816 			&policy_mgr_context->channel_switch_complete_evt);
3817 
3818 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3819 		policy_mgr_err("reset event failed");
3820 		return QDF_STATUS_E_FAILURE;
3821 	}
3822 
3823 	return QDF_STATUS_SUCCESS;
3824 }
3825 
policy_mgr_set_opportunistic_update(struct wlan_objmgr_psoc * psoc)3826 QDF_STATUS policy_mgr_set_opportunistic_update(struct wlan_objmgr_psoc *psoc)
3827 {
3828 	QDF_STATUS status;
3829 	struct policy_mgr_psoc_priv_obj *policy_mgr_context;
3830 
3831 	policy_mgr_context = policy_mgr_get_context(psoc);
3832 	if (!policy_mgr_context) {
3833 		policy_mgr_err("Invalid context");
3834 		return QDF_STATUS_E_FAILURE;
3835 	}
3836 
3837 	status = qdf_event_set(
3838 			&policy_mgr_context->opportunistic_update_done_evt);
3839 
3840 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3841 		policy_mgr_err("set event failed");
3842 		return QDF_STATUS_E_FAILURE;
3843 	}
3844 
3845 	return QDF_STATUS_SUCCESS;
3846 }
3847 
policy_mgr_stop_opportunistic_timer(struct wlan_objmgr_psoc * psoc)3848 QDF_STATUS policy_mgr_stop_opportunistic_timer(struct wlan_objmgr_psoc *psoc)
3849 {
3850 	struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
3851 
3852 	policy_mgr_ctx = policy_mgr_get_context(psoc);
3853 	if (!policy_mgr_ctx) {
3854 		policy_mgr_err("Invalid context");
3855 		return QDF_STATUS_E_FAILURE;
3856 	}
3857 
3858 	if (policy_mgr_ctx->dbs_opportunistic_timer.state !=
3859 	    QDF_TIMER_STATE_RUNNING)
3860 		return QDF_STATUS_SUCCESS;
3861 
3862 	qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer);
3863 	return QDF_STATUS_SUCCESS;
3864 }
3865 
policy_mgr_restart_opportunistic_timer(struct wlan_objmgr_psoc * psoc,bool check_state)3866 QDF_STATUS policy_mgr_restart_opportunistic_timer(
3867 		struct wlan_objmgr_psoc *psoc, bool check_state)
3868 {
3869 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
3870 	struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
3871 
3872 	if (policy_mgr_is_hwmode_offload_enabled(psoc))
3873 		return QDF_STATUS_E_NOSUPPORT;
3874 
3875 	policy_mgr_ctx = policy_mgr_get_context(psoc);
3876 	if (!policy_mgr_ctx) {
3877 		policy_mgr_err("Invalid context");
3878 		return status;
3879 	}
3880 
3881 	if (check_state &&
3882 			QDF_TIMER_STATE_RUNNING !=
3883 			policy_mgr_ctx->dbs_opportunistic_timer.state)
3884 		return status;
3885 
3886 	qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer);
3887 
3888 	status = qdf_mc_timer_start(
3889 			&policy_mgr_ctx->dbs_opportunistic_timer,
3890 			DBS_OPPORTUNISTIC_TIME * 1000);
3891 
3892 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3893 		policy_mgr_err("failed to start opportunistic timer");
3894 		return status;
3895 	}
3896 
3897 	return status;
3898 }
3899 
policy_mgr_set_hw_mode_on_channel_switch(struct wlan_objmgr_psoc * psoc,uint8_t session_id)3900 QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch(
3901 			struct wlan_objmgr_psoc *psoc, uint8_t session_id)
3902 {
3903 	QDF_STATUS status = QDF_STATUS_E_FAILURE, qdf_status;
3904 	enum policy_mgr_conc_next_action action;
3905 
3906 	if (policy_mgr_is_hwmode_offload_enabled(psoc))
3907 		return QDF_STATUS_E_NOSUPPORT;
3908 
3909 	if (!policy_mgr_is_hw_dbs_capable(psoc)) {
3910 		policy_mgr_rl_debug("PM/DBS is disabled");
3911 		return status;
3912 	}
3913 
3914 	action = (*policy_mgr_get_current_pref_hw_mode_ptr)(psoc);
3915 	if ((action != PM_DBS_DOWNGRADE) &&
3916 	    (action != PM_SINGLE_MAC_UPGRADE) &&
3917 	    (action != PM_DBS1_DOWNGRADE) &&
3918 	    (action != PM_DBS2_DOWNGRADE)) {
3919 		policy_mgr_err("Invalid action: %d", action);
3920 		status = QDF_STATUS_SUCCESS;
3921 		goto done;
3922 	}
3923 
3924 	policy_mgr_debug("action:%d session id:%d", action, session_id);
3925 
3926 	/* Opportunistic timer is started, PM will check if MCC upgrade can be
3927 	 * done on timer expiry. This avoids any possible ping pong effect
3928 	 * as well.
3929 	 */
3930 	if (action == PM_SINGLE_MAC_UPGRADE) {
3931 		qdf_status = policy_mgr_restart_opportunistic_timer(
3932 			psoc, false);
3933 		if (QDF_IS_STATUS_SUCCESS(qdf_status))
3934 			policy_mgr_debug("opportunistic timer for MCC upgrade");
3935 		goto done;
3936 	}
3937 
3938 	/* For DBS, we want to move right away to DBS mode */
3939 	status = policy_mgr_next_actions(psoc, session_id, action,
3940 			POLICY_MGR_UPDATE_REASON_AFTER_CHANNEL_SWITCH,
3941 			POLICY_MGR_DEF_REQ_ID);
3942 	if (!QDF_IS_STATUS_SUCCESS(status)) {
3943 		policy_mgr_err("no set hw mode command was issued");
3944 		goto done;
3945 	}
3946 done:
3947 	/* success must be returned only when a set hw mode was done */
3948 	return status;
3949 }
3950 
policy_mgr_check_and_set_hw_mode_for_channel_switch(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,uint32_t ch_freq,enum policy_mgr_conn_update_reason reason)3951 QDF_STATUS policy_mgr_check_and_set_hw_mode_for_channel_switch(
3952 		struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
3953 		uint32_t ch_freq, enum policy_mgr_conn_update_reason reason)
3954 {
3955 	QDF_STATUS status;
3956 	struct policy_mgr_conc_connection_info info;
3957 	uint8_t num_cxn_del = 0;
3958 	struct policy_mgr_psoc_priv_obj *pm_ctx;
3959 	enum policy_mgr_conc_next_action next_action = PM_NOP;
3960 	bool eht_capab =  false;
3961 
3962 	pm_ctx = policy_mgr_get_context(psoc);
3963 	if (!pm_ctx) {
3964 		policy_mgr_err("Invalid context");
3965 		return QDF_STATUS_E_FAILURE;
3966 	}
3967 
3968 	wlan_psoc_mlme_get_11be_capab(psoc, &eht_capab);
3969 	if (eht_capab &&
3970 	    policy_mgr_mode_specific_connection_count(psoc,
3971 						      PM_SAP_MODE,
3972 						      NULL) == 1) {
3973 		policy_mgr_stop_opportunistic_timer(psoc);
3974 		goto ch_width_update;
3975 	}
3976 
3977 	if (!policy_mgr_is_hw_dbs_capable(psoc) ||
3978 	    (!policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
3979 	    !policy_mgr_is_hw_dbs_required_for_band(
3980 					psoc, HW_MODE_MAC_BAND_2G)))
3981 		return QDF_STATUS_E_NOSUPPORT;
3982 
3983 	/*
3984 	 * Stop opportunistic timer as current connection info will change once
3985 	 * channel is switched and thus if required it will be started once
3986 	 * channel switch is completed. With new connection info.
3987 	 */
3988 	policy_mgr_stop_opportunistic_timer(psoc);
3989 
3990 	if (wlan_reg_freq_to_band(ch_freq) != REG_BAND_2G)
3991 		return QDF_STATUS_E_NOSUPPORT;
3992 
3993 ch_width_update:
3994 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
3995 	/*
3996 	 * Store the connection's parameter and temporarily delete it
3997 	 * from the concurrency table. This way the allow concurrency
3998 	 * check can be used as though a new connection is coming up,
3999 	 * after check, restore the connection to concurrency table.
4000 	 */
4001 	policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id,
4002 						      &info, &num_cxn_del);
4003 
4004 	status = policy_mgr_get_next_action(psoc, vdev_id, ch_freq,
4005 					    reason, &next_action);
4006 	/* Restore the connection entry */
4007 	if (num_cxn_del)
4008 		policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del);
4009 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4010 
4011 	if (QDF_IS_STATUS_ERROR(status))
4012 		goto chk_opportunistic_timer;
4013 
4014 	if (PM_NOP != next_action)
4015 		status = policy_mgr_next_actions(psoc, vdev_id,
4016 						 next_action, reason,
4017 						 POLICY_MGR_DEF_REQ_ID);
4018 	else
4019 		status = QDF_STATUS_E_NOSUPPORT;
4020 
4021 chk_opportunistic_timer:
4022 	/*
4023 	 * If hw mode change failed restart the opportunistic timer to
4024 	 * Switch to single mac if required.
4025 	 */
4026 	if (status == QDF_STATUS_E_FAILURE) {
4027 		policy_mgr_err("Failed to update HW modeStatus %d", status);
4028 		policy_mgr_check_n_start_opportunistic_timer(psoc);
4029 	}
4030 
4031 	return status;
4032 }
4033 
policy_mgr_checkn_update_hw_mode_single_mac_mode(struct wlan_objmgr_psoc * psoc,uint32_t ch_freq)4034 void policy_mgr_checkn_update_hw_mode_single_mac_mode(
4035 		struct wlan_objmgr_psoc *psoc, uint32_t ch_freq)
4036 {
4037 	uint8_t i;
4038 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4039 	bool dbs_required_2g;
4040 	pm_ctx = policy_mgr_get_context(psoc);
4041 	if (!pm_ctx) {
4042 		policy_mgr_err("Invalid Context");
4043 		return;
4044 	}
4045 
4046 	if (!policy_mgr_is_hw_dbs_capable(psoc))
4047 		return;
4048 
4049 	if (QDF_TIMER_STATE_RUNNING == pm_ctx->dbs_opportunistic_timer.state)
4050 		qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
4051 
4052 	dbs_required_2g =
4053 	    policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G);
4054 
4055 	if (dbs_required_2g && WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) {
4056 		policy_mgr_debug("DBS required for new connection");
4057 		return;
4058 	}
4059 
4060 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4061 	for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
4062 		if (pm_conc_connection_list[i].in_use) {
4063 			if (!WLAN_REG_IS_SAME_BAND_FREQS(
4064 			    ch_freq, pm_conc_connection_list[i].freq) &&
4065 			    (WLAN_REG_IS_24GHZ_CH_FREQ(
4066 			    pm_conc_connection_list[i].freq) ||
4067 			    WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))) {
4068 				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4069 				policy_mgr_debug("DBS required");
4070 				return;
4071 			}
4072 			if (dbs_required_2g && WLAN_REG_IS_24GHZ_CH_FREQ(
4073 			    pm_conc_connection_list[i].freq)) {
4074 				qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4075 				policy_mgr_debug("DBS required");
4076 				return;
4077 			}
4078 		}
4079 	}
4080 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4081 	pm_dbs_opportunistic_timer_handler((void *)psoc);
4082 }
4083 
policy_mgr_check_and_stop_opportunistic_timer(struct wlan_objmgr_psoc * psoc,uint8_t id)4084 void policy_mgr_check_and_stop_opportunistic_timer(
4085 	struct wlan_objmgr_psoc *psoc, uint8_t id)
4086 {
4087 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4088 	enum policy_mgr_conc_next_action action = PM_NOP;
4089 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
4090 	enum policy_mgr_conn_update_reason reason =
4091 					POLICY_MGR_UPDATE_REASON_MAX;
4092 
4093 	pm_ctx = policy_mgr_get_context(psoc);
4094 	if (!pm_ctx) {
4095 		policy_mgr_err("Invalid Context");
4096 		return;
4097 	}
4098 	if (QDF_TIMER_STATE_RUNNING ==
4099 		pm_ctx->dbs_opportunistic_timer.state) {
4100 		qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
4101 		action = policy_mgr_need_opportunistic_upgrade(psoc, &reason);
4102 		if (action) {
4103 			qdf_event_reset(&pm_ctx->opportunistic_update_done_evt);
4104 			status = policy_mgr_next_actions(psoc, id, action,
4105 							 reason,
4106 							 POLICY_MGR_DEF_REQ_ID);
4107 			if (status != QDF_STATUS_SUCCESS) {
4108 				policy_mgr_err("Failed in policy_mgr_next_actions");
4109 				return;
4110 			}
4111 			status = qdf_wait_single_event(
4112 					&pm_ctx->opportunistic_update_done_evt,
4113 					CONNECTION_UPDATE_TIMEOUT);
4114 
4115 			if (!QDF_IS_STATUS_SUCCESS(status)) {
4116 				policy_mgr_err("wait for event failed");
4117 				return;
4118 			}
4119 		}
4120 	}
4121 }
4122 
policy_mgr_set_hw_mode_change_in_progress(struct wlan_objmgr_psoc * psoc,enum policy_mgr_hw_mode_change value)4123 void policy_mgr_set_hw_mode_change_in_progress(
4124 	struct wlan_objmgr_psoc *psoc, enum policy_mgr_hw_mode_change value)
4125 {
4126 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4127 
4128 	pm_ctx = policy_mgr_get_context(psoc);
4129 	if (!pm_ctx) {
4130 		policy_mgr_err("Invalid Context");
4131 		return;
4132 	}
4133 
4134 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4135 	pm_ctx->hw_mode_change_in_progress = value;
4136 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4137 
4138 	policy_mgr_debug("hw_mode_change_in_progress:%d", value);
4139 }
4140 
policy_mgr_is_hw_mode_change_in_progress(struct wlan_objmgr_psoc * psoc)4141 enum policy_mgr_hw_mode_change policy_mgr_is_hw_mode_change_in_progress(
4142 	struct wlan_objmgr_psoc *psoc)
4143 {
4144 	enum policy_mgr_hw_mode_change value;
4145 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4146 
4147 	value = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
4148 
4149 	pm_ctx = policy_mgr_get_context(psoc);
4150 	if (!pm_ctx) {
4151 		policy_mgr_err("Invalid Context");
4152 		return value;
4153 	}
4154 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
4155 	value = pm_ctx->hw_mode_change_in_progress;
4156 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
4157 
4158 	return value;
4159 }
4160 
policy_mgr_get_hw_mode_change_from_hw_mode_index(struct wlan_objmgr_psoc * psoc,uint32_t hw_mode_index)4161 enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index(
4162 	struct wlan_objmgr_psoc *psoc, uint32_t hw_mode_index)
4163 {
4164 	struct policy_mgr_psoc_priv_obj *pm_ctx;
4165 	struct policy_mgr_hw_mode_params hw_mode;
4166 	enum policy_mgr_hw_mode_change value
4167 		= POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
4168 	QDF_STATUS status;
4169 
4170 	pm_ctx = policy_mgr_get_context(psoc);
4171 	if (!pm_ctx) {
4172 		policy_mgr_err("Invalid Context");
4173 		return value;
4174 	}
4175 
4176 	status = policy_mgr_get_hw_mode_from_idx(psoc, hw_mode_index, &hw_mode);
4177 	if (status != QDF_STATUS_SUCCESS) {
4178 		policy_mgr_err("Failed to get HW mode index");
4179 		return value;
4180 	}
4181 
4182 	if (hw_mode.dbs_cap) {
4183 		policy_mgr_debug("DBS is requested with HW (%d)",
4184 				 hw_mode_index);
4185 		value = POLICY_MGR_DBS_IN_PROGRESS;
4186 		goto ret_value;
4187 	}
4188 
4189 	if (hw_mode.sbs_cap) {
4190 		policy_mgr_debug("SBS is requested with HW (%d)",
4191 				 hw_mode_index);
4192 		value = POLICY_MGR_SBS_IN_PROGRESS;
4193 		goto ret_value;
4194 	}
4195 
4196 	value = POLICY_MGR_SMM_IN_PROGRESS;
4197 	policy_mgr_debug("SMM is requested with HW (%d)", hw_mode_index);
4198 
4199 ret_value:
4200 	return value;
4201 }
4202 
4203 #ifdef WLAN_FEATURE_TDLS_CONCURRENCIES
4204 bool
policy_mgr_get_allowed_tdls_offchannel_freq(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,qdf_freq_t * ch_freq)4205 policy_mgr_get_allowed_tdls_offchannel_freq(struct wlan_objmgr_psoc *psoc,
4206 					    struct wlan_objmgr_vdev *vdev,
4207 					    qdf_freq_t *ch_freq)
4208 {
4209 	struct connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
4210 	uint8_t connection_count, i, j, sta_vdev_id;
4211 
4212 	*ch_freq = 0;
4213 	/*
4214 	 * TDLS off channel is not allowed in any MCC scenario
4215 	 */
4216 	if (policy_mgr_current_concurrency_is_mcc(psoc)) {
4217 		policy_mgr_dump_current_concurrency(psoc);
4218 		policy_mgr_debug("TDLS off channel not allowed in MCC");
4219 		return false;
4220 	}
4221 
4222 	/*
4223 	 * TDLS offchannel is done only when STA is connected on 2G channel and
4224 	 * the current concurrency is not MCC
4225 	 */
4226 	if (!policy_mgr_is_sta_connected_2g(psoc)) {
4227 		policy_mgr_debug("STA not-connected on 2.4 Ghz");
4228 		return false;
4229 	}
4230 
4231 	/*
4232 	 * 2 Port DBS scenario - Allow non-STA vdev channel for
4233 	 * TDLS off-channel operation
4234 	 *
4235 	 * 3 Port Scenario - If STA Vdev is on SCC, allow TDLS off-channel on
4236 	 * the channel of vdev on the other MAC
4237 	 * If STA vdev is standalone on one mac, and scc on another mac, then
4238 	 * allow TDLS off channel on other mac scc channel
4239 	 */
4240 	sta_vdev_id = wlan_vdev_get_id(vdev);
4241 	connection_count = policy_mgr_get_connection_info(psoc, info);
4242 	switch (connection_count) {
4243 	case 1:
4244 		return true;
4245 	case 2:
4246 		/*
4247 		 * Allow all the 5GHz/6GHz channels when STA is in SCC
4248 		 */
4249 		if (policy_mgr_current_concurrency_is_scc(psoc)) {
4250 			*ch_freq = 0;
4251 			return true;
4252 		} else if (policy_mgr_is_current_hwmode_dbs(psoc)) {
4253 			/*
4254 			 * In DBS case, allow off-channel operation on the
4255 			 * other mac 5GHz/6GHz channel where the STA is not
4256 			 * present
4257 			 * Don't consider SBS case since STA should be
4258 			 * connected in 2.4GHz channel for TDLS
4259 			 * off-channel and MCC on SBS ex. 3 PORT
4260 			 * 2.4GHz STA + 5GHz Lower MCC + 5GHz Upper will
4261 			 * not be allowed
4262 			 */
4263 			if (sta_vdev_id == info[0].vdev_id)
4264 				*ch_freq = info[1].ch_freq;
4265 			else
4266 				*ch_freq = info[0].ch_freq;
4267 
4268 			return true;
4269 		}
4270 
4271 		break;
4272 	case 3:
4273 
4274 		/*
4275 		 * 3 Vdev SCC on 2.4GHz band. Allow TDLS off-channel operation
4276 		 * on all the 5GHz & 6GHz channels
4277 		 */
4278 		if (info[0].ch_freq == info[1].ch_freq &&
4279 		    info[0].ch_freq == info[2].ch_freq) {
4280 			*ch_freq = 0;
4281 			return true;
4282 		}
4283 
4284 		/*
4285 		 * DBS with SCC on one vdev scenario. Allow TDLS off-channel
4286 		 * on other mac frequency where STA is not present
4287 		 * SBS case is not considered since STA should be connected
4288 		 * on 2.4GHz and TDLS off-channel on SBS MCC is not allowed
4289 		 */
4290 		for (i = 0; i < connection_count; i++) {
4291 			for (j = i + 1; j < connection_count; j++) {
4292 				/*
4293 				 * Find 2 vdevs such that STA is one of the vdev
4294 				 * and STA + other vdev are not on same mac.
4295 				 * Return the foreign vdev frequency which is
4296 				 * not on same mac along with STA
4297 				 */
4298 				if (!policy_mgr_2_freq_always_on_same_mac(
4299 							psoc, info[i].ch_freq,
4300 							info[j].ch_freq)) {
4301 					if (sta_vdev_id == info[i].vdev_id) {
4302 						*ch_freq = info[j].ch_freq;
4303 						return true;
4304 					} else if (sta_vdev_id ==
4305 						   info[j].vdev_id) {
4306 						*ch_freq = info[i].ch_freq;
4307 						return true;
4308 					}
4309 				}
4310 			}
4311 		}
4312 
4313 		return false;
4314 	default:
4315 		policy_mgr_debug("TDLS off channel not allowed on > 3 port conc");
4316 		break;
4317 	}
4318 
4319 	return false;
4320 }
4321 #endif
4322