blob: 1bd5c4d1cecb3992465df09e339bcb8bea2320bf [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,
102 enum hw_mode_dbs_capab dbs,
103 enum hw_mode_agile_dfs_capab dfs,
104 enum hw_mode_sbs_capab sbs,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800105 enum policy_mgr_conn_update_reason reason,
106 uint8_t next_action)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800107{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800108 int8_t hw_mode_index;
109 struct policy_mgr_hw_mode msg;
110 QDF_STATUS status;
111 struct policy_mgr_psoc_priv_obj *pm_ctx;
112
113 pm_ctx = policy_mgr_get_context(psoc);
114 if (!pm_ctx) {
115 policy_mgr_err("Invalid context");
116 return QDF_STATUS_E_FAILURE;
117 }
118
119 /*
120 * if HW is not capable of doing 2x2 or ini config disabled 2x2, don't
121 * allow to request FW for 2x2
122 */
Tushnim Bhattacharyya68f709d2017-03-23 18:00:04 -0700123 if ((HW_MODE_SS_2x2 == mac0_ss) && (!pm_ctx->user_cfg.enable2x2)) {
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -0700124 policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac0");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800125 mac0_ss = HW_MODE_SS_1x1;
126 }
Tushnim Bhattacharyya68f709d2017-03-23 18:00:04 -0700127 if ((HW_MODE_SS_2x2 == mac1_ss) && (!pm_ctx->user_cfg.enable2x2)) {
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -0700128 policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac1");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800129 mac1_ss = HW_MODE_SS_1x1;
130 }
131
132 hw_mode_index = policy_mgr_get_hw_mode_idx_from_dbs_hw_list(psoc,
133 mac0_ss, mac0_bw, mac1_ss, mac1_bw, dbs, dfs, sbs);
134 if (hw_mode_index < 0) {
135 policy_mgr_err("Invalid HW mode index obtained");
136 return QDF_STATUS_E_FAILURE;
137 }
138
139 msg.hw_mode_index = hw_mode_index;
140 msg.set_hw_mode_cb = (void *)policy_mgr_pdev_set_hw_mode_cb;
141 msg.reason = reason;
142 msg.session_id = session_id;
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800143 msg.next_action = next_action;
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -0700144 msg.context = psoc;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800145
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -0700146 policy_mgr_debug("set hw mode to sme: hw_mode_index: %d session:%d reason:%d",
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800147 msg.hw_mode_index, msg.session_id, msg.reason);
148
149 status = pm_ctx->sme_cbacks.sme_pdev_set_hw_mode(msg);
150 if (status != QDF_STATUS_SUCCESS) {
151 policy_mgr_err("Failed to set hw mode to SME");
152 return status;
153 }
154
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800155 return QDF_STATUS_SUCCESS;
156}
157
158enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade(
159 struct wlan_objmgr_psoc *psoc)
160{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800161 uint32_t conn_index;
162 enum policy_mgr_conc_next_action upgrade = PM_NOP;
163 uint8_t mac = 0;
164 struct policy_mgr_hw_mode_params hw_mode;
165 QDF_STATUS status = QDF_STATUS_E_FAILURE;
166 struct policy_mgr_psoc_priv_obj *pm_ctx;
167
168 pm_ctx = policy_mgr_get_context(psoc);
169 if (!pm_ctx) {
170 policy_mgr_err("Invalid Context");
171 goto done;
172 }
173
174 if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
175 policy_mgr_err("driver isn't dbs capable, no further action needed");
176 goto done;
177 }
178
179 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
180 if (!QDF_IS_STATUS_SUCCESS(status)) {
181 policy_mgr_err("policy_mgr_get_current_hw_mode failed");
182 goto done;
183 }
184 if (!hw_mode.dbs_cap) {
185 policy_mgr_notice("current HW mode is non-DBS capable");
186 goto done;
187 }
188
189 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
190 /* Are both mac's still in use */
191 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
192 conn_index++) {
193 policy_mgr_debug("index:%d mac:%d in_use:%d chan:%d org_nss:%d",
194 conn_index,
195 pm_conc_connection_list[conn_index].mac,
196 pm_conc_connection_list[conn_index].in_use,
197 pm_conc_connection_list[conn_index].chan,
198 pm_conc_connection_list[conn_index].original_nss);
199 if ((pm_conc_connection_list[conn_index].mac == 0) &&
200 pm_conc_connection_list[conn_index].in_use) {
201 mac |= POLICY_MGR_MAC0;
202 if (POLICY_MGR_MAC0_AND_MAC1 == mac) {
203 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
204 goto done;
205 }
206 } else if ((pm_conc_connection_list[conn_index].mac == 1) &&
207 pm_conc_connection_list[conn_index].in_use) {
208 mac |= POLICY_MGR_MAC1;
Archana Ramachandran944f1fd2017-06-02 16:48:17 -0700209 if (policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
210 WLAN_REG_IS_24GHZ_CH(
211 pm_conc_connection_list[conn_index].chan)
212 ) {
213 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
214 policy_mgr_debug("2X2 DBS capable with 2.4 GHZ connection");
215 goto done;
216 }
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800217 if (POLICY_MGR_MAC0_AND_MAC1 == mac) {
218 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
219 goto done;
220 }
221 }
222 }
223 /* Let's request for single MAC mode */
224 upgrade = PM_SINGLE_MAC;
225 /* Is there any connection had an initial connection with 2x2 */
226 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
227 conn_index++) {
228 if ((pm_conc_connection_list[conn_index].original_nss == 2) &&
229 pm_conc_connection_list[conn_index].in_use) {
230 upgrade = PM_SINGLE_MAC_UPGRADE;
231 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
232 goto done;
233 }
234 }
235 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
236
237done:
238 return upgrade;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800239}
240
241QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc,
242 uint32_t vdev_id)
243{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800244 QDF_STATUS status = QDF_STATUS_E_FAILURE;
245 uint32_t conn_index = 0;
246 bool found = false;
247 struct policy_mgr_vdev_entry_info conn_table_entry;
248 enum policy_mgr_chain_mode chain_mask = POLICY_MGR_ONE_ONE;
249 uint8_t nss_2g, nss_5g;
250 enum policy_mgr_con_mode mode;
251 uint8_t chan;
252 uint32_t nss = 0;
253 struct policy_mgr_psoc_priv_obj *pm_ctx;
254
255 pm_ctx = policy_mgr_get_context(psoc);
256 if (!pm_ctx) {
257 policy_mgr_err("Invalid Context");
258 return status;
259 }
260
261 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
262 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
263 if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
264 /* debug msg */
265 found = true;
266 break;
267 }
268 conn_index++;
269 }
270 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
271 if (!found) {
272 /* err msg */
273 policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list",
274 vdev_id);
275 return status;
276 }
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700277 if (pm_ctx->wma_cbacks.wma_get_connection_info) {
278 status = pm_ctx->wma_cbacks.wma_get_connection_info(
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800279 vdev_id, &conn_table_entry);
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700280 if (QDF_STATUS_SUCCESS != status) {
281 policy_mgr_err("can't find vdev_id %d in connection table",
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800282 vdev_id);
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700283 return status;
284 }
285 } else {
286 policy_mgr_err("wma_get_connection_info is NULL");
287 return QDF_STATUS_E_FAILURE;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800288 }
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700289
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800290 mode = policy_mgr_get_mode(conn_table_entry.type,
291 conn_table_entry.sub_type);
Tushnim Bhattacharyyace237d62017-04-05 12:52:36 -0700292 chan = wlan_reg_freq_to_chan(pm_ctx->pdev, conn_table_entry.mhz);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800293 status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g);
294 if (QDF_IS_STATUS_SUCCESS(status)) {
295 if ((WLAN_REG_IS_24GHZ_CH(chan) && (nss_2g > 1)) ||
296 (WLAN_REG_IS_5GHZ_CH(chan) && (nss_5g > 1)))
297 chain_mask = POLICY_MGR_TWO_TWO;
298 else
299 chain_mask = POLICY_MGR_ONE_ONE;
300 nss = (WLAN_REG_IS_24GHZ_CH(chan)) ? nss_2g : nss_5g;
301 } else {
302 policy_mgr_err("Error in getting nss");
303 }
304
305 policy_mgr_debug("update PM connection table for vdev:%d", vdev_id);
306
307 /* add the entry */
308 policy_mgr_update_conc_list(psoc, conn_index,
309 mode,
310 chan,
311 policy_mgr_get_bw(conn_table_entry.chan_width),
312 conn_table_entry.mac_id,
313 chain_mask,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +0530314 nss, vdev_id, true, true);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800315
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800316 return QDF_STATUS_SUCCESS;
317}
318
319QDF_STATUS policy_mgr_update_and_wait_for_connection_update(
320 struct wlan_objmgr_psoc *psoc,
321 uint8_t session_id,
322 uint8_t channel,
323 enum policy_mgr_conn_update_reason reason)
324{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800325 QDF_STATUS status;
326
327 policy_mgr_debug("session:%d channel:%d reason:%d",
328 session_id, channel, reason);
329
330 status = policy_mgr_reset_connection_update(psoc);
331 if (QDF_IS_STATUS_ERROR(status))
332 policy_mgr_err("clearing event failed");
333
334 status = policy_mgr_current_connections_update(psoc,
335 session_id, channel, reason);
336 if (QDF_STATUS_E_FAILURE == status) {
337 policy_mgr_err("connections update failed");
338 return QDF_STATUS_E_FAILURE;
339 }
340
341 /* Wait only when status is success */
342 if (QDF_IS_STATUS_SUCCESS(status)) {
343 status = policy_mgr_wait_for_connection_update(psoc);
344 if (QDF_IS_STATUS_ERROR(status)) {
345 policy_mgr_err("qdf wait for event failed");
346 return QDF_STATUS_E_FAILURE;
347 }
348 }
349
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800350 return QDF_STATUS_SUCCESS;
351}
352
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530353/**
354 * policy_mgr_is_dbs_allowed_for_concurrency() - If dbs is allowed for current
355 * concurreny
356 * @new_conn_mode: new connection mode
357 *
358 * When a new connection is about to come up, check if dbs is allowed for
359 * STA+STA or STA+P2P
360 *
361 * Return: true if dbs is allowed for STA+STA or STA+P2P else false
362 */
Bala Venkatesh28477d32018-05-07 21:35:55 +0530363bool policy_mgr_is_dbs_allowed_for_concurrency(
364 struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE new_conn_mode)
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530365{
366 struct policy_mgr_psoc_priv_obj *pm_ctx;
367 uint32_t count, dbs_for_sta_sta, dbs_for_sta_p2p;
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530368 bool ret = true;
369
370 pm_ctx = policy_mgr_get_context(psoc);
371 if (!pm_ctx) {
372 policy_mgr_err("Invalid context");
373 return ret;
374 }
375
376 count = policy_mgr_get_connection_count(psoc);
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530377
378 if (count != 1 || new_conn_mode == QDF_MAX_NO_OF_MODE)
379 return ret;
380
381 dbs_for_sta_sta = PM_CHANNEL_SELECT_LOGIC_STA_STA_GET(pm_ctx->user_cfg.
382 channel_select_logic_conc);
383 dbs_for_sta_p2p = PM_CHANNEL_SELECT_LOGIC_STA_P2P_GET(pm_ctx->user_cfg.
384 channel_select_logic_conc);
385
386 switch (pm_conc_connection_list[0].mode) {
387 case PM_STA_MODE:
388 switch (new_conn_mode) {
389 case QDF_STA_MODE:
390 if (!dbs_for_sta_sta)
391 return false;
392 break;
393 case QDF_P2P_DEVICE_MODE:
394 case QDF_P2P_CLIENT_MODE:
395 case QDF_P2P_GO_MODE:
396 if (!dbs_for_sta_p2p)
397 return false;
398 break;
399 default:
400 break;
401 }
402 break;
403 case PM_P2P_CLIENT_MODE:
404 case PM_P2P_GO_MODE:
405 switch (new_conn_mode) {
406 case QDF_STA_MODE:
407 if (!dbs_for_sta_p2p)
408 return false;
409 break;
410 default:
411 break;
412 }
413 break;
414 default:
415 break;
416 }
417
418 return ret;
419}
420
Krunal Soni637eba52018-06-14 17:55:15 -0700421static bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc,
422 uint8_t channel)
423{
424 uint8_t i, pm_chnl;
425 struct policy_mgr_psoc_priv_obj *pm_ctx;
426
427 pm_ctx = policy_mgr_get_context(psoc);
428 if (!pm_ctx) {
429 policy_mgr_err("Invalid Context");
430 return false;
431 }
432
433 /*
434 * check given channel against already existing connections'
435 * channels. if they differ then channels are in different bands
436 */
437 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
438 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
439 pm_chnl = pm_conc_connection_list[i].chan;
440 if (pm_conc_connection_list[i].in_use)
441 if (!WLAN_REG_IS_SAME_BAND_CHANNELS(channel, pm_chnl)) {
442 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
443 policy_mgr_debug("channel is in diff band");
444 return true;
445 }
446 }
447 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
448
449 return false;
450}
451
452bool policy_mgr_is_hwmode_set_for_given_chnl(struct wlan_objmgr_psoc *psoc,
453 uint8_t channel)
454{
455 enum policy_mgr_band band;
456 bool is_hwmode_dbs, is_2x2_dbs;
457
458 if (policy_mgr_is_hw_dbs_capable(psoc) == false)
459 return true;
460
461 if (WLAN_REG_IS_24GHZ_CH(channel))
462 band = POLICY_MGR_BAND_24;
463 else
464 band = POLICY_MGR_BAND_5;
465
466 is_hwmode_dbs = policy_mgr_is_current_hwmode_dbs(psoc);
467 is_2x2_dbs = policy_mgr_is_hw_dbs_2x2_capable(psoc);
468 /*
469 * If HW supports 2x2 chains in DBS HW mode and if DBS HW mode is not
470 * yet set then this is the right time to block the connection.
471 */
472 if ((band == POLICY_MGR_BAND_24) && is_2x2_dbs && !is_hwmode_dbs) {
473 policy_mgr_err("HW mode is not yet in DBS!!!!!");
474 return false;
475 }
476
477 /*
478 * If HW supports 1x1 chains DBS HW mode and if first connection is
479 * 2G or 5G band and if second connection is coming up in diffrent
480 * band than the first connection and if current HW mode is not yet
481 * set in DBS then this is the right time to block the connection.
482 */
483 if (policy_mgr_is_chnl_in_diff_band(psoc, channel) && !is_hwmode_dbs) {
484 policy_mgr_err("Given channel & existing conn is diff band & HW mode is not yet in DBS !!!!");
485 return false;
486 }
487
488 return true;
489}
490
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800491QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc,
492 uint32_t session_id,
493 uint8_t channel,
494 enum policy_mgr_conn_update_reason reason)
495{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800496 enum policy_mgr_conc_next_action next_action = PM_NOP;
497 uint32_t num_connections = 0;
498 enum policy_mgr_one_connection_mode second_index = 0;
499 enum policy_mgr_two_connection_mode third_index = 0;
500 enum policy_mgr_band band;
501 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Bala Venkatesh28477d32018-05-07 21:35:55 +0530502 struct policy_mgr_psoc_priv_obj *pm_ctx;
503 enum QDF_OPMODE new_conn_mode = QDF_MAX_NO_OF_MODE;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800504
505 if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
506 policy_mgr_err("driver isn't dbs capable, no further action needed");
507 return QDF_STATUS_E_NOSUPPORT;
508 }
509 if (WLAN_REG_IS_24GHZ_CH(channel))
510 band = POLICY_MGR_BAND_24;
511 else
512 band = POLICY_MGR_BAND_5;
513
514 num_connections = policy_mgr_get_connection_count(psoc);
515
516 policy_mgr_debug("num_connections=%d channel=%d",
517 num_connections, channel);
518
519 switch (num_connections) {
520 case 0:
521 if (band == POLICY_MGR_BAND_24)
522 if (policy_mgr_is_hw_dbs_2x2_capable(psoc))
523 next_action = PM_DBS;
524 else
525 next_action = PM_NOP;
526 else
527 next_action = PM_NOP;
528 break;
529 case 1:
530 second_index =
531 policy_mgr_get_second_connection_pcl_table_index(psoc);
532 if (PM_MAX_ONE_CONNECTION_MODE == second_index) {
533 policy_mgr_err(
534 "couldn't find index for 2nd connection next action table");
535 goto done;
536 }
537 next_action =
538 (*next_action_two_connection_table)[second_index][band];
539 break;
540 case 2:
541 third_index =
542 policy_mgr_get_third_connection_pcl_table_index(psoc);
543 if (PM_MAX_TWO_CONNECTION_MODE == third_index) {
544 policy_mgr_err(
545 "couldn't find index for 3rd connection next action table");
546 goto done;
547 }
548 next_action = (*next_action_three_connection_table)
549 [third_index][band];
550 break;
551 default:
552 policy_mgr_err("unexpected num_connections value %d",
553 num_connections);
554 break;
555 }
556
Bala Venkatesh28477d32018-05-07 21:35:55 +0530557 pm_ctx = policy_mgr_get_context(psoc);
558 if (!pm_ctx) {
559 policy_mgr_err("Invalid context");
560 goto done;
561 }
562
563 if (pm_ctx->hdd_cbacks.hdd_get_device_mode)
564 new_conn_mode = pm_ctx->hdd_cbacks.
565 hdd_get_device_mode(session_id);
566
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530567 /*
568 * Based on channel_select_logic_conc ini, hw mode is set
569 * when second connection is about to come up that results
570 * in STA+STA and STA+P2P concurrency.
571 * 1) If MCC is set and if current hw mode is dbs, hw mode
572 * should be set to single mac for above concurrency.
573 * 2) If MCC is set and if current hw mode is not dbs, hw
574 * mode change is not required.
575 */
576 if (policy_mgr_is_current_hwmode_dbs(psoc) &&
Bala Venkatesh28477d32018-05-07 21:35:55 +0530577 !policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode))
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530578 next_action = PM_SINGLE_MAC;
579 else if (!policy_mgr_is_current_hwmode_dbs(psoc) &&
Bala Venkatesh28477d32018-05-07 21:35:55 +0530580 !policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode))
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530581 next_action = PM_NOP;
582
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800583 if (PM_NOP != next_action)
584 status = policy_mgr_next_actions(psoc, session_id,
585 next_action, reason);
586 else
587 status = QDF_STATUS_E_NOSUPPORT;
588
589 policy_mgr_debug(
590 "idx2=%d idx3=%d next_action=%d, band=%d status=%d reason=%d session_id=%d",
591 second_index, third_index, next_action, band, status,
592 reason, session_id);
593
594done:
595 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800596}
597
598QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc,
599 uint32_t session_id,
600 enum policy_mgr_conc_next_action action,
601 enum policy_mgr_conn_update_reason reason)
602{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800603 QDF_STATUS status = QDF_STATUS_E_FAILURE;
604 struct policy_mgr_hw_mode_params hw_mode;
Varun Reddy Yeturue23b6bc2018-01-08 13:18:41 -0800605 struct dbs_nss nss_dbs = {0};
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800606
607 if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
608 policy_mgr_err("driver isn't dbs capable, no further action needed");
609 return QDF_STATUS_E_NOSUPPORT;
610 }
611
612 /* check for the current HW index to see if really need any action */
613 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
614 if (!QDF_IS_STATUS_SUCCESS(status)) {
615 policy_mgr_err("policy_mgr_get_current_hw_mode failed");
616 return status;
617 }
618 /**
619 * if already in DBS no need to request DBS. Might be needed
620 * to extend the logic when multiple dbs HW mode is available
621 */
622 if ((((PM_DBS_DOWNGRADE == action) || (PM_DBS == action) ||
623 (PM_DBS_UPGRADE == action))
624 && hw_mode.dbs_cap)) {
625 policy_mgr_err("driver is already in %s mode, no further action needed",
626 (hw_mode.dbs_cap) ? "dbs" : "non dbs");
627 return QDF_STATUS_E_ALREADY;
628 }
629
630 if ((PM_SBS == action) || (action == PM_SBS_DOWNGRADE)) {
631 if (!policy_mgr_is_hw_sbs_capable(psoc)) {
632 /* No action */
633 policy_mgr_notice("firmware is not sbs capable");
Tushnim Bhattacharyyafe511702017-04-24 15:21:59 -0700634 return QDF_STATUS_E_NOSUPPORT;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800635 }
636 /* check if current mode is already SBS nothing to be
637 * done
638 */
639
640 }
641
642 switch (action) {
643 case PM_DBS_DOWNGRADE:
644 /*
645 * check if we have a beaconing entity that is using 2x2. If yes,
646 * update the beacon template & notify FW. Once FW confirms
647 * beacon updated, send down the HW mode change req
648 */
649 status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
650 PM_DBS, reason, session_id);
651 break;
652 case PM_DBS:
Vikrampal31eb12c2017-04-28 17:44:30 +0530653 (void)policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs);
654
655 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
656 nss_dbs.mac0_ss,
657 HW_MODE_80_MHZ,
658 nss_dbs.mac1_ss,
659 HW_MODE_40_MHZ,
660 HW_MODE_DBS,
661 HW_MODE_AGILE_DFS_NONE,
662 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800663 reason, PM_NOP);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800664 break;
665 case PM_SINGLE_MAC_UPGRADE:
666 /*
667 * change the HW mode first before the NSS upgrade
668 */
669 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
670 HW_MODE_SS_2x2,
671 HW_MODE_80_MHZ,
672 HW_MODE_SS_0x0, HW_MODE_BW_NONE,
673 HW_MODE_DBS_NONE,
674 HW_MODE_AGILE_DFS_NONE,
675 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800676 reason, PM_UPGRADE);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800677 break;
678 case PM_SINGLE_MAC:
679 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
680 HW_MODE_SS_2x2,
681 HW_MODE_80_MHZ,
682 HW_MODE_SS_0x0, HW_MODE_BW_NONE,
683 HW_MODE_DBS_NONE,
684 HW_MODE_AGILE_DFS_NONE,
685 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800686 reason, PM_NOP);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800687 break;
688 case PM_DBS_UPGRADE:
689 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
690 HW_MODE_SS_2x2,
691 HW_MODE_80_MHZ,
692 HW_MODE_SS_2x2, HW_MODE_80_MHZ,
693 HW_MODE_DBS,
694 HW_MODE_AGILE_DFS_NONE,
695 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800696 reason, PM_UPGRADE);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800697 break;
698 case PM_SBS_DOWNGRADE:
699 status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
700 PM_SBS, reason, session_id);
701 break;
702 case PM_SBS:
703 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
704 HW_MODE_SS_1x1,
705 HW_MODE_80_MHZ,
706 HW_MODE_SS_1x1, HW_MODE_80_MHZ,
707 HW_MODE_DBS,
708 HW_MODE_AGILE_DFS_NONE,
709 HW_MODE_SBS,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800710 reason, PM_NOP);
711 break;
712 case PM_DOWNGRADE:
713 /*
714 * check if we have a beaconing entity that advertised 2x2
715 * intially. If yes, update the beacon template & notify FW.
716 */
717 status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_1,
718 PM_NOP, reason);
719 break;
720 case PM_UPGRADE:
721 /*
722 * check if we have a beaconing entity that advertised 2x2
723 * intially. If yes, update the beacon template & notify FW.
724 */
725 status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_2,
726 PM_NOP, reason);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800727 break;
728 default:
729 policy_mgr_err("unexpected action value %d", action);
730 status = QDF_STATUS_E_FAILURE;
731 break;
732 }
733
734 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800735}
736
737QDF_STATUS policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc,
738 uint8_t session_id, uint8_t channel)
739{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800740 QDF_STATUS status;
741
742 if (!policy_mgr_check_for_session_conc(psoc, session_id, channel)) {
743 policy_mgr_err("Conc not allowed for the session %d",
744 session_id);
745 return QDF_STATUS_E_FAILURE;
746 }
747
748 status = policy_mgr_reset_connection_update(psoc);
749 if (!QDF_IS_STATUS_SUCCESS(status))
750 policy_mgr_err("clearing event failed");
751
752 status = policy_mgr_current_connections_update(psoc, session_id,
753 channel,
754 POLICY_MGR_UPDATE_REASON_NORMAL_STA);
755 if (QDF_STATUS_E_FAILURE == status) {
756 policy_mgr_err("connections update failed");
757 return status;
758 }
759
760 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800761}
762
763#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +0530764void policy_mgr_update_user_config_sap_chan(
765 struct wlan_objmgr_psoc *psoc, uint32_t channel)
766{
767 struct policy_mgr_psoc_priv_obj *pm_ctx;
768
769 pm_ctx = policy_mgr_get_context(psoc);
770 if (!pm_ctx) {
771 policy_mgr_err("Invalid pm context and failed to update the user config sap channel");
772 return;
773 }
774 pm_ctx->user_config_sap_channel = channel;
775}
776
Archana Ramachandran544ce172017-03-14 15:12:09 -0700777/**
778 * policy_mgr_is_restart_sap_allowed() - Check if restart SAP
779 * allowed during SCC -> MCC switch
780 * @psoc: PSOC object data
781 * @mcc_to_scc_switch: MCC to SCC switch enabled user config
782 *
783 * Check if restart SAP allowed during SCC->MCC switch
784 *
785 * Restart: true or false
786 */
787static bool policy_mgr_is_restart_sap_allowed(
788 struct wlan_objmgr_psoc *psoc,
789 uint32_t mcc_to_scc_switch)
790{
Rachit Kankanea07e4b92017-09-15 19:38:49 +0530791 uint32_t sta_ap_bit_mask = QDF_STA_MASK | QDF_SAP_MASK;
792 uint32_t sta_go_bit_mask = QDF_STA_MASK | QDF_P2P_GO_MASK;
793
Archana Ramachandran544ce172017-03-14 15:12:09 -0700794 if ((mcc_to_scc_switch == QDF_MCC_TO_SCC_SWITCH_DISABLE) ||
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -0700795 !policy_mgr_concurrent_open_sessions_running(psoc) ||
Rachit Kankanea07e4b92017-09-15 19:38:49 +0530796 !(((policy_mgr_get_concurrency_mode(psoc) & sta_ap_bit_mask)
797 == sta_ap_bit_mask) ||
Tushnim Bhattacharyyab7f83962018-06-14 17:56:38 -0700798 ((mcc_to_scc_switch ==
799 QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) &&
Rachit Kankanea07e4b92017-09-15 19:38:49 +0530800 ((policy_mgr_get_concurrency_mode(psoc) & sta_go_bit_mask)
Tushnim Bhattacharyyab7f83962018-06-14 17:56:38 -0700801 == sta_go_bit_mask)))) {
Abhinav Kumar77cb42a2018-06-15 16:46:30 +0530802 policy_mgr_debug("MCC switch disabled or not concurrent STA/SAP, STA/GO");
Archana Ramachandran544ce172017-03-14 15:12:09 -0700803 return false;
804 }
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -0700805
Archana Ramachandran544ce172017-03-14 15:12:09 -0700806 return true;
807}
808
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -0700809bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc,
810 uint8_t channel)
811{
812 struct policy_mgr_psoc_priv_obj *pm_ctx;
813 bool is_safe = true;
814 uint8_t j;
815
816 pm_ctx = policy_mgr_get_context(psoc);
817 if (!pm_ctx) {
818 policy_mgr_err("Invalid context");
819 return is_safe;
820 }
821
822
823 if (pm_ctx->unsafe_channel_count == 0) {
824 policy_mgr_debug("There are no unsafe channels");
825 return is_safe;
826 }
827
828 for (j = 0; j < pm_ctx->unsafe_channel_count; j++) {
829 if (channel == pm_ctx->unsafe_channel_list[j]) {
830 is_safe = false;
831 policy_mgr_warn("CH %d is not safe", channel);
832 break;
833 }
834 }
835
836 return is_safe;
837}
838
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +0530839bool policy_mgr_is_sap_restart_required_after_sta_disconnect(
840 struct wlan_objmgr_psoc *psoc, uint8_t *intf_ch)
841{
842 struct policy_mgr_psoc_priv_obj *pm_ctx;
843 uint8_t sap_chan = policy_mgr_mode_specific_get_channel(psoc,
844 PM_SAP_MODE);
845 bool sta_sap_scc_on_dfs_chan =
846 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
847
848 *intf_ch = 0;
849
850 pm_ctx = policy_mgr_get_context(psoc);
851 if (!pm_ctx) {
852 policy_mgr_err("Invalid pm context");
853 return false;
854 }
855
856 policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sap_chan %u",
857 sta_sap_scc_on_dfs_chan, sap_chan);
858
Jianmin Zhu7f6bdd32018-06-29 10:39:30 +0800859 if ((!sta_sap_scc_on_dfs_chan ||
860 !(sap_chan && WLAN_REG_IS_5GHZ_CH(sap_chan) &&
861 (wlan_reg_get_channel_state(pm_ctx->pdev, sap_chan) ==
862 CHANNEL_STATE_DFS))) &&
863 (!policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) ||
864 policy_mgr_is_safe_channel(psoc, sap_chan))) {
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +0530865 return false;
866 }
867
868 *intf_ch = pm_ctx->user_config_sap_channel;
869 policy_mgr_debug("Standalone SAP is not allowed on DFS channel, Move it to channel %u",
870 *intf_ch);
871
872 return true;
873}
874
Archana Ramachandran544ce172017-03-14 15:12:09 -0700875/**
Archana Ramachandran544ce172017-03-14 15:12:09 -0700876 * policy_mgr_check_sta_ap_concurrent_ch_intf() - Restart SAP in STA-AP case
877 * @data: Pointer check concurrent channel work data
878 *
879 * Restarts the SAP interface in STA-AP concurrency scenario
880 *
881 * Restart: None
882 */
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800883void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data)
884{
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -0700885 struct wlan_objmgr_psoc *psoc;
886 struct policy_mgr_psoc_priv_obj *pm_ctx = NULL;
887 struct sta_ap_intf_check_work_ctx *work_info = NULL;
Rachit Kankanea07e4b92017-09-15 19:38:49 +0530888 uint32_t mcc_to_scc_switch, cc_count = 0, i;
Archana Ramachandran544ce172017-03-14 15:12:09 -0700889 QDF_STATUS status;
890 uint8_t channel, sec_ch;
Rachit Kankanea07e4b92017-09-15 19:38:49 +0530891 uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS];
892 uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS];
Archana Ramachandran544ce172017-03-14 15:12:09 -0700893
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -0700894 work_info = (struct sta_ap_intf_check_work_ctx *) data;
895 if (!work_info) {
896 policy_mgr_err("Invalid work_info");
897 goto end;
898 }
899
900 psoc = work_info->psoc;
901 if (!psoc) {
902 policy_mgr_err("Invalid psoc");
903 goto end;
904 }
905
Archana Ramachandran544ce172017-03-14 15:12:09 -0700906 pm_ctx = policy_mgr_get_context(psoc);
907 if (!pm_ctx) {
908 policy_mgr_err("Invalid context");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -0700909 goto end;
Archana Ramachandran544ce172017-03-14 15:12:09 -0700910 }
911 mcc_to_scc_switch =
912 policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc);
913
914 policy_mgr_info("Concurrent open sessions running: %d",
915 policy_mgr_concurrent_open_sessions_running(psoc));
916
917 if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch))
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -0700918 goto end;
Archana Ramachandran6199b642017-03-20 13:31:36 -0700919
Rachit Kankanea07e4b92017-09-15 19:38:49 +0530920 cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
921 &operating_channel[cc_count],
922 &vdev_id[cc_count],
923 PM_SAP_MODE);
924 policy_mgr_debug("Number of concurrent SAP: %d", cc_count);
925 cc_count = cc_count + policy_mgr_get_mode_specific_conn_info(psoc,
926 &operating_channel[cc_count],
927 &vdev_id[cc_count],
928 PM_P2P_GO_MODE);
929 policy_mgr_debug("Number of beaconing entities (SAP + GO):%d",
930 cc_count);
931 if (!cc_count) {
Ajit Pal Singhc1246b12017-06-16 11:36:12 +0530932 policy_mgr_err("Could not retrieve SAP/GO operating channel&vdevid");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -0700933 goto end;
Archana Ramachandran6199b642017-03-20 13:31:36 -0700934 }
935
Bala Venkatesh378064b2018-06-11 15:06:53 +0530936 policy_mgr_debug("wait if channel switch is already in progress");
937 status = qdf_wait_single_event(
938 &pm_ctx->channel_switch_complete_evt,
939 CHANNEL_SWITCH_COMPLETE_TIMEOUT);
940
941 if (!QDF_IS_STATUS_SUCCESS(status)) {
942 policy_mgr_err("wait for event failed, still continue with channel switch");
943 }
Archana Ramachandran631fd9f2017-03-19 18:51:30 -0700944 if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) {
945 policy_mgr_err("SAP restart get channel callback in NULL");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -0700946 goto end;
Archana Ramachandran631fd9f2017-03-19 18:51:30 -0700947 }
Rachit Kankanea07e4b92017-09-15 19:38:49 +0530948 for (i = 0; i < cc_count; i++) {
949 status = pm_ctx->hdd_cbacks.
950 wlan_hdd_get_channel_for_sap_restart(psoc,
951 vdev_id[i], &channel, &sec_ch);
952 if (status == QDF_STATUS_SUCCESS) {
953 policy_mgr_info("SAP restarts due to MCC->SCC switch, old chan :%d new chan: %d"
954 , operating_channel[i], channel);
955 break;
956 }
Archana Ramachandran544ce172017-03-14 15:12:09 -0700957 }
Rachit Kankanea07e4b92017-09-15 19:38:49 +0530958 if (status != QDF_STATUS_SUCCESS)
959 policy_mgr_err("Failed to switch SAP channel");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -0700960end:
961 if (work_info) {
962 qdf_mem_free(work_info);
963 if (pm_ctx)
964 pm_ctx->sta_ap_intf_check_work_info = NULL;
965 }
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800966}
967
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -0700968static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc,
969 uint8_t sta_channel)
970{
971 struct policy_mgr_psoc_priv_obj *pm_ctx;
972
973 pm_ctx = policy_mgr_get_context(psoc);
974 if (!pm_ctx) {
975 policy_mgr_err("Invalid context");
976 return false;
977 }
978
Ganesh Kondabattini8a611c62017-11-21 15:01:31 +0530979 if ((wlan_reg_is_dfs_ch(pm_ctx->pdev, sta_channel) &&
980 (!policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc))) ||
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -0700981 wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev, sta_channel) ||
Ganesh Kondabattini8a611c62017-11-21 15:01:31 +0530982 !policy_mgr_is_safe_channel(psoc, sta_channel)) {
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -0700983 if (policy_mgr_is_hw_dbs_capable(psoc))
984 return true;
985 else
986 return false;
Ganesh Kondabattini8a611c62017-11-21 15:01:31 +0530987 }
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -0700988 else
989 return true;
990}
991
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -0700992QDF_STATUS policy_mgr_valid_sap_conc_channel_check(
993 struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch)
994{
995 uint8_t channel = *con_ch;
996 uint8_t temp_channel = 0;
997 struct policy_mgr_psoc_priv_obj *pm_ctx;
Bala Venkatesh7c96e542018-06-07 19:32:27 +0530998 bool sta_sap_scc_on_dfs_chan;
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -0700999
1000 pm_ctx = policy_mgr_get_context(psoc);
1001 if (!pm_ctx) {
1002 policy_mgr_err("Invalid context");
1003 return QDF_STATUS_E_FAILURE;
1004 }
1005
1006 /*
1007 * if force SCC is set, Check if conc channel is DFS
1008 * or passive or part of LTE avoided channel list.
1009 * In that case move SAP to other band if DBS is supported,
1010 * return otherwise
1011 */
1012 if (!policy_mgr_is_force_scc(psoc))
1013 return QDF_STATUS_SUCCESS;
1014
1015 /*
1016 * if interference is 0, check if it is DBS case. If DBS case
1017 * return from here. If SCC, check further if SAP can move to
1018 * STA's channel.
1019 */
1020 if (!channel &&
1021 (sap_ch != policy_mgr_mode_specific_get_channel(
1022 psoc, PM_STA_MODE)))
1023 return QDF_STATUS_SUCCESS;
1024 else if (!channel)
1025 channel = sap_ch;
1026
Bala Venkatesh7c96e542018-06-07 19:32:27 +05301027 sta_sap_scc_on_dfs_chan =
1028 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
1029
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001030 if (policy_mgr_valid_sta_channel_check(psoc, channel)) {
1031 if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) ||
Zhu Jianmin5ac66ef2018-06-11 19:03:39 +08001032 wlan_reg_is_passive_or_disable_ch(
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001033 pm_ctx->pdev, channel) ||
Zhu Jianmin5ac66ef2018-06-11 19:03:39 +08001034 !(policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) ||
1035 policy_mgr_is_safe_channel(psoc, channel))) {
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001036 if (policy_mgr_is_hw_dbs_capable(psoc)) {
1037 temp_channel =
1038 policy_mgr_get_alternate_channel_for_sap(psoc);
1039 policy_mgr_debug("temp_channel is %d",
1040 temp_channel);
1041 if (temp_channel) {
1042 channel = temp_channel;
1043 } else {
1044 if (WLAN_REG_IS_5GHZ_CH(channel))
1045 channel = PM_24_GHZ_CHANNEL_6;
1046 else
1047 channel = PM_5_GHZ_CHANNEL_36;
1048 }
1049 if (!policy_mgr_is_safe_channel(
1050 psoc, channel)) {
1051 policy_mgr_warn(
1052 "Can't have concurrency on %d as it is not safe",
1053 channel);
1054 return QDF_STATUS_E_FAILURE;
1055 }
1056 } else {
Bala Venkatesh7c96e542018-06-07 19:32:27 +05301057 if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) &&
1058 sta_sap_scc_on_dfs_chan) {
1059 policy_mgr_debug("STA SAP SCC is allowed on DFS channel");
1060 goto update_chan;
1061 }
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001062 policy_mgr_warn("Can't have concurrency on %d",
1063 channel);
1064 return QDF_STATUS_E_FAILURE;
1065 }
1066 }
1067 }
1068
Bala Venkatesh7c96e542018-06-07 19:32:27 +05301069update_chan:
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001070 if (channel != sap_ch)
1071 *con_ch = channel;
1072
1073 return QDF_STATUS_SUCCESS;
1074}
1075
Archana Ramachandran107d3782017-03-06 17:07:44 -08001076/**
1077 * policy_mgr_check_concurrent_intf_and_restart_sap() - Check
1078 * concurrent change intf
1079 * @psoc: PSOC object information
1080 * @operation_channel: operation channel
Archana Ramachandran544ce172017-03-14 15:12:09 -07001081 * @vdev_id: vdev id of SAP
Archana Ramachandran107d3782017-03-06 17:07:44 -08001082 *
1083 * Checks the concurrent change interface and restarts SAP
1084 *
1085 * Return: None
1086 */
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001087void policy_mgr_check_concurrent_intf_and_restart_sap(
Archana Ramachandran6199b642017-03-20 13:31:36 -07001088 struct wlan_objmgr_psoc *psoc)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001089{
Archana Ramachandran266613f2017-03-13 16:36:55 -07001090 struct policy_mgr_psoc_priv_obj *pm_ctx;
1091 uint32_t mcc_to_scc_switch;
Tushnim Bhattacharyyaf8417d12018-05-08 15:31:21 -07001092 uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
1093 uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
1094 uint32_t cc_count = 0;
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301095 bool restart_sap = false;
1096 uint8_t sap_ch;
Archana Ramachandran266613f2017-03-13 16:36:55 -07001097
1098 pm_ctx = policy_mgr_get_context(psoc);
1099 if (!pm_ctx) {
1100 policy_mgr_err("Invalid context");
1101 return;
1102 }
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301103 if (policy_mgr_get_connection_count(psoc) == 1) {
1104 /*
1105 * If STA+SAP sessions are on DFS channel and STA+SAP SCC is
1106 * enabled on DFS channel then move the SAP out of DFS channel
1107 * as soon as STA gets disconnect.
Jianmin Zhu7f6bdd32018-06-29 10:39:30 +08001108 * If STA+SAP sessions are on unsafe channel and STA+SAP SCC is
1109 * enabled on unsafe channel then move the SAP to safe channel
1110 * as soon as STA disconnected.
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301111 */
1112 if (policy_mgr_is_sap_restart_required_after_sta_disconnect(
1113 psoc, &sap_ch)) {
1114 policy_mgr_debug("move the SAP to configured channel %u",
1115 sap_ch);
1116 restart_sap = true;
1117 goto sap_restart;
1118 }
1119 }
Archana Ramachandran266613f2017-03-13 16:36:55 -07001120
Tushnim Bhattacharyyaf8417d12018-05-08 15:31:21 -07001121 /*
1122 * force SCC with STA+STA+SAP will need some additional logic
1123 */
1124 cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
1125 &operating_channel[cc_count],
1126 &vdev_id[cc_count], PM_STA_MODE);
1127 if (!cc_count) {
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301128 policy_mgr_err("Could not get STA operating channel&vdevid");
Archana Ramachandran6199b642017-03-20 13:31:36 -07001129 return;
1130 }
1131
Archana Ramachandran266613f2017-03-13 16:36:55 -07001132 mcc_to_scc_switch =
1133 policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc);
1134 policy_mgr_info("MCC to SCC switch: %d chan: %d",
Tushnim Bhattacharyyaf8417d12018-05-08 15:31:21 -07001135 mcc_to_scc_switch, operating_channel[0]);
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001136
1137 if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch)) {
1138 policy_mgr_debug(
1139 "No action taken at check_concurrent_intf_and_restart_sap");
1140 return;
1141 }
1142
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301143sap_restart:
1144 /*
1145 * If sta_sap_scc_on_dfs_chan is true then standalone SAP is not
1146 * allowed on DFS channel. SAP is allowed on DFS channel only when STA
1147 * is already connected on that channel.
1148 * In following condition restart_sap will be true if
1149 * sta_sap_scc_on_dfs_chan is true and SAP is on DFS channel.
1150 * This scenario can come if STA+SAP are operating on DFS channel and
1151 * STA gets disconnected.
1152 */
1153 if (restart_sap ||
1154 ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) &&
1155 policy_mgr_valid_sta_channel_check(psoc, operating_channel[0]) &&
1156 !pm_ctx->sta_ap_intf_check_work_info)) {
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001157 struct sta_ap_intf_check_work_ctx *work_info;
1158 work_info = qdf_mem_malloc(
1159 sizeof(struct sta_ap_intf_check_work_ctx));
1160 pm_ctx->sta_ap_intf_check_work_info = work_info;
1161 if (work_info) {
1162 work_info->psoc = psoc;
1163 qdf_create_work(0, &pm_ctx->sta_ap_intf_check_work,
Archana Ramachandran6199b642017-03-20 13:31:36 -07001164 policy_mgr_check_sta_ap_concurrent_ch_intf,
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001165 work_info);
1166 qdf_sched_work(0, &pm_ctx->sta_ap_intf_check_work);
1167 policy_mgr_info(
1168 "Checking for Concurrent Change interference");
1169 }
Archana Ramachandran266613f2017-03-13 16:36:55 -07001170 }
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001171}
1172#endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */
1173
1174#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Archana Ramachandran0edce252017-03-06 14:36:29 -08001175/**
1176 * policy_mgr_change_sap_channel_with_csa() - Move SAP channel using (E)CSA
1177 * @psoc: PSOC object information
1178 * @vdev_id: Vdev id
1179 * @channel: Channel to change
1180 * @ch_width: channel width to change
Min Liuc5b10432018-01-19 18:01:44 +08001181 * @forced: Force to switch channel, ignore SCC/MCC check
Archana Ramachandran0edce252017-03-06 14:36:29 -08001182 *
1183 * Invoke the callback function to change SAP channel using (E)CSA
1184 *
1185 * Return: None
1186 */
1187void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc,
1188 uint8_t vdev_id, uint32_t channel,
Min Liuc5b10432018-01-19 18:01:44 +08001189 uint32_t ch_width,
1190 bool forced)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001191{
Archana Ramachandran0edce252017-03-06 14:36:29 -08001192 struct policy_mgr_psoc_priv_obj *pm_ctx;
1193
1194 pm_ctx = policy_mgr_get_context(psoc);
1195 if (!pm_ctx) {
1196 policy_mgr_err("Invalid context");
1197 return;
1198 }
1199
Archana Ramachandran544ce172017-03-14 15:12:09 -07001200 if (pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb) {
Archana Ramachandran0edce252017-03-06 14:36:29 -08001201 policy_mgr_info("SAP change change without restart");
Archana Ramachandran631fd9f2017-03-19 18:51:30 -07001202 pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb(psoc,
Min Liuc5b10432018-01-19 18:01:44 +08001203 vdev_id, channel, ch_width, forced);
Archana Ramachandran0edce252017-03-06 14:36:29 -08001204 }
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001205}
1206#endif
1207
1208QDF_STATUS policy_mgr_wait_for_connection_update(struct wlan_objmgr_psoc *psoc)
1209{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001210 QDF_STATUS status;
1211 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1212
1213 policy_mgr_context = policy_mgr_get_context(psoc);
1214 if (!policy_mgr_context) {
1215 policy_mgr_err("Invalid context");
1216 return QDF_STATUS_E_FAILURE;
1217 }
1218
1219 status = qdf_wait_single_event(
1220 &policy_mgr_context->connection_update_done_evt,
1221 CONNECTION_UPDATE_TIMEOUT);
1222
1223 if (!QDF_IS_STATUS_SUCCESS(status)) {
1224 policy_mgr_err("wait for event failed");
1225 return QDF_STATUS_E_FAILURE;
1226 }
1227
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001228 return QDF_STATUS_SUCCESS;
1229}
1230
1231QDF_STATUS policy_mgr_reset_connection_update(struct wlan_objmgr_psoc *psoc)
1232{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001233 QDF_STATUS status;
1234 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1235
1236 policy_mgr_context = policy_mgr_get_context(psoc);
1237 if (!policy_mgr_context) {
1238 policy_mgr_err("Invalid context");
1239 return QDF_STATUS_E_FAILURE;
1240 }
1241
1242 status = qdf_event_reset(
1243 &policy_mgr_context->connection_update_done_evt);
1244
1245 if (!QDF_IS_STATUS_SUCCESS(status)) {
1246 policy_mgr_err("clear event failed");
1247 return QDF_STATUS_E_FAILURE;
1248 }
1249
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001250 return QDF_STATUS_SUCCESS;
1251}
1252
1253QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc)
1254{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001255 QDF_STATUS status;
1256 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1257
1258 policy_mgr_context = policy_mgr_get_context(psoc);
1259 if (!policy_mgr_context) {
1260 policy_mgr_err("Invalid context");
1261 return QDF_STATUS_E_FAILURE;
1262 }
1263
1264 status = qdf_event_set(&policy_mgr_context->connection_update_done_evt);
1265
1266 if (!QDF_IS_STATUS_SUCCESS(status)) {
1267 policy_mgr_err("set event failed");
1268 return QDF_STATUS_E_FAILURE;
1269 }
1270
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001271 return QDF_STATUS_SUCCESS;
1272}
1273
Bala Venkatesh378064b2018-06-11 15:06:53 +05301274QDF_STATUS policy_mgr_set_chan_switch_complete_evt(
1275 struct wlan_objmgr_psoc *psoc)
1276{
1277 QDF_STATUS status;
1278 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1279
1280 policy_mgr_context = policy_mgr_get_context(psoc);
1281
1282 if (!policy_mgr_context) {
1283 policy_mgr_err("Invalid context");
1284 return QDF_STATUS_E_FAILURE;
1285 }
1286 status = qdf_event_set(
1287 &policy_mgr_context->channel_switch_complete_evt);
1288
1289 if (!QDF_IS_STATUS_SUCCESS(status)) {
1290 policy_mgr_err("set event failed");
1291 return QDF_STATUS_E_FAILURE;
1292 }
1293
1294 return QDF_STATUS_SUCCESS;
1295}
1296
1297QDF_STATUS policy_mgr_reset_chan_switch_complete_evt(
1298 struct wlan_objmgr_psoc *psoc)
1299{
1300 QDF_STATUS status;
1301 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1302
1303 policy_mgr_context = policy_mgr_get_context(psoc);
1304
1305 if (!policy_mgr_context) {
1306 policy_mgr_err("Invalid context");
1307 return QDF_STATUS_E_FAILURE;
1308 }
1309 status = qdf_event_reset(
1310 &policy_mgr_context->channel_switch_complete_evt);
1311
1312 if (!QDF_IS_STATUS_SUCCESS(status)) {
1313 policy_mgr_err("reset event failed");
1314 return QDF_STATUS_E_FAILURE;
1315 }
1316
1317 return QDF_STATUS_SUCCESS;
1318}
1319
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001320QDF_STATUS policy_mgr_set_opportunistic_update(struct wlan_objmgr_psoc *psoc)
1321{
1322 QDF_STATUS status;
1323 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1324
1325 policy_mgr_context = policy_mgr_get_context(psoc);
1326 if (!policy_mgr_context) {
1327 policy_mgr_err("Invalid context");
1328 return QDF_STATUS_E_FAILURE;
1329 }
1330
1331 status = qdf_event_set(
1332 &policy_mgr_context->opportunistic_update_done_evt);
1333
1334 if (!QDF_IS_STATUS_SUCCESS(status)) {
1335 policy_mgr_err("set event failed");
1336 return QDF_STATUS_E_FAILURE;
1337 }
1338
1339 return QDF_STATUS_SUCCESS;
1340}
1341
Himanshu Agarwal70a52d92018-05-04 14:37:48 +05301342QDF_STATUS policy_mgr_stop_opportunistic_timer(struct wlan_objmgr_psoc *psoc)
1343{
1344 struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
1345
1346 policy_mgr_ctx = policy_mgr_get_context(psoc);
1347 if (!policy_mgr_ctx) {
1348 policy_mgr_err("Invalid context");
1349 return QDF_STATUS_E_FAILURE;
1350 }
1351
1352 if (policy_mgr_ctx->dbs_opportunistic_timer.state !=
1353 QDF_TIMER_STATE_RUNNING)
1354 return QDF_STATUS_SUCCESS;
1355
1356 qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer);
1357 return QDF_STATUS_SUCCESS;
1358}
1359
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001360QDF_STATUS policy_mgr_restart_opportunistic_timer(
1361 struct wlan_objmgr_psoc *psoc, bool check_state)
1362{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001363 QDF_STATUS status = QDF_STATUS_E_FAILURE;
1364 struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
1365
1366 policy_mgr_ctx = policy_mgr_get_context(psoc);
1367 if (!policy_mgr_ctx) {
1368 policy_mgr_err("Invalid context");
1369 return status;
1370 }
1371
1372 if (check_state &&
1373 QDF_TIMER_STATE_RUNNING !=
1374 policy_mgr_ctx->dbs_opportunistic_timer.state)
1375 return status;
1376
1377 qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer);
1378
1379 status = qdf_mc_timer_start(
1380 &policy_mgr_ctx->dbs_opportunistic_timer,
1381 DBS_OPPORTUNISTIC_TIME * 1000);
1382
1383 if (!QDF_IS_STATUS_SUCCESS(status)) {
1384 policy_mgr_err("failed to start opportunistic timer");
1385 return status;
1386 }
1387
1388 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001389}
1390
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001391QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch(
1392 struct wlan_objmgr_psoc *psoc, uint8_t session_id)
1393{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001394 QDF_STATUS status = QDF_STATUS_E_FAILURE, qdf_status;
1395 enum policy_mgr_conc_next_action action;
1396
1397 if (!policy_mgr_is_hw_dbs_capable(psoc)) {
1398 policy_mgr_err("PM/DBS is disabled");
1399 return status;
1400 }
1401
1402 action = (*policy_mgr_get_current_pref_hw_mode_ptr)(psoc);
1403 if ((action != PM_DBS_DOWNGRADE) &&
1404 (action != PM_SINGLE_MAC_UPGRADE)) {
1405 policy_mgr_err("Invalid action: %d", action);
1406 status = QDF_STATUS_SUCCESS;
1407 goto done;
1408 }
1409
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001410 policy_mgr_debug("action:%d session id:%d", action, session_id);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001411
1412 /* Opportunistic timer is started, PM will check if MCC upgrade can be
1413 * done on timer expiry. This avoids any possible ping pong effect
1414 * as well.
1415 */
1416 if (action == PM_SINGLE_MAC_UPGRADE) {
1417 qdf_status = policy_mgr_restart_opportunistic_timer(
1418 psoc, false);
1419 if (QDF_IS_STATUS_SUCCESS(qdf_status))
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001420 policy_mgr_debug("opportunistic timer for MCC upgrade");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001421 goto done;
1422 }
1423
1424 /* For DBS, we want to move right away to DBS mode */
1425 status = policy_mgr_next_actions(psoc, session_id, action,
1426 POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH);
1427 if (!QDF_IS_STATUS_SUCCESS(status)) {
1428 policy_mgr_err("no set hw mode command was issued");
1429 goto done;
1430 }
1431done:
1432 /* success must be returned only when a set hw mode was done */
1433 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001434}
1435
1436void policy_mgr_checkn_update_hw_mode_single_mac_mode(
1437 struct wlan_objmgr_psoc *psoc, uint8_t channel)
1438{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001439 uint8_t i;
1440 struct policy_mgr_psoc_priv_obj *pm_ctx;
1441
1442 pm_ctx = policy_mgr_get_context(psoc);
1443 if (!pm_ctx) {
1444 policy_mgr_err("Invalid Context");
1445 return;
1446 }
1447
gaurank kathpaliaafa4e1b2018-07-05 15:04:46 +05301448 if (QDF_TIMER_STATE_RUNNING ==
1449 pm_ctx->dbs_opportunistic_timer.state)
1450 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
1451
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001452 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1453 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
1454 if (pm_conc_connection_list[i].in_use)
1455 if (!WLAN_REG_IS_SAME_BAND_CHANNELS(channel,
1456 pm_conc_connection_list[i].chan)) {
1457 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001458 policy_mgr_debug("DBS required");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001459 return;
1460 }
1461 }
1462 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001463 pm_dbs_opportunistic_timer_handler((void *)psoc);
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001464}
1465
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001466void policy_mgr_check_and_stop_opportunistic_timer(
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001467 struct wlan_objmgr_psoc *psoc, uint8_t id)
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001468{
1469 struct policy_mgr_psoc_priv_obj *pm_ctx;
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001470 enum policy_mgr_conc_next_action action = PM_NOP;
1471 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001472
1473 pm_ctx = policy_mgr_get_context(psoc);
1474 if (!pm_ctx) {
1475 policy_mgr_err("Invalid Context");
1476 return;
1477 }
1478 if (QDF_TIMER_STATE_RUNNING ==
1479 pm_ctx->dbs_opportunistic_timer.state) {
1480 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001481 action = policy_mgr_need_opportunistic_upgrade(psoc);
1482 if (action) {
Krunal Soni4943b902018-01-05 17:36:40 -08001483 qdf_event_reset(&pm_ctx->opportunistic_update_done_evt);
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001484 status = policy_mgr_next_actions(psoc, id, action,
1485 POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC);
1486 if (status != QDF_STATUS_SUCCESS) {
1487 policy_mgr_err("Failed in policy_mgr_next_actions");
1488 return;
1489 }
1490 status = qdf_wait_single_event(
1491 &pm_ctx->opportunistic_update_done_evt,
1492 CONNECTION_UPDATE_TIMEOUT);
1493
1494 if (!QDF_IS_STATUS_SUCCESS(status)) {
1495 policy_mgr_err("wait for event failed");
1496 return;
1497 }
1498 }
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001499 }
1500}
1501
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07001502void policy_mgr_set_hw_mode_change_in_progress(
1503 struct wlan_objmgr_psoc *psoc, enum policy_mgr_hw_mode_change value)
1504{
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001505 struct policy_mgr_psoc_priv_obj *pm_ctx;
1506
1507 pm_ctx = policy_mgr_get_context(psoc);
1508 if (!pm_ctx) {
1509 policy_mgr_err("Invalid Context");
1510 return;
1511 }
1512
1513 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1514 pm_ctx->hw_mode_change_in_progress = value;
1515 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1516
1517 policy_mgr_debug("hw_mode_change_in_progress:%d", value);
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07001518}
1519
1520enum policy_mgr_hw_mode_change policy_mgr_is_hw_mode_change_in_progress(
1521 struct wlan_objmgr_psoc *psoc)
1522{
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001523 enum policy_mgr_hw_mode_change value;
1524 struct policy_mgr_psoc_priv_obj *pm_ctx;
1525
1526 value = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
1527
1528 pm_ctx = policy_mgr_get_context(psoc);
1529 if (!pm_ctx) {
1530 policy_mgr_err("Invalid Context");
1531 return value;
1532 }
1533 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1534 value = pm_ctx->hw_mode_change_in_progress;
1535 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1536
1537 return value;
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07001538}
1539
1540enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index(
1541 struct wlan_objmgr_psoc *psoc, uint32_t hw_mode_index)
1542{
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001543 struct policy_mgr_psoc_priv_obj *pm_ctx;
1544 uint32_t param = 0;
1545 enum policy_mgr_hw_mode_change value
1546 = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
1547
1548 pm_ctx = policy_mgr_get_context(psoc);
1549 if (!pm_ctx) {
1550 policy_mgr_err("Invalid Context");
1551 return value;
1552 }
1553
1554 policy_mgr_info("HW param: %x", param);
1555 param = pm_ctx->hw_mode.hw_mode_list[hw_mode_index];
1556 if (POLICY_MGR_HW_MODE_DBS_MODE_GET(param)) {
1557 policy_mgr_info("DBS is requested with HW (%d)",
1558 hw_mode_index);
1559 value = POLICY_MGR_DBS_IN_PROGRESS;
1560 goto ret_value;
1561 }
1562
1563 if (POLICY_MGR_HW_MODE_SBS_MODE_GET(param)) {
1564 policy_mgr_info("SBS is requested with HW (%d)",
1565 hw_mode_index);
1566 value = POLICY_MGR_SBS_IN_PROGRESS;
1567 goto ret_value;
1568 }
1569
1570 value = POLICY_MGR_SMM_IN_PROGRESS;
1571 policy_mgr_info("SMM is requested with HW (%d)", hw_mode_index);
1572
1573ret_value:
1574 return value;
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07001575}
1576
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001577#ifdef MPC_UT_FRAMEWORK
1578QDF_STATUS policy_mgr_update_connection_info_utfw(
1579 struct wlan_objmgr_psoc *psoc,
1580 uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
1581 uint32_t chain_mask, uint32_t type, uint32_t sub_type,
1582 uint32_t channelid, uint32_t mac_id)
1583{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001584 QDF_STATUS status = QDF_STATUS_E_FAILURE;
1585 uint32_t conn_index = 0, found = 0;
1586 struct policy_mgr_psoc_priv_obj *pm_ctx;
1587
1588 pm_ctx = policy_mgr_get_context(psoc);
1589 if (!pm_ctx) {
1590 policy_mgr_err("Invalid Context");
1591 return status;
1592 }
1593
1594 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1595 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
1596 if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
1597 /* debug msg */
1598 found = 1;
1599 break;
1600 }
1601 conn_index++;
1602 }
1603 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1604 if (!found) {
1605 /* err msg */
1606 policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list",
1607 vdev_id);
1608 return status;
1609 }
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001610 policy_mgr_debug("--> updating entry at index[%d]", conn_index);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001611
1612 policy_mgr_update_conc_list(psoc, conn_index,
1613 policy_mgr_get_mode(type, sub_type),
1614 channelid, HW_MODE_20_MHZ,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05301615 mac_id, chain_mask, 0, vdev_id, true, true);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001616
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001617 return QDF_STATUS_SUCCESS;
1618}
1619
1620QDF_STATUS policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc,
1621 uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
1622 uint32_t chain_mask, uint32_t type, uint32_t sub_type,
1623 uint32_t channelid, uint32_t mac_id)
1624{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001625 QDF_STATUS status = QDF_STATUS_E_FAILURE;
1626 uint32_t conn_index = 0;
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05301627 bool update_conn = true;
1628 enum policy_mgr_con_mode mode;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001629
1630 conn_index = policy_mgr_get_connection_count(psoc);
1631 if (MAX_NUMBER_OF_CONC_CONNECTIONS <= conn_index) {
1632 /* err msg */
1633 policy_mgr_err("exceeded max connection limit %d",
1634 MAX_NUMBER_OF_CONC_CONNECTIONS);
1635 return status;
1636 }
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001637 policy_mgr_debug("--> filling entry at index[%d]", conn_index);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001638
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05301639 mode = policy_mgr_get_mode(type, sub_type);
1640 if (mode == PM_STA_MODE || mode == PM_P2P_CLIENT_MODE)
1641 update_conn = false;
1642
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001643 policy_mgr_update_conc_list(psoc, conn_index,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05301644 mode,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001645 channelid, HW_MODE_20_MHZ,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05301646 mac_id, chain_mask, 0, vdev_id, true,
1647 update_conn);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001648
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001649 return QDF_STATUS_SUCCESS;
1650}
1651
1652QDF_STATUS policy_mgr_decr_connection_count_utfw(struct wlan_objmgr_psoc *psoc,
1653 uint32_t del_all, uint32_t vdev_id)
1654{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001655 QDF_STATUS status;
1656
1657 if (del_all) {
1658 status = policy_mgr_psoc_enable(psoc);
1659 if (!QDF_IS_STATUS_SUCCESS(status)) {
1660 policy_mgr_err("Policy manager initialization failed");
1661 return QDF_STATUS_E_FAILURE;
1662 }
1663 } else {
1664 policy_mgr_decr_connection_count(psoc, vdev_id);
1665 }
1666
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001667 return QDF_STATUS_SUCCESS;
1668}
1669
1670enum policy_mgr_pcl_type policy_mgr_get_pcl_from_first_conn_table(
1671 enum policy_mgr_con_mode type,
1672 enum policy_mgr_conc_priority_mode sys_pref)
1673{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001674 if ((sys_pref >= PM_MAX_CONC_PRIORITY_MODE) ||
1675 (type >= PM_MAX_NUM_OF_MODE))
1676 return PM_MAX_PCL_TYPE;
1677 return first_connection_pcl_table[type][sys_pref];
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001678}
1679
1680enum policy_mgr_pcl_type policy_mgr_get_pcl_from_second_conn_table(
1681 enum policy_mgr_one_connection_mode idx, enum policy_mgr_con_mode type,
1682 enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable)
1683{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001684 if ((idx >= PM_MAX_ONE_CONNECTION_MODE) ||
1685 (sys_pref >= PM_MAX_CONC_PRIORITY_MODE) ||
1686 (type >= PM_MAX_NUM_OF_MODE))
1687 return PM_MAX_PCL_TYPE;
1688 if (dbs_capable)
1689 return (*second_connection_pcl_dbs_table)[idx][type][sys_pref];
1690 else
1691 return second_connection_pcl_nodbs_table[idx][type][sys_pref];
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001692}
1693
1694enum policy_mgr_pcl_type policy_mgr_get_pcl_from_third_conn_table(
1695 enum policy_mgr_two_connection_mode idx, enum policy_mgr_con_mode type,
1696 enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable)
1697{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001698 if ((idx >= PM_MAX_TWO_CONNECTION_MODE) ||
1699 (sys_pref >= PM_MAX_CONC_PRIORITY_MODE) ||
1700 (type >= PM_MAX_NUM_OF_MODE))
1701 return PM_MAX_PCL_TYPE;
1702 if (dbs_capable)
1703 return (*third_connection_pcl_dbs_table)[idx][type][sys_pref];
1704 else
1705 return third_connection_pcl_nodbs_table[idx][type][sys_pref];
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001706}
1707#endif