blob: 47b0d6de58dc9d948285432d8c28883c20f16fab [file] [log] [blame]
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001/*
Liangwei Dong77ff66c2018-12-27 22:48:30 -05002 * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08003 *
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08004 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -080019/**
20 * DOC: wlan_policy_mgr_action.c
21 *
22 * WLAN Concurrenct Connection Management APIs
23 *
24 */
25
26/* Include files */
27
28#include "wlan_policy_mgr_api.h"
29#include "wlan_policy_mgr_tables_no_dbs_i.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"
Tushnim Bhattacharyya89036a72018-10-01 14:50:15 -070034#include "qdf_platform.h"
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -080035
36enum policy_mgr_conc_next_action (*policy_mgr_get_current_pref_hw_mode_ptr)
37 (struct wlan_objmgr_psoc *psoc);
38
39void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index,
40 uint32_t new_hw_mode_index,
41 uint32_t num_vdev_mac_entries,
42 struct policy_mgr_vdev_mac_map *vdev_mac_map,
43 struct wlan_objmgr_psoc *context)
44{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -080045 QDF_STATUS status;
46 struct policy_mgr_hw_mode_params hw_mode;
47 uint32_t i;
Yeshwanth Sriram Guntuka6a3be162018-02-23 12:14:46 +053048 struct policy_mgr_psoc_priv_obj *pm_ctx;
49
50 pm_ctx = policy_mgr_get_context(context);
51 if (!pm_ctx) {
52 policy_mgr_err("Invalid context");
53 return;
54 }
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -080055
56 if (!vdev_mac_map) {
57 policy_mgr_err("vdev_mac_map is NULL");
58 return;
59 }
60
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -070061 policy_mgr_debug("old_hw_mode_index=%d, new_hw_mode_index=%d",
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -080062 old_hw_mode_index, new_hw_mode_index);
63
64 for (i = 0; i < num_vdev_mac_entries; i++)
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -070065 policy_mgr_debug("vdev_id:%d mac_id:%d",
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -080066 vdev_mac_map[i].vdev_id,
67 vdev_mac_map[i].mac_id);
68
69 status = policy_mgr_get_hw_mode_from_idx(context,
70 new_hw_mode_index, &hw_mode);
71 if (status != QDF_STATUS_SUCCESS) {
72 policy_mgr_err("Get HW mode failed: %d", status);
73 return;
74 }
75
Liangwei Donge57b6b72018-05-21 04:51:47 -040076 policy_mgr_debug("MAC0: TxSS:%d, RxSS:%d, Bw:%d band_cap:%d",
77 hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss,
78 hw_mode.mac0_bw, hw_mode.mac0_band_cap);
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -070079 policy_mgr_debug("MAC1: TxSS:%d, RxSS:%d, Bw:%d",
Liangwei Donge57b6b72018-05-21 04:51:47 -040080 hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss,
81 hw_mode.mac1_bw);
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -070082 policy_mgr_debug("DBS:%d, Agile DFS:%d, SBS:%d",
Liangwei Donge57b6b72018-05-21 04:51:47 -040083 hw_mode.dbs_cap, hw_mode.agile_dfs_cap,
84 hw_mode.sbs_cap);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -080085
86 /* update pm_conc_connection_list */
87 policy_mgr_update_hw_mode_conn_info(context, num_vdev_mac_entries,
88 vdev_mac_map,
89 hw_mode);
90
Yeshwanth Sriram Guntuka6a3be162018-02-23 12:14:46 +053091 if (pm_ctx->mode_change_cb)
92 pm_ctx->mode_change_cb();
93
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -080094 return;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -080095}
96
Tushnim Bhattacharyyac304f892018-08-01 19:15:55 -070097QDF_STATUS policy_mgr_check_n_start_opportunistic_timer(
98 struct wlan_objmgr_psoc *psoc)
99{
100 struct policy_mgr_psoc_priv_obj *pm_ctx;
101 QDF_STATUS status = QDF_STATUS_E_FAILURE;
102
103 pm_ctx = policy_mgr_get_context(psoc);
104 if (!pm_ctx) {
105 policy_mgr_err("PM ctx not valid. Oppurtunistic timer cannot start");
106 return QDF_STATUS_E_FAILURE;
107 }
Liangwei Dong88ddf822018-05-25 05:55:37 -0400108 if (policy_mgr_need_opportunistic_upgrade(psoc, NULL)) {
Tushnim Bhattacharyyac304f892018-08-01 19:15:55 -0700109 /* let's start the timer */
110 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
111 status = qdf_mc_timer_start(
112 &pm_ctx->dbs_opportunistic_timer,
113 DBS_OPPORTUNISTIC_TIME * 1000);
114 if (!QDF_IS_STATUS_SUCCESS(status))
115 policy_mgr_err("Failed to start dbs opportunistic timer");
116 }
117 return status;
118}
119
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800120QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc,
121 uint32_t session_id,
122 enum hw_mode_ss_config mac0_ss,
123 enum hw_mode_bandwidth mac0_bw,
124 enum hw_mode_ss_config mac1_ss,
125 enum hw_mode_bandwidth mac1_bw,
Liangwei Dong9ace8a92018-05-21 05:39:04 -0400126 enum hw_mode_mac_band_cap mac0_band_cap,
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800127 enum hw_mode_dbs_capab dbs,
128 enum hw_mode_agile_dfs_capab dfs,
129 enum hw_mode_sbs_capab sbs,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800130 enum policy_mgr_conn_update_reason reason,
131 uint8_t next_action)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800132{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800133 int8_t hw_mode_index;
134 struct policy_mgr_hw_mode msg;
135 QDF_STATUS status;
136 struct policy_mgr_psoc_priv_obj *pm_ctx;
137
138 pm_ctx = policy_mgr_get_context(psoc);
139 if (!pm_ctx) {
140 policy_mgr_err("Invalid context");
141 return QDF_STATUS_E_FAILURE;
142 }
143
144 /*
145 * if HW is not capable of doing 2x2 or ini config disabled 2x2, don't
146 * allow to request FW for 2x2
147 */
Tushnim Bhattacharyya68f709d2017-03-23 18:00:04 -0700148 if ((HW_MODE_SS_2x2 == mac0_ss) && (!pm_ctx->user_cfg.enable2x2)) {
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -0700149 policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac0");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800150 mac0_ss = HW_MODE_SS_1x1;
151 }
Tushnim Bhattacharyya68f709d2017-03-23 18:00:04 -0700152 if ((HW_MODE_SS_2x2 == mac1_ss) && (!pm_ctx->user_cfg.enable2x2)) {
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -0700153 policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac1");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800154 mac1_ss = HW_MODE_SS_1x1;
155 }
156
157 hw_mode_index = policy_mgr_get_hw_mode_idx_from_dbs_hw_list(psoc,
Liangwei Dong9ace8a92018-05-21 05:39:04 -0400158 mac0_ss, mac0_bw, mac1_ss, mac1_bw, mac0_band_cap,
159 dbs, dfs, sbs);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800160 if (hw_mode_index < 0) {
161 policy_mgr_err("Invalid HW mode index obtained");
162 return QDF_STATUS_E_FAILURE;
163 }
164
165 msg.hw_mode_index = hw_mode_index;
166 msg.set_hw_mode_cb = (void *)policy_mgr_pdev_set_hw_mode_cb;
167 msg.reason = reason;
168 msg.session_id = session_id;
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800169 msg.next_action = next_action;
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -0700170 msg.context = psoc;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800171
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -0700172 policy_mgr_debug("set hw mode to sme: hw_mode_index: %d session:%d reason:%d",
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800173 msg.hw_mode_index, msg.session_id, msg.reason);
174
175 status = pm_ctx->sme_cbacks.sme_pdev_set_hw_mode(msg);
176 if (status != QDF_STATUS_SUCCESS) {
177 policy_mgr_err("Failed to set hw mode to SME");
178 return status;
179 }
180
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800181 return QDF_STATUS_SUCCESS;
182}
183
184enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade(
Liangwei Dong88ddf822018-05-25 05:55:37 -0400185 struct wlan_objmgr_psoc *psoc,
186 enum policy_mgr_conn_update_reason *reason)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800187{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800188 uint32_t conn_index;
189 enum policy_mgr_conc_next_action upgrade = PM_NOP;
Liangwei Dong88ddf822018-05-25 05:55:37 -0400190 enum policy_mgr_conc_next_action preferred_dbs_action;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800191 uint8_t mac = 0;
192 struct policy_mgr_hw_mode_params hw_mode;
193 QDF_STATUS status = QDF_STATUS_E_FAILURE;
194 struct policy_mgr_psoc_priv_obj *pm_ctx;
195
196 pm_ctx = policy_mgr_get_context(psoc);
197 if (!pm_ctx) {
198 policy_mgr_err("Invalid Context");
Liangwei Dong88ddf822018-05-25 05:55:37 -0400199 goto exit;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800200 }
201
202 if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
203 policy_mgr_err("driver isn't dbs capable, no further action needed");
Liangwei Dong88ddf822018-05-25 05:55:37 -0400204 goto exit;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800205 }
206
207 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
208 if (!QDF_IS_STATUS_SUCCESS(status)) {
209 policy_mgr_err("policy_mgr_get_current_hw_mode failed");
Liangwei Dong88ddf822018-05-25 05:55:37 -0400210 goto exit;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800211 }
212 if (!hw_mode.dbs_cap) {
Yeshwanth Sriram Guntukad540cd02018-08-23 18:25:28 +0530213 policy_mgr_debug("current HW mode is non-DBS capable");
Liangwei Dong88ddf822018-05-25 05:55:37 -0400214 goto exit;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800215 }
216
217 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
218 /* Are both mac's still in use */
219 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
220 conn_index++) {
221 policy_mgr_debug("index:%d mac:%d in_use:%d chan:%d org_nss:%d",
222 conn_index,
223 pm_conc_connection_list[conn_index].mac,
224 pm_conc_connection_list[conn_index].in_use,
225 pm_conc_connection_list[conn_index].chan,
226 pm_conc_connection_list[conn_index].original_nss);
227 if ((pm_conc_connection_list[conn_index].mac == 0) &&
228 pm_conc_connection_list[conn_index].in_use) {
229 mac |= POLICY_MGR_MAC0;
230 if (POLICY_MGR_MAC0_AND_MAC1 == mac) {
231 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
232 goto done;
233 }
234 } else if ((pm_conc_connection_list[conn_index].mac == 1) &&
235 pm_conc_connection_list[conn_index].in_use) {
236 mac |= POLICY_MGR_MAC1;
Archana Ramachandran944f1fd2017-06-02 16:48:17 -0700237 if (policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
238 WLAN_REG_IS_24GHZ_CH(
239 pm_conc_connection_list[conn_index].chan)
240 ) {
241 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
242 policy_mgr_debug("2X2 DBS capable with 2.4 GHZ connection");
243 goto done;
244 }
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800245 if (POLICY_MGR_MAC0_AND_MAC1 == mac) {
246 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
247 goto done;
248 }
249 }
250 }
251 /* Let's request for single MAC mode */
252 upgrade = PM_SINGLE_MAC;
Liangwei Dong88ddf822018-05-25 05:55:37 -0400253 if (reason)
254 *reason = POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800255 /* Is there any connection had an initial connection with 2x2 */
256 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
257 conn_index++) {
258 if ((pm_conc_connection_list[conn_index].original_nss == 2) &&
259 pm_conc_connection_list[conn_index].in_use) {
260 upgrade = PM_SINGLE_MAC_UPGRADE;
261 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
262 goto done;
263 }
264 }
265 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
266
267done:
Liangwei Dong88ddf822018-05-25 05:55:37 -0400268 if (upgrade == PM_NOP && hw_mode.dbs_cap &&
269 policy_mgr_is_2x2_1x1_dbs_capable(psoc)) {
270 preferred_dbs_action =
271 policy_mgr_get_preferred_dbs_action_table(
272 psoc, INVALID_VDEV_ID, 0, 0);
273 if (hw_mode.action_type == PM_DBS1 &&
274 preferred_dbs_action == PM_DBS2) {
275 upgrade = PM_DBS2_DOWNGRADE;
276 if (reason)
277 *reason =
278 POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE;
279 } else if (hw_mode.action_type == PM_DBS2 &&
280 preferred_dbs_action == PM_DBS1) {
281 upgrade = PM_DBS1_DOWNGRADE;
282 if (reason)
283 *reason =
284 POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE;
285 }
286 }
287exit:
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800288 return upgrade;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800289}
290
291QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc,
292 uint32_t vdev_id)
293{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800294 QDF_STATUS status = QDF_STATUS_E_FAILURE;
295 uint32_t conn_index = 0;
296 bool found = false;
297 struct policy_mgr_vdev_entry_info conn_table_entry;
298 enum policy_mgr_chain_mode chain_mask = POLICY_MGR_ONE_ONE;
299 uint8_t nss_2g, nss_5g;
300 enum policy_mgr_con_mode mode;
301 uint8_t chan;
302 uint32_t nss = 0;
303 struct policy_mgr_psoc_priv_obj *pm_ctx;
304
305 pm_ctx = policy_mgr_get_context(psoc);
306 if (!pm_ctx) {
307 policy_mgr_err("Invalid Context");
308 return status;
309 }
310
311 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
312 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
313 if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
314 /* debug msg */
315 found = true;
316 break;
317 }
318 conn_index++;
319 }
320 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
321 if (!found) {
322 /* err msg */
323 policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list",
324 vdev_id);
325 return status;
326 }
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700327 if (pm_ctx->wma_cbacks.wma_get_connection_info) {
328 status = pm_ctx->wma_cbacks.wma_get_connection_info(
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800329 vdev_id, &conn_table_entry);
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700330 if (QDF_STATUS_SUCCESS != status) {
331 policy_mgr_err("can't find vdev_id %d in connection table",
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800332 vdev_id);
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700333 return status;
334 }
335 } else {
336 policy_mgr_err("wma_get_connection_info is NULL");
337 return QDF_STATUS_E_FAILURE;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800338 }
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700339
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800340 mode = policy_mgr_get_mode(conn_table_entry.type,
341 conn_table_entry.sub_type);
Tushnim Bhattacharyyace237d62017-04-05 12:52:36 -0700342 chan = wlan_reg_freq_to_chan(pm_ctx->pdev, conn_table_entry.mhz);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800343 status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g);
344 if (QDF_IS_STATUS_SUCCESS(status)) {
345 if ((WLAN_REG_IS_24GHZ_CH(chan) && (nss_2g > 1)) ||
346 (WLAN_REG_IS_5GHZ_CH(chan) && (nss_5g > 1)))
347 chain_mask = POLICY_MGR_TWO_TWO;
348 else
349 chain_mask = POLICY_MGR_ONE_ONE;
350 nss = (WLAN_REG_IS_24GHZ_CH(chan)) ? nss_2g : nss_5g;
351 } else {
352 policy_mgr_err("Error in getting nss");
353 }
354
355 policy_mgr_debug("update PM connection table for vdev:%d", vdev_id);
356
357 /* add the entry */
358 policy_mgr_update_conc_list(psoc, conn_index,
359 mode,
360 chan,
361 policy_mgr_get_bw(conn_table_entry.chan_width),
362 conn_table_entry.mac_id,
363 chain_mask,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +0530364 nss, vdev_id, true, true);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800365
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800366 return QDF_STATUS_SUCCESS;
367}
368
369QDF_STATUS policy_mgr_update_and_wait_for_connection_update(
370 struct wlan_objmgr_psoc *psoc,
371 uint8_t session_id,
372 uint8_t channel,
373 enum policy_mgr_conn_update_reason reason)
374{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800375 QDF_STATUS status;
376
377 policy_mgr_debug("session:%d channel:%d reason:%d",
378 session_id, channel, reason);
379
380 status = policy_mgr_reset_connection_update(psoc);
381 if (QDF_IS_STATUS_ERROR(status))
382 policy_mgr_err("clearing event failed");
383
384 status = policy_mgr_current_connections_update(psoc,
385 session_id, channel, reason);
386 if (QDF_STATUS_E_FAILURE == status) {
387 policy_mgr_err("connections update failed");
388 return QDF_STATUS_E_FAILURE;
389 }
390
391 /* Wait only when status is success */
392 if (QDF_IS_STATUS_SUCCESS(status)) {
393 status = policy_mgr_wait_for_connection_update(psoc);
394 if (QDF_IS_STATUS_ERROR(status)) {
395 policy_mgr_err("qdf wait for event failed");
396 return QDF_STATUS_E_FAILURE;
397 }
398 }
399
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800400 return QDF_STATUS_SUCCESS;
401}
402
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530403/**
404 * policy_mgr_is_dbs_allowed_for_concurrency() - If dbs is allowed for current
405 * concurreny
406 * @new_conn_mode: new connection mode
407 *
408 * When a new connection is about to come up, check if dbs is allowed for
409 * STA+STA or STA+P2P
410 *
411 * Return: true if dbs is allowed for STA+STA or STA+P2P else false
412 */
Bala Venkatesh28477d32018-05-07 21:35:55 +0530413bool policy_mgr_is_dbs_allowed_for_concurrency(
414 struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE new_conn_mode)
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530415{
416 struct policy_mgr_psoc_priv_obj *pm_ctx;
417 uint32_t count, dbs_for_sta_sta, dbs_for_sta_p2p;
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530418 bool ret = true;
Krunal Sonid4e542b2018-09-27 12:40:33 -0700419 uint32_t ch_sel_plcy;
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530420
421 pm_ctx = policy_mgr_get_context(psoc);
422 if (!pm_ctx) {
423 policy_mgr_err("Invalid context");
424 return ret;
425 }
426
427 count = policy_mgr_get_connection_count(psoc);
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530428
429 if (count != 1 || new_conn_mode == QDF_MAX_NO_OF_MODE)
430 return ret;
431
Krunal Sonid4e542b2018-09-27 12:40:33 -0700432 ch_sel_plcy = pm_ctx->cfg.chnl_select_plcy;
433 dbs_for_sta_sta = PM_CHANNEL_SELECT_LOGIC_STA_STA_GET(ch_sel_plcy);
434 dbs_for_sta_p2p = PM_CHANNEL_SELECT_LOGIC_STA_P2P_GET(ch_sel_plcy);
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530435
436 switch (pm_conc_connection_list[0].mode) {
437 case PM_STA_MODE:
438 switch (new_conn_mode) {
439 case QDF_STA_MODE:
440 if (!dbs_for_sta_sta)
441 return false;
442 break;
443 case QDF_P2P_DEVICE_MODE:
444 case QDF_P2P_CLIENT_MODE:
445 case QDF_P2P_GO_MODE:
446 if (!dbs_for_sta_p2p)
447 return false;
448 break;
449 default:
450 break;
451 }
452 break;
453 case PM_P2P_CLIENT_MODE:
454 case PM_P2P_GO_MODE:
455 switch (new_conn_mode) {
456 case QDF_STA_MODE:
457 if (!dbs_for_sta_p2p)
458 return false;
459 break;
460 default:
461 break;
462 }
463 break;
464 default:
465 break;
466 }
467
468 return ret;
469}
470
gaurank kathpalia9ba5f5e2018-10-04 01:36:09 +0530471bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc,
Krunal Soni637eba52018-06-14 17:55:15 -0700472 uint8_t channel)
473{
474 uint8_t i, pm_chnl;
475 struct policy_mgr_psoc_priv_obj *pm_ctx;
476
477 pm_ctx = policy_mgr_get_context(psoc);
478 if (!pm_ctx) {
479 policy_mgr_err("Invalid Context");
480 return false;
481 }
482
483 /*
484 * check given channel against already existing connections'
485 * channels. if they differ then channels are in different bands
486 */
487 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
488 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
489 pm_chnl = pm_conc_connection_list[i].chan;
490 if (pm_conc_connection_list[i].in_use)
491 if (!WLAN_REG_IS_SAME_BAND_CHANNELS(channel, pm_chnl)) {
492 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
493 policy_mgr_debug("channel is in diff band");
494 return true;
495 }
496 }
497 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
498
499 return false;
500}
501
502bool policy_mgr_is_hwmode_set_for_given_chnl(struct wlan_objmgr_psoc *psoc,
503 uint8_t channel)
504{
505 enum policy_mgr_band band;
506 bool is_hwmode_dbs, is_2x2_dbs;
507
508 if (policy_mgr_is_hw_dbs_capable(psoc) == false)
509 return true;
510
511 if (WLAN_REG_IS_24GHZ_CH(channel))
512 band = POLICY_MGR_BAND_24;
513 else
514 band = POLICY_MGR_BAND_5;
515
516 is_hwmode_dbs = policy_mgr_is_current_hwmode_dbs(psoc);
517 is_2x2_dbs = policy_mgr_is_hw_dbs_2x2_capable(psoc);
518 /*
519 * If HW supports 2x2 chains in DBS HW mode and if DBS HW mode is not
520 * yet set then this is the right time to block the connection.
521 */
522 if ((band == POLICY_MGR_BAND_24) && is_2x2_dbs && !is_hwmode_dbs) {
523 policy_mgr_err("HW mode is not yet in DBS!!!!!");
524 return false;
525 }
526
527 /*
528 * If HW supports 1x1 chains DBS HW mode and if first connection is
529 * 2G or 5G band and if second connection is coming up in diffrent
530 * band than the first connection and if current HW mode is not yet
531 * set in DBS then this is the right time to block the connection.
532 */
533 if (policy_mgr_is_chnl_in_diff_band(psoc, channel) && !is_hwmode_dbs) {
534 policy_mgr_err("Given channel & existing conn is diff band & HW mode is not yet in DBS !!!!");
535 return false;
536 }
537
538 return true;
539}
540
Liangwei Dongecbf1132018-05-25 05:24:12 -0400541/**
542 * policy_mgr_pri_id_to_con_mode() - convert policy_mgr_pri_id to
543 * policy_mgr_con_mode
544 * @pri_id: policy_mgr_pri_id
545 *
546 * The help function converts policy_mgr_pri_id type to policy_mgr_con_mode
547 * type.
548 *
549 * Return: policy_mgr_con_mode type.
550 */
551static
552enum policy_mgr_con_mode policy_mgr_pri_id_to_con_mode(
553 enum policy_mgr_pri_id pri_id)
554{
555 switch (pri_id) {
556 case PM_STA_PRI_ID:
557 return PM_STA_MODE;
558 case PM_SAP_PRI_ID:
559 return PM_SAP_MODE;
560 case PM_P2P_GO_PRI_ID:
561 return PM_P2P_GO_MODE;
562 case PM_P2P_CLI_PRI_ID:
563 return PM_P2P_CLIENT_MODE;
564 default:
565 return PM_MAX_NUM_OF_MODE;
566 }
567}
568
569enum policy_mgr_conc_next_action
570policy_mgr_get_preferred_dbs_action_table(
571 struct wlan_objmgr_psoc *psoc,
572 uint32_t vdev_id,
573 uint8_t channel,
574 enum policy_mgr_conn_update_reason reason)
575{
576 struct policy_mgr_psoc_priv_obj *pm_ctx;
577 enum policy_mgr_con_mode pri_conn_mode = PM_MAX_NUM_OF_MODE;
578 enum policy_mgr_con_mode new_conn_mode = PM_MAX_NUM_OF_MODE;
579 enum QDF_OPMODE new_conn_op_mode = QDF_MAX_NO_OF_MODE;
580 bool band_pref_5g = true;
581 bool vdev_priority_enabled = false;
582 bool dbs_2x2_5g_1x1_2g_supported;
583 bool dbs_2x2_2g_1x1_5g_supported;
584 uint32_t vdev_pri_list, vdev_pri_id;
585 uint8_t chan_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
586 uint8_t vdev_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
587 uint32_t vdev_count = 0;
588 uint32_t i;
589 bool found;
590
591 pm_ctx = policy_mgr_get_context(psoc);
592 if (!pm_ctx) {
593 policy_mgr_err("Invalid context");
594 return PM_NOP;
595 }
596 dbs_2x2_5g_1x1_2g_supported =
597 policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc);
598 dbs_2x2_2g_1x1_5g_supported =
599 policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc);
600 policy_mgr_debug("target support DBS1 %d DBS2 %d",
601 dbs_2x2_5g_1x1_2g_supported,
602 dbs_2x2_2g_1x1_5g_supported);
603 /*
604 * If both DBS1 and DBS2 not supported, this should be Legacy Single
605 * DBS mode HW. The policy_mgr_psoc_enable has setup the correct
606 * action tables.
607 */
608 if (!dbs_2x2_5g_1x1_2g_supported && !dbs_2x2_2g_1x1_5g_supported)
609 return PM_NOP;
610 if (!dbs_2x2_5g_1x1_2g_supported) {
611 band_pref_5g = false;
612 policy_mgr_debug("target only supports DBS2!");
613 goto DONE;
614 }
615 if (!dbs_2x2_2g_1x1_5g_supported) {
616 policy_mgr_debug("target only supports DBS1!");
617 goto DONE;
618 }
Krunal Sonid4e542b2018-09-27 12:40:33 -0700619 if (PM_GET_BAND_PREFERRED(pm_ctx->cfg.dbs_selection_plcy) == 1)
Liangwei Dongecbf1132018-05-25 05:24:12 -0400620 band_pref_5g = false;
621
622 if (PM_GET_VDEV_PRIORITY_ENABLED(
Krunal Sonid4e542b2018-09-27 12:40:33 -0700623 pm_ctx->cfg.dbs_selection_plcy) == 1 &&
624 pm_ctx->cfg.vdev_priority_list)
Liangwei Dongecbf1132018-05-25 05:24:12 -0400625 vdev_priority_enabled = true;
626
627 if (!vdev_priority_enabled)
628 goto DONE;
629
630 if (vdev_id != INVALID_VDEV_ID && channel) {
631 if (pm_ctx->hdd_cbacks.hdd_get_device_mode)
632 new_conn_op_mode = pm_ctx->hdd_cbacks.
633 hdd_get_device_mode(vdev_id);
634
635 new_conn_mode = policy_mgr_convert_device_mode_to_qdf_type(
636 new_conn_op_mode);
637 if (new_conn_mode == PM_MAX_NUM_OF_MODE)
638 policy_mgr_debug("new vdev %d op_mode %d chan %d reason %d: not prioritized",
639 vdev_id, new_conn_op_mode,
640 channel, reason);
641 else
642 policy_mgr_debug("new vdev %d op_mode %d chan %d : reason %d",
643 vdev_id, new_conn_op_mode, channel,
644 reason);
645 }
Krunal Sonid4e542b2018-09-27 12:40:33 -0700646 vdev_pri_list = pm_ctx->cfg.vdev_priority_list;
Liangwei Dongecbf1132018-05-25 05:24:12 -0400647 while (vdev_pri_list) {
648 vdev_pri_id = vdev_pri_list & 0xF;
649 pri_conn_mode = policy_mgr_pri_id_to_con_mode(vdev_pri_id);
650 if (pri_conn_mode == PM_MAX_NUM_OF_MODE) {
651 policy_mgr_debug("vdev_pri_id %d prioritization not supported",
652 vdev_pri_id);
653 goto NEXT;
654 }
655 vdev_count = policy_mgr_get_mode_specific_conn_info(
656 psoc, chan_list, vdev_list, pri_conn_mode);
657 /**
658 * Take care of duplication case, the vdev id may
659 * exist in the conn list already with old chan.
660 * Replace with new chan before make decision.
661 */
662 found = false;
663 for (i = 0; i < vdev_count; i++) {
664 policy_mgr_debug("[%d] vdev %d chan %d conn_mode %d",
665 i, vdev_list[i], chan_list[i],
666 pri_conn_mode);
667
668 if (new_conn_mode == pri_conn_mode &&
669 vdev_list[i] == vdev_id) {
670 chan_list[i] = channel;
671 found = true;
672 }
673 }
674 /**
675 * The new coming vdev should be added to the list to
676 * make decision if it is prioritized.
677 */
678 if (!found && new_conn_mode == pri_conn_mode) {
679 chan_list[vdev_count] = channel;
680 vdev_list[vdev_count++] = vdev_id;
681 }
682 /**
683 * if more than one vdev has same priority, keep "band_pref_5g"
684 * value as default band preference setting.
685 */
686 if (vdev_count > 1)
687 break;
688 /**
689 * select the only active vdev (or new coming vdev) chan as
690 * preferred band.
691 */
692 if (vdev_count > 0) {
693 band_pref_5g = WLAN_REG_IS_5GHZ_CH(chan_list[0]);
694 break;
695 }
696NEXT:
697 vdev_pri_list >>= 4;
698 }
699DONE:
700 policy_mgr_debug("band_pref_5g %d", band_pref_5g);
701 if (band_pref_5g)
702 return PM_DBS1;
703 else
704 return PM_DBS2;
705}
706
707/**
708 * policy_mgr_get_second_conn_action_table() - get second conn action table
709 * @psoc: Pointer to psoc
710 * @vdev_id: vdev Id
711 * @channel: channel of vdev.
712 * @reason: reason of request
713 *
714 * Get the action table based on current HW Caps and INI user preference.
715 * This function will be called by policy_mgr_current_connections_update during
716 * DBS action decision.
717 *
718 * return : action table address
719 */
720static policy_mgr_next_action_two_connection_table_type *
721policy_mgr_get_second_conn_action_table(
722 struct wlan_objmgr_psoc *psoc,
723 uint32_t vdev_id,
724 uint8_t channel,
725 enum policy_mgr_conn_update_reason reason)
726{
727 enum policy_mgr_conc_next_action preferred_action;
728
729 if (!policy_mgr_is_2x2_1x1_dbs_capable(psoc))
730 return next_action_two_connection_table;
731
732 preferred_action = policy_mgr_get_preferred_dbs_action_table(
733 psoc, vdev_id, channel, reason);
734 switch (preferred_action) {
735 case PM_DBS2:
736 return next_action_two_connection_2x2_2g_1x1_5g_table;
737 default:
738 return next_action_two_connection_table;
739 }
740}
741
742/**
743 * policy_mgr_get_third_conn_action_table() - get third connection action table
744 * @psoc: Pointer to psoc
745 * @vdev_id: vdev Id
746 * @channel: channel of vdev.
747 * @reason: reason of request
748 *
749 * Get the action table based on current HW Caps and INI user preference.
750 * This function will be called by policy_mgr_current_connections_update during
751 * DBS action decision.
752 *
753 * return : action table address
754 */
755static policy_mgr_next_action_three_connection_table_type *
756policy_mgr_get_third_conn_action_table(
757 struct wlan_objmgr_psoc *psoc,
758 uint32_t vdev_id,
759 uint8_t channel,
760 enum policy_mgr_conn_update_reason reason)
761{
762 enum policy_mgr_conc_next_action preferred_action;
763
764 if (!policy_mgr_is_2x2_1x1_dbs_capable(psoc))
765 return next_action_three_connection_table;
766
767 preferred_action = policy_mgr_get_preferred_dbs_action_table(
768 psoc, vdev_id, channel, reason);
769 switch (preferred_action) {
770 case PM_DBS2:
771 return next_action_three_connection_2x2_2g_1x1_5g_table;
772 default:
773 return next_action_three_connection_table;
774 }
775}
776
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800777QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc,
778 uint32_t session_id,
779 uint8_t channel,
780 enum policy_mgr_conn_update_reason reason)
781{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800782 enum policy_mgr_conc_next_action next_action = PM_NOP;
783 uint32_t num_connections = 0;
784 enum policy_mgr_one_connection_mode second_index = 0;
785 enum policy_mgr_two_connection_mode third_index = 0;
Liangwei Dongecbf1132018-05-25 05:24:12 -0400786 policy_mgr_next_action_two_connection_table_type *second_conn_table;
787 policy_mgr_next_action_three_connection_table_type *third_conn_table;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800788 enum policy_mgr_band band;
789 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Bala Venkatesh28477d32018-05-07 21:35:55 +0530790 struct policy_mgr_psoc_priv_obj *pm_ctx;
791 enum QDF_OPMODE new_conn_mode = QDF_MAX_NO_OF_MODE;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800792
793 if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
794 policy_mgr_err("driver isn't dbs capable, no further action needed");
795 return QDF_STATUS_E_NOSUPPORT;
796 }
797 if (WLAN_REG_IS_24GHZ_CH(channel))
798 band = POLICY_MGR_BAND_24;
799 else
800 band = POLICY_MGR_BAND_5;
801
802 num_connections = policy_mgr_get_connection_count(psoc);
803
804 policy_mgr_debug("num_connections=%d channel=%d",
805 num_connections, channel);
806
807 switch (num_connections) {
808 case 0:
809 if (band == POLICY_MGR_BAND_24)
810 if (policy_mgr_is_hw_dbs_2x2_capable(psoc))
811 next_action = PM_DBS;
812 else
813 next_action = PM_NOP;
814 else
815 next_action = PM_NOP;
816 break;
817 case 1:
818 second_index =
819 policy_mgr_get_second_connection_pcl_table_index(psoc);
820 if (PM_MAX_ONE_CONNECTION_MODE == second_index) {
821 policy_mgr_err(
822 "couldn't find index for 2nd connection next action table");
823 goto done;
824 }
Liangwei Dongecbf1132018-05-25 05:24:12 -0400825 second_conn_table = policy_mgr_get_second_conn_action_table(
826 psoc, session_id, channel, reason);
827 next_action = (*second_conn_table)[second_index][band];
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800828 break;
829 case 2:
830 third_index =
831 policy_mgr_get_third_connection_pcl_table_index(psoc);
832 if (PM_MAX_TWO_CONNECTION_MODE == third_index) {
833 policy_mgr_err(
834 "couldn't find index for 3rd connection next action table");
835 goto done;
836 }
Liangwei Dongecbf1132018-05-25 05:24:12 -0400837 third_conn_table = policy_mgr_get_third_conn_action_table(
838 psoc, session_id, channel, reason);
839 next_action = (*third_conn_table)[third_index][band];
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800840 break;
841 default:
842 policy_mgr_err("unexpected num_connections value %d",
843 num_connections);
844 break;
845 }
846
Bala Venkatesh28477d32018-05-07 21:35:55 +0530847 pm_ctx = policy_mgr_get_context(psoc);
848 if (!pm_ctx) {
849 policy_mgr_err("Invalid context");
850 goto done;
851 }
852
Nachiket Kukadecf941602018-12-12 14:32:35 +0530853 /*
854 * There is no adapter associated with NAN Discovery, hence skip the
855 * HDD callback and fill separately.
856 */
857 if (reason == POLICY_MGR_UPDATE_REASON_NAN_DISCOVERY)
858 new_conn_mode = QDF_NAN_DISC_MODE;
859 else if (pm_ctx->hdd_cbacks.hdd_get_device_mode)
Bala Venkatesh28477d32018-05-07 21:35:55 +0530860 new_conn_mode = pm_ctx->hdd_cbacks.
861 hdd_get_device_mode(session_id);
862
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530863 /*
864 * Based on channel_select_logic_conc ini, hw mode is set
865 * when second connection is about to come up that results
866 * in STA+STA and STA+P2P concurrency.
867 * 1) If MCC is set and if current hw mode is dbs, hw mode
868 * should be set to single mac for above concurrency.
869 * 2) If MCC is set and if current hw mode is not dbs, hw
870 * mode change is not required.
871 */
872 if (policy_mgr_is_current_hwmode_dbs(psoc) &&
Bala Venkatesh28477d32018-05-07 21:35:55 +0530873 !policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode))
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530874 next_action = PM_SINGLE_MAC;
875 else if (!policy_mgr_is_current_hwmode_dbs(psoc) &&
Bala Venkatesh28477d32018-05-07 21:35:55 +0530876 !policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode))
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530877 next_action = PM_NOP;
878
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800879 if (PM_NOP != next_action)
880 status = policy_mgr_next_actions(psoc, session_id,
881 next_action, reason);
882 else
883 status = QDF_STATUS_E_NOSUPPORT;
884
885 policy_mgr_debug(
886 "idx2=%d idx3=%d next_action=%d, band=%d status=%d reason=%d session_id=%d",
887 second_index, third_index, next_action, band, status,
888 reason, session_id);
889
890done:
891 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800892}
893
Liangwei Dong18300132018-05-25 01:25:24 -0400894/**
895 * policy_mgr_validate_dbs_switch() - Check DBS action valid or not
896 * @psoc: Pointer to psoc
897 * @session_id: vdev id
898 * @action: action requested
899 * @reason: reason of hw mode change
900 *
901 * This routine will check the current hw mode with requested action.
902 * If we are already in the mode, the caller will do nothing.
903 * This will be called by policy_mgr_next_actions to check the action needed
904 * or not.
905 *
906 * return : QDF_STATUS_SUCCESS, action is allowed.
907 * QDF_STATUS_E_ALREADY, action is not needed.
908 * QDF_STATUS_E_FAILURE, error happens.
909 * QDF_STATUS_E_NOSUPPORT, the requested mode not supported.
910 */
911static
912QDF_STATUS policy_mgr_validate_dbs_switch(
913 struct wlan_objmgr_psoc *psoc,
914 uint32_t session_id,
915 enum policy_mgr_conc_next_action action,
916 enum policy_mgr_conn_update_reason reason)
917{
918 QDF_STATUS status;
919 struct policy_mgr_hw_mode_params hw_mode;
920
921 /* check for the current HW index to see if really need any action */
922 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
923 if (!QDF_IS_STATUS_SUCCESS(status)) {
924 policy_mgr_err("policy_mgr_get_current_hw_mode failed");
925 return status;
926 }
927
Liangwei Dongb0078632018-12-24 02:45:05 -0500928 if ((action == PM_SBS) || (action == PM_SBS_DOWNGRADE)) {
929 if (!policy_mgr_is_hw_sbs_capable(psoc)) {
930 /* No action */
931 policy_mgr_notice("firmware is not sbs capable");
932 return QDF_STATUS_E_NOSUPPORT;
Liangwei Dong18300132018-05-25 01:25:24 -0400933 }
Liangwei Dongb0078632018-12-24 02:45:05 -0500934 /* current mode is already SBS nothing to be
935 * done
936 */
Liangwei Dong77ff66c2018-12-27 22:48:30 -0500937 if (hw_mode.sbs_cap) {
Liangwei Dongb0078632018-12-24 02:45:05 -0500938 policy_mgr_notice("current mode is already SBS");
939 return QDF_STATUS_E_ALREADY;
940 }
941 return QDF_STATUS_SUCCESS;
Liangwei Dong18300132018-05-25 01:25:24 -0400942 }
943
944 if (!hw_mode.dbs_cap) {
945 if (action == PM_SINGLE_MAC ||
946 action == PM_SINGLE_MAC_UPGRADE) {
947 policy_mgr_notice("current mode is already single MAC");
948 return QDF_STATUS_E_ALREADY;
949 } else {
950 return QDF_STATUS_SUCCESS;
951 }
952 }
953 /**
954 * If already in DBS, no need to request DBS again (HL, Napier).
955 * For dual DBS HW, in case DBS1 -> DBS2 or DBS2 -> DBS1
956 * switching, we need to check the current DBS mode is same as
957 * requested or not.
958 */
959 if (policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc) ||
960 policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc)) {
961 policy_mgr_info("curr dbs action %d new action %d",
962 hw_mode.action_type, action);
963 if (hw_mode.action_type == PM_DBS1 &&
964 ((action == PM_DBS1 ||
965 action == PM_DBS1_DOWNGRADE))) {
966 policy_mgr_err("driver is already in DBS_5G_2x2_24G_1x1 (%d), no further action %d needed",
967 hw_mode.action_type, action);
968 return QDF_STATUS_E_ALREADY;
969 } else if (hw_mode.action_type == PM_DBS2 &&
970 ((action == PM_DBS2 ||
971 action == PM_DBS2_DOWNGRADE))) {
972 policy_mgr_err("driver is already in DBS_24G_2x2_5G_1x1 (%d), no further action %d needed",
973 hw_mode.action_type, action);
974 return QDF_STATUS_E_ALREADY;
975 }
976 } else if ((action == PM_DBS_DOWNGRADE) || (action == PM_DBS) ||
977 (action == PM_DBS_UPGRADE)) {
978 policy_mgr_err("driver is already in %s mode, no further action needed",
979 (hw_mode.dbs_cap) ? "dbs" : "non dbs");
980 return QDF_STATUS_E_ALREADY;
981 }
982 return QDF_STATUS_SUCCESS;
983}
984
985QDF_STATUS policy_mgr_next_actions(
986 struct wlan_objmgr_psoc *psoc,
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800987 uint32_t session_id,
988 enum policy_mgr_conc_next_action action,
989 enum policy_mgr_conn_update_reason reason)
990{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800991 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Varun Reddy Yeturue23b6bc2018-01-08 13:18:41 -0800992 struct dbs_nss nss_dbs = {0};
Liangwei Dong18300132018-05-25 01:25:24 -0400993 struct policy_mgr_hw_mode_params hw_mode;
994 enum policy_mgr_conc_next_action next_action;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800995
996 if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
997 policy_mgr_err("driver isn't dbs capable, no further action needed");
998 return QDF_STATUS_E_NOSUPPORT;
999 }
1000
1001 /* check for the current HW index to see if really need any action */
1002 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
1003 if (!QDF_IS_STATUS_SUCCESS(status)) {
1004 policy_mgr_err("policy_mgr_get_current_hw_mode failed");
1005 return status;
1006 }
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001007
Liangwei Dong18300132018-05-25 01:25:24 -04001008 /* check for the current HW index to see if really need any action */
1009 status = policy_mgr_validate_dbs_switch(psoc, session_id, action,
1010 reason);
1011 if (!QDF_IS_STATUS_SUCCESS(status)) {
1012 policy_mgr_err(" not take action %d reason %d session %d status %d",
1013 action, reason, session_id, status);
1014 return status;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001015 }
1016
1017 switch (action) {
1018 case PM_DBS_DOWNGRADE:
1019 /*
1020 * check if we have a beaconing entity that is using 2x2. If yes,
1021 * update the beacon template & notify FW. Once FW confirms
1022 * beacon updated, send down the HW mode change req
1023 */
1024 status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
1025 PM_DBS, reason, session_id);
1026 break;
1027 case PM_DBS:
Vikrampal31eb12c2017-04-28 17:44:30 +05301028 (void)policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs);
1029
1030 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1031 nss_dbs.mac0_ss,
1032 HW_MODE_80_MHZ,
1033 nss_dbs.mac1_ss,
1034 HW_MODE_40_MHZ,
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001035 HW_MODE_MAC_BAND_NONE,
Vikrampal31eb12c2017-04-28 17:44:30 +05301036 HW_MODE_DBS,
1037 HW_MODE_AGILE_DFS_NONE,
1038 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -08001039 reason, PM_NOP);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001040 break;
1041 case PM_SINGLE_MAC_UPGRADE:
1042 /*
1043 * change the HW mode first before the NSS upgrade
1044 */
1045 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1046 HW_MODE_SS_2x2,
1047 HW_MODE_80_MHZ,
1048 HW_MODE_SS_0x0, HW_MODE_BW_NONE,
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001049 HW_MODE_MAC_BAND_NONE,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001050 HW_MODE_DBS_NONE,
1051 HW_MODE_AGILE_DFS_NONE,
1052 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -08001053 reason, PM_UPGRADE);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001054 break;
1055 case PM_SINGLE_MAC:
1056 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1057 HW_MODE_SS_2x2,
1058 HW_MODE_80_MHZ,
1059 HW_MODE_SS_0x0, HW_MODE_BW_NONE,
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001060 HW_MODE_MAC_BAND_NONE,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001061 HW_MODE_DBS_NONE,
1062 HW_MODE_AGILE_DFS_NONE,
1063 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -08001064 reason, PM_NOP);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001065 break;
1066 case PM_DBS_UPGRADE:
1067 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1068 HW_MODE_SS_2x2,
1069 HW_MODE_80_MHZ,
1070 HW_MODE_SS_2x2, HW_MODE_80_MHZ,
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001071 HW_MODE_MAC_BAND_NONE,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001072 HW_MODE_DBS,
1073 HW_MODE_AGILE_DFS_NONE,
1074 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -08001075 reason, PM_UPGRADE);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001076 break;
1077 case PM_SBS_DOWNGRADE:
1078 status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
1079 PM_SBS, reason, session_id);
1080 break;
1081 case PM_SBS:
1082 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1083 HW_MODE_SS_1x1,
1084 HW_MODE_80_MHZ,
1085 HW_MODE_SS_1x1, HW_MODE_80_MHZ,
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001086 HW_MODE_MAC_BAND_NONE,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001087 HW_MODE_DBS,
1088 HW_MODE_AGILE_DFS_NONE,
1089 HW_MODE_SBS,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -08001090 reason, PM_NOP);
1091 break;
1092 case PM_DOWNGRADE:
1093 /*
1094 * check if we have a beaconing entity that advertised 2x2
1095 * intially. If yes, update the beacon template & notify FW.
1096 */
1097 status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_1,
Liangwei Dongdae31902018-10-21 23:40:06 -04001098 PM_NOP, POLICY_MGR_ANY, reason,
1099 session_id);
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -08001100 break;
1101 case PM_UPGRADE:
1102 /*
1103 * check if we have a beaconing entity that advertised 2x2
1104 * intially. If yes, update the beacon template & notify FW.
1105 */
1106 status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_2,
Liangwei Dongdae31902018-10-21 23:40:06 -04001107 PM_NOP, POLICY_MGR_ANY, reason,
1108 session_id);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001109 break;
Liangwei Dong18300132018-05-25 01:25:24 -04001110 case PM_DBS1_DOWNGRADE:
1111 status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
1112 PM_DBS1, reason,
1113 session_id);
1114 break;
1115 case PM_DBS2_DOWNGRADE:
1116 status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
1117 PM_DBS2, reason,
1118 session_id);
1119 break;
1120 case PM_DBS1:
1121 /*
1122 * PM_DBS1 (2x2 5G + 1x1 2G) will support 5G 2x2. If previous
1123 * mode is DBS, that should be 2x2 2G + 1x1 5G mode and
1124 * the 5G band was downgraded to 1x1. So, we need to
1125 * upgrade 5G vdevs after hw mode change.
1126 */
1127 if (hw_mode.dbs_cap)
1128 next_action = PM_UPGRADE_5G;
1129 else
1130 next_action = PM_NOP;
1131 status = policy_mgr_pdev_set_hw_mode(
1132 psoc, session_id,
1133 HW_MODE_SS_2x2,
1134 HW_MODE_80_MHZ,
1135 HW_MODE_SS_1x1, HW_MODE_40_MHZ,
1136 HW_MODE_MAC_BAND_5G,
1137 HW_MODE_DBS,
1138 HW_MODE_AGILE_DFS_NONE,
1139 HW_MODE_SBS_NONE,
1140 reason, next_action);
1141 break;
1142 case PM_DBS2:
1143 /*
1144 * PM_DBS2 (2x2 2G + 1x1 5G) will support 2G 2x2. If previous
1145 * mode is DBS, that should be 2x2 5G + 1x1 2G mode and
1146 * the 2G band was downgraded to 1x1. So, we need to
1147 * upgrade 5G vdevs after hw mode change.
1148 */
1149 if (hw_mode.dbs_cap)
1150 next_action = PM_UPGRADE_2G;
1151 else
1152 next_action = PM_NOP;
1153 status = policy_mgr_pdev_set_hw_mode(
1154 psoc, session_id,
1155 HW_MODE_SS_2x2,
1156 HW_MODE_40_MHZ,
1157 HW_MODE_SS_1x1, HW_MODE_40_MHZ,
1158 HW_MODE_MAC_BAND_2G,
1159 HW_MODE_DBS,
1160 HW_MODE_AGILE_DFS_NONE,
1161 HW_MODE_SBS_NONE,
1162 reason, next_action);
1163 break;
1164 case PM_UPGRADE_5G:
1165 status = policy_mgr_nss_update(
1166 psoc, POLICY_MGR_RX_NSS_2,
Liangwei Dongdae31902018-10-21 23:40:06 -04001167 PM_NOP, POLICY_MGR_BAND_5, reason,
1168 session_id);
Liangwei Dong18300132018-05-25 01:25:24 -04001169 break;
1170 case PM_UPGRADE_2G:
1171 status = policy_mgr_nss_update(
1172 psoc, POLICY_MGR_RX_NSS_2,
Liangwei Dongdae31902018-10-21 23:40:06 -04001173 PM_NOP, POLICY_MGR_BAND_24, reason,
1174 session_id);
Liangwei Dong18300132018-05-25 01:25:24 -04001175 break;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001176 default:
1177 policy_mgr_err("unexpected action value %d", action);
1178 status = QDF_STATUS_E_FAILURE;
1179 break;
1180 }
1181
1182 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001183}
1184
1185QDF_STATUS policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc,
1186 uint8_t session_id, uint8_t channel)
1187{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001188 QDF_STATUS status;
1189
1190 if (!policy_mgr_check_for_session_conc(psoc, session_id, channel)) {
1191 policy_mgr_err("Conc not allowed for the session %d",
1192 session_id);
1193 return QDF_STATUS_E_FAILURE;
1194 }
1195
1196 status = policy_mgr_reset_connection_update(psoc);
1197 if (!QDF_IS_STATUS_SUCCESS(status))
1198 policy_mgr_err("clearing event failed");
1199
1200 status = policy_mgr_current_connections_update(psoc, session_id,
1201 channel,
1202 POLICY_MGR_UPDATE_REASON_NORMAL_STA);
1203 if (QDF_STATUS_E_FAILURE == status) {
1204 policy_mgr_err("connections update failed");
1205 return status;
1206 }
1207
1208 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001209}
1210
1211#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301212void policy_mgr_update_user_config_sap_chan(
1213 struct wlan_objmgr_psoc *psoc, uint32_t channel)
1214{
1215 struct policy_mgr_psoc_priv_obj *pm_ctx;
1216
1217 pm_ctx = policy_mgr_get_context(psoc);
1218 if (!pm_ctx) {
1219 policy_mgr_err("Invalid pm context and failed to update the user config sap channel");
1220 return;
1221 }
1222 pm_ctx->user_config_sap_channel = channel;
1223}
1224
Archana Ramachandran544ce172017-03-14 15:12:09 -07001225/**
1226 * policy_mgr_is_restart_sap_allowed() - Check if restart SAP
1227 * allowed during SCC -> MCC switch
1228 * @psoc: PSOC object data
1229 * @mcc_to_scc_switch: MCC to SCC switch enabled user config
1230 *
1231 * Check if restart SAP allowed during SCC->MCC switch
1232 *
1233 * Restart: true or false
1234 */
1235static bool policy_mgr_is_restart_sap_allowed(
1236 struct wlan_objmgr_psoc *psoc,
1237 uint32_t mcc_to_scc_switch)
1238{
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301239 uint32_t sta_ap_bit_mask = QDF_STA_MASK | QDF_SAP_MASK;
1240 uint32_t sta_go_bit_mask = QDF_STA_MASK | QDF_P2P_GO_MASK;
1241
Archana Ramachandran544ce172017-03-14 15:12:09 -07001242 if ((mcc_to_scc_switch == QDF_MCC_TO_SCC_SWITCH_DISABLE) ||
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001243 !policy_mgr_concurrent_open_sessions_running(psoc) ||
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301244 !(((policy_mgr_get_concurrency_mode(psoc) & sta_ap_bit_mask)
1245 == sta_ap_bit_mask) ||
Tushnim Bhattacharyyab7f83962018-06-14 17:56:38 -07001246 ((mcc_to_scc_switch ==
1247 QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) &&
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301248 ((policy_mgr_get_concurrency_mode(psoc) & sta_go_bit_mask)
Tushnim Bhattacharyyab7f83962018-06-14 17:56:38 -07001249 == sta_go_bit_mask)))) {
Abhinav Kumar77cb42a2018-06-15 16:46:30 +05301250 policy_mgr_debug("MCC switch disabled or not concurrent STA/SAP, STA/GO");
Archana Ramachandran544ce172017-03-14 15:12:09 -07001251 return false;
1252 }
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001253
Archana Ramachandran544ce172017-03-14 15:12:09 -07001254 return true;
1255}
1256
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -07001257bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc,
1258 uint8_t channel)
1259{
1260 struct policy_mgr_psoc_priv_obj *pm_ctx;
1261 bool is_safe = true;
1262 uint8_t j;
1263
1264 pm_ctx = policy_mgr_get_context(psoc);
1265 if (!pm_ctx) {
1266 policy_mgr_err("Invalid context");
1267 return is_safe;
1268 }
1269
1270
1271 if (pm_ctx->unsafe_channel_count == 0) {
1272 policy_mgr_debug("There are no unsafe channels");
1273 return is_safe;
1274 }
1275
1276 for (j = 0; j < pm_ctx->unsafe_channel_count; j++) {
1277 if (channel == pm_ctx->unsafe_channel_list[j]) {
1278 is_safe = false;
1279 policy_mgr_warn("CH %d is not safe", channel);
1280 break;
1281 }
1282 }
1283
1284 return is_safe;
1285}
1286
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301287bool policy_mgr_is_sap_restart_required_after_sta_disconnect(
1288 struct wlan_objmgr_psoc *psoc, uint8_t *intf_ch)
1289{
1290 struct policy_mgr_psoc_priv_obj *pm_ctx;
1291 uint8_t sap_chan = policy_mgr_mode_specific_get_channel(psoc,
1292 PM_SAP_MODE);
1293 bool sta_sap_scc_on_dfs_chan =
1294 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
1295
1296 *intf_ch = 0;
1297
1298 pm_ctx = policy_mgr_get_context(psoc);
1299 if (!pm_ctx) {
1300 policy_mgr_err("Invalid pm context");
1301 return false;
1302 }
1303
1304 policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sap_chan %u",
1305 sta_sap_scc_on_dfs_chan, sap_chan);
1306
Jianmin Zhu7f6bdd32018-06-29 10:39:30 +08001307 if ((!sta_sap_scc_on_dfs_chan ||
1308 !(sap_chan && WLAN_REG_IS_5GHZ_CH(sap_chan) &&
1309 (wlan_reg_get_channel_state(pm_ctx->pdev, sap_chan) ==
1310 CHANNEL_STATE_DFS))) &&
1311 (!policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) ||
1312 policy_mgr_is_safe_channel(psoc, sap_chan))) {
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301313 return false;
1314 }
1315
1316 *intf_ch = pm_ctx->user_config_sap_channel;
1317 policy_mgr_debug("Standalone SAP is not allowed on DFS channel, Move it to channel %u",
1318 *intf_ch);
1319
1320 return true;
1321}
1322
Tushnim Bhattacharyya89036a72018-10-01 14:50:15 -07001323static void __policy_mgr_check_sta_ap_concurrent_ch_intf(void *data)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001324{
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001325 struct wlan_objmgr_psoc *psoc;
1326 struct policy_mgr_psoc_priv_obj *pm_ctx = NULL;
1327 struct sta_ap_intf_check_work_ctx *work_info = NULL;
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301328 uint32_t mcc_to_scc_switch, cc_count = 0, i;
Archana Ramachandran544ce172017-03-14 15:12:09 -07001329 QDF_STATUS status;
1330 uint8_t channel, sec_ch;
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301331 uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS];
1332 uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS];
Archana Ramachandran544ce172017-03-14 15:12:09 -07001333
Tushnim Bhattacharyya89036a72018-10-01 14:50:15 -07001334 if (qdf_is_module_state_transitioning()) {
1335 policy_mgr_err("Module transition in progress");
1336 goto end;
1337 }
1338
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001339 work_info = (struct sta_ap_intf_check_work_ctx *) data;
1340 if (!work_info) {
1341 policy_mgr_err("Invalid work_info");
1342 goto end;
1343 }
1344
1345 psoc = work_info->psoc;
1346 if (!psoc) {
1347 policy_mgr_err("Invalid psoc");
1348 goto end;
1349 }
1350
Archana Ramachandran544ce172017-03-14 15:12:09 -07001351 pm_ctx = policy_mgr_get_context(psoc);
1352 if (!pm_ctx) {
1353 policy_mgr_err("Invalid context");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001354 goto end;
Archana Ramachandran544ce172017-03-14 15:12:09 -07001355 }
1356 mcc_to_scc_switch =
Krunal Sonid36b2072018-09-26 17:02:14 -07001357 policy_mgr_get_mcc_to_scc_switch_mode(psoc);
Archana Ramachandran544ce172017-03-14 15:12:09 -07001358
1359 policy_mgr_info("Concurrent open sessions running: %d",
1360 policy_mgr_concurrent_open_sessions_running(psoc));
1361
1362 if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch))
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001363 goto end;
Archana Ramachandran6199b642017-03-20 13:31:36 -07001364
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301365 cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
1366 &operating_channel[cc_count],
1367 &vdev_id[cc_count],
1368 PM_SAP_MODE);
1369 policy_mgr_debug("Number of concurrent SAP: %d", cc_count);
Tushnim Bhattacharyya1acaac72018-10-08 12:47:26 -07001370 if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS)
1371 cc_count = cc_count +
1372 policy_mgr_get_mode_specific_conn_info
1373 (psoc,
1374 &operating_channel[cc_count],
1375 &vdev_id[cc_count],
1376 PM_P2P_GO_MODE);
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301377 policy_mgr_debug("Number of beaconing entities (SAP + GO):%d",
1378 cc_count);
1379 if (!cc_count) {
Ajit Pal Singhc1246b12017-06-16 11:36:12 +05301380 policy_mgr_err("Could not retrieve SAP/GO operating channel&vdevid");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001381 goto end;
Archana Ramachandran6199b642017-03-20 13:31:36 -07001382 }
1383
Bala Venkatesh378064b2018-06-11 15:06:53 +05301384 policy_mgr_debug("wait if channel switch is already in progress");
1385 status = qdf_wait_single_event(
1386 &pm_ctx->channel_switch_complete_evt,
1387 CHANNEL_SWITCH_COMPLETE_TIMEOUT);
1388
1389 if (!QDF_IS_STATUS_SUCCESS(status)) {
1390 policy_mgr_err("wait for event failed, still continue with channel switch");
1391 }
Archana Ramachandran631fd9f2017-03-19 18:51:30 -07001392 if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) {
1393 policy_mgr_err("SAP restart get channel callback in NULL");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001394 goto end;
Archana Ramachandran631fd9f2017-03-19 18:51:30 -07001395 }
Tushnim Bhattacharyya1acaac72018-10-08 12:47:26 -07001396 if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS)
1397 for (i = 0; i < cc_count; i++) {
1398 status = pm_ctx->hdd_cbacks.
1399 wlan_hdd_get_channel_for_sap_restart
1400 (psoc,
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301401 vdev_id[i], &channel, &sec_ch);
Tushnim Bhattacharyya1acaac72018-10-08 12:47:26 -07001402 if (status == QDF_STATUS_SUCCESS) {
1403 policy_mgr_info("SAP restarts due to MCC->SCC switch, old chan :%d new chan: %d"
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301404 , operating_channel[i], channel);
Tushnim Bhattacharyya1acaac72018-10-08 12:47:26 -07001405 break;
1406 }
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301407 }
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301408 if (status != QDF_STATUS_SUCCESS)
1409 policy_mgr_err("Failed to switch SAP channel");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001410end:
1411 if (work_info) {
1412 qdf_mem_free(work_info);
1413 if (pm_ctx)
1414 pm_ctx->sta_ap_intf_check_work_info = NULL;
1415 }
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001416}
1417
Tushnim Bhattacharyya89036a72018-10-01 14:50:15 -07001418void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data)
1419{
1420 qdf_ssr_protect(__func__);
1421 __policy_mgr_check_sta_ap_concurrent_ch_intf(data);
1422 qdf_ssr_unprotect(__func__);
1423}
1424
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -07001425static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc,
1426 uint8_t sta_channel)
1427{
1428 struct policy_mgr_psoc_priv_obj *pm_ctx;
1429
1430 pm_ctx = policy_mgr_get_context(psoc);
1431 if (!pm_ctx) {
1432 policy_mgr_err("Invalid context");
1433 return false;
1434 }
1435
Ganesh Kondabattini8a611c62017-11-21 15:01:31 +05301436 if ((wlan_reg_is_dfs_ch(pm_ctx->pdev, sta_channel) &&
1437 (!policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc))) ||
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -07001438 wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev, sta_channel) ||
Ganesh Kondabattini8a611c62017-11-21 15:01:31 +05301439 !policy_mgr_is_safe_channel(psoc, sta_channel)) {
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -07001440 if (policy_mgr_is_hw_dbs_capable(psoc))
1441 return true;
1442 else
1443 return false;
Ganesh Kondabattini8a611c62017-11-21 15:01:31 +05301444 }
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -07001445 else
1446 return true;
1447}
1448
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001449QDF_STATUS policy_mgr_valid_sap_conc_channel_check(
1450 struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch)
1451{
1452 uint8_t channel = *con_ch;
1453 uint8_t temp_channel = 0;
1454 struct policy_mgr_psoc_priv_obj *pm_ctx;
Bala Venkatesh7c96e542018-06-07 19:32:27 +05301455 bool sta_sap_scc_on_dfs_chan;
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001456
1457 pm_ctx = policy_mgr_get_context(psoc);
1458 if (!pm_ctx) {
1459 policy_mgr_err("Invalid context");
1460 return QDF_STATUS_E_FAILURE;
1461 }
1462
1463 /*
1464 * if force SCC is set, Check if conc channel is DFS
1465 * or passive or part of LTE avoided channel list.
1466 * In that case move SAP to other band if DBS is supported,
1467 * return otherwise
1468 */
1469 if (!policy_mgr_is_force_scc(psoc))
1470 return QDF_STATUS_SUCCESS;
1471
1472 /*
1473 * if interference is 0, check if it is DBS case. If DBS case
1474 * return from here. If SCC, check further if SAP can move to
1475 * STA's channel.
1476 */
1477 if (!channel &&
1478 (sap_ch != policy_mgr_mode_specific_get_channel(
1479 psoc, PM_STA_MODE)))
1480 return QDF_STATUS_SUCCESS;
1481 else if (!channel)
1482 channel = sap_ch;
1483
Bala Venkatesh7c96e542018-06-07 19:32:27 +05301484 sta_sap_scc_on_dfs_chan =
1485 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
1486
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001487 if (policy_mgr_valid_sta_channel_check(psoc, channel)) {
1488 if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) ||
Abhinav Kumar93b3c7f2018-08-23 21:46:44 +05301489 wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev, channel) ||
Zhu Jianmin5ac66ef2018-06-11 19:03:39 +08001490 !(policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) ||
Abhinav Kumar93b3c7f2018-08-23 21:46:44 +05301491 policy_mgr_is_safe_channel(psoc, channel)) ||
Ashish Kumar Dhanotiyaaa9fdbb2018-12-14 15:29:14 +05301492 (!wlan_reg_is_etsi13_srd_chan_allowed_master_mode(
1493 pm_ctx->pdev) &&
1494 wlan_reg_is_etsi13_srd_chan(pm_ctx->pdev, channel))) {
Liangwei Dongbd8b24b2018-09-05 23:13:52 -04001495 if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) &&
1496 sta_sap_scc_on_dfs_chan) {
1497 policy_mgr_debug("STA SAP SCC is allowed on DFS channel");
1498 goto update_chan;
1499 }
1500
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001501 if (policy_mgr_is_hw_dbs_capable(psoc)) {
1502 temp_channel =
1503 policy_mgr_get_alternate_channel_for_sap(psoc);
1504 policy_mgr_debug("temp_channel is %d",
1505 temp_channel);
1506 if (temp_channel) {
1507 channel = temp_channel;
1508 } else {
1509 if (WLAN_REG_IS_5GHZ_CH(channel))
1510 channel = PM_24_GHZ_CHANNEL_6;
1511 else
1512 channel = PM_5_GHZ_CHANNEL_36;
1513 }
1514 if (!policy_mgr_is_safe_channel(
1515 psoc, channel)) {
1516 policy_mgr_warn(
1517 "Can't have concurrency on %d as it is not safe",
1518 channel);
1519 return QDF_STATUS_E_FAILURE;
1520 }
1521 } else {
1522 policy_mgr_warn("Can't have concurrency on %d",
1523 channel);
1524 return QDF_STATUS_E_FAILURE;
1525 }
1526 }
1527 }
1528
Bala Venkatesh7c96e542018-06-07 19:32:27 +05301529update_chan:
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001530 if (channel != sap_ch)
1531 *con_ch = channel;
1532
1533 return QDF_STATUS_SUCCESS;
1534}
1535
Archana Ramachandran107d3782017-03-06 17:07:44 -08001536/**
1537 * policy_mgr_check_concurrent_intf_and_restart_sap() - Check
1538 * concurrent change intf
1539 * @psoc: PSOC object information
1540 * @operation_channel: operation channel
Archana Ramachandran544ce172017-03-14 15:12:09 -07001541 * @vdev_id: vdev id of SAP
Archana Ramachandran107d3782017-03-06 17:07:44 -08001542 *
1543 * Checks the concurrent change interface and restarts SAP
1544 *
1545 * Return: None
1546 */
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001547void policy_mgr_check_concurrent_intf_and_restart_sap(
Archana Ramachandran6199b642017-03-20 13:31:36 -07001548 struct wlan_objmgr_psoc *psoc)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001549{
Archana Ramachandran266613f2017-03-13 16:36:55 -07001550 struct policy_mgr_psoc_priv_obj *pm_ctx;
1551 uint32_t mcc_to_scc_switch;
Tushnim Bhattacharyyaf8417d12018-05-08 15:31:21 -07001552 uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
1553 uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
1554 uint32_t cc_count = 0;
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301555 bool restart_sap = false;
1556 uint8_t sap_ch;
Archana Ramachandran266613f2017-03-13 16:36:55 -07001557
1558 pm_ctx = policy_mgr_get_context(psoc);
1559 if (!pm_ctx) {
1560 policy_mgr_err("Invalid context");
1561 return;
1562 }
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301563 if (policy_mgr_get_connection_count(psoc) == 1) {
1564 /*
1565 * If STA+SAP sessions are on DFS channel and STA+SAP SCC is
1566 * enabled on DFS channel then move the SAP out of DFS channel
1567 * as soon as STA gets disconnect.
Jianmin Zhu7f6bdd32018-06-29 10:39:30 +08001568 * If STA+SAP sessions are on unsafe channel and STA+SAP SCC is
1569 * enabled on unsafe channel then move the SAP to safe channel
1570 * as soon as STA disconnected.
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301571 */
1572 if (policy_mgr_is_sap_restart_required_after_sta_disconnect(
1573 psoc, &sap_ch)) {
1574 policy_mgr_debug("move the SAP to configured channel %u",
1575 sap_ch);
1576 restart_sap = true;
1577 goto sap_restart;
1578 }
1579 }
Archana Ramachandran266613f2017-03-13 16:36:55 -07001580
Tushnim Bhattacharyyaf8417d12018-05-08 15:31:21 -07001581 /*
1582 * force SCC with STA+STA+SAP will need some additional logic
1583 */
1584 cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
1585 &operating_channel[cc_count],
1586 &vdev_id[cc_count], PM_STA_MODE);
1587 if (!cc_count) {
Yeshwanth Sriram Guntukad540cd02018-08-23 18:25:28 +05301588 policy_mgr_debug("Could not get STA operating channel&vdevid");
Archana Ramachandran6199b642017-03-20 13:31:36 -07001589 return;
1590 }
1591
Archana Ramachandran266613f2017-03-13 16:36:55 -07001592 mcc_to_scc_switch =
Krunal Sonid36b2072018-09-26 17:02:14 -07001593 policy_mgr_get_mcc_to_scc_switch_mode(psoc);
Archana Ramachandran266613f2017-03-13 16:36:55 -07001594 policy_mgr_info("MCC to SCC switch: %d chan: %d",
Tushnim Bhattacharyyaf8417d12018-05-08 15:31:21 -07001595 mcc_to_scc_switch, operating_channel[0]);
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001596
1597 if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch)) {
1598 policy_mgr_debug(
1599 "No action taken at check_concurrent_intf_and_restart_sap");
1600 return;
1601 }
1602
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301603sap_restart:
1604 /*
1605 * If sta_sap_scc_on_dfs_chan is true then standalone SAP is not
1606 * allowed on DFS channel. SAP is allowed on DFS channel only when STA
1607 * is already connected on that channel.
1608 * In following condition restart_sap will be true if
1609 * sta_sap_scc_on_dfs_chan is true and SAP is on DFS channel.
1610 * This scenario can come if STA+SAP are operating on DFS channel and
1611 * STA gets disconnected.
1612 */
1613 if (restart_sap ||
1614 ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) &&
1615 policy_mgr_valid_sta_channel_check(psoc, operating_channel[0]) &&
1616 !pm_ctx->sta_ap_intf_check_work_info)) {
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001617 struct sta_ap_intf_check_work_ctx *work_info;
1618 work_info = qdf_mem_malloc(
1619 sizeof(struct sta_ap_intf_check_work_ctx));
1620 pm_ctx->sta_ap_intf_check_work_info = work_info;
1621 if (work_info) {
1622 work_info->psoc = psoc;
1623 qdf_create_work(0, &pm_ctx->sta_ap_intf_check_work,
Archana Ramachandran6199b642017-03-20 13:31:36 -07001624 policy_mgr_check_sta_ap_concurrent_ch_intf,
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001625 work_info);
1626 qdf_sched_work(0, &pm_ctx->sta_ap_intf_check_work);
1627 policy_mgr_info(
1628 "Checking for Concurrent Change interference");
1629 }
Archana Ramachandran266613f2017-03-13 16:36:55 -07001630 }
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001631}
1632#endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */
1633
1634#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Archana Ramachandran0edce252017-03-06 14:36:29 -08001635/**
1636 * policy_mgr_change_sap_channel_with_csa() - Move SAP channel using (E)CSA
1637 * @psoc: PSOC object information
1638 * @vdev_id: Vdev id
1639 * @channel: Channel to change
1640 * @ch_width: channel width to change
Min Liuc5b10432018-01-19 18:01:44 +08001641 * @forced: Force to switch channel, ignore SCC/MCC check
Archana Ramachandran0edce252017-03-06 14:36:29 -08001642 *
1643 * Invoke the callback function to change SAP channel using (E)CSA
1644 *
1645 * Return: None
1646 */
1647void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc,
1648 uint8_t vdev_id, uint32_t channel,
Min Liuc5b10432018-01-19 18:01:44 +08001649 uint32_t ch_width,
1650 bool forced)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001651{
Archana Ramachandran0edce252017-03-06 14:36:29 -08001652 struct policy_mgr_psoc_priv_obj *pm_ctx;
1653
1654 pm_ctx = policy_mgr_get_context(psoc);
1655 if (!pm_ctx) {
1656 policy_mgr_err("Invalid context");
1657 return;
1658 }
1659
Archana Ramachandran544ce172017-03-14 15:12:09 -07001660 if (pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb) {
Archana Ramachandran0edce252017-03-06 14:36:29 -08001661 policy_mgr_info("SAP change change without restart");
Archana Ramachandran631fd9f2017-03-19 18:51:30 -07001662 pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb(psoc,
Min Liuc5b10432018-01-19 18:01:44 +08001663 vdev_id, channel, ch_width, forced);
Archana Ramachandran0edce252017-03-06 14:36:29 -08001664 }
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001665}
1666#endif
1667
1668QDF_STATUS policy_mgr_wait_for_connection_update(struct wlan_objmgr_psoc *psoc)
1669{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001670 QDF_STATUS status;
1671 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1672
1673 policy_mgr_context = policy_mgr_get_context(psoc);
1674 if (!policy_mgr_context) {
1675 policy_mgr_err("Invalid context");
1676 return QDF_STATUS_E_FAILURE;
1677 }
1678
1679 status = qdf_wait_single_event(
1680 &policy_mgr_context->connection_update_done_evt,
1681 CONNECTION_UPDATE_TIMEOUT);
1682
1683 if (!QDF_IS_STATUS_SUCCESS(status)) {
1684 policy_mgr_err("wait for event failed");
1685 return QDF_STATUS_E_FAILURE;
1686 }
1687
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001688 return QDF_STATUS_SUCCESS;
1689}
1690
1691QDF_STATUS policy_mgr_reset_connection_update(struct wlan_objmgr_psoc *psoc)
1692{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001693 QDF_STATUS status;
1694 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1695
1696 policy_mgr_context = policy_mgr_get_context(psoc);
1697 if (!policy_mgr_context) {
1698 policy_mgr_err("Invalid context");
1699 return QDF_STATUS_E_FAILURE;
1700 }
1701
1702 status = qdf_event_reset(
1703 &policy_mgr_context->connection_update_done_evt);
1704
1705 if (!QDF_IS_STATUS_SUCCESS(status)) {
1706 policy_mgr_err("clear event failed");
1707 return QDF_STATUS_E_FAILURE;
1708 }
1709
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001710 return QDF_STATUS_SUCCESS;
1711}
1712
1713QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc)
1714{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001715 QDF_STATUS status;
1716 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1717
1718 policy_mgr_context = policy_mgr_get_context(psoc);
1719 if (!policy_mgr_context) {
1720 policy_mgr_err("Invalid context");
1721 return QDF_STATUS_E_FAILURE;
1722 }
1723
1724 status = qdf_event_set(&policy_mgr_context->connection_update_done_evt);
1725
1726 if (!QDF_IS_STATUS_SUCCESS(status)) {
1727 policy_mgr_err("set event failed");
1728 return QDF_STATUS_E_FAILURE;
1729 }
1730
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001731 return QDF_STATUS_SUCCESS;
1732}
1733
Bala Venkatesh378064b2018-06-11 15:06:53 +05301734QDF_STATUS policy_mgr_set_chan_switch_complete_evt(
1735 struct wlan_objmgr_psoc *psoc)
1736{
1737 QDF_STATUS status;
1738 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1739
1740 policy_mgr_context = policy_mgr_get_context(psoc);
1741
1742 if (!policy_mgr_context) {
1743 policy_mgr_err("Invalid context");
1744 return QDF_STATUS_E_FAILURE;
1745 }
1746 status = qdf_event_set(
1747 &policy_mgr_context->channel_switch_complete_evt);
1748
1749 if (!QDF_IS_STATUS_SUCCESS(status)) {
1750 policy_mgr_err("set event failed");
1751 return QDF_STATUS_E_FAILURE;
1752 }
1753
1754 return QDF_STATUS_SUCCESS;
1755}
1756
1757QDF_STATUS policy_mgr_reset_chan_switch_complete_evt(
1758 struct wlan_objmgr_psoc *psoc)
1759{
1760 QDF_STATUS status;
1761 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1762
1763 policy_mgr_context = policy_mgr_get_context(psoc);
1764
1765 if (!policy_mgr_context) {
1766 policy_mgr_err("Invalid context");
1767 return QDF_STATUS_E_FAILURE;
1768 }
1769 status = qdf_event_reset(
1770 &policy_mgr_context->channel_switch_complete_evt);
1771
1772 if (!QDF_IS_STATUS_SUCCESS(status)) {
1773 policy_mgr_err("reset event failed");
1774 return QDF_STATUS_E_FAILURE;
1775 }
1776
1777 return QDF_STATUS_SUCCESS;
1778}
1779
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001780QDF_STATUS policy_mgr_set_opportunistic_update(struct wlan_objmgr_psoc *psoc)
1781{
1782 QDF_STATUS status;
1783 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1784
1785 policy_mgr_context = policy_mgr_get_context(psoc);
1786 if (!policy_mgr_context) {
1787 policy_mgr_err("Invalid context");
1788 return QDF_STATUS_E_FAILURE;
1789 }
1790
1791 status = qdf_event_set(
1792 &policy_mgr_context->opportunistic_update_done_evt);
1793
1794 if (!QDF_IS_STATUS_SUCCESS(status)) {
1795 policy_mgr_err("set event failed");
1796 return QDF_STATUS_E_FAILURE;
1797 }
1798
1799 return QDF_STATUS_SUCCESS;
1800}
1801
Himanshu Agarwal70a52d92018-05-04 14:37:48 +05301802QDF_STATUS policy_mgr_stop_opportunistic_timer(struct wlan_objmgr_psoc *psoc)
1803{
1804 struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
1805
1806 policy_mgr_ctx = policy_mgr_get_context(psoc);
1807 if (!policy_mgr_ctx) {
1808 policy_mgr_err("Invalid context");
1809 return QDF_STATUS_E_FAILURE;
1810 }
1811
1812 if (policy_mgr_ctx->dbs_opportunistic_timer.state !=
1813 QDF_TIMER_STATE_RUNNING)
1814 return QDF_STATUS_SUCCESS;
1815
1816 qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer);
1817 return QDF_STATUS_SUCCESS;
1818}
1819
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001820QDF_STATUS policy_mgr_restart_opportunistic_timer(
1821 struct wlan_objmgr_psoc *psoc, bool check_state)
1822{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001823 QDF_STATUS status = QDF_STATUS_E_FAILURE;
1824 struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
1825
1826 policy_mgr_ctx = policy_mgr_get_context(psoc);
1827 if (!policy_mgr_ctx) {
1828 policy_mgr_err("Invalid context");
1829 return status;
1830 }
1831
1832 if (check_state &&
1833 QDF_TIMER_STATE_RUNNING !=
1834 policy_mgr_ctx->dbs_opportunistic_timer.state)
1835 return status;
1836
1837 qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer);
1838
1839 status = qdf_mc_timer_start(
1840 &policy_mgr_ctx->dbs_opportunistic_timer,
1841 DBS_OPPORTUNISTIC_TIME * 1000);
1842
1843 if (!QDF_IS_STATUS_SUCCESS(status)) {
1844 policy_mgr_err("failed to start opportunistic timer");
1845 return status;
1846 }
1847
1848 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001849}
1850
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001851QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch(
1852 struct wlan_objmgr_psoc *psoc, uint8_t session_id)
1853{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001854 QDF_STATUS status = QDF_STATUS_E_FAILURE, qdf_status;
1855 enum policy_mgr_conc_next_action action;
1856
1857 if (!policy_mgr_is_hw_dbs_capable(psoc)) {
1858 policy_mgr_err("PM/DBS is disabled");
1859 return status;
1860 }
1861
1862 action = (*policy_mgr_get_current_pref_hw_mode_ptr)(psoc);
1863 if ((action != PM_DBS_DOWNGRADE) &&
Liangwei Donge85dfe62018-05-25 06:31:57 -04001864 (action != PM_SINGLE_MAC_UPGRADE) &&
1865 (action != PM_DBS1_DOWNGRADE) &&
1866 (action != PM_DBS2_DOWNGRADE)) {
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001867 policy_mgr_err("Invalid action: %d", action);
1868 status = QDF_STATUS_SUCCESS;
1869 goto done;
1870 }
1871
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001872 policy_mgr_debug("action:%d session id:%d", action, session_id);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001873
1874 /* Opportunistic timer is started, PM will check if MCC upgrade can be
1875 * done on timer expiry. This avoids any possible ping pong effect
1876 * as well.
1877 */
1878 if (action == PM_SINGLE_MAC_UPGRADE) {
1879 qdf_status = policy_mgr_restart_opportunistic_timer(
1880 psoc, false);
1881 if (QDF_IS_STATUS_SUCCESS(qdf_status))
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001882 policy_mgr_debug("opportunistic timer for MCC upgrade");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001883 goto done;
1884 }
1885
1886 /* For DBS, we want to move right away to DBS mode */
1887 status = policy_mgr_next_actions(psoc, session_id, action,
1888 POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH);
1889 if (!QDF_IS_STATUS_SUCCESS(status)) {
1890 policy_mgr_err("no set hw mode command was issued");
1891 goto done;
1892 }
1893done:
1894 /* success must be returned only when a set hw mode was done */
1895 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001896}
1897
1898void policy_mgr_checkn_update_hw_mode_single_mac_mode(
1899 struct wlan_objmgr_psoc *psoc, uint8_t channel)
1900{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001901 uint8_t i;
1902 struct policy_mgr_psoc_priv_obj *pm_ctx;
1903
1904 pm_ctx = policy_mgr_get_context(psoc);
1905 if (!pm_ctx) {
1906 policy_mgr_err("Invalid Context");
1907 return;
1908 }
1909
gaurank kathpaliaafa4e1b2018-07-05 15:04:46 +05301910 if (QDF_TIMER_STATE_RUNNING ==
1911 pm_ctx->dbs_opportunistic_timer.state)
1912 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
1913
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001914 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1915 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
Tushnim Bhattacharyyac304f892018-08-01 19:15:55 -07001916 if (pm_conc_connection_list[i].in_use) {
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001917 if (!WLAN_REG_IS_SAME_BAND_CHANNELS(channel,
1918 pm_conc_connection_list[i].chan)) {
1919 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001920 policy_mgr_debug("DBS required");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001921 return;
1922 }
Tushnim Bhattacharyyac304f892018-08-01 19:15:55 -07001923 if (policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
1924 (WLAN_REG_IS_24GHZ_CH(channel) ||
1925 WLAN_REG_IS_24GHZ_CH
1926 (pm_conc_connection_list[i].chan))) {
1927 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1928 policy_mgr_debug("DBS required");
1929 return;
1930 }
1931 }
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001932 }
1933 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001934 pm_dbs_opportunistic_timer_handler((void *)psoc);
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001935}
1936
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001937void policy_mgr_check_and_stop_opportunistic_timer(
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001938 struct wlan_objmgr_psoc *psoc, uint8_t id)
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001939{
1940 struct policy_mgr_psoc_priv_obj *pm_ctx;
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001941 enum policy_mgr_conc_next_action action = PM_NOP;
1942 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Liangwei Dong88ddf822018-05-25 05:55:37 -04001943 enum policy_mgr_conn_update_reason reason;
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001944
1945 pm_ctx = policy_mgr_get_context(psoc);
1946 if (!pm_ctx) {
1947 policy_mgr_err("Invalid Context");
1948 return;
1949 }
1950 if (QDF_TIMER_STATE_RUNNING ==
1951 pm_ctx->dbs_opportunistic_timer.state) {
1952 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
Liangwei Dong88ddf822018-05-25 05:55:37 -04001953 action = policy_mgr_need_opportunistic_upgrade(psoc, &reason);
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001954 if (action) {
Krunal Soni4943b902018-01-05 17:36:40 -08001955 qdf_event_reset(&pm_ctx->opportunistic_update_done_evt);
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001956 status = policy_mgr_next_actions(psoc, id, action,
Liangwei Dong88ddf822018-05-25 05:55:37 -04001957 reason);
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001958 if (status != QDF_STATUS_SUCCESS) {
1959 policy_mgr_err("Failed in policy_mgr_next_actions");
1960 return;
1961 }
1962 status = qdf_wait_single_event(
1963 &pm_ctx->opportunistic_update_done_evt,
1964 CONNECTION_UPDATE_TIMEOUT);
1965
1966 if (!QDF_IS_STATUS_SUCCESS(status)) {
1967 policy_mgr_err("wait for event failed");
1968 return;
1969 }
1970 }
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001971 }
1972}
1973
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07001974void policy_mgr_set_hw_mode_change_in_progress(
1975 struct wlan_objmgr_psoc *psoc, enum policy_mgr_hw_mode_change value)
1976{
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001977 struct policy_mgr_psoc_priv_obj *pm_ctx;
1978
1979 pm_ctx = policy_mgr_get_context(psoc);
1980 if (!pm_ctx) {
1981 policy_mgr_err("Invalid Context");
1982 return;
1983 }
1984
1985 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1986 pm_ctx->hw_mode_change_in_progress = value;
1987 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1988
1989 policy_mgr_debug("hw_mode_change_in_progress:%d", value);
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07001990}
1991
1992enum policy_mgr_hw_mode_change policy_mgr_is_hw_mode_change_in_progress(
1993 struct wlan_objmgr_psoc *psoc)
1994{
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001995 enum policy_mgr_hw_mode_change value;
1996 struct policy_mgr_psoc_priv_obj *pm_ctx;
1997
1998 value = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
1999
2000 pm_ctx = policy_mgr_get_context(psoc);
2001 if (!pm_ctx) {
2002 policy_mgr_err("Invalid Context");
2003 return value;
2004 }
2005 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2006 value = pm_ctx->hw_mode_change_in_progress;
2007 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2008
2009 return value;
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07002010}
2011
2012enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index(
2013 struct wlan_objmgr_psoc *psoc, uint32_t hw_mode_index)
2014{
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07002015 struct policy_mgr_psoc_priv_obj *pm_ctx;
Liangwei Dong9ace8a92018-05-21 05:39:04 -04002016 struct policy_mgr_hw_mode_params hw_mode;
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07002017 enum policy_mgr_hw_mode_change value
2018 = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
Liangwei Dong9ace8a92018-05-21 05:39:04 -04002019 QDF_STATUS status;
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07002020
2021 pm_ctx = policy_mgr_get_context(psoc);
2022 if (!pm_ctx) {
2023 policy_mgr_err("Invalid Context");
2024 return value;
2025 }
2026
Liangwei Dong9ace8a92018-05-21 05:39:04 -04002027 status = policy_mgr_get_hw_mode_from_idx(psoc, hw_mode_index, &hw_mode);
2028 if (status != QDF_STATUS_SUCCESS) {
2029 policy_mgr_err("Failed to get HW mode index");
2030 return value;
2031 }
2032
2033 if (hw_mode.dbs_cap) {
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07002034 policy_mgr_info("DBS is requested with HW (%d)",
2035 hw_mode_index);
2036 value = POLICY_MGR_DBS_IN_PROGRESS;
2037 goto ret_value;
2038 }
2039
Liangwei Dong9ace8a92018-05-21 05:39:04 -04002040 if (hw_mode.sbs_cap) {
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07002041 policy_mgr_info("SBS is requested with HW (%d)",
2042 hw_mode_index);
2043 value = POLICY_MGR_SBS_IN_PROGRESS;
2044 goto ret_value;
2045 }
2046
2047 value = POLICY_MGR_SMM_IN_PROGRESS;
2048 policy_mgr_info("SMM is requested with HW (%d)", hw_mode_index);
2049
2050ret_value:
2051 return value;
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07002052}
2053
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002054#ifdef MPC_UT_FRAMEWORK
2055QDF_STATUS policy_mgr_update_connection_info_utfw(
2056 struct wlan_objmgr_psoc *psoc,
2057 uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
2058 uint32_t chain_mask, uint32_t type, uint32_t sub_type,
2059 uint32_t channelid, uint32_t mac_id)
2060{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002061 QDF_STATUS status = QDF_STATUS_E_FAILURE;
2062 uint32_t conn_index = 0, found = 0;
2063 struct policy_mgr_psoc_priv_obj *pm_ctx;
2064
2065 pm_ctx = policy_mgr_get_context(psoc);
2066 if (!pm_ctx) {
2067 policy_mgr_err("Invalid Context");
2068 return status;
2069 }
2070
2071 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2072 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2073 if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
2074 /* debug msg */
2075 found = 1;
2076 break;
2077 }
2078 conn_index++;
2079 }
2080 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2081 if (!found) {
2082 /* err msg */
2083 policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list",
2084 vdev_id);
2085 return status;
2086 }
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07002087 policy_mgr_debug("--> updating entry at index[%d]", conn_index);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002088
2089 policy_mgr_update_conc_list(psoc, conn_index,
2090 policy_mgr_get_mode(type, sub_type),
2091 channelid, HW_MODE_20_MHZ,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05302092 mac_id, chain_mask, 0, vdev_id, true, true);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002093
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002094 return QDF_STATUS_SUCCESS;
2095}
2096
2097QDF_STATUS policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc,
2098 uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
2099 uint32_t chain_mask, uint32_t type, uint32_t sub_type,
2100 uint32_t channelid, uint32_t mac_id)
2101{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002102 QDF_STATUS status = QDF_STATUS_E_FAILURE;
2103 uint32_t conn_index = 0;
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05302104 bool update_conn = true;
2105 enum policy_mgr_con_mode mode;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002106
2107 conn_index = policy_mgr_get_connection_count(psoc);
2108 if (MAX_NUMBER_OF_CONC_CONNECTIONS <= conn_index) {
2109 /* err msg */
2110 policy_mgr_err("exceeded max connection limit %d",
2111 MAX_NUMBER_OF_CONC_CONNECTIONS);
2112 return status;
2113 }
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07002114 policy_mgr_debug("--> filling entry at index[%d]", conn_index);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002115
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05302116 mode = policy_mgr_get_mode(type, sub_type);
2117 if (mode == PM_STA_MODE || mode == PM_P2P_CLIENT_MODE)
2118 update_conn = false;
2119
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002120 policy_mgr_update_conc_list(psoc, conn_index,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05302121 mode,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002122 channelid, HW_MODE_20_MHZ,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05302123 mac_id, chain_mask, 0, vdev_id, true,
2124 update_conn);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002125
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002126 return QDF_STATUS_SUCCESS;
2127}
2128
2129QDF_STATUS policy_mgr_decr_connection_count_utfw(struct wlan_objmgr_psoc *psoc,
2130 uint32_t del_all, uint32_t vdev_id)
2131{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002132 QDF_STATUS status;
2133
2134 if (del_all) {
Krunal Sonic54f1a62018-09-05 10:58:05 -07002135 status = policy_mgr_psoc_disable(psoc);
2136 if (!QDF_IS_STATUS_SUCCESS(status)) {
2137 policy_mgr_err("Policy manager initialization failed");
2138 return QDF_STATUS_E_FAILURE;
2139 }
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002140 status = policy_mgr_psoc_enable(psoc);
2141 if (!QDF_IS_STATUS_SUCCESS(status)) {
2142 policy_mgr_err("Policy manager initialization failed");
2143 return QDF_STATUS_E_FAILURE;
2144 }
2145 } else {
2146 policy_mgr_decr_connection_count(psoc, vdev_id);
2147 }
2148
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002149 return QDF_STATUS_SUCCESS;
2150}
2151
2152enum policy_mgr_pcl_type policy_mgr_get_pcl_from_first_conn_table(
2153 enum policy_mgr_con_mode type,
2154 enum policy_mgr_conc_priority_mode sys_pref)
2155{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002156 if ((sys_pref >= PM_MAX_CONC_PRIORITY_MODE) ||
2157 (type >= PM_MAX_NUM_OF_MODE))
2158 return PM_MAX_PCL_TYPE;
2159 return first_connection_pcl_table[type][sys_pref];
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002160}
2161
2162enum policy_mgr_pcl_type policy_mgr_get_pcl_from_second_conn_table(
2163 enum policy_mgr_one_connection_mode idx, enum policy_mgr_con_mode type,
2164 enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable)
2165{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002166 if ((idx >= PM_MAX_ONE_CONNECTION_MODE) ||
2167 (sys_pref >= PM_MAX_CONC_PRIORITY_MODE) ||
2168 (type >= PM_MAX_NUM_OF_MODE))
2169 return PM_MAX_PCL_TYPE;
2170 if (dbs_capable)
2171 return (*second_connection_pcl_dbs_table)[idx][type][sys_pref];
2172 else
2173 return second_connection_pcl_nodbs_table[idx][type][sys_pref];
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002174}
2175
2176enum policy_mgr_pcl_type policy_mgr_get_pcl_from_third_conn_table(
2177 enum policy_mgr_two_connection_mode idx, enum policy_mgr_con_mode type,
2178 enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable)
2179{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002180 if ((idx >= PM_MAX_TWO_CONNECTION_MODE) ||
2181 (sys_pref >= PM_MAX_CONC_PRIORITY_MODE) ||
2182 (type >= PM_MAX_NUM_OF_MODE))
2183 return PM_MAX_PCL_TYPE;
2184 if (dbs_capable)
2185 return (*third_connection_pcl_dbs_table)[idx][type][sys_pref];
2186 else
2187 return third_connection_pcl_nodbs_table[idx][type][sys_pref];
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002188}
2189#endif