blob: 603382bfd95cc50e6e09bbfc967a2132710c8cb4 [file] [log] [blame]
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001/*
Varun Reddy Yeturue23b6bc2018-01-08 13:18:41 -08002 * Copyright (c) 2012-2018 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"
34
35enum policy_mgr_conc_next_action (*policy_mgr_get_current_pref_hw_mode_ptr)
36 (struct wlan_objmgr_psoc *psoc);
37
38void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index,
39 uint32_t new_hw_mode_index,
40 uint32_t num_vdev_mac_entries,
41 struct policy_mgr_vdev_mac_map *vdev_mac_map,
42 struct wlan_objmgr_psoc *context)
43{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -080044 QDF_STATUS status;
45 struct policy_mgr_hw_mode_params hw_mode;
46 uint32_t i;
Yeshwanth Sriram Guntuka6a3be162018-02-23 12:14:46 +053047 struct policy_mgr_psoc_priv_obj *pm_ctx;
48
49 pm_ctx = policy_mgr_get_context(context);
50 if (!pm_ctx) {
51 policy_mgr_err("Invalid context");
52 return;
53 }
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -080054
55 if (!vdev_mac_map) {
56 policy_mgr_err("vdev_mac_map is NULL");
57 return;
58 }
59
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -070060 policy_mgr_debug("old_hw_mode_index=%d, new_hw_mode_index=%d",
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -080061 old_hw_mode_index, new_hw_mode_index);
62
63 for (i = 0; i < num_vdev_mac_entries; i++)
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -070064 policy_mgr_debug("vdev_id:%d mac_id:%d",
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -080065 vdev_mac_map[i].vdev_id,
66 vdev_mac_map[i].mac_id);
67
68 status = policy_mgr_get_hw_mode_from_idx(context,
69 new_hw_mode_index, &hw_mode);
70 if (status != QDF_STATUS_SUCCESS) {
71 policy_mgr_err("Get HW mode failed: %d", status);
72 return;
73 }
74
Liangwei Donge57b6b72018-05-21 04:51:47 -040075 policy_mgr_debug("MAC0: TxSS:%d, RxSS:%d, Bw:%d band_cap:%d",
76 hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss,
77 hw_mode.mac0_bw, hw_mode.mac0_band_cap);
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -070078 policy_mgr_debug("MAC1: TxSS:%d, RxSS:%d, Bw:%d",
Liangwei Donge57b6b72018-05-21 04:51:47 -040079 hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss,
80 hw_mode.mac1_bw);
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -070081 policy_mgr_debug("DBS:%d, Agile DFS:%d, SBS:%d",
Liangwei Donge57b6b72018-05-21 04:51:47 -040082 hw_mode.dbs_cap, hw_mode.agile_dfs_cap,
83 hw_mode.sbs_cap);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -080084
85 /* update pm_conc_connection_list */
86 policy_mgr_update_hw_mode_conn_info(context, num_vdev_mac_entries,
87 vdev_mac_map,
88 hw_mode);
89
Yeshwanth Sriram Guntuka6a3be162018-02-23 12:14:46 +053090 if (pm_ctx->mode_change_cb)
91 pm_ctx->mode_change_cb();
92
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -080093 return;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -080094}
95
96QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc,
97 uint32_t session_id,
98 enum hw_mode_ss_config mac0_ss,
99 enum hw_mode_bandwidth mac0_bw,
100 enum hw_mode_ss_config mac1_ss,
101 enum hw_mode_bandwidth mac1_bw,
Liangwei Dong9ace8a92018-05-21 05:39:04 -0400102 enum hw_mode_mac_band_cap mac0_band_cap,
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800103 enum hw_mode_dbs_capab dbs,
104 enum hw_mode_agile_dfs_capab dfs,
105 enum hw_mode_sbs_capab sbs,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800106 enum policy_mgr_conn_update_reason reason,
107 uint8_t next_action)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800108{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800109 int8_t hw_mode_index;
110 struct policy_mgr_hw_mode msg;
111 QDF_STATUS status;
112 struct policy_mgr_psoc_priv_obj *pm_ctx;
113
114 pm_ctx = policy_mgr_get_context(psoc);
115 if (!pm_ctx) {
116 policy_mgr_err("Invalid context");
117 return QDF_STATUS_E_FAILURE;
118 }
119
120 /*
121 * if HW is not capable of doing 2x2 or ini config disabled 2x2, don't
122 * allow to request FW for 2x2
123 */
Tushnim Bhattacharyya68f709d2017-03-23 18:00:04 -0700124 if ((HW_MODE_SS_2x2 == mac0_ss) && (!pm_ctx->user_cfg.enable2x2)) {
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -0700125 policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac0");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800126 mac0_ss = HW_MODE_SS_1x1;
127 }
Tushnim Bhattacharyya68f709d2017-03-23 18:00:04 -0700128 if ((HW_MODE_SS_2x2 == mac1_ss) && (!pm_ctx->user_cfg.enable2x2)) {
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -0700129 policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac1");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800130 mac1_ss = HW_MODE_SS_1x1;
131 }
132
133 hw_mode_index = policy_mgr_get_hw_mode_idx_from_dbs_hw_list(psoc,
Liangwei Dong9ace8a92018-05-21 05:39:04 -0400134 mac0_ss, mac0_bw, mac1_ss, mac1_bw, mac0_band_cap,
135 dbs, dfs, sbs);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800136 if (hw_mode_index < 0) {
137 policy_mgr_err("Invalid HW mode index obtained");
138 return QDF_STATUS_E_FAILURE;
139 }
140
141 msg.hw_mode_index = hw_mode_index;
142 msg.set_hw_mode_cb = (void *)policy_mgr_pdev_set_hw_mode_cb;
143 msg.reason = reason;
144 msg.session_id = session_id;
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800145 msg.next_action = next_action;
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -0700146 msg.context = psoc;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800147
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -0700148 policy_mgr_debug("set hw mode to sme: hw_mode_index: %d session:%d reason:%d",
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800149 msg.hw_mode_index, msg.session_id, msg.reason);
150
151 status = pm_ctx->sme_cbacks.sme_pdev_set_hw_mode(msg);
152 if (status != QDF_STATUS_SUCCESS) {
153 policy_mgr_err("Failed to set hw mode to SME");
154 return status;
155 }
156
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800157 return QDF_STATUS_SUCCESS;
158}
159
160enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade(
161 struct wlan_objmgr_psoc *psoc)
162{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800163 uint32_t conn_index;
164 enum policy_mgr_conc_next_action upgrade = PM_NOP;
165 uint8_t mac = 0;
166 struct policy_mgr_hw_mode_params hw_mode;
167 QDF_STATUS status = QDF_STATUS_E_FAILURE;
168 struct policy_mgr_psoc_priv_obj *pm_ctx;
169
170 pm_ctx = policy_mgr_get_context(psoc);
171 if (!pm_ctx) {
172 policy_mgr_err("Invalid Context");
173 goto done;
174 }
175
176 if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
177 policy_mgr_err("driver isn't dbs capable, no further action needed");
178 goto done;
179 }
180
181 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
182 if (!QDF_IS_STATUS_SUCCESS(status)) {
183 policy_mgr_err("policy_mgr_get_current_hw_mode failed");
184 goto done;
185 }
186 if (!hw_mode.dbs_cap) {
187 policy_mgr_notice("current HW mode is non-DBS capable");
188 goto done;
189 }
190
191 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
192 /* Are both mac's still in use */
193 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
194 conn_index++) {
195 policy_mgr_debug("index:%d mac:%d in_use:%d chan:%d org_nss:%d",
196 conn_index,
197 pm_conc_connection_list[conn_index].mac,
198 pm_conc_connection_list[conn_index].in_use,
199 pm_conc_connection_list[conn_index].chan,
200 pm_conc_connection_list[conn_index].original_nss);
201 if ((pm_conc_connection_list[conn_index].mac == 0) &&
202 pm_conc_connection_list[conn_index].in_use) {
203 mac |= POLICY_MGR_MAC0;
204 if (POLICY_MGR_MAC0_AND_MAC1 == mac) {
205 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
206 goto done;
207 }
208 } else if ((pm_conc_connection_list[conn_index].mac == 1) &&
209 pm_conc_connection_list[conn_index].in_use) {
210 mac |= POLICY_MGR_MAC1;
Archana Ramachandran944f1fd2017-06-02 16:48:17 -0700211 if (policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
212 WLAN_REG_IS_24GHZ_CH(
213 pm_conc_connection_list[conn_index].chan)
214 ) {
215 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
216 policy_mgr_debug("2X2 DBS capable with 2.4 GHZ connection");
217 goto done;
218 }
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800219 if (POLICY_MGR_MAC0_AND_MAC1 == mac) {
220 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
221 goto done;
222 }
223 }
224 }
225 /* Let's request for single MAC mode */
226 upgrade = PM_SINGLE_MAC;
227 /* Is there any connection had an initial connection with 2x2 */
228 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
229 conn_index++) {
230 if ((pm_conc_connection_list[conn_index].original_nss == 2) &&
231 pm_conc_connection_list[conn_index].in_use) {
232 upgrade = PM_SINGLE_MAC_UPGRADE;
233 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
234 goto done;
235 }
236 }
237 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
238
239done:
240 return upgrade;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800241}
242
243QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc,
244 uint32_t vdev_id)
245{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800246 QDF_STATUS status = QDF_STATUS_E_FAILURE;
247 uint32_t conn_index = 0;
248 bool found = false;
249 struct policy_mgr_vdev_entry_info conn_table_entry;
250 enum policy_mgr_chain_mode chain_mask = POLICY_MGR_ONE_ONE;
251 uint8_t nss_2g, nss_5g;
252 enum policy_mgr_con_mode mode;
253 uint8_t chan;
254 uint32_t nss = 0;
255 struct policy_mgr_psoc_priv_obj *pm_ctx;
256
257 pm_ctx = policy_mgr_get_context(psoc);
258 if (!pm_ctx) {
259 policy_mgr_err("Invalid Context");
260 return status;
261 }
262
263 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
264 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
265 if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
266 /* debug msg */
267 found = true;
268 break;
269 }
270 conn_index++;
271 }
272 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
273 if (!found) {
274 /* err msg */
275 policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list",
276 vdev_id);
277 return status;
278 }
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700279 if (pm_ctx->wma_cbacks.wma_get_connection_info) {
280 status = pm_ctx->wma_cbacks.wma_get_connection_info(
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800281 vdev_id, &conn_table_entry);
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700282 if (QDF_STATUS_SUCCESS != status) {
283 policy_mgr_err("can't find vdev_id %d in connection table",
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800284 vdev_id);
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700285 return status;
286 }
287 } else {
288 policy_mgr_err("wma_get_connection_info is NULL");
289 return QDF_STATUS_E_FAILURE;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800290 }
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700291
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800292 mode = policy_mgr_get_mode(conn_table_entry.type,
293 conn_table_entry.sub_type);
Tushnim Bhattacharyyace237d62017-04-05 12:52:36 -0700294 chan = wlan_reg_freq_to_chan(pm_ctx->pdev, conn_table_entry.mhz);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800295 status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g);
296 if (QDF_IS_STATUS_SUCCESS(status)) {
297 if ((WLAN_REG_IS_24GHZ_CH(chan) && (nss_2g > 1)) ||
298 (WLAN_REG_IS_5GHZ_CH(chan) && (nss_5g > 1)))
299 chain_mask = POLICY_MGR_TWO_TWO;
300 else
301 chain_mask = POLICY_MGR_ONE_ONE;
302 nss = (WLAN_REG_IS_24GHZ_CH(chan)) ? nss_2g : nss_5g;
303 } else {
304 policy_mgr_err("Error in getting nss");
305 }
306
307 policy_mgr_debug("update PM connection table for vdev:%d", vdev_id);
308
309 /* add the entry */
310 policy_mgr_update_conc_list(psoc, conn_index,
311 mode,
312 chan,
313 policy_mgr_get_bw(conn_table_entry.chan_width),
314 conn_table_entry.mac_id,
315 chain_mask,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +0530316 nss, vdev_id, true, true);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800317
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800318 return QDF_STATUS_SUCCESS;
319}
320
321QDF_STATUS policy_mgr_update_and_wait_for_connection_update(
322 struct wlan_objmgr_psoc *psoc,
323 uint8_t session_id,
324 uint8_t channel,
325 enum policy_mgr_conn_update_reason reason)
326{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800327 QDF_STATUS status;
328
329 policy_mgr_debug("session:%d channel:%d reason:%d",
330 session_id, channel, reason);
331
332 status = policy_mgr_reset_connection_update(psoc);
333 if (QDF_IS_STATUS_ERROR(status))
334 policy_mgr_err("clearing event failed");
335
336 status = policy_mgr_current_connections_update(psoc,
337 session_id, channel, reason);
338 if (QDF_STATUS_E_FAILURE == status) {
339 policy_mgr_err("connections update failed");
340 return QDF_STATUS_E_FAILURE;
341 }
342
343 /* Wait only when status is success */
344 if (QDF_IS_STATUS_SUCCESS(status)) {
345 status = policy_mgr_wait_for_connection_update(psoc);
346 if (QDF_IS_STATUS_ERROR(status)) {
347 policy_mgr_err("qdf wait for event failed");
348 return QDF_STATUS_E_FAILURE;
349 }
350 }
351
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800352 return QDF_STATUS_SUCCESS;
353}
354
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530355/**
356 * policy_mgr_is_dbs_allowed_for_concurrency() - If dbs is allowed for current
357 * concurreny
358 * @new_conn_mode: new connection mode
359 *
360 * When a new connection is about to come up, check if dbs is allowed for
361 * STA+STA or STA+P2P
362 *
363 * Return: true if dbs is allowed for STA+STA or STA+P2P else false
364 */
Bala Venkatesh28477d32018-05-07 21:35:55 +0530365bool policy_mgr_is_dbs_allowed_for_concurrency(
366 struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE new_conn_mode)
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530367{
368 struct policy_mgr_psoc_priv_obj *pm_ctx;
369 uint32_t count, dbs_for_sta_sta, dbs_for_sta_p2p;
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530370 bool ret = true;
371
372 pm_ctx = policy_mgr_get_context(psoc);
373 if (!pm_ctx) {
374 policy_mgr_err("Invalid context");
375 return ret;
376 }
377
378 count = policy_mgr_get_connection_count(psoc);
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530379
380 if (count != 1 || new_conn_mode == QDF_MAX_NO_OF_MODE)
381 return ret;
382
383 dbs_for_sta_sta = PM_CHANNEL_SELECT_LOGIC_STA_STA_GET(pm_ctx->user_cfg.
384 channel_select_logic_conc);
385 dbs_for_sta_p2p = PM_CHANNEL_SELECT_LOGIC_STA_P2P_GET(pm_ctx->user_cfg.
386 channel_select_logic_conc);
387
388 switch (pm_conc_connection_list[0].mode) {
389 case PM_STA_MODE:
390 switch (new_conn_mode) {
391 case QDF_STA_MODE:
392 if (!dbs_for_sta_sta)
393 return false;
394 break;
395 case QDF_P2P_DEVICE_MODE:
396 case QDF_P2P_CLIENT_MODE:
397 case QDF_P2P_GO_MODE:
398 if (!dbs_for_sta_p2p)
399 return false;
400 break;
401 default:
402 break;
403 }
404 break;
405 case PM_P2P_CLIENT_MODE:
406 case PM_P2P_GO_MODE:
407 switch (new_conn_mode) {
408 case QDF_STA_MODE:
409 if (!dbs_for_sta_p2p)
410 return false;
411 break;
412 default:
413 break;
414 }
415 break;
416 default:
417 break;
418 }
419
420 return ret;
421}
422
Krunal Soni637eba52018-06-14 17:55:15 -0700423static bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc,
424 uint8_t channel)
425{
426 uint8_t i, pm_chnl;
427 struct policy_mgr_psoc_priv_obj *pm_ctx;
428
429 pm_ctx = policy_mgr_get_context(psoc);
430 if (!pm_ctx) {
431 policy_mgr_err("Invalid Context");
432 return false;
433 }
434
435 /*
436 * check given channel against already existing connections'
437 * channels. if they differ then channels are in different bands
438 */
439 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
440 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
441 pm_chnl = pm_conc_connection_list[i].chan;
442 if (pm_conc_connection_list[i].in_use)
443 if (!WLAN_REG_IS_SAME_BAND_CHANNELS(channel, pm_chnl)) {
444 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
445 policy_mgr_debug("channel is in diff band");
446 return true;
447 }
448 }
449 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
450
451 return false;
452}
453
454bool policy_mgr_is_hwmode_set_for_given_chnl(struct wlan_objmgr_psoc *psoc,
455 uint8_t channel)
456{
457 enum policy_mgr_band band;
458 bool is_hwmode_dbs, is_2x2_dbs;
459
460 if (policy_mgr_is_hw_dbs_capable(psoc) == false)
461 return true;
462
463 if (WLAN_REG_IS_24GHZ_CH(channel))
464 band = POLICY_MGR_BAND_24;
465 else
466 band = POLICY_MGR_BAND_5;
467
468 is_hwmode_dbs = policy_mgr_is_current_hwmode_dbs(psoc);
469 is_2x2_dbs = policy_mgr_is_hw_dbs_2x2_capable(psoc);
470 /*
471 * If HW supports 2x2 chains in DBS HW mode and if DBS HW mode is not
472 * yet set then this is the right time to block the connection.
473 */
474 if ((band == POLICY_MGR_BAND_24) && is_2x2_dbs && !is_hwmode_dbs) {
475 policy_mgr_err("HW mode is not yet in DBS!!!!!");
476 return false;
477 }
478
479 /*
480 * If HW supports 1x1 chains DBS HW mode and if first connection is
481 * 2G or 5G band and if second connection is coming up in diffrent
482 * band than the first connection and if current HW mode is not yet
483 * set in DBS then this is the right time to block the connection.
484 */
485 if (policy_mgr_is_chnl_in_diff_band(psoc, channel) && !is_hwmode_dbs) {
486 policy_mgr_err("Given channel & existing conn is diff band & HW mode is not yet in DBS !!!!");
487 return false;
488 }
489
490 return true;
491}
492
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800493QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc,
494 uint32_t session_id,
495 uint8_t channel,
496 enum policy_mgr_conn_update_reason reason)
497{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800498 enum policy_mgr_conc_next_action next_action = PM_NOP;
499 uint32_t num_connections = 0;
500 enum policy_mgr_one_connection_mode second_index = 0;
501 enum policy_mgr_two_connection_mode third_index = 0;
502 enum policy_mgr_band band;
503 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Bala Venkatesh28477d32018-05-07 21:35:55 +0530504 struct policy_mgr_psoc_priv_obj *pm_ctx;
505 enum QDF_OPMODE new_conn_mode = QDF_MAX_NO_OF_MODE;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800506
507 if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
508 policy_mgr_err("driver isn't dbs capable, no further action needed");
509 return QDF_STATUS_E_NOSUPPORT;
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 num_connections = policy_mgr_get_connection_count(psoc);
517
518 policy_mgr_debug("num_connections=%d channel=%d",
519 num_connections, channel);
520
521 switch (num_connections) {
522 case 0:
523 if (band == POLICY_MGR_BAND_24)
524 if (policy_mgr_is_hw_dbs_2x2_capable(psoc))
525 next_action = PM_DBS;
526 else
527 next_action = PM_NOP;
528 else
529 next_action = PM_NOP;
530 break;
531 case 1:
532 second_index =
533 policy_mgr_get_second_connection_pcl_table_index(psoc);
534 if (PM_MAX_ONE_CONNECTION_MODE == second_index) {
535 policy_mgr_err(
536 "couldn't find index for 2nd connection next action table");
537 goto done;
538 }
539 next_action =
540 (*next_action_two_connection_table)[second_index][band];
541 break;
542 case 2:
543 third_index =
544 policy_mgr_get_third_connection_pcl_table_index(psoc);
545 if (PM_MAX_TWO_CONNECTION_MODE == third_index) {
546 policy_mgr_err(
547 "couldn't find index for 3rd connection next action table");
548 goto done;
549 }
550 next_action = (*next_action_three_connection_table)
551 [third_index][band];
552 break;
553 default:
554 policy_mgr_err("unexpected num_connections value %d",
555 num_connections);
556 break;
557 }
558
Bala Venkatesh28477d32018-05-07 21:35:55 +0530559 pm_ctx = policy_mgr_get_context(psoc);
560 if (!pm_ctx) {
561 policy_mgr_err("Invalid context");
562 goto done;
563 }
564
565 if (pm_ctx->hdd_cbacks.hdd_get_device_mode)
566 new_conn_mode = pm_ctx->hdd_cbacks.
567 hdd_get_device_mode(session_id);
568
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530569 /*
570 * Based on channel_select_logic_conc ini, hw mode is set
571 * when second connection is about to come up that results
572 * in STA+STA and STA+P2P concurrency.
573 * 1) If MCC is set and if current hw mode is dbs, hw mode
574 * should be set to single mac for above concurrency.
575 * 2) If MCC is set and if current hw mode is not dbs, hw
576 * mode change is not required.
577 */
578 if (policy_mgr_is_current_hwmode_dbs(psoc) &&
Bala Venkatesh28477d32018-05-07 21:35:55 +0530579 !policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode))
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530580 next_action = PM_SINGLE_MAC;
581 else if (!policy_mgr_is_current_hwmode_dbs(psoc) &&
Bala Venkatesh28477d32018-05-07 21:35:55 +0530582 !policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode))
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530583 next_action = PM_NOP;
584
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800585 if (PM_NOP != next_action)
586 status = policy_mgr_next_actions(psoc, session_id,
587 next_action, reason);
588 else
589 status = QDF_STATUS_E_NOSUPPORT;
590
591 policy_mgr_debug(
592 "idx2=%d idx3=%d next_action=%d, band=%d status=%d reason=%d session_id=%d",
593 second_index, third_index, next_action, band, status,
594 reason, session_id);
595
596done:
597 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800598}
599
600QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc,
601 uint32_t session_id,
602 enum policy_mgr_conc_next_action action,
603 enum policy_mgr_conn_update_reason reason)
604{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800605 QDF_STATUS status = QDF_STATUS_E_FAILURE;
606 struct policy_mgr_hw_mode_params hw_mode;
Varun Reddy Yeturue23b6bc2018-01-08 13:18:41 -0800607 struct dbs_nss nss_dbs = {0};
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800608
609 if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
610 policy_mgr_err("driver isn't dbs capable, no further action needed");
611 return QDF_STATUS_E_NOSUPPORT;
612 }
613
614 /* check for the current HW index to see if really need any action */
615 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
616 if (!QDF_IS_STATUS_SUCCESS(status)) {
617 policy_mgr_err("policy_mgr_get_current_hw_mode failed");
618 return status;
619 }
620 /**
621 * if already in DBS no need to request DBS. Might be needed
622 * to extend the logic when multiple dbs HW mode is available
623 */
624 if ((((PM_DBS_DOWNGRADE == action) || (PM_DBS == action) ||
625 (PM_DBS_UPGRADE == action))
626 && hw_mode.dbs_cap)) {
627 policy_mgr_err("driver is already in %s mode, no further action needed",
628 (hw_mode.dbs_cap) ? "dbs" : "non dbs");
629 return QDF_STATUS_E_ALREADY;
630 }
631
632 if ((PM_SBS == action) || (action == PM_SBS_DOWNGRADE)) {
633 if (!policy_mgr_is_hw_sbs_capable(psoc)) {
634 /* No action */
635 policy_mgr_notice("firmware is not sbs capable");
Tushnim Bhattacharyyafe511702017-04-24 15:21:59 -0700636 return QDF_STATUS_E_NOSUPPORT;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800637 }
638 /* check if current mode is already SBS nothing to be
639 * done
640 */
641
642 }
643
644 switch (action) {
645 case PM_DBS_DOWNGRADE:
646 /*
647 * check if we have a beaconing entity that is using 2x2. If yes,
648 * update the beacon template & notify FW. Once FW confirms
649 * beacon updated, send down the HW mode change req
650 */
651 status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
652 PM_DBS, reason, session_id);
653 break;
654 case PM_DBS:
Vikrampal31eb12c2017-04-28 17:44:30 +0530655 (void)policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs);
656
657 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
658 nss_dbs.mac0_ss,
659 HW_MODE_80_MHZ,
660 nss_dbs.mac1_ss,
661 HW_MODE_40_MHZ,
Liangwei Dong9ace8a92018-05-21 05:39:04 -0400662 HW_MODE_MAC_BAND_NONE,
Vikrampal31eb12c2017-04-28 17:44:30 +0530663 HW_MODE_DBS,
664 HW_MODE_AGILE_DFS_NONE,
665 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800666 reason, PM_NOP);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800667 break;
668 case PM_SINGLE_MAC_UPGRADE:
669 /*
670 * change the HW mode first before the NSS upgrade
671 */
672 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
673 HW_MODE_SS_2x2,
674 HW_MODE_80_MHZ,
675 HW_MODE_SS_0x0, HW_MODE_BW_NONE,
Liangwei Dong9ace8a92018-05-21 05:39:04 -0400676 HW_MODE_MAC_BAND_NONE,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800677 HW_MODE_DBS_NONE,
678 HW_MODE_AGILE_DFS_NONE,
679 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800680 reason, PM_UPGRADE);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800681 break;
682 case PM_SINGLE_MAC:
683 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
684 HW_MODE_SS_2x2,
685 HW_MODE_80_MHZ,
686 HW_MODE_SS_0x0, HW_MODE_BW_NONE,
Liangwei Dong9ace8a92018-05-21 05:39:04 -0400687 HW_MODE_MAC_BAND_NONE,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800688 HW_MODE_DBS_NONE,
689 HW_MODE_AGILE_DFS_NONE,
690 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800691 reason, PM_NOP);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800692 break;
693 case PM_DBS_UPGRADE:
694 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
695 HW_MODE_SS_2x2,
696 HW_MODE_80_MHZ,
697 HW_MODE_SS_2x2, HW_MODE_80_MHZ,
Liangwei Dong9ace8a92018-05-21 05:39:04 -0400698 HW_MODE_MAC_BAND_NONE,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800699 HW_MODE_DBS,
700 HW_MODE_AGILE_DFS_NONE,
701 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800702 reason, PM_UPGRADE);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800703 break;
704 case PM_SBS_DOWNGRADE:
705 status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
706 PM_SBS, reason, session_id);
707 break;
708 case PM_SBS:
709 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
710 HW_MODE_SS_1x1,
711 HW_MODE_80_MHZ,
712 HW_MODE_SS_1x1, HW_MODE_80_MHZ,
Liangwei Dong9ace8a92018-05-21 05:39:04 -0400713 HW_MODE_MAC_BAND_NONE,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800714 HW_MODE_DBS,
715 HW_MODE_AGILE_DFS_NONE,
716 HW_MODE_SBS,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800717 reason, PM_NOP);
718 break;
719 case PM_DOWNGRADE:
720 /*
721 * check if we have a beaconing entity that advertised 2x2
722 * intially. If yes, update the beacon template & notify FW.
723 */
724 status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_1,
725 PM_NOP, reason);
726 break;
727 case PM_UPGRADE:
728 /*
729 * check if we have a beaconing entity that advertised 2x2
730 * intially. If yes, update the beacon template & notify FW.
731 */
732 status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_2,
733 PM_NOP, reason);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800734 break;
735 default:
736 policy_mgr_err("unexpected action value %d", action);
737 status = QDF_STATUS_E_FAILURE;
738 break;
739 }
740
741 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800742}
743
744QDF_STATUS policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc,
745 uint8_t session_id, uint8_t channel)
746{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800747 QDF_STATUS status;
748
749 if (!policy_mgr_check_for_session_conc(psoc, session_id, channel)) {
750 policy_mgr_err("Conc not allowed for the session %d",
751 session_id);
752 return QDF_STATUS_E_FAILURE;
753 }
754
755 status = policy_mgr_reset_connection_update(psoc);
756 if (!QDF_IS_STATUS_SUCCESS(status))
757 policy_mgr_err("clearing event failed");
758
759 status = policy_mgr_current_connections_update(psoc, session_id,
760 channel,
761 POLICY_MGR_UPDATE_REASON_NORMAL_STA);
762 if (QDF_STATUS_E_FAILURE == status) {
763 policy_mgr_err("connections update failed");
764 return status;
765 }
766
767 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800768}
769
770#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +0530771void policy_mgr_update_user_config_sap_chan(
772 struct wlan_objmgr_psoc *psoc, uint32_t channel)
773{
774 struct policy_mgr_psoc_priv_obj *pm_ctx;
775
776 pm_ctx = policy_mgr_get_context(psoc);
777 if (!pm_ctx) {
778 policy_mgr_err("Invalid pm context and failed to update the user config sap channel");
779 return;
780 }
781 pm_ctx->user_config_sap_channel = channel;
782}
783
Archana Ramachandran544ce172017-03-14 15:12:09 -0700784/**
785 * policy_mgr_is_restart_sap_allowed() - Check if restart SAP
786 * allowed during SCC -> MCC switch
787 * @psoc: PSOC object data
788 * @mcc_to_scc_switch: MCC to SCC switch enabled user config
789 *
790 * Check if restart SAP allowed during SCC->MCC switch
791 *
792 * Restart: true or false
793 */
794static bool policy_mgr_is_restart_sap_allowed(
795 struct wlan_objmgr_psoc *psoc,
796 uint32_t mcc_to_scc_switch)
797{
Rachit Kankanea07e4b92017-09-15 19:38:49 +0530798 uint32_t sta_ap_bit_mask = QDF_STA_MASK | QDF_SAP_MASK;
799 uint32_t sta_go_bit_mask = QDF_STA_MASK | QDF_P2P_GO_MASK;
800
Archana Ramachandran544ce172017-03-14 15:12:09 -0700801 if ((mcc_to_scc_switch == QDF_MCC_TO_SCC_SWITCH_DISABLE) ||
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -0700802 !policy_mgr_concurrent_open_sessions_running(psoc) ||
Rachit Kankanea07e4b92017-09-15 19:38:49 +0530803 !(((policy_mgr_get_concurrency_mode(psoc) & sta_ap_bit_mask)
804 == sta_ap_bit_mask) ||
Tushnim Bhattacharyyab7f83962018-06-14 17:56:38 -0700805 ((mcc_to_scc_switch ==
806 QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) &&
Rachit Kankanea07e4b92017-09-15 19:38:49 +0530807 ((policy_mgr_get_concurrency_mode(psoc) & sta_go_bit_mask)
Tushnim Bhattacharyyab7f83962018-06-14 17:56:38 -0700808 == sta_go_bit_mask)))) {
Abhinav Kumar77cb42a2018-06-15 16:46:30 +0530809 policy_mgr_debug("MCC switch disabled or not concurrent STA/SAP, STA/GO");
Archana Ramachandran544ce172017-03-14 15:12:09 -0700810 return false;
811 }
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -0700812
Archana Ramachandran544ce172017-03-14 15:12:09 -0700813 return true;
814}
815
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -0700816bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc,
817 uint8_t channel)
818{
819 struct policy_mgr_psoc_priv_obj *pm_ctx;
820 bool is_safe = true;
821 uint8_t j;
822
823 pm_ctx = policy_mgr_get_context(psoc);
824 if (!pm_ctx) {
825 policy_mgr_err("Invalid context");
826 return is_safe;
827 }
828
829
830 if (pm_ctx->unsafe_channel_count == 0) {
831 policy_mgr_debug("There are no unsafe channels");
832 return is_safe;
833 }
834
835 for (j = 0; j < pm_ctx->unsafe_channel_count; j++) {
836 if (channel == pm_ctx->unsafe_channel_list[j]) {
837 is_safe = false;
838 policy_mgr_warn("CH %d is not safe", channel);
839 break;
840 }
841 }
842
843 return is_safe;
844}
845
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +0530846bool policy_mgr_is_sap_restart_required_after_sta_disconnect(
847 struct wlan_objmgr_psoc *psoc, uint8_t *intf_ch)
848{
849 struct policy_mgr_psoc_priv_obj *pm_ctx;
850 uint8_t sap_chan = policy_mgr_mode_specific_get_channel(psoc,
851 PM_SAP_MODE);
852 bool sta_sap_scc_on_dfs_chan =
853 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
854
855 *intf_ch = 0;
856
857 pm_ctx = policy_mgr_get_context(psoc);
858 if (!pm_ctx) {
859 policy_mgr_err("Invalid pm context");
860 return false;
861 }
862
863 policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sap_chan %u",
864 sta_sap_scc_on_dfs_chan, sap_chan);
865
Jianmin Zhu7f6bdd32018-06-29 10:39:30 +0800866 if ((!sta_sap_scc_on_dfs_chan ||
867 !(sap_chan && WLAN_REG_IS_5GHZ_CH(sap_chan) &&
868 (wlan_reg_get_channel_state(pm_ctx->pdev, sap_chan) ==
869 CHANNEL_STATE_DFS))) &&
870 (!policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) ||
871 policy_mgr_is_safe_channel(psoc, sap_chan))) {
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +0530872 return false;
873 }
874
875 *intf_ch = pm_ctx->user_config_sap_channel;
876 policy_mgr_debug("Standalone SAP is not allowed on DFS channel, Move it to channel %u",
877 *intf_ch);
878
879 return true;
880}
881
Archana Ramachandran544ce172017-03-14 15:12:09 -0700882/**
Archana Ramachandran544ce172017-03-14 15:12:09 -0700883 * policy_mgr_check_sta_ap_concurrent_ch_intf() - Restart SAP in STA-AP case
884 * @data: Pointer check concurrent channel work data
885 *
886 * Restarts the SAP interface in STA-AP concurrency scenario
887 *
888 * Restart: None
889 */
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800890void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data)
891{
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -0700892 struct wlan_objmgr_psoc *psoc;
893 struct policy_mgr_psoc_priv_obj *pm_ctx = NULL;
894 struct sta_ap_intf_check_work_ctx *work_info = NULL;
Rachit Kankanea07e4b92017-09-15 19:38:49 +0530895 uint32_t mcc_to_scc_switch, cc_count = 0, i;
Archana Ramachandran544ce172017-03-14 15:12:09 -0700896 QDF_STATUS status;
897 uint8_t channel, sec_ch;
Rachit Kankanea07e4b92017-09-15 19:38:49 +0530898 uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS];
899 uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS];
Archana Ramachandran544ce172017-03-14 15:12:09 -0700900
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -0700901 work_info = (struct sta_ap_intf_check_work_ctx *) data;
902 if (!work_info) {
903 policy_mgr_err("Invalid work_info");
904 goto end;
905 }
906
907 psoc = work_info->psoc;
908 if (!psoc) {
909 policy_mgr_err("Invalid psoc");
910 goto end;
911 }
912
Archana Ramachandran544ce172017-03-14 15:12:09 -0700913 pm_ctx = policy_mgr_get_context(psoc);
914 if (!pm_ctx) {
915 policy_mgr_err("Invalid context");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -0700916 goto end;
Archana Ramachandran544ce172017-03-14 15:12:09 -0700917 }
918 mcc_to_scc_switch =
919 policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc);
920
921 policy_mgr_info("Concurrent open sessions running: %d",
922 policy_mgr_concurrent_open_sessions_running(psoc));
923
924 if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch))
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -0700925 goto end;
Archana Ramachandran6199b642017-03-20 13:31:36 -0700926
Rachit Kankanea07e4b92017-09-15 19:38:49 +0530927 cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
928 &operating_channel[cc_count],
929 &vdev_id[cc_count],
930 PM_SAP_MODE);
931 policy_mgr_debug("Number of concurrent SAP: %d", cc_count);
932 cc_count = cc_count + policy_mgr_get_mode_specific_conn_info(psoc,
933 &operating_channel[cc_count],
934 &vdev_id[cc_count],
935 PM_P2P_GO_MODE);
936 policy_mgr_debug("Number of beaconing entities (SAP + GO):%d",
937 cc_count);
938 if (!cc_count) {
Ajit Pal Singhc1246b12017-06-16 11:36:12 +0530939 policy_mgr_err("Could not retrieve SAP/GO operating channel&vdevid");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -0700940 goto end;
Archana Ramachandran6199b642017-03-20 13:31:36 -0700941 }
942
Bala Venkatesh378064b2018-06-11 15:06:53 +0530943 policy_mgr_debug("wait if channel switch is already in progress");
944 status = qdf_wait_single_event(
945 &pm_ctx->channel_switch_complete_evt,
946 CHANNEL_SWITCH_COMPLETE_TIMEOUT);
947
948 if (!QDF_IS_STATUS_SUCCESS(status)) {
949 policy_mgr_err("wait for event failed, still continue with channel switch");
950 }
Archana Ramachandran631fd9f2017-03-19 18:51:30 -0700951 if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) {
952 policy_mgr_err("SAP restart get channel callback in NULL");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -0700953 goto end;
Archana Ramachandran631fd9f2017-03-19 18:51:30 -0700954 }
Rachit Kankanea07e4b92017-09-15 19:38:49 +0530955 for (i = 0; i < cc_count; i++) {
956 status = pm_ctx->hdd_cbacks.
957 wlan_hdd_get_channel_for_sap_restart(psoc,
958 vdev_id[i], &channel, &sec_ch);
959 if (status == QDF_STATUS_SUCCESS) {
960 policy_mgr_info("SAP restarts due to MCC->SCC switch, old chan :%d new chan: %d"
961 , operating_channel[i], channel);
962 break;
963 }
Archana Ramachandran544ce172017-03-14 15:12:09 -0700964 }
Rachit Kankanea07e4b92017-09-15 19:38:49 +0530965 if (status != QDF_STATUS_SUCCESS)
966 policy_mgr_err("Failed to switch SAP channel");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -0700967end:
968 if (work_info) {
969 qdf_mem_free(work_info);
970 if (pm_ctx)
971 pm_ctx->sta_ap_intf_check_work_info = NULL;
972 }
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800973}
974
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -0700975static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc,
976 uint8_t sta_channel)
977{
978 struct policy_mgr_psoc_priv_obj *pm_ctx;
979
980 pm_ctx = policy_mgr_get_context(psoc);
981 if (!pm_ctx) {
982 policy_mgr_err("Invalid context");
983 return false;
984 }
985
Ganesh Kondabattini8a611c62017-11-21 15:01:31 +0530986 if ((wlan_reg_is_dfs_ch(pm_ctx->pdev, sta_channel) &&
987 (!policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc))) ||
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -0700988 wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev, sta_channel) ||
Ganesh Kondabattini8a611c62017-11-21 15:01:31 +0530989 !policy_mgr_is_safe_channel(psoc, sta_channel)) {
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -0700990 if (policy_mgr_is_hw_dbs_capable(psoc))
991 return true;
992 else
993 return false;
Ganesh Kondabattini8a611c62017-11-21 15:01:31 +0530994 }
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -0700995 else
996 return true;
997}
998
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -0700999QDF_STATUS policy_mgr_valid_sap_conc_channel_check(
1000 struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch)
1001{
1002 uint8_t channel = *con_ch;
1003 uint8_t temp_channel = 0;
1004 struct policy_mgr_psoc_priv_obj *pm_ctx;
Bala Venkatesh7c96e542018-06-07 19:32:27 +05301005 bool sta_sap_scc_on_dfs_chan;
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001006
1007 pm_ctx = policy_mgr_get_context(psoc);
1008 if (!pm_ctx) {
1009 policy_mgr_err("Invalid context");
1010 return QDF_STATUS_E_FAILURE;
1011 }
1012
1013 /*
1014 * if force SCC is set, Check if conc channel is DFS
1015 * or passive or part of LTE avoided channel list.
1016 * In that case move SAP to other band if DBS is supported,
1017 * return otherwise
1018 */
1019 if (!policy_mgr_is_force_scc(psoc))
1020 return QDF_STATUS_SUCCESS;
1021
1022 /*
1023 * if interference is 0, check if it is DBS case. If DBS case
1024 * return from here. If SCC, check further if SAP can move to
1025 * STA's channel.
1026 */
1027 if (!channel &&
1028 (sap_ch != policy_mgr_mode_specific_get_channel(
1029 psoc, PM_STA_MODE)))
1030 return QDF_STATUS_SUCCESS;
1031 else if (!channel)
1032 channel = sap_ch;
1033
Bala Venkatesh7c96e542018-06-07 19:32:27 +05301034 sta_sap_scc_on_dfs_chan =
1035 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
1036
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001037 if (policy_mgr_valid_sta_channel_check(psoc, channel)) {
1038 if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) ||
Zhu Jianmin5ac66ef2018-06-11 19:03:39 +08001039 wlan_reg_is_passive_or_disable_ch(
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001040 pm_ctx->pdev, channel) ||
Zhu Jianmin5ac66ef2018-06-11 19:03:39 +08001041 !(policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) ||
1042 policy_mgr_is_safe_channel(psoc, channel))) {
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001043 if (policy_mgr_is_hw_dbs_capable(psoc)) {
1044 temp_channel =
1045 policy_mgr_get_alternate_channel_for_sap(psoc);
1046 policy_mgr_debug("temp_channel is %d",
1047 temp_channel);
1048 if (temp_channel) {
1049 channel = temp_channel;
1050 } else {
1051 if (WLAN_REG_IS_5GHZ_CH(channel))
1052 channel = PM_24_GHZ_CHANNEL_6;
1053 else
1054 channel = PM_5_GHZ_CHANNEL_36;
1055 }
1056 if (!policy_mgr_is_safe_channel(
1057 psoc, channel)) {
1058 policy_mgr_warn(
1059 "Can't have concurrency on %d as it is not safe",
1060 channel);
1061 return QDF_STATUS_E_FAILURE;
1062 }
1063 } else {
Bala Venkatesh7c96e542018-06-07 19:32:27 +05301064 if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) &&
1065 sta_sap_scc_on_dfs_chan) {
1066 policy_mgr_debug("STA SAP SCC is allowed on DFS channel");
1067 goto update_chan;
1068 }
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001069 policy_mgr_warn("Can't have concurrency on %d",
1070 channel);
1071 return QDF_STATUS_E_FAILURE;
1072 }
1073 }
1074 }
1075
Bala Venkatesh7c96e542018-06-07 19:32:27 +05301076update_chan:
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001077 if (channel != sap_ch)
1078 *con_ch = channel;
1079
1080 return QDF_STATUS_SUCCESS;
1081}
1082
Archana Ramachandran107d3782017-03-06 17:07:44 -08001083/**
1084 * policy_mgr_check_concurrent_intf_and_restart_sap() - Check
1085 * concurrent change intf
1086 * @psoc: PSOC object information
1087 * @operation_channel: operation channel
Archana Ramachandran544ce172017-03-14 15:12:09 -07001088 * @vdev_id: vdev id of SAP
Archana Ramachandran107d3782017-03-06 17:07:44 -08001089 *
1090 * Checks the concurrent change interface and restarts SAP
1091 *
1092 * Return: None
1093 */
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001094void policy_mgr_check_concurrent_intf_and_restart_sap(
Archana Ramachandran6199b642017-03-20 13:31:36 -07001095 struct wlan_objmgr_psoc *psoc)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001096{
Archana Ramachandran266613f2017-03-13 16:36:55 -07001097 struct policy_mgr_psoc_priv_obj *pm_ctx;
1098 uint32_t mcc_to_scc_switch;
Tushnim Bhattacharyyaf8417d12018-05-08 15:31:21 -07001099 uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
1100 uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
1101 uint32_t cc_count = 0;
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301102 bool restart_sap = false;
1103 uint8_t sap_ch;
Archana Ramachandran266613f2017-03-13 16:36:55 -07001104
1105 pm_ctx = policy_mgr_get_context(psoc);
1106 if (!pm_ctx) {
1107 policy_mgr_err("Invalid context");
1108 return;
1109 }
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301110 if (policy_mgr_get_connection_count(psoc) == 1) {
1111 /*
1112 * If STA+SAP sessions are on DFS channel and STA+SAP SCC is
1113 * enabled on DFS channel then move the SAP out of DFS channel
1114 * as soon as STA gets disconnect.
Jianmin Zhu7f6bdd32018-06-29 10:39:30 +08001115 * If STA+SAP sessions are on unsafe channel and STA+SAP SCC is
1116 * enabled on unsafe channel then move the SAP to safe channel
1117 * as soon as STA disconnected.
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301118 */
1119 if (policy_mgr_is_sap_restart_required_after_sta_disconnect(
1120 psoc, &sap_ch)) {
1121 policy_mgr_debug("move the SAP to configured channel %u",
1122 sap_ch);
1123 restart_sap = true;
1124 goto sap_restart;
1125 }
1126 }
Archana Ramachandran266613f2017-03-13 16:36:55 -07001127
Tushnim Bhattacharyyaf8417d12018-05-08 15:31:21 -07001128 /*
1129 * force SCC with STA+STA+SAP will need some additional logic
1130 */
1131 cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
1132 &operating_channel[cc_count],
1133 &vdev_id[cc_count], PM_STA_MODE);
1134 if (!cc_count) {
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301135 policy_mgr_err("Could not get STA operating channel&vdevid");
Archana Ramachandran6199b642017-03-20 13:31:36 -07001136 return;
1137 }
1138
Archana Ramachandran266613f2017-03-13 16:36:55 -07001139 mcc_to_scc_switch =
1140 policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc);
1141 policy_mgr_info("MCC to SCC switch: %d chan: %d",
Tushnim Bhattacharyyaf8417d12018-05-08 15:31:21 -07001142 mcc_to_scc_switch, operating_channel[0]);
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001143
1144 if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch)) {
1145 policy_mgr_debug(
1146 "No action taken at check_concurrent_intf_and_restart_sap");
1147 return;
1148 }
1149
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301150sap_restart:
1151 /*
1152 * If sta_sap_scc_on_dfs_chan is true then standalone SAP is not
1153 * allowed on DFS channel. SAP is allowed on DFS channel only when STA
1154 * is already connected on that channel.
1155 * In following condition restart_sap will be true if
1156 * sta_sap_scc_on_dfs_chan is true and SAP is on DFS channel.
1157 * This scenario can come if STA+SAP are operating on DFS channel and
1158 * STA gets disconnected.
1159 */
1160 if (restart_sap ||
1161 ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) &&
1162 policy_mgr_valid_sta_channel_check(psoc, operating_channel[0]) &&
1163 !pm_ctx->sta_ap_intf_check_work_info)) {
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001164 struct sta_ap_intf_check_work_ctx *work_info;
1165 work_info = qdf_mem_malloc(
1166 sizeof(struct sta_ap_intf_check_work_ctx));
1167 pm_ctx->sta_ap_intf_check_work_info = work_info;
1168 if (work_info) {
1169 work_info->psoc = psoc;
1170 qdf_create_work(0, &pm_ctx->sta_ap_intf_check_work,
Archana Ramachandran6199b642017-03-20 13:31:36 -07001171 policy_mgr_check_sta_ap_concurrent_ch_intf,
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001172 work_info);
1173 qdf_sched_work(0, &pm_ctx->sta_ap_intf_check_work);
1174 policy_mgr_info(
1175 "Checking for Concurrent Change interference");
1176 }
Archana Ramachandran266613f2017-03-13 16:36:55 -07001177 }
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001178}
1179#endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */
1180
1181#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Archana Ramachandran0edce252017-03-06 14:36:29 -08001182/**
1183 * policy_mgr_change_sap_channel_with_csa() - Move SAP channel using (E)CSA
1184 * @psoc: PSOC object information
1185 * @vdev_id: Vdev id
1186 * @channel: Channel to change
1187 * @ch_width: channel width to change
Min Liuc5b10432018-01-19 18:01:44 +08001188 * @forced: Force to switch channel, ignore SCC/MCC check
Archana Ramachandran0edce252017-03-06 14:36:29 -08001189 *
1190 * Invoke the callback function to change SAP channel using (E)CSA
1191 *
1192 * Return: None
1193 */
1194void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc,
1195 uint8_t vdev_id, uint32_t channel,
Min Liuc5b10432018-01-19 18:01:44 +08001196 uint32_t ch_width,
1197 bool forced)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001198{
Archana Ramachandran0edce252017-03-06 14:36:29 -08001199 struct policy_mgr_psoc_priv_obj *pm_ctx;
1200
1201 pm_ctx = policy_mgr_get_context(psoc);
1202 if (!pm_ctx) {
1203 policy_mgr_err("Invalid context");
1204 return;
1205 }
1206
Archana Ramachandran544ce172017-03-14 15:12:09 -07001207 if (pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb) {
Archana Ramachandran0edce252017-03-06 14:36:29 -08001208 policy_mgr_info("SAP change change without restart");
Archana Ramachandran631fd9f2017-03-19 18:51:30 -07001209 pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb(psoc,
Min Liuc5b10432018-01-19 18:01:44 +08001210 vdev_id, channel, ch_width, forced);
Archana Ramachandran0edce252017-03-06 14:36:29 -08001211 }
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001212}
1213#endif
1214
1215QDF_STATUS policy_mgr_wait_for_connection_update(struct wlan_objmgr_psoc *psoc)
1216{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001217 QDF_STATUS status;
1218 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1219
1220 policy_mgr_context = policy_mgr_get_context(psoc);
1221 if (!policy_mgr_context) {
1222 policy_mgr_err("Invalid context");
1223 return QDF_STATUS_E_FAILURE;
1224 }
1225
1226 status = qdf_wait_single_event(
1227 &policy_mgr_context->connection_update_done_evt,
1228 CONNECTION_UPDATE_TIMEOUT);
1229
1230 if (!QDF_IS_STATUS_SUCCESS(status)) {
1231 policy_mgr_err("wait for event failed");
1232 return QDF_STATUS_E_FAILURE;
1233 }
1234
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001235 return QDF_STATUS_SUCCESS;
1236}
1237
1238QDF_STATUS policy_mgr_reset_connection_update(struct wlan_objmgr_psoc *psoc)
1239{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001240 QDF_STATUS status;
1241 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1242
1243 policy_mgr_context = policy_mgr_get_context(psoc);
1244 if (!policy_mgr_context) {
1245 policy_mgr_err("Invalid context");
1246 return QDF_STATUS_E_FAILURE;
1247 }
1248
1249 status = qdf_event_reset(
1250 &policy_mgr_context->connection_update_done_evt);
1251
1252 if (!QDF_IS_STATUS_SUCCESS(status)) {
1253 policy_mgr_err("clear event failed");
1254 return QDF_STATUS_E_FAILURE;
1255 }
1256
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001257 return QDF_STATUS_SUCCESS;
1258}
1259
1260QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc)
1261{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001262 QDF_STATUS status;
1263 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1264
1265 policy_mgr_context = policy_mgr_get_context(psoc);
1266 if (!policy_mgr_context) {
1267 policy_mgr_err("Invalid context");
1268 return QDF_STATUS_E_FAILURE;
1269 }
1270
1271 status = qdf_event_set(&policy_mgr_context->connection_update_done_evt);
1272
1273 if (!QDF_IS_STATUS_SUCCESS(status)) {
1274 policy_mgr_err("set event failed");
1275 return QDF_STATUS_E_FAILURE;
1276 }
1277
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001278 return QDF_STATUS_SUCCESS;
1279}
1280
Bala Venkatesh378064b2018-06-11 15:06:53 +05301281QDF_STATUS policy_mgr_set_chan_switch_complete_evt(
1282 struct wlan_objmgr_psoc *psoc)
1283{
1284 QDF_STATUS status;
1285 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1286
1287 policy_mgr_context = policy_mgr_get_context(psoc);
1288
1289 if (!policy_mgr_context) {
1290 policy_mgr_err("Invalid context");
1291 return QDF_STATUS_E_FAILURE;
1292 }
1293 status = qdf_event_set(
1294 &policy_mgr_context->channel_switch_complete_evt);
1295
1296 if (!QDF_IS_STATUS_SUCCESS(status)) {
1297 policy_mgr_err("set event failed");
1298 return QDF_STATUS_E_FAILURE;
1299 }
1300
1301 return QDF_STATUS_SUCCESS;
1302}
1303
1304QDF_STATUS policy_mgr_reset_chan_switch_complete_evt(
1305 struct wlan_objmgr_psoc *psoc)
1306{
1307 QDF_STATUS status;
1308 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1309
1310 policy_mgr_context = policy_mgr_get_context(psoc);
1311
1312 if (!policy_mgr_context) {
1313 policy_mgr_err("Invalid context");
1314 return QDF_STATUS_E_FAILURE;
1315 }
1316 status = qdf_event_reset(
1317 &policy_mgr_context->channel_switch_complete_evt);
1318
1319 if (!QDF_IS_STATUS_SUCCESS(status)) {
1320 policy_mgr_err("reset event failed");
1321 return QDF_STATUS_E_FAILURE;
1322 }
1323
1324 return QDF_STATUS_SUCCESS;
1325}
1326
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001327QDF_STATUS policy_mgr_set_opportunistic_update(struct wlan_objmgr_psoc *psoc)
1328{
1329 QDF_STATUS status;
1330 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1331
1332 policy_mgr_context = policy_mgr_get_context(psoc);
1333 if (!policy_mgr_context) {
1334 policy_mgr_err("Invalid context");
1335 return QDF_STATUS_E_FAILURE;
1336 }
1337
1338 status = qdf_event_set(
1339 &policy_mgr_context->opportunistic_update_done_evt);
1340
1341 if (!QDF_IS_STATUS_SUCCESS(status)) {
1342 policy_mgr_err("set event failed");
1343 return QDF_STATUS_E_FAILURE;
1344 }
1345
1346 return QDF_STATUS_SUCCESS;
1347}
1348
Himanshu Agarwal70a52d92018-05-04 14:37:48 +05301349QDF_STATUS policy_mgr_stop_opportunistic_timer(struct wlan_objmgr_psoc *psoc)
1350{
1351 struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
1352
1353 policy_mgr_ctx = policy_mgr_get_context(psoc);
1354 if (!policy_mgr_ctx) {
1355 policy_mgr_err("Invalid context");
1356 return QDF_STATUS_E_FAILURE;
1357 }
1358
1359 if (policy_mgr_ctx->dbs_opportunistic_timer.state !=
1360 QDF_TIMER_STATE_RUNNING)
1361 return QDF_STATUS_SUCCESS;
1362
1363 qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer);
1364 return QDF_STATUS_SUCCESS;
1365}
1366
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001367QDF_STATUS policy_mgr_restart_opportunistic_timer(
1368 struct wlan_objmgr_psoc *psoc, bool check_state)
1369{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001370 QDF_STATUS status = QDF_STATUS_E_FAILURE;
1371 struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
1372
1373 policy_mgr_ctx = policy_mgr_get_context(psoc);
1374 if (!policy_mgr_ctx) {
1375 policy_mgr_err("Invalid context");
1376 return status;
1377 }
1378
1379 if (check_state &&
1380 QDF_TIMER_STATE_RUNNING !=
1381 policy_mgr_ctx->dbs_opportunistic_timer.state)
1382 return status;
1383
1384 qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer);
1385
1386 status = qdf_mc_timer_start(
1387 &policy_mgr_ctx->dbs_opportunistic_timer,
1388 DBS_OPPORTUNISTIC_TIME * 1000);
1389
1390 if (!QDF_IS_STATUS_SUCCESS(status)) {
1391 policy_mgr_err("failed to start opportunistic timer");
1392 return status;
1393 }
1394
1395 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001396}
1397
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001398QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch(
1399 struct wlan_objmgr_psoc *psoc, uint8_t session_id)
1400{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001401 QDF_STATUS status = QDF_STATUS_E_FAILURE, qdf_status;
1402 enum policy_mgr_conc_next_action action;
1403
1404 if (!policy_mgr_is_hw_dbs_capable(psoc)) {
1405 policy_mgr_err("PM/DBS is disabled");
1406 return status;
1407 }
1408
1409 action = (*policy_mgr_get_current_pref_hw_mode_ptr)(psoc);
1410 if ((action != PM_DBS_DOWNGRADE) &&
1411 (action != PM_SINGLE_MAC_UPGRADE)) {
1412 policy_mgr_err("Invalid action: %d", action);
1413 status = QDF_STATUS_SUCCESS;
1414 goto done;
1415 }
1416
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001417 policy_mgr_debug("action:%d session id:%d", action, session_id);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001418
1419 /* Opportunistic timer is started, PM will check if MCC upgrade can be
1420 * done on timer expiry. This avoids any possible ping pong effect
1421 * as well.
1422 */
1423 if (action == PM_SINGLE_MAC_UPGRADE) {
1424 qdf_status = policy_mgr_restart_opportunistic_timer(
1425 psoc, false);
1426 if (QDF_IS_STATUS_SUCCESS(qdf_status))
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001427 policy_mgr_debug("opportunistic timer for MCC upgrade");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001428 goto done;
1429 }
1430
1431 /* For DBS, we want to move right away to DBS mode */
1432 status = policy_mgr_next_actions(psoc, session_id, action,
1433 POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH);
1434 if (!QDF_IS_STATUS_SUCCESS(status)) {
1435 policy_mgr_err("no set hw mode command was issued");
1436 goto done;
1437 }
1438done:
1439 /* success must be returned only when a set hw mode was done */
1440 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001441}
1442
1443void policy_mgr_checkn_update_hw_mode_single_mac_mode(
1444 struct wlan_objmgr_psoc *psoc, uint8_t channel)
1445{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001446 uint8_t i;
1447 struct policy_mgr_psoc_priv_obj *pm_ctx;
1448
1449 pm_ctx = policy_mgr_get_context(psoc);
1450 if (!pm_ctx) {
1451 policy_mgr_err("Invalid Context");
1452 return;
1453 }
1454
gaurank kathpaliaafa4e1b2018-07-05 15:04:46 +05301455 if (QDF_TIMER_STATE_RUNNING ==
1456 pm_ctx->dbs_opportunistic_timer.state)
1457 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
1458
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001459 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1460 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
1461 if (pm_conc_connection_list[i].in_use)
1462 if (!WLAN_REG_IS_SAME_BAND_CHANNELS(channel,
1463 pm_conc_connection_list[i].chan)) {
1464 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001465 policy_mgr_debug("DBS required");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001466 return;
1467 }
1468 }
1469 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001470 pm_dbs_opportunistic_timer_handler((void *)psoc);
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001471}
1472
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001473void policy_mgr_check_and_stop_opportunistic_timer(
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001474 struct wlan_objmgr_psoc *psoc, uint8_t id)
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001475{
1476 struct policy_mgr_psoc_priv_obj *pm_ctx;
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001477 enum policy_mgr_conc_next_action action = PM_NOP;
1478 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001479
1480 pm_ctx = policy_mgr_get_context(psoc);
1481 if (!pm_ctx) {
1482 policy_mgr_err("Invalid Context");
1483 return;
1484 }
1485 if (QDF_TIMER_STATE_RUNNING ==
1486 pm_ctx->dbs_opportunistic_timer.state) {
1487 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001488 action = policy_mgr_need_opportunistic_upgrade(psoc);
1489 if (action) {
Krunal Soni4943b902018-01-05 17:36:40 -08001490 qdf_event_reset(&pm_ctx->opportunistic_update_done_evt);
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001491 status = policy_mgr_next_actions(psoc, id, action,
1492 POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC);
1493 if (status != QDF_STATUS_SUCCESS) {
1494 policy_mgr_err("Failed in policy_mgr_next_actions");
1495 return;
1496 }
1497 status = qdf_wait_single_event(
1498 &pm_ctx->opportunistic_update_done_evt,
1499 CONNECTION_UPDATE_TIMEOUT);
1500
1501 if (!QDF_IS_STATUS_SUCCESS(status)) {
1502 policy_mgr_err("wait for event failed");
1503 return;
1504 }
1505 }
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001506 }
1507}
1508
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07001509void policy_mgr_set_hw_mode_change_in_progress(
1510 struct wlan_objmgr_psoc *psoc, enum policy_mgr_hw_mode_change value)
1511{
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001512 struct policy_mgr_psoc_priv_obj *pm_ctx;
1513
1514 pm_ctx = policy_mgr_get_context(psoc);
1515 if (!pm_ctx) {
1516 policy_mgr_err("Invalid Context");
1517 return;
1518 }
1519
1520 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1521 pm_ctx->hw_mode_change_in_progress = value;
1522 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1523
1524 policy_mgr_debug("hw_mode_change_in_progress:%d", value);
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07001525}
1526
1527enum policy_mgr_hw_mode_change policy_mgr_is_hw_mode_change_in_progress(
1528 struct wlan_objmgr_psoc *psoc)
1529{
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001530 enum policy_mgr_hw_mode_change value;
1531 struct policy_mgr_psoc_priv_obj *pm_ctx;
1532
1533 value = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
1534
1535 pm_ctx = policy_mgr_get_context(psoc);
1536 if (!pm_ctx) {
1537 policy_mgr_err("Invalid Context");
1538 return value;
1539 }
1540 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1541 value = pm_ctx->hw_mode_change_in_progress;
1542 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1543
1544 return value;
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07001545}
1546
1547enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index(
1548 struct wlan_objmgr_psoc *psoc, uint32_t hw_mode_index)
1549{
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001550 struct policy_mgr_psoc_priv_obj *pm_ctx;
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001551 struct policy_mgr_hw_mode_params hw_mode;
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001552 enum policy_mgr_hw_mode_change value
1553 = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001554 QDF_STATUS status;
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001555
1556 pm_ctx = policy_mgr_get_context(psoc);
1557 if (!pm_ctx) {
1558 policy_mgr_err("Invalid Context");
1559 return value;
1560 }
1561
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001562 status = policy_mgr_get_hw_mode_from_idx(psoc, hw_mode_index, &hw_mode);
1563 if (status != QDF_STATUS_SUCCESS) {
1564 policy_mgr_err("Failed to get HW mode index");
1565 return value;
1566 }
1567
1568 if (hw_mode.dbs_cap) {
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001569 policy_mgr_info("DBS is requested with HW (%d)",
1570 hw_mode_index);
1571 value = POLICY_MGR_DBS_IN_PROGRESS;
1572 goto ret_value;
1573 }
1574
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001575 if (hw_mode.sbs_cap) {
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001576 policy_mgr_info("SBS is requested with HW (%d)",
1577 hw_mode_index);
1578 value = POLICY_MGR_SBS_IN_PROGRESS;
1579 goto ret_value;
1580 }
1581
1582 value = POLICY_MGR_SMM_IN_PROGRESS;
1583 policy_mgr_info("SMM is requested with HW (%d)", hw_mode_index);
1584
1585ret_value:
1586 return value;
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07001587}
1588
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001589#ifdef MPC_UT_FRAMEWORK
1590QDF_STATUS policy_mgr_update_connection_info_utfw(
1591 struct wlan_objmgr_psoc *psoc,
1592 uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
1593 uint32_t chain_mask, uint32_t type, uint32_t sub_type,
1594 uint32_t channelid, uint32_t mac_id)
1595{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001596 QDF_STATUS status = QDF_STATUS_E_FAILURE;
1597 uint32_t conn_index = 0, found = 0;
1598 struct policy_mgr_psoc_priv_obj *pm_ctx;
1599
1600 pm_ctx = policy_mgr_get_context(psoc);
1601 if (!pm_ctx) {
1602 policy_mgr_err("Invalid Context");
1603 return status;
1604 }
1605
1606 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1607 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
1608 if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
1609 /* debug msg */
1610 found = 1;
1611 break;
1612 }
1613 conn_index++;
1614 }
1615 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1616 if (!found) {
1617 /* err msg */
1618 policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list",
1619 vdev_id);
1620 return status;
1621 }
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001622 policy_mgr_debug("--> updating entry at index[%d]", conn_index);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001623
1624 policy_mgr_update_conc_list(psoc, conn_index,
1625 policy_mgr_get_mode(type, sub_type),
1626 channelid, HW_MODE_20_MHZ,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05301627 mac_id, chain_mask, 0, vdev_id, true, true);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001628
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001629 return QDF_STATUS_SUCCESS;
1630}
1631
1632QDF_STATUS policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc,
1633 uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
1634 uint32_t chain_mask, uint32_t type, uint32_t sub_type,
1635 uint32_t channelid, uint32_t mac_id)
1636{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001637 QDF_STATUS status = QDF_STATUS_E_FAILURE;
1638 uint32_t conn_index = 0;
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05301639 bool update_conn = true;
1640 enum policy_mgr_con_mode mode;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001641
1642 conn_index = policy_mgr_get_connection_count(psoc);
1643 if (MAX_NUMBER_OF_CONC_CONNECTIONS <= conn_index) {
1644 /* err msg */
1645 policy_mgr_err("exceeded max connection limit %d",
1646 MAX_NUMBER_OF_CONC_CONNECTIONS);
1647 return status;
1648 }
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001649 policy_mgr_debug("--> filling entry at index[%d]", conn_index);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001650
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05301651 mode = policy_mgr_get_mode(type, sub_type);
1652 if (mode == PM_STA_MODE || mode == PM_P2P_CLIENT_MODE)
1653 update_conn = false;
1654
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001655 policy_mgr_update_conc_list(psoc, conn_index,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05301656 mode,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001657 channelid, HW_MODE_20_MHZ,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05301658 mac_id, chain_mask, 0, vdev_id, true,
1659 update_conn);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001660
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001661 return QDF_STATUS_SUCCESS;
1662}
1663
1664QDF_STATUS policy_mgr_decr_connection_count_utfw(struct wlan_objmgr_psoc *psoc,
1665 uint32_t del_all, uint32_t vdev_id)
1666{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001667 QDF_STATUS status;
1668
1669 if (del_all) {
1670 status = policy_mgr_psoc_enable(psoc);
1671 if (!QDF_IS_STATUS_SUCCESS(status)) {
1672 policy_mgr_err("Policy manager initialization failed");
1673 return QDF_STATUS_E_FAILURE;
1674 }
1675 } else {
1676 policy_mgr_decr_connection_count(psoc, vdev_id);
1677 }
1678
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001679 return QDF_STATUS_SUCCESS;
1680}
1681
1682enum policy_mgr_pcl_type policy_mgr_get_pcl_from_first_conn_table(
1683 enum policy_mgr_con_mode type,
1684 enum policy_mgr_conc_priority_mode sys_pref)
1685{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001686 if ((sys_pref >= PM_MAX_CONC_PRIORITY_MODE) ||
1687 (type >= PM_MAX_NUM_OF_MODE))
1688 return PM_MAX_PCL_TYPE;
1689 return first_connection_pcl_table[type][sys_pref];
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001690}
1691
1692enum policy_mgr_pcl_type policy_mgr_get_pcl_from_second_conn_table(
1693 enum policy_mgr_one_connection_mode idx, enum policy_mgr_con_mode type,
1694 enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable)
1695{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001696 if ((idx >= PM_MAX_ONE_CONNECTION_MODE) ||
1697 (sys_pref >= PM_MAX_CONC_PRIORITY_MODE) ||
1698 (type >= PM_MAX_NUM_OF_MODE))
1699 return PM_MAX_PCL_TYPE;
1700 if (dbs_capable)
1701 return (*second_connection_pcl_dbs_table)[idx][type][sys_pref];
1702 else
1703 return second_connection_pcl_nodbs_table[idx][type][sys_pref];
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001704}
1705
1706enum policy_mgr_pcl_type policy_mgr_get_pcl_from_third_conn_table(
1707 enum policy_mgr_two_connection_mode idx, enum policy_mgr_con_mode type,
1708 enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable)
1709{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001710 if ((idx >= PM_MAX_TWO_CONNECTION_MODE) ||
1711 (sys_pref >= PM_MAX_CONC_PRIORITY_MODE) ||
1712 (type >= PM_MAX_NUM_OF_MODE))
1713 return PM_MAX_PCL_TYPE;
1714 if (dbs_capable)
1715 return (*third_connection_pcl_dbs_table)[idx][type][sys_pref];
1716 else
1717 return third_connection_pcl_nodbs_table[idx][type][sys_pref];
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001718}
1719#endif