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