blob: 22c07a0bd7779dfacd600ec7fb593211beae432b [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
Tushnim Bhattacharyyac304f892018-08-01 19:15:55 -070096QDF_STATUS policy_mgr_check_n_start_opportunistic_timer(
97 struct wlan_objmgr_psoc *psoc)
98{
99 struct policy_mgr_psoc_priv_obj *pm_ctx;
100 QDF_STATUS status = QDF_STATUS_E_FAILURE;
101
102 pm_ctx = policy_mgr_get_context(psoc);
103 if (!pm_ctx) {
104 policy_mgr_err("PM ctx not valid. Oppurtunistic timer cannot start");
105 return QDF_STATUS_E_FAILURE;
106 }
107 if (policy_mgr_need_opportunistic_upgrade(psoc)) {
108 /* let's start the timer */
109 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
110 status = qdf_mc_timer_start(
111 &pm_ctx->dbs_opportunistic_timer,
112 DBS_OPPORTUNISTIC_TIME * 1000);
113 if (!QDF_IS_STATUS_SUCCESS(status))
114 policy_mgr_err("Failed to start dbs opportunistic timer");
115 }
116 return status;
117}
118
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800119QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc,
120 uint32_t session_id,
121 enum hw_mode_ss_config mac0_ss,
122 enum hw_mode_bandwidth mac0_bw,
123 enum hw_mode_ss_config mac1_ss,
124 enum hw_mode_bandwidth mac1_bw,
Liangwei Dong9ace8a92018-05-21 05:39:04 -0400125 enum hw_mode_mac_band_cap mac0_band_cap,
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800126 enum hw_mode_dbs_capab dbs,
127 enum hw_mode_agile_dfs_capab dfs,
128 enum hw_mode_sbs_capab sbs,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800129 enum policy_mgr_conn_update_reason reason,
130 uint8_t next_action)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800131{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800132 int8_t hw_mode_index;
133 struct policy_mgr_hw_mode msg;
134 QDF_STATUS status;
135 struct policy_mgr_psoc_priv_obj *pm_ctx;
136
137 pm_ctx = policy_mgr_get_context(psoc);
138 if (!pm_ctx) {
139 policy_mgr_err("Invalid context");
140 return QDF_STATUS_E_FAILURE;
141 }
142
143 /*
144 * if HW is not capable of doing 2x2 or ini config disabled 2x2, don't
145 * allow to request FW for 2x2
146 */
Tushnim Bhattacharyya68f709d2017-03-23 18:00:04 -0700147 if ((HW_MODE_SS_2x2 == mac0_ss) && (!pm_ctx->user_cfg.enable2x2)) {
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -0700148 policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac0");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800149 mac0_ss = HW_MODE_SS_1x1;
150 }
Tushnim Bhattacharyya68f709d2017-03-23 18:00:04 -0700151 if ((HW_MODE_SS_2x2 == mac1_ss) && (!pm_ctx->user_cfg.enable2x2)) {
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -0700152 policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac1");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800153 mac1_ss = HW_MODE_SS_1x1;
154 }
155
156 hw_mode_index = policy_mgr_get_hw_mode_idx_from_dbs_hw_list(psoc,
Liangwei Dong9ace8a92018-05-21 05:39:04 -0400157 mac0_ss, mac0_bw, mac1_ss, mac1_bw, mac0_band_cap,
158 dbs, dfs, sbs);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800159 if (hw_mode_index < 0) {
160 policy_mgr_err("Invalid HW mode index obtained");
161 return QDF_STATUS_E_FAILURE;
162 }
163
164 msg.hw_mode_index = hw_mode_index;
165 msg.set_hw_mode_cb = (void *)policy_mgr_pdev_set_hw_mode_cb;
166 msg.reason = reason;
167 msg.session_id = session_id;
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800168 msg.next_action = next_action;
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -0700169 msg.context = psoc;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800170
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -0700171 policy_mgr_debug("set hw mode to sme: hw_mode_index: %d session:%d reason:%d",
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800172 msg.hw_mode_index, msg.session_id, msg.reason);
173
174 status = pm_ctx->sme_cbacks.sme_pdev_set_hw_mode(msg);
175 if (status != QDF_STATUS_SUCCESS) {
176 policy_mgr_err("Failed to set hw mode to SME");
177 return status;
178 }
179
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800180 return QDF_STATUS_SUCCESS;
181}
182
183enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade(
184 struct wlan_objmgr_psoc *psoc)
185{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800186 uint32_t conn_index;
187 enum policy_mgr_conc_next_action upgrade = PM_NOP;
188 uint8_t mac = 0;
189 struct policy_mgr_hw_mode_params hw_mode;
190 QDF_STATUS status = QDF_STATUS_E_FAILURE;
191 struct policy_mgr_psoc_priv_obj *pm_ctx;
192
193 pm_ctx = policy_mgr_get_context(psoc);
194 if (!pm_ctx) {
195 policy_mgr_err("Invalid Context");
196 goto done;
197 }
198
199 if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
200 policy_mgr_err("driver isn't dbs capable, no further action needed");
201 goto done;
202 }
203
204 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
205 if (!QDF_IS_STATUS_SUCCESS(status)) {
206 policy_mgr_err("policy_mgr_get_current_hw_mode failed");
207 goto done;
208 }
209 if (!hw_mode.dbs_cap) {
Yeshwanth Sriram Guntukad540cd02018-08-23 18:25:28 +0530210 policy_mgr_debug("current HW mode is non-DBS capable");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800211 goto done;
212 }
213
214 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
215 /* Are both mac's still in use */
216 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
217 conn_index++) {
218 policy_mgr_debug("index:%d mac:%d in_use:%d chan:%d org_nss:%d",
219 conn_index,
220 pm_conc_connection_list[conn_index].mac,
221 pm_conc_connection_list[conn_index].in_use,
222 pm_conc_connection_list[conn_index].chan,
223 pm_conc_connection_list[conn_index].original_nss);
224 if ((pm_conc_connection_list[conn_index].mac == 0) &&
225 pm_conc_connection_list[conn_index].in_use) {
226 mac |= POLICY_MGR_MAC0;
227 if (POLICY_MGR_MAC0_AND_MAC1 == mac) {
228 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
229 goto done;
230 }
231 } else if ((pm_conc_connection_list[conn_index].mac == 1) &&
232 pm_conc_connection_list[conn_index].in_use) {
233 mac |= POLICY_MGR_MAC1;
Archana Ramachandran944f1fd2017-06-02 16:48:17 -0700234 if (policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
235 WLAN_REG_IS_24GHZ_CH(
236 pm_conc_connection_list[conn_index].chan)
237 ) {
238 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
239 policy_mgr_debug("2X2 DBS capable with 2.4 GHZ connection");
240 goto done;
241 }
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800242 if (POLICY_MGR_MAC0_AND_MAC1 == mac) {
243 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
244 goto done;
245 }
246 }
247 }
248 /* Let's request for single MAC mode */
249 upgrade = PM_SINGLE_MAC;
250 /* Is there any connection had an initial connection with 2x2 */
251 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
252 conn_index++) {
253 if ((pm_conc_connection_list[conn_index].original_nss == 2) &&
254 pm_conc_connection_list[conn_index].in_use) {
255 upgrade = PM_SINGLE_MAC_UPGRADE;
256 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
257 goto done;
258 }
259 }
260 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
261
262done:
263 return upgrade;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800264}
265
266QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc,
267 uint32_t vdev_id)
268{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800269 QDF_STATUS status = QDF_STATUS_E_FAILURE;
270 uint32_t conn_index = 0;
271 bool found = false;
272 struct policy_mgr_vdev_entry_info conn_table_entry;
273 enum policy_mgr_chain_mode chain_mask = POLICY_MGR_ONE_ONE;
274 uint8_t nss_2g, nss_5g;
275 enum policy_mgr_con_mode mode;
276 uint8_t chan;
277 uint32_t nss = 0;
278 struct policy_mgr_psoc_priv_obj *pm_ctx;
279
280 pm_ctx = policy_mgr_get_context(psoc);
281 if (!pm_ctx) {
282 policy_mgr_err("Invalid Context");
283 return status;
284 }
285
286 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
287 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
288 if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
289 /* debug msg */
290 found = true;
291 break;
292 }
293 conn_index++;
294 }
295 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
296 if (!found) {
297 /* err msg */
298 policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list",
299 vdev_id);
300 return status;
301 }
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700302 if (pm_ctx->wma_cbacks.wma_get_connection_info) {
303 status = pm_ctx->wma_cbacks.wma_get_connection_info(
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800304 vdev_id, &conn_table_entry);
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700305 if (QDF_STATUS_SUCCESS != status) {
306 policy_mgr_err("can't find vdev_id %d in connection table",
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800307 vdev_id);
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700308 return status;
309 }
310 } else {
311 policy_mgr_err("wma_get_connection_info is NULL");
312 return QDF_STATUS_E_FAILURE;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800313 }
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700314
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800315 mode = policy_mgr_get_mode(conn_table_entry.type,
316 conn_table_entry.sub_type);
Tushnim Bhattacharyyace237d62017-04-05 12:52:36 -0700317 chan = wlan_reg_freq_to_chan(pm_ctx->pdev, conn_table_entry.mhz);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800318 status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g);
319 if (QDF_IS_STATUS_SUCCESS(status)) {
320 if ((WLAN_REG_IS_24GHZ_CH(chan) && (nss_2g > 1)) ||
321 (WLAN_REG_IS_5GHZ_CH(chan) && (nss_5g > 1)))
322 chain_mask = POLICY_MGR_TWO_TWO;
323 else
324 chain_mask = POLICY_MGR_ONE_ONE;
325 nss = (WLAN_REG_IS_24GHZ_CH(chan)) ? nss_2g : nss_5g;
326 } else {
327 policy_mgr_err("Error in getting nss");
328 }
329
330 policy_mgr_debug("update PM connection table for vdev:%d", vdev_id);
331
332 /* add the entry */
333 policy_mgr_update_conc_list(psoc, conn_index,
334 mode,
335 chan,
336 policy_mgr_get_bw(conn_table_entry.chan_width),
337 conn_table_entry.mac_id,
338 chain_mask,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +0530339 nss, vdev_id, true, true);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800340
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800341 return QDF_STATUS_SUCCESS;
342}
343
344QDF_STATUS policy_mgr_update_and_wait_for_connection_update(
345 struct wlan_objmgr_psoc *psoc,
346 uint8_t session_id,
347 uint8_t channel,
348 enum policy_mgr_conn_update_reason reason)
349{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800350 QDF_STATUS status;
351
352 policy_mgr_debug("session:%d channel:%d reason:%d",
353 session_id, channel, reason);
354
355 status = policy_mgr_reset_connection_update(psoc);
356 if (QDF_IS_STATUS_ERROR(status))
357 policy_mgr_err("clearing event failed");
358
359 status = policy_mgr_current_connections_update(psoc,
360 session_id, channel, reason);
361 if (QDF_STATUS_E_FAILURE == status) {
362 policy_mgr_err("connections update failed");
363 return QDF_STATUS_E_FAILURE;
364 }
365
366 /* Wait only when status is success */
367 if (QDF_IS_STATUS_SUCCESS(status)) {
368 status = policy_mgr_wait_for_connection_update(psoc);
369 if (QDF_IS_STATUS_ERROR(status)) {
370 policy_mgr_err("qdf wait for event failed");
371 return QDF_STATUS_E_FAILURE;
372 }
373 }
374
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800375 return QDF_STATUS_SUCCESS;
376}
377
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530378/**
379 * policy_mgr_is_dbs_allowed_for_concurrency() - If dbs is allowed for current
380 * concurreny
381 * @new_conn_mode: new connection mode
382 *
383 * When a new connection is about to come up, check if dbs is allowed for
384 * STA+STA or STA+P2P
385 *
386 * Return: true if dbs is allowed for STA+STA or STA+P2P else false
387 */
Bala Venkatesh28477d32018-05-07 21:35:55 +0530388bool policy_mgr_is_dbs_allowed_for_concurrency(
389 struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE new_conn_mode)
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530390{
391 struct policy_mgr_psoc_priv_obj *pm_ctx;
392 uint32_t count, dbs_for_sta_sta, dbs_for_sta_p2p;
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530393 bool ret = true;
394
395 pm_ctx = policy_mgr_get_context(psoc);
396 if (!pm_ctx) {
397 policy_mgr_err("Invalid context");
398 return ret;
399 }
400
401 count = policy_mgr_get_connection_count(psoc);
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530402
403 if (count != 1 || new_conn_mode == QDF_MAX_NO_OF_MODE)
404 return ret;
405
406 dbs_for_sta_sta = PM_CHANNEL_SELECT_LOGIC_STA_STA_GET(pm_ctx->user_cfg.
407 channel_select_logic_conc);
408 dbs_for_sta_p2p = PM_CHANNEL_SELECT_LOGIC_STA_P2P_GET(pm_ctx->user_cfg.
409 channel_select_logic_conc);
410
411 switch (pm_conc_connection_list[0].mode) {
412 case PM_STA_MODE:
413 switch (new_conn_mode) {
414 case QDF_STA_MODE:
415 if (!dbs_for_sta_sta)
416 return false;
417 break;
418 case QDF_P2P_DEVICE_MODE:
419 case QDF_P2P_CLIENT_MODE:
420 case QDF_P2P_GO_MODE:
421 if (!dbs_for_sta_p2p)
422 return false;
423 break;
424 default:
425 break;
426 }
427 break;
428 case PM_P2P_CLIENT_MODE:
429 case PM_P2P_GO_MODE:
430 switch (new_conn_mode) {
431 case QDF_STA_MODE:
432 if (!dbs_for_sta_p2p)
433 return false;
434 break;
435 default:
436 break;
437 }
438 break;
439 default:
440 break;
441 }
442
443 return ret;
444}
445
Krunal Soni637eba52018-06-14 17:55:15 -0700446static bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc,
447 uint8_t channel)
448{
449 uint8_t i, pm_chnl;
450 struct policy_mgr_psoc_priv_obj *pm_ctx;
451
452 pm_ctx = policy_mgr_get_context(psoc);
453 if (!pm_ctx) {
454 policy_mgr_err("Invalid Context");
455 return false;
456 }
457
458 /*
459 * check given channel against already existing connections'
460 * channels. if they differ then channels are in different bands
461 */
462 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
463 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
464 pm_chnl = pm_conc_connection_list[i].chan;
465 if (pm_conc_connection_list[i].in_use)
466 if (!WLAN_REG_IS_SAME_BAND_CHANNELS(channel, pm_chnl)) {
467 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
468 policy_mgr_debug("channel is in diff band");
469 return true;
470 }
471 }
472 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
473
474 return false;
475}
476
477bool policy_mgr_is_hwmode_set_for_given_chnl(struct wlan_objmgr_psoc *psoc,
478 uint8_t channel)
479{
480 enum policy_mgr_band band;
481 bool is_hwmode_dbs, is_2x2_dbs;
482
483 if (policy_mgr_is_hw_dbs_capable(psoc) == false)
484 return true;
485
486 if (WLAN_REG_IS_24GHZ_CH(channel))
487 band = POLICY_MGR_BAND_24;
488 else
489 band = POLICY_MGR_BAND_5;
490
491 is_hwmode_dbs = policy_mgr_is_current_hwmode_dbs(psoc);
492 is_2x2_dbs = policy_mgr_is_hw_dbs_2x2_capable(psoc);
493 /*
494 * If HW supports 2x2 chains in DBS HW mode and if DBS HW mode is not
495 * yet set then this is the right time to block the connection.
496 */
497 if ((band == POLICY_MGR_BAND_24) && is_2x2_dbs && !is_hwmode_dbs) {
498 policy_mgr_err("HW mode is not yet in DBS!!!!!");
499 return false;
500 }
501
502 /*
503 * If HW supports 1x1 chains DBS HW mode and if first connection is
504 * 2G or 5G band and if second connection is coming up in diffrent
505 * band than the first connection and if current HW mode is not yet
506 * set in DBS then this is the right time to block the connection.
507 */
508 if (policy_mgr_is_chnl_in_diff_band(psoc, channel) && !is_hwmode_dbs) {
509 policy_mgr_err("Given channel & existing conn is diff band & HW mode is not yet in DBS !!!!");
510 return false;
511 }
512
513 return true;
514}
515
Liangwei Dongecbf1132018-05-25 05:24:12 -0400516/**
517 * policy_mgr_pri_id_to_con_mode() - convert policy_mgr_pri_id to
518 * policy_mgr_con_mode
519 * @pri_id: policy_mgr_pri_id
520 *
521 * The help function converts policy_mgr_pri_id type to policy_mgr_con_mode
522 * type.
523 *
524 * Return: policy_mgr_con_mode type.
525 */
526static
527enum policy_mgr_con_mode policy_mgr_pri_id_to_con_mode(
528 enum policy_mgr_pri_id pri_id)
529{
530 switch (pri_id) {
531 case PM_STA_PRI_ID:
532 return PM_STA_MODE;
533 case PM_SAP_PRI_ID:
534 return PM_SAP_MODE;
535 case PM_P2P_GO_PRI_ID:
536 return PM_P2P_GO_MODE;
537 case PM_P2P_CLI_PRI_ID:
538 return PM_P2P_CLIENT_MODE;
539 default:
540 return PM_MAX_NUM_OF_MODE;
541 }
542}
543
544enum policy_mgr_conc_next_action
545policy_mgr_get_preferred_dbs_action_table(
546 struct wlan_objmgr_psoc *psoc,
547 uint32_t vdev_id,
548 uint8_t channel,
549 enum policy_mgr_conn_update_reason reason)
550{
551 struct policy_mgr_psoc_priv_obj *pm_ctx;
552 enum policy_mgr_con_mode pri_conn_mode = PM_MAX_NUM_OF_MODE;
553 enum policy_mgr_con_mode new_conn_mode = PM_MAX_NUM_OF_MODE;
554 enum QDF_OPMODE new_conn_op_mode = QDF_MAX_NO_OF_MODE;
555 bool band_pref_5g = true;
556 bool vdev_priority_enabled = false;
557 bool dbs_2x2_5g_1x1_2g_supported;
558 bool dbs_2x2_2g_1x1_5g_supported;
559 uint32_t vdev_pri_list, vdev_pri_id;
560 uint8_t chan_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
561 uint8_t vdev_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
562 uint32_t vdev_count = 0;
563 uint32_t i;
564 bool found;
565
566 pm_ctx = policy_mgr_get_context(psoc);
567 if (!pm_ctx) {
568 policy_mgr_err("Invalid context");
569 return PM_NOP;
570 }
571 dbs_2x2_5g_1x1_2g_supported =
572 policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc);
573 dbs_2x2_2g_1x1_5g_supported =
574 policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc);
575 policy_mgr_debug("target support DBS1 %d DBS2 %d",
576 dbs_2x2_5g_1x1_2g_supported,
577 dbs_2x2_2g_1x1_5g_supported);
578 /*
579 * If both DBS1 and DBS2 not supported, this should be Legacy Single
580 * DBS mode HW. The policy_mgr_psoc_enable has setup the correct
581 * action tables.
582 */
583 if (!dbs_2x2_5g_1x1_2g_supported && !dbs_2x2_2g_1x1_5g_supported)
584 return PM_NOP;
585 if (!dbs_2x2_5g_1x1_2g_supported) {
586 band_pref_5g = false;
587 policy_mgr_debug("target only supports DBS2!");
588 goto DONE;
589 }
590 if (!dbs_2x2_2g_1x1_5g_supported) {
591 policy_mgr_debug("target only supports DBS1!");
592 goto DONE;
593 }
594 if (PM_GET_BAND_PREFERRED(pm_ctx->user_cfg.dbs_selection_policy) == 1)
595 band_pref_5g = false;
596
597 if (PM_GET_VDEV_PRIORITY_ENABLED(
598 pm_ctx->user_cfg.dbs_selection_policy) == 1 &&
599 pm_ctx->user_cfg.vdev_priority_list)
600 vdev_priority_enabled = true;
601
602 if (!vdev_priority_enabled)
603 goto DONE;
604
605 if (vdev_id != INVALID_VDEV_ID && channel) {
606 if (pm_ctx->hdd_cbacks.hdd_get_device_mode)
607 new_conn_op_mode = pm_ctx->hdd_cbacks.
608 hdd_get_device_mode(vdev_id);
609
610 new_conn_mode = policy_mgr_convert_device_mode_to_qdf_type(
611 new_conn_op_mode);
612 if (new_conn_mode == PM_MAX_NUM_OF_MODE)
613 policy_mgr_debug("new vdev %d op_mode %d chan %d reason %d: not prioritized",
614 vdev_id, new_conn_op_mode,
615 channel, reason);
616 else
617 policy_mgr_debug("new vdev %d op_mode %d chan %d : reason %d",
618 vdev_id, new_conn_op_mode, channel,
619 reason);
620 }
621 vdev_pri_list = pm_ctx->user_cfg.vdev_priority_list;
622 while (vdev_pri_list) {
623 vdev_pri_id = vdev_pri_list & 0xF;
624 pri_conn_mode = policy_mgr_pri_id_to_con_mode(vdev_pri_id);
625 if (pri_conn_mode == PM_MAX_NUM_OF_MODE) {
626 policy_mgr_debug("vdev_pri_id %d prioritization not supported",
627 vdev_pri_id);
628 goto NEXT;
629 }
630 vdev_count = policy_mgr_get_mode_specific_conn_info(
631 psoc, chan_list, vdev_list, pri_conn_mode);
632 /**
633 * Take care of duplication case, the vdev id may
634 * exist in the conn list already with old chan.
635 * Replace with new chan before make decision.
636 */
637 found = false;
638 for (i = 0; i < vdev_count; i++) {
639 policy_mgr_debug("[%d] vdev %d chan %d conn_mode %d",
640 i, vdev_list[i], chan_list[i],
641 pri_conn_mode);
642
643 if (new_conn_mode == pri_conn_mode &&
644 vdev_list[i] == vdev_id) {
645 chan_list[i] = channel;
646 found = true;
647 }
648 }
649 /**
650 * The new coming vdev should be added to the list to
651 * make decision if it is prioritized.
652 */
653 if (!found && new_conn_mode == pri_conn_mode) {
654 chan_list[vdev_count] = channel;
655 vdev_list[vdev_count++] = vdev_id;
656 }
657 /**
658 * if more than one vdev has same priority, keep "band_pref_5g"
659 * value as default band preference setting.
660 */
661 if (vdev_count > 1)
662 break;
663 /**
664 * select the only active vdev (or new coming vdev) chan as
665 * preferred band.
666 */
667 if (vdev_count > 0) {
668 band_pref_5g = WLAN_REG_IS_5GHZ_CH(chan_list[0]);
669 break;
670 }
671NEXT:
672 vdev_pri_list >>= 4;
673 }
674DONE:
675 policy_mgr_debug("band_pref_5g %d", band_pref_5g);
676 if (band_pref_5g)
677 return PM_DBS1;
678 else
679 return PM_DBS2;
680}
681
682/**
683 * policy_mgr_get_second_conn_action_table() - get second conn action table
684 * @psoc: Pointer to psoc
685 * @vdev_id: vdev Id
686 * @channel: channel of vdev.
687 * @reason: reason of request
688 *
689 * Get the action table based on current HW Caps and INI user preference.
690 * This function will be called by policy_mgr_current_connections_update during
691 * DBS action decision.
692 *
693 * return : action table address
694 */
695static policy_mgr_next_action_two_connection_table_type *
696policy_mgr_get_second_conn_action_table(
697 struct wlan_objmgr_psoc *psoc,
698 uint32_t vdev_id,
699 uint8_t channel,
700 enum policy_mgr_conn_update_reason reason)
701{
702 enum policy_mgr_conc_next_action preferred_action;
703
704 if (!policy_mgr_is_2x2_1x1_dbs_capable(psoc))
705 return next_action_two_connection_table;
706
707 preferred_action = policy_mgr_get_preferred_dbs_action_table(
708 psoc, vdev_id, channel, reason);
709 switch (preferred_action) {
710 case PM_DBS2:
711 return next_action_two_connection_2x2_2g_1x1_5g_table;
712 default:
713 return next_action_two_connection_table;
714 }
715}
716
717/**
718 * policy_mgr_get_third_conn_action_table() - get third connection action table
719 * @psoc: Pointer to psoc
720 * @vdev_id: vdev Id
721 * @channel: channel of vdev.
722 * @reason: reason of request
723 *
724 * Get the action table based on current HW Caps and INI user preference.
725 * This function will be called by policy_mgr_current_connections_update during
726 * DBS action decision.
727 *
728 * return : action table address
729 */
730static policy_mgr_next_action_three_connection_table_type *
731policy_mgr_get_third_conn_action_table(
732 struct wlan_objmgr_psoc *psoc,
733 uint32_t vdev_id,
734 uint8_t channel,
735 enum policy_mgr_conn_update_reason reason)
736{
737 enum policy_mgr_conc_next_action preferred_action;
738
739 if (!policy_mgr_is_2x2_1x1_dbs_capable(psoc))
740 return next_action_three_connection_table;
741
742 preferred_action = policy_mgr_get_preferred_dbs_action_table(
743 psoc, vdev_id, channel, reason);
744 switch (preferred_action) {
745 case PM_DBS2:
746 return next_action_three_connection_2x2_2g_1x1_5g_table;
747 default:
748 return next_action_three_connection_table;
749 }
750}
751
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800752QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc,
753 uint32_t session_id,
754 uint8_t channel,
755 enum policy_mgr_conn_update_reason reason)
756{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800757 enum policy_mgr_conc_next_action next_action = PM_NOP;
758 uint32_t num_connections = 0;
759 enum policy_mgr_one_connection_mode second_index = 0;
760 enum policy_mgr_two_connection_mode third_index = 0;
Liangwei Dongecbf1132018-05-25 05:24:12 -0400761 policy_mgr_next_action_two_connection_table_type *second_conn_table;
762 policy_mgr_next_action_three_connection_table_type *third_conn_table;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800763 enum policy_mgr_band band;
764 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Bala Venkatesh28477d32018-05-07 21:35:55 +0530765 struct policy_mgr_psoc_priv_obj *pm_ctx;
766 enum QDF_OPMODE new_conn_mode = QDF_MAX_NO_OF_MODE;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800767
768 if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
769 policy_mgr_err("driver isn't dbs capable, no further action needed");
770 return QDF_STATUS_E_NOSUPPORT;
771 }
772 if (WLAN_REG_IS_24GHZ_CH(channel))
773 band = POLICY_MGR_BAND_24;
774 else
775 band = POLICY_MGR_BAND_5;
776
777 num_connections = policy_mgr_get_connection_count(psoc);
778
779 policy_mgr_debug("num_connections=%d channel=%d",
780 num_connections, channel);
781
782 switch (num_connections) {
783 case 0:
784 if (band == POLICY_MGR_BAND_24)
785 if (policy_mgr_is_hw_dbs_2x2_capable(psoc))
786 next_action = PM_DBS;
787 else
788 next_action = PM_NOP;
789 else
790 next_action = PM_NOP;
791 break;
792 case 1:
793 second_index =
794 policy_mgr_get_second_connection_pcl_table_index(psoc);
795 if (PM_MAX_ONE_CONNECTION_MODE == second_index) {
796 policy_mgr_err(
797 "couldn't find index for 2nd connection next action table");
798 goto done;
799 }
Liangwei Dongecbf1132018-05-25 05:24:12 -0400800 second_conn_table = policy_mgr_get_second_conn_action_table(
801 psoc, session_id, channel, reason);
802 next_action = (*second_conn_table)[second_index][band];
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800803 break;
804 case 2:
805 third_index =
806 policy_mgr_get_third_connection_pcl_table_index(psoc);
807 if (PM_MAX_TWO_CONNECTION_MODE == third_index) {
808 policy_mgr_err(
809 "couldn't find index for 3rd connection next action table");
810 goto done;
811 }
Liangwei Dongecbf1132018-05-25 05:24:12 -0400812 third_conn_table = policy_mgr_get_third_conn_action_table(
813 psoc, session_id, channel, reason);
814 next_action = (*third_conn_table)[third_index][band];
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800815 break;
816 default:
817 policy_mgr_err("unexpected num_connections value %d",
818 num_connections);
819 break;
820 }
821
Bala Venkatesh28477d32018-05-07 21:35:55 +0530822 pm_ctx = policy_mgr_get_context(psoc);
823 if (!pm_ctx) {
824 policy_mgr_err("Invalid context");
825 goto done;
826 }
827
828 if (pm_ctx->hdd_cbacks.hdd_get_device_mode)
829 new_conn_mode = pm_ctx->hdd_cbacks.
830 hdd_get_device_mode(session_id);
831
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530832 /*
833 * Based on channel_select_logic_conc ini, hw mode is set
834 * when second connection is about to come up that results
835 * in STA+STA and STA+P2P concurrency.
836 * 1) If MCC is set and if current hw mode is dbs, hw mode
837 * should be set to single mac for above concurrency.
838 * 2) If MCC is set and if current hw mode is not dbs, hw
839 * mode change is not required.
840 */
841 if (policy_mgr_is_current_hwmode_dbs(psoc) &&
Bala Venkatesh28477d32018-05-07 21:35:55 +0530842 !policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode))
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530843 next_action = PM_SINGLE_MAC;
844 else if (!policy_mgr_is_current_hwmode_dbs(psoc) &&
Bala Venkatesh28477d32018-05-07 21:35:55 +0530845 !policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode))
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530846 next_action = PM_NOP;
847
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800848 if (PM_NOP != next_action)
849 status = policy_mgr_next_actions(psoc, session_id,
850 next_action, reason);
851 else
852 status = QDF_STATUS_E_NOSUPPORT;
853
854 policy_mgr_debug(
855 "idx2=%d idx3=%d next_action=%d, band=%d status=%d reason=%d session_id=%d",
856 second_index, third_index, next_action, band, status,
857 reason, session_id);
858
859done:
860 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800861}
862
Liangwei Dong18300132018-05-25 01:25:24 -0400863/**
864 * policy_mgr_validate_dbs_switch() - Check DBS action valid or not
865 * @psoc: Pointer to psoc
866 * @session_id: vdev id
867 * @action: action requested
868 * @reason: reason of hw mode change
869 *
870 * This routine will check the current hw mode with requested action.
871 * If we are already in the mode, the caller will do nothing.
872 * This will be called by policy_mgr_next_actions to check the action needed
873 * or not.
874 *
875 * return : QDF_STATUS_SUCCESS, action is allowed.
876 * QDF_STATUS_E_ALREADY, action is not needed.
877 * QDF_STATUS_E_FAILURE, error happens.
878 * QDF_STATUS_E_NOSUPPORT, the requested mode not supported.
879 */
880static
881QDF_STATUS policy_mgr_validate_dbs_switch(
882 struct wlan_objmgr_psoc *psoc,
883 uint32_t session_id,
884 enum policy_mgr_conc_next_action action,
885 enum policy_mgr_conn_update_reason reason)
886{
887 QDF_STATUS status;
888 struct policy_mgr_hw_mode_params hw_mode;
889
890 /* check for the current HW index to see if really need any action */
891 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
892 if (!QDF_IS_STATUS_SUCCESS(status)) {
893 policy_mgr_err("policy_mgr_get_current_hw_mode failed");
894 return status;
895 }
896
897 if (hw_mode.sbs_cap) {
898 if ((action == PM_SBS) || (action == PM_SBS_DOWNGRADE)) {
899 if (!policy_mgr_is_hw_sbs_capable(psoc)) {
900 /* No action */
901 policy_mgr_notice("firmware is not sbs capable");
902 return QDF_STATUS_E_NOSUPPORT;
903 }
904 /* current mode is already SBS nothing to be
905 * done
906 */
907 policy_mgr_notice("current mode is already SBS");
908 return QDF_STATUS_E_ALREADY;
909 } else {
910 return QDF_STATUS_SUCCESS;
911 }
912 }
913
914 if (!hw_mode.dbs_cap) {
915 if (action == PM_SINGLE_MAC ||
916 action == PM_SINGLE_MAC_UPGRADE) {
917 policy_mgr_notice("current mode is already single MAC");
918 return QDF_STATUS_E_ALREADY;
919 } else {
920 return QDF_STATUS_SUCCESS;
921 }
922 }
923 /**
924 * If already in DBS, no need to request DBS again (HL, Napier).
925 * For dual DBS HW, in case DBS1 -> DBS2 or DBS2 -> DBS1
926 * switching, we need to check the current DBS mode is same as
927 * requested or not.
928 */
929 if (policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc) ||
930 policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc)) {
931 policy_mgr_info("curr dbs action %d new action %d",
932 hw_mode.action_type, action);
933 if (hw_mode.action_type == PM_DBS1 &&
934 ((action == PM_DBS1 ||
935 action == PM_DBS1_DOWNGRADE))) {
936 policy_mgr_err("driver is already in DBS_5G_2x2_24G_1x1 (%d), no further action %d needed",
937 hw_mode.action_type, action);
938 return QDF_STATUS_E_ALREADY;
939 } else if (hw_mode.action_type == PM_DBS2 &&
940 ((action == PM_DBS2 ||
941 action == PM_DBS2_DOWNGRADE))) {
942 policy_mgr_err("driver is already in DBS_24G_2x2_5G_1x1 (%d), no further action %d needed",
943 hw_mode.action_type, action);
944 return QDF_STATUS_E_ALREADY;
945 }
946 } else if ((action == PM_DBS_DOWNGRADE) || (action == PM_DBS) ||
947 (action == PM_DBS_UPGRADE)) {
948 policy_mgr_err("driver is already in %s mode, no further action needed",
949 (hw_mode.dbs_cap) ? "dbs" : "non dbs");
950 return QDF_STATUS_E_ALREADY;
951 }
952 return QDF_STATUS_SUCCESS;
953}
954
955QDF_STATUS policy_mgr_next_actions(
956 struct wlan_objmgr_psoc *psoc,
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800957 uint32_t session_id,
958 enum policy_mgr_conc_next_action action,
959 enum policy_mgr_conn_update_reason reason)
960{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800961 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Varun Reddy Yeturue23b6bc2018-01-08 13:18:41 -0800962 struct dbs_nss nss_dbs = {0};
Liangwei Dong18300132018-05-25 01:25:24 -0400963 struct policy_mgr_hw_mode_params hw_mode;
964 enum policy_mgr_conc_next_action next_action;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800965
966 if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
967 policy_mgr_err("driver isn't dbs capable, no further action needed");
968 return QDF_STATUS_E_NOSUPPORT;
969 }
970
971 /* check for the current HW index to see if really need any action */
972 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
973 if (!QDF_IS_STATUS_SUCCESS(status)) {
974 policy_mgr_err("policy_mgr_get_current_hw_mode failed");
975 return status;
976 }
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800977
Liangwei Dong18300132018-05-25 01:25:24 -0400978 /* check for the current HW index to see if really need any action */
979 status = policy_mgr_validate_dbs_switch(psoc, session_id, action,
980 reason);
981 if (!QDF_IS_STATUS_SUCCESS(status)) {
982 policy_mgr_err(" not take action %d reason %d session %d status %d",
983 action, reason, session_id, status);
984 return status;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800985 }
986
987 switch (action) {
988 case PM_DBS_DOWNGRADE:
989 /*
990 * check if we have a beaconing entity that is using 2x2. If yes,
991 * update the beacon template & notify FW. Once FW confirms
992 * beacon updated, send down the HW mode change req
993 */
994 status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
995 PM_DBS, reason, session_id);
996 break;
997 case PM_DBS:
Vikrampal31eb12c2017-04-28 17:44:30 +0530998 (void)policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs);
999
1000 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1001 nss_dbs.mac0_ss,
1002 HW_MODE_80_MHZ,
1003 nss_dbs.mac1_ss,
1004 HW_MODE_40_MHZ,
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001005 HW_MODE_MAC_BAND_NONE,
Vikrampal31eb12c2017-04-28 17:44:30 +05301006 HW_MODE_DBS,
1007 HW_MODE_AGILE_DFS_NONE,
1008 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -08001009 reason, PM_NOP);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001010 break;
1011 case PM_SINGLE_MAC_UPGRADE:
1012 /*
1013 * change the HW mode first before the NSS upgrade
1014 */
1015 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1016 HW_MODE_SS_2x2,
1017 HW_MODE_80_MHZ,
1018 HW_MODE_SS_0x0, HW_MODE_BW_NONE,
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001019 HW_MODE_MAC_BAND_NONE,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001020 HW_MODE_DBS_NONE,
1021 HW_MODE_AGILE_DFS_NONE,
1022 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -08001023 reason, PM_UPGRADE);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001024 break;
1025 case PM_SINGLE_MAC:
1026 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1027 HW_MODE_SS_2x2,
1028 HW_MODE_80_MHZ,
1029 HW_MODE_SS_0x0, HW_MODE_BW_NONE,
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001030 HW_MODE_MAC_BAND_NONE,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001031 HW_MODE_DBS_NONE,
1032 HW_MODE_AGILE_DFS_NONE,
1033 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -08001034 reason, PM_NOP);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001035 break;
1036 case PM_DBS_UPGRADE:
1037 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1038 HW_MODE_SS_2x2,
1039 HW_MODE_80_MHZ,
1040 HW_MODE_SS_2x2, HW_MODE_80_MHZ,
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001041 HW_MODE_MAC_BAND_NONE,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001042 HW_MODE_DBS,
1043 HW_MODE_AGILE_DFS_NONE,
1044 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -08001045 reason, PM_UPGRADE);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001046 break;
1047 case PM_SBS_DOWNGRADE:
1048 status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
1049 PM_SBS, reason, session_id);
1050 break;
1051 case PM_SBS:
1052 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1053 HW_MODE_SS_1x1,
1054 HW_MODE_80_MHZ,
1055 HW_MODE_SS_1x1, HW_MODE_80_MHZ,
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001056 HW_MODE_MAC_BAND_NONE,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001057 HW_MODE_DBS,
1058 HW_MODE_AGILE_DFS_NONE,
1059 HW_MODE_SBS,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -08001060 reason, PM_NOP);
1061 break;
1062 case PM_DOWNGRADE:
1063 /*
1064 * check if we have a beaconing entity that advertised 2x2
1065 * intially. If yes, update the beacon template & notify FW.
1066 */
1067 status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_1,
Liangwei Donga590ecd2018-05-25 00:56:38 -04001068 PM_NOP, POLICY_MGR_ANY, reason);
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -08001069 break;
1070 case PM_UPGRADE:
1071 /*
1072 * check if we have a beaconing entity that advertised 2x2
1073 * intially. If yes, update the beacon template & notify FW.
1074 */
1075 status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_2,
Liangwei Donga590ecd2018-05-25 00:56:38 -04001076 PM_NOP, POLICY_MGR_ANY, reason);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001077 break;
Liangwei Dong18300132018-05-25 01:25:24 -04001078 case PM_DBS1_DOWNGRADE:
1079 status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
1080 PM_DBS1, reason,
1081 session_id);
1082 break;
1083 case PM_DBS2_DOWNGRADE:
1084 status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
1085 PM_DBS2, reason,
1086 session_id);
1087 break;
1088 case PM_DBS1:
1089 /*
1090 * PM_DBS1 (2x2 5G + 1x1 2G) will support 5G 2x2. If previous
1091 * mode is DBS, that should be 2x2 2G + 1x1 5G mode and
1092 * the 5G band was downgraded to 1x1. So, we need to
1093 * upgrade 5G vdevs after hw mode change.
1094 */
1095 if (hw_mode.dbs_cap)
1096 next_action = PM_UPGRADE_5G;
1097 else
1098 next_action = PM_NOP;
1099 status = policy_mgr_pdev_set_hw_mode(
1100 psoc, session_id,
1101 HW_MODE_SS_2x2,
1102 HW_MODE_80_MHZ,
1103 HW_MODE_SS_1x1, HW_MODE_40_MHZ,
1104 HW_MODE_MAC_BAND_5G,
1105 HW_MODE_DBS,
1106 HW_MODE_AGILE_DFS_NONE,
1107 HW_MODE_SBS_NONE,
1108 reason, next_action);
1109 break;
1110 case PM_DBS2:
1111 /*
1112 * PM_DBS2 (2x2 2G + 1x1 5G) will support 2G 2x2. If previous
1113 * mode is DBS, that should be 2x2 5G + 1x1 2G mode and
1114 * the 2G band was downgraded to 1x1. So, we need to
1115 * upgrade 5G vdevs after hw mode change.
1116 */
1117 if (hw_mode.dbs_cap)
1118 next_action = PM_UPGRADE_2G;
1119 else
1120 next_action = PM_NOP;
1121 status = policy_mgr_pdev_set_hw_mode(
1122 psoc, session_id,
1123 HW_MODE_SS_2x2,
1124 HW_MODE_40_MHZ,
1125 HW_MODE_SS_1x1, HW_MODE_40_MHZ,
1126 HW_MODE_MAC_BAND_2G,
1127 HW_MODE_DBS,
1128 HW_MODE_AGILE_DFS_NONE,
1129 HW_MODE_SBS_NONE,
1130 reason, next_action);
1131 break;
1132 case PM_UPGRADE_5G:
1133 status = policy_mgr_nss_update(
1134 psoc, POLICY_MGR_RX_NSS_2,
1135 PM_NOP, POLICY_MGR_BAND_5, reason);
1136 break;
1137 case PM_UPGRADE_2G:
1138 status = policy_mgr_nss_update(
1139 psoc, POLICY_MGR_RX_NSS_2,
1140 PM_NOP, POLICY_MGR_BAND_24, reason);
1141 break;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001142 default:
1143 policy_mgr_err("unexpected action value %d", action);
1144 status = QDF_STATUS_E_FAILURE;
1145 break;
1146 }
1147
1148 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001149}
1150
1151QDF_STATUS policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc,
1152 uint8_t session_id, uint8_t channel)
1153{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001154 QDF_STATUS status;
1155
1156 if (!policy_mgr_check_for_session_conc(psoc, session_id, channel)) {
1157 policy_mgr_err("Conc not allowed for the session %d",
1158 session_id);
1159 return QDF_STATUS_E_FAILURE;
1160 }
1161
1162 status = policy_mgr_reset_connection_update(psoc);
1163 if (!QDF_IS_STATUS_SUCCESS(status))
1164 policy_mgr_err("clearing event failed");
1165
1166 status = policy_mgr_current_connections_update(psoc, session_id,
1167 channel,
1168 POLICY_MGR_UPDATE_REASON_NORMAL_STA);
1169 if (QDF_STATUS_E_FAILURE == status) {
1170 policy_mgr_err("connections update failed");
1171 return status;
1172 }
1173
1174 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001175}
1176
1177#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301178void policy_mgr_update_user_config_sap_chan(
1179 struct wlan_objmgr_psoc *psoc, uint32_t channel)
1180{
1181 struct policy_mgr_psoc_priv_obj *pm_ctx;
1182
1183 pm_ctx = policy_mgr_get_context(psoc);
1184 if (!pm_ctx) {
1185 policy_mgr_err("Invalid pm context and failed to update the user config sap channel");
1186 return;
1187 }
1188 pm_ctx->user_config_sap_channel = channel;
1189}
1190
Archana Ramachandran544ce172017-03-14 15:12:09 -07001191/**
1192 * policy_mgr_is_restart_sap_allowed() - Check if restart SAP
1193 * allowed during SCC -> MCC switch
1194 * @psoc: PSOC object data
1195 * @mcc_to_scc_switch: MCC to SCC switch enabled user config
1196 *
1197 * Check if restart SAP allowed during SCC->MCC switch
1198 *
1199 * Restart: true or false
1200 */
1201static bool policy_mgr_is_restart_sap_allowed(
1202 struct wlan_objmgr_psoc *psoc,
1203 uint32_t mcc_to_scc_switch)
1204{
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301205 uint32_t sta_ap_bit_mask = QDF_STA_MASK | QDF_SAP_MASK;
1206 uint32_t sta_go_bit_mask = QDF_STA_MASK | QDF_P2P_GO_MASK;
1207
Archana Ramachandran544ce172017-03-14 15:12:09 -07001208 if ((mcc_to_scc_switch == QDF_MCC_TO_SCC_SWITCH_DISABLE) ||
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001209 !policy_mgr_concurrent_open_sessions_running(psoc) ||
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301210 !(((policy_mgr_get_concurrency_mode(psoc) & sta_ap_bit_mask)
1211 == sta_ap_bit_mask) ||
Tushnim Bhattacharyyab7f83962018-06-14 17:56:38 -07001212 ((mcc_to_scc_switch ==
1213 QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) &&
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301214 ((policy_mgr_get_concurrency_mode(psoc) & sta_go_bit_mask)
Tushnim Bhattacharyyab7f83962018-06-14 17:56:38 -07001215 == sta_go_bit_mask)))) {
Abhinav Kumar77cb42a2018-06-15 16:46:30 +05301216 policy_mgr_debug("MCC switch disabled or not concurrent STA/SAP, STA/GO");
Archana Ramachandran544ce172017-03-14 15:12:09 -07001217 return false;
1218 }
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001219
Archana Ramachandran544ce172017-03-14 15:12:09 -07001220 return true;
1221}
1222
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -07001223bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc,
1224 uint8_t channel)
1225{
1226 struct policy_mgr_psoc_priv_obj *pm_ctx;
1227 bool is_safe = true;
1228 uint8_t j;
1229
1230 pm_ctx = policy_mgr_get_context(psoc);
1231 if (!pm_ctx) {
1232 policy_mgr_err("Invalid context");
1233 return is_safe;
1234 }
1235
1236
1237 if (pm_ctx->unsafe_channel_count == 0) {
1238 policy_mgr_debug("There are no unsafe channels");
1239 return is_safe;
1240 }
1241
1242 for (j = 0; j < pm_ctx->unsafe_channel_count; j++) {
1243 if (channel == pm_ctx->unsafe_channel_list[j]) {
1244 is_safe = false;
1245 policy_mgr_warn("CH %d is not safe", channel);
1246 break;
1247 }
1248 }
1249
1250 return is_safe;
1251}
1252
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301253bool policy_mgr_is_sap_restart_required_after_sta_disconnect(
1254 struct wlan_objmgr_psoc *psoc, uint8_t *intf_ch)
1255{
1256 struct policy_mgr_psoc_priv_obj *pm_ctx;
1257 uint8_t sap_chan = policy_mgr_mode_specific_get_channel(psoc,
1258 PM_SAP_MODE);
1259 bool sta_sap_scc_on_dfs_chan =
1260 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
1261
1262 *intf_ch = 0;
1263
1264 pm_ctx = policy_mgr_get_context(psoc);
1265 if (!pm_ctx) {
1266 policy_mgr_err("Invalid pm context");
1267 return false;
1268 }
1269
1270 policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sap_chan %u",
1271 sta_sap_scc_on_dfs_chan, sap_chan);
1272
Jianmin Zhu7f6bdd32018-06-29 10:39:30 +08001273 if ((!sta_sap_scc_on_dfs_chan ||
1274 !(sap_chan && WLAN_REG_IS_5GHZ_CH(sap_chan) &&
1275 (wlan_reg_get_channel_state(pm_ctx->pdev, sap_chan) ==
1276 CHANNEL_STATE_DFS))) &&
1277 (!policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) ||
1278 policy_mgr_is_safe_channel(psoc, sap_chan))) {
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301279 return false;
1280 }
1281
1282 *intf_ch = pm_ctx->user_config_sap_channel;
1283 policy_mgr_debug("Standalone SAP is not allowed on DFS channel, Move it to channel %u",
1284 *intf_ch);
1285
1286 return true;
1287}
1288
Archana Ramachandran544ce172017-03-14 15:12:09 -07001289/**
Archana Ramachandran544ce172017-03-14 15:12:09 -07001290 * policy_mgr_check_sta_ap_concurrent_ch_intf() - Restart SAP in STA-AP case
1291 * @data: Pointer check concurrent channel work data
1292 *
1293 * Restarts the SAP interface in STA-AP concurrency scenario
1294 *
1295 * Restart: None
1296 */
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001297void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data)
1298{
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001299 struct wlan_objmgr_psoc *psoc;
1300 struct policy_mgr_psoc_priv_obj *pm_ctx = NULL;
1301 struct sta_ap_intf_check_work_ctx *work_info = NULL;
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301302 uint32_t mcc_to_scc_switch, cc_count = 0, i;
Archana Ramachandran544ce172017-03-14 15:12:09 -07001303 QDF_STATUS status;
1304 uint8_t channel, sec_ch;
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301305 uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS];
1306 uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS];
Archana Ramachandran544ce172017-03-14 15:12:09 -07001307
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001308 work_info = (struct sta_ap_intf_check_work_ctx *) data;
1309 if (!work_info) {
1310 policy_mgr_err("Invalid work_info");
1311 goto end;
1312 }
1313
1314 psoc = work_info->psoc;
1315 if (!psoc) {
1316 policy_mgr_err("Invalid psoc");
1317 goto end;
1318 }
1319
Archana Ramachandran544ce172017-03-14 15:12:09 -07001320 pm_ctx = policy_mgr_get_context(psoc);
1321 if (!pm_ctx) {
1322 policy_mgr_err("Invalid context");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001323 goto end;
Archana Ramachandran544ce172017-03-14 15:12:09 -07001324 }
1325 mcc_to_scc_switch =
1326 policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc);
1327
1328 policy_mgr_info("Concurrent open sessions running: %d",
1329 policy_mgr_concurrent_open_sessions_running(psoc));
1330
1331 if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch))
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001332 goto end;
Archana Ramachandran6199b642017-03-20 13:31:36 -07001333
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301334 cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
1335 &operating_channel[cc_count],
1336 &vdev_id[cc_count],
1337 PM_SAP_MODE);
1338 policy_mgr_debug("Number of concurrent SAP: %d", cc_count);
1339 cc_count = cc_count + policy_mgr_get_mode_specific_conn_info(psoc,
1340 &operating_channel[cc_count],
1341 &vdev_id[cc_count],
1342 PM_P2P_GO_MODE);
1343 policy_mgr_debug("Number of beaconing entities (SAP + GO):%d",
1344 cc_count);
1345 if (!cc_count) {
Ajit Pal Singhc1246b12017-06-16 11:36:12 +05301346 policy_mgr_err("Could not retrieve SAP/GO operating channel&vdevid");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001347 goto end;
Archana Ramachandran6199b642017-03-20 13:31:36 -07001348 }
1349
Bala Venkatesh378064b2018-06-11 15:06:53 +05301350 policy_mgr_debug("wait if channel switch is already in progress");
1351 status = qdf_wait_single_event(
1352 &pm_ctx->channel_switch_complete_evt,
1353 CHANNEL_SWITCH_COMPLETE_TIMEOUT);
1354
1355 if (!QDF_IS_STATUS_SUCCESS(status)) {
1356 policy_mgr_err("wait for event failed, still continue with channel switch");
1357 }
Archana Ramachandran631fd9f2017-03-19 18:51:30 -07001358 if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) {
1359 policy_mgr_err("SAP restart get channel callback in NULL");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001360 goto end;
Archana Ramachandran631fd9f2017-03-19 18:51:30 -07001361 }
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301362 for (i = 0; i < cc_count; i++) {
1363 status = pm_ctx->hdd_cbacks.
1364 wlan_hdd_get_channel_for_sap_restart(psoc,
1365 vdev_id[i], &channel, &sec_ch);
1366 if (status == QDF_STATUS_SUCCESS) {
1367 policy_mgr_info("SAP restarts due to MCC->SCC switch, old chan :%d new chan: %d"
1368 , operating_channel[i], channel);
1369 break;
1370 }
Archana Ramachandran544ce172017-03-14 15:12:09 -07001371 }
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301372 if (status != QDF_STATUS_SUCCESS)
1373 policy_mgr_err("Failed to switch SAP channel");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001374end:
1375 if (work_info) {
1376 qdf_mem_free(work_info);
1377 if (pm_ctx)
1378 pm_ctx->sta_ap_intf_check_work_info = NULL;
1379 }
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001380}
1381
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -07001382static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc,
1383 uint8_t sta_channel)
1384{
1385 struct policy_mgr_psoc_priv_obj *pm_ctx;
1386
1387 pm_ctx = policy_mgr_get_context(psoc);
1388 if (!pm_ctx) {
1389 policy_mgr_err("Invalid context");
1390 return false;
1391 }
1392
Ganesh Kondabattini8a611c62017-11-21 15:01:31 +05301393 if ((wlan_reg_is_dfs_ch(pm_ctx->pdev, sta_channel) &&
1394 (!policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc))) ||
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -07001395 wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev, sta_channel) ||
Ganesh Kondabattini8a611c62017-11-21 15:01:31 +05301396 !policy_mgr_is_safe_channel(psoc, sta_channel)) {
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -07001397 if (policy_mgr_is_hw_dbs_capable(psoc))
1398 return true;
1399 else
1400 return false;
Ganesh Kondabattini8a611c62017-11-21 15:01:31 +05301401 }
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -07001402 else
1403 return true;
1404}
1405
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001406QDF_STATUS policy_mgr_valid_sap_conc_channel_check(
1407 struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch)
1408{
1409 uint8_t channel = *con_ch;
1410 uint8_t temp_channel = 0;
1411 struct policy_mgr_psoc_priv_obj *pm_ctx;
Bala Venkatesh7c96e542018-06-07 19:32:27 +05301412 bool sta_sap_scc_on_dfs_chan;
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001413
1414 pm_ctx = policy_mgr_get_context(psoc);
1415 if (!pm_ctx) {
1416 policy_mgr_err("Invalid context");
1417 return QDF_STATUS_E_FAILURE;
1418 }
1419
1420 /*
1421 * if force SCC is set, Check if conc channel is DFS
1422 * or passive or part of LTE avoided channel list.
1423 * In that case move SAP to other band if DBS is supported,
1424 * return otherwise
1425 */
1426 if (!policy_mgr_is_force_scc(psoc))
1427 return QDF_STATUS_SUCCESS;
1428
1429 /*
1430 * if interference is 0, check if it is DBS case. If DBS case
1431 * return from here. If SCC, check further if SAP can move to
1432 * STA's channel.
1433 */
1434 if (!channel &&
1435 (sap_ch != policy_mgr_mode_specific_get_channel(
1436 psoc, PM_STA_MODE)))
1437 return QDF_STATUS_SUCCESS;
1438 else if (!channel)
1439 channel = sap_ch;
1440
Bala Venkatesh7c96e542018-06-07 19:32:27 +05301441 sta_sap_scc_on_dfs_chan =
1442 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
1443
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001444 if (policy_mgr_valid_sta_channel_check(psoc, channel)) {
1445 if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) ||
Zhu Jianmin5ac66ef2018-06-11 19:03:39 +08001446 wlan_reg_is_passive_or_disable_ch(
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001447 pm_ctx->pdev, channel) ||
Zhu Jianmin5ac66ef2018-06-11 19:03:39 +08001448 !(policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) ||
1449 policy_mgr_is_safe_channel(psoc, channel))) {
Liangwei Dongbd8b24b2018-09-05 23:13:52 -04001450 if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) &&
1451 sta_sap_scc_on_dfs_chan) {
1452 policy_mgr_debug("STA SAP SCC is allowed on DFS channel");
1453 goto update_chan;
1454 }
1455
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001456 if (policy_mgr_is_hw_dbs_capable(psoc)) {
1457 temp_channel =
1458 policy_mgr_get_alternate_channel_for_sap(psoc);
1459 policy_mgr_debug("temp_channel is %d",
1460 temp_channel);
1461 if (temp_channel) {
1462 channel = temp_channel;
1463 } else {
1464 if (WLAN_REG_IS_5GHZ_CH(channel))
1465 channel = PM_24_GHZ_CHANNEL_6;
1466 else
1467 channel = PM_5_GHZ_CHANNEL_36;
1468 }
1469 if (!policy_mgr_is_safe_channel(
1470 psoc, channel)) {
1471 policy_mgr_warn(
1472 "Can't have concurrency on %d as it is not safe",
1473 channel);
1474 return QDF_STATUS_E_FAILURE;
1475 }
1476 } else {
1477 policy_mgr_warn("Can't have concurrency on %d",
1478 channel);
1479 return QDF_STATUS_E_FAILURE;
1480 }
1481 }
1482 }
1483
Bala Venkatesh7c96e542018-06-07 19:32:27 +05301484update_chan:
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001485 if (channel != sap_ch)
1486 *con_ch = channel;
1487
1488 return QDF_STATUS_SUCCESS;
1489}
1490
Archana Ramachandran107d3782017-03-06 17:07:44 -08001491/**
1492 * policy_mgr_check_concurrent_intf_and_restart_sap() - Check
1493 * concurrent change intf
1494 * @psoc: PSOC object information
1495 * @operation_channel: operation channel
Archana Ramachandran544ce172017-03-14 15:12:09 -07001496 * @vdev_id: vdev id of SAP
Archana Ramachandran107d3782017-03-06 17:07:44 -08001497 *
1498 * Checks the concurrent change interface and restarts SAP
1499 *
1500 * Return: None
1501 */
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001502void policy_mgr_check_concurrent_intf_and_restart_sap(
Archana Ramachandran6199b642017-03-20 13:31:36 -07001503 struct wlan_objmgr_psoc *psoc)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001504{
Archana Ramachandran266613f2017-03-13 16:36:55 -07001505 struct policy_mgr_psoc_priv_obj *pm_ctx;
1506 uint32_t mcc_to_scc_switch;
Tushnim Bhattacharyyaf8417d12018-05-08 15:31:21 -07001507 uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
1508 uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
1509 uint32_t cc_count = 0;
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301510 bool restart_sap = false;
1511 uint8_t sap_ch;
Archana Ramachandran266613f2017-03-13 16:36:55 -07001512
1513 pm_ctx = policy_mgr_get_context(psoc);
1514 if (!pm_ctx) {
1515 policy_mgr_err("Invalid context");
1516 return;
1517 }
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301518 if (policy_mgr_get_connection_count(psoc) == 1) {
1519 /*
1520 * If STA+SAP sessions are on DFS channel and STA+SAP SCC is
1521 * enabled on DFS channel then move the SAP out of DFS channel
1522 * as soon as STA gets disconnect.
Jianmin Zhu7f6bdd32018-06-29 10:39:30 +08001523 * If STA+SAP sessions are on unsafe channel and STA+SAP SCC is
1524 * enabled on unsafe channel then move the SAP to safe channel
1525 * as soon as STA disconnected.
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301526 */
1527 if (policy_mgr_is_sap_restart_required_after_sta_disconnect(
1528 psoc, &sap_ch)) {
1529 policy_mgr_debug("move the SAP to configured channel %u",
1530 sap_ch);
1531 restart_sap = true;
1532 goto sap_restart;
1533 }
1534 }
Archana Ramachandran266613f2017-03-13 16:36:55 -07001535
Tushnim Bhattacharyyaf8417d12018-05-08 15:31:21 -07001536 /*
1537 * force SCC with STA+STA+SAP will need some additional logic
1538 */
1539 cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
1540 &operating_channel[cc_count],
1541 &vdev_id[cc_count], PM_STA_MODE);
1542 if (!cc_count) {
Yeshwanth Sriram Guntukad540cd02018-08-23 18:25:28 +05301543 policy_mgr_debug("Could not get STA operating channel&vdevid");
Archana Ramachandran6199b642017-03-20 13:31:36 -07001544 return;
1545 }
1546
Archana Ramachandran266613f2017-03-13 16:36:55 -07001547 mcc_to_scc_switch =
1548 policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc);
1549 policy_mgr_info("MCC to SCC switch: %d chan: %d",
Tushnim Bhattacharyyaf8417d12018-05-08 15:31:21 -07001550 mcc_to_scc_switch, operating_channel[0]);
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001551
1552 if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch)) {
1553 policy_mgr_debug(
1554 "No action taken at check_concurrent_intf_and_restart_sap");
1555 return;
1556 }
1557
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301558sap_restart:
1559 /*
1560 * If sta_sap_scc_on_dfs_chan is true then standalone SAP is not
1561 * allowed on DFS channel. SAP is allowed on DFS channel only when STA
1562 * is already connected on that channel.
1563 * In following condition restart_sap will be true if
1564 * sta_sap_scc_on_dfs_chan is true and SAP is on DFS channel.
1565 * This scenario can come if STA+SAP are operating on DFS channel and
1566 * STA gets disconnected.
1567 */
1568 if (restart_sap ||
1569 ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) &&
1570 policy_mgr_valid_sta_channel_check(psoc, operating_channel[0]) &&
1571 !pm_ctx->sta_ap_intf_check_work_info)) {
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001572 struct sta_ap_intf_check_work_ctx *work_info;
1573 work_info = qdf_mem_malloc(
1574 sizeof(struct sta_ap_intf_check_work_ctx));
1575 pm_ctx->sta_ap_intf_check_work_info = work_info;
1576 if (work_info) {
1577 work_info->psoc = psoc;
1578 qdf_create_work(0, &pm_ctx->sta_ap_intf_check_work,
Archana Ramachandran6199b642017-03-20 13:31:36 -07001579 policy_mgr_check_sta_ap_concurrent_ch_intf,
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001580 work_info);
1581 qdf_sched_work(0, &pm_ctx->sta_ap_intf_check_work);
1582 policy_mgr_info(
1583 "Checking for Concurrent Change interference");
1584 }
Archana Ramachandran266613f2017-03-13 16:36:55 -07001585 }
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001586}
1587#endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */
1588
1589#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Archana Ramachandran0edce252017-03-06 14:36:29 -08001590/**
1591 * policy_mgr_change_sap_channel_with_csa() - Move SAP channel using (E)CSA
1592 * @psoc: PSOC object information
1593 * @vdev_id: Vdev id
1594 * @channel: Channel to change
1595 * @ch_width: channel width to change
Min Liuc5b10432018-01-19 18:01:44 +08001596 * @forced: Force to switch channel, ignore SCC/MCC check
Archana Ramachandran0edce252017-03-06 14:36:29 -08001597 *
1598 * Invoke the callback function to change SAP channel using (E)CSA
1599 *
1600 * Return: None
1601 */
1602void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc,
1603 uint8_t vdev_id, uint32_t channel,
Min Liuc5b10432018-01-19 18:01:44 +08001604 uint32_t ch_width,
1605 bool forced)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001606{
Archana Ramachandran0edce252017-03-06 14:36:29 -08001607 struct policy_mgr_psoc_priv_obj *pm_ctx;
1608
1609 pm_ctx = policy_mgr_get_context(psoc);
1610 if (!pm_ctx) {
1611 policy_mgr_err("Invalid context");
1612 return;
1613 }
1614
Archana Ramachandran544ce172017-03-14 15:12:09 -07001615 if (pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb) {
Archana Ramachandran0edce252017-03-06 14:36:29 -08001616 policy_mgr_info("SAP change change without restart");
Archana Ramachandran631fd9f2017-03-19 18:51:30 -07001617 pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb(psoc,
Min Liuc5b10432018-01-19 18:01:44 +08001618 vdev_id, channel, ch_width, forced);
Archana Ramachandran0edce252017-03-06 14:36:29 -08001619 }
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001620}
1621#endif
1622
1623QDF_STATUS policy_mgr_wait_for_connection_update(struct wlan_objmgr_psoc *psoc)
1624{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001625 QDF_STATUS status;
1626 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1627
1628 policy_mgr_context = policy_mgr_get_context(psoc);
1629 if (!policy_mgr_context) {
1630 policy_mgr_err("Invalid context");
1631 return QDF_STATUS_E_FAILURE;
1632 }
1633
1634 status = qdf_wait_single_event(
1635 &policy_mgr_context->connection_update_done_evt,
1636 CONNECTION_UPDATE_TIMEOUT);
1637
1638 if (!QDF_IS_STATUS_SUCCESS(status)) {
1639 policy_mgr_err("wait for event failed");
1640 return QDF_STATUS_E_FAILURE;
1641 }
1642
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001643 return QDF_STATUS_SUCCESS;
1644}
1645
1646QDF_STATUS policy_mgr_reset_connection_update(struct wlan_objmgr_psoc *psoc)
1647{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001648 QDF_STATUS status;
1649 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1650
1651 policy_mgr_context = policy_mgr_get_context(psoc);
1652 if (!policy_mgr_context) {
1653 policy_mgr_err("Invalid context");
1654 return QDF_STATUS_E_FAILURE;
1655 }
1656
1657 status = qdf_event_reset(
1658 &policy_mgr_context->connection_update_done_evt);
1659
1660 if (!QDF_IS_STATUS_SUCCESS(status)) {
1661 policy_mgr_err("clear event failed");
1662 return QDF_STATUS_E_FAILURE;
1663 }
1664
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001665 return QDF_STATUS_SUCCESS;
1666}
1667
1668QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc)
1669{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001670 QDF_STATUS status;
1671 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1672
1673 policy_mgr_context = policy_mgr_get_context(psoc);
1674 if (!policy_mgr_context) {
1675 policy_mgr_err("Invalid context");
1676 return QDF_STATUS_E_FAILURE;
1677 }
1678
1679 status = qdf_event_set(&policy_mgr_context->connection_update_done_evt);
1680
1681 if (!QDF_IS_STATUS_SUCCESS(status)) {
1682 policy_mgr_err("set event failed");
1683 return QDF_STATUS_E_FAILURE;
1684 }
1685
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001686 return QDF_STATUS_SUCCESS;
1687}
1688
Bala Venkatesh378064b2018-06-11 15:06:53 +05301689QDF_STATUS policy_mgr_set_chan_switch_complete_evt(
1690 struct wlan_objmgr_psoc *psoc)
1691{
1692 QDF_STATUS status;
1693 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1694
1695 policy_mgr_context = policy_mgr_get_context(psoc);
1696
1697 if (!policy_mgr_context) {
1698 policy_mgr_err("Invalid context");
1699 return QDF_STATUS_E_FAILURE;
1700 }
1701 status = qdf_event_set(
1702 &policy_mgr_context->channel_switch_complete_evt);
1703
1704 if (!QDF_IS_STATUS_SUCCESS(status)) {
1705 policy_mgr_err("set event failed");
1706 return QDF_STATUS_E_FAILURE;
1707 }
1708
1709 return QDF_STATUS_SUCCESS;
1710}
1711
1712QDF_STATUS policy_mgr_reset_chan_switch_complete_evt(
1713 struct wlan_objmgr_psoc *psoc)
1714{
1715 QDF_STATUS status;
1716 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1717
1718 policy_mgr_context = policy_mgr_get_context(psoc);
1719
1720 if (!policy_mgr_context) {
1721 policy_mgr_err("Invalid context");
1722 return QDF_STATUS_E_FAILURE;
1723 }
1724 status = qdf_event_reset(
1725 &policy_mgr_context->channel_switch_complete_evt);
1726
1727 if (!QDF_IS_STATUS_SUCCESS(status)) {
1728 policy_mgr_err("reset event failed");
1729 return QDF_STATUS_E_FAILURE;
1730 }
1731
1732 return QDF_STATUS_SUCCESS;
1733}
1734
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001735QDF_STATUS policy_mgr_set_opportunistic_update(struct wlan_objmgr_psoc *psoc)
1736{
1737 QDF_STATUS status;
1738 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1739
1740 policy_mgr_context = policy_mgr_get_context(psoc);
1741 if (!policy_mgr_context) {
1742 policy_mgr_err("Invalid context");
1743 return QDF_STATUS_E_FAILURE;
1744 }
1745
1746 status = qdf_event_set(
1747 &policy_mgr_context->opportunistic_update_done_evt);
1748
1749 if (!QDF_IS_STATUS_SUCCESS(status)) {
1750 policy_mgr_err("set event failed");
1751 return QDF_STATUS_E_FAILURE;
1752 }
1753
1754 return QDF_STATUS_SUCCESS;
1755}
1756
Himanshu Agarwal70a52d92018-05-04 14:37:48 +05301757QDF_STATUS policy_mgr_stop_opportunistic_timer(struct wlan_objmgr_psoc *psoc)
1758{
1759 struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
1760
1761 policy_mgr_ctx = policy_mgr_get_context(psoc);
1762 if (!policy_mgr_ctx) {
1763 policy_mgr_err("Invalid context");
1764 return QDF_STATUS_E_FAILURE;
1765 }
1766
1767 if (policy_mgr_ctx->dbs_opportunistic_timer.state !=
1768 QDF_TIMER_STATE_RUNNING)
1769 return QDF_STATUS_SUCCESS;
1770
1771 qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer);
1772 return QDF_STATUS_SUCCESS;
1773}
1774
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001775QDF_STATUS policy_mgr_restart_opportunistic_timer(
1776 struct wlan_objmgr_psoc *psoc, bool check_state)
1777{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001778 QDF_STATUS status = QDF_STATUS_E_FAILURE;
1779 struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
1780
1781 policy_mgr_ctx = policy_mgr_get_context(psoc);
1782 if (!policy_mgr_ctx) {
1783 policy_mgr_err("Invalid context");
1784 return status;
1785 }
1786
1787 if (check_state &&
1788 QDF_TIMER_STATE_RUNNING !=
1789 policy_mgr_ctx->dbs_opportunistic_timer.state)
1790 return status;
1791
1792 qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer);
1793
1794 status = qdf_mc_timer_start(
1795 &policy_mgr_ctx->dbs_opportunistic_timer,
1796 DBS_OPPORTUNISTIC_TIME * 1000);
1797
1798 if (!QDF_IS_STATUS_SUCCESS(status)) {
1799 policy_mgr_err("failed to start opportunistic timer");
1800 return status;
1801 }
1802
1803 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001804}
1805
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001806QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch(
1807 struct wlan_objmgr_psoc *psoc, uint8_t session_id)
1808{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001809 QDF_STATUS status = QDF_STATUS_E_FAILURE, qdf_status;
1810 enum policy_mgr_conc_next_action action;
1811
1812 if (!policy_mgr_is_hw_dbs_capable(psoc)) {
1813 policy_mgr_err("PM/DBS is disabled");
1814 return status;
1815 }
1816
1817 action = (*policy_mgr_get_current_pref_hw_mode_ptr)(psoc);
1818 if ((action != PM_DBS_DOWNGRADE) &&
1819 (action != PM_SINGLE_MAC_UPGRADE)) {
1820 policy_mgr_err("Invalid action: %d", action);
1821 status = QDF_STATUS_SUCCESS;
1822 goto done;
1823 }
1824
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001825 policy_mgr_debug("action:%d session id:%d", action, session_id);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001826
1827 /* Opportunistic timer is started, PM will check if MCC upgrade can be
1828 * done on timer expiry. This avoids any possible ping pong effect
1829 * as well.
1830 */
1831 if (action == PM_SINGLE_MAC_UPGRADE) {
1832 qdf_status = policy_mgr_restart_opportunistic_timer(
1833 psoc, false);
1834 if (QDF_IS_STATUS_SUCCESS(qdf_status))
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001835 policy_mgr_debug("opportunistic timer for MCC upgrade");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001836 goto done;
1837 }
1838
1839 /* For DBS, we want to move right away to DBS mode */
1840 status = policy_mgr_next_actions(psoc, session_id, action,
1841 POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH);
1842 if (!QDF_IS_STATUS_SUCCESS(status)) {
1843 policy_mgr_err("no set hw mode command was issued");
1844 goto done;
1845 }
1846done:
1847 /* success must be returned only when a set hw mode was done */
1848 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001849}
1850
1851void policy_mgr_checkn_update_hw_mode_single_mac_mode(
1852 struct wlan_objmgr_psoc *psoc, uint8_t channel)
1853{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001854 uint8_t i;
1855 struct policy_mgr_psoc_priv_obj *pm_ctx;
1856
1857 pm_ctx = policy_mgr_get_context(psoc);
1858 if (!pm_ctx) {
1859 policy_mgr_err("Invalid Context");
1860 return;
1861 }
1862
gaurank kathpaliaafa4e1b2018-07-05 15:04:46 +05301863 if (QDF_TIMER_STATE_RUNNING ==
1864 pm_ctx->dbs_opportunistic_timer.state)
1865 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
1866
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001867 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1868 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
Tushnim Bhattacharyyac304f892018-08-01 19:15:55 -07001869 if (pm_conc_connection_list[i].in_use) {
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001870 if (!WLAN_REG_IS_SAME_BAND_CHANNELS(channel,
1871 pm_conc_connection_list[i].chan)) {
1872 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001873 policy_mgr_debug("DBS required");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001874 return;
1875 }
Tushnim Bhattacharyyac304f892018-08-01 19:15:55 -07001876 if (policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
1877 (WLAN_REG_IS_24GHZ_CH(channel) ||
1878 WLAN_REG_IS_24GHZ_CH
1879 (pm_conc_connection_list[i].chan))) {
1880 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1881 policy_mgr_debug("DBS required");
1882 return;
1883 }
1884 }
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001885 }
1886 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001887 pm_dbs_opportunistic_timer_handler((void *)psoc);
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001888}
1889
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001890void policy_mgr_check_and_stop_opportunistic_timer(
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001891 struct wlan_objmgr_psoc *psoc, uint8_t id)
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001892{
1893 struct policy_mgr_psoc_priv_obj *pm_ctx;
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001894 enum policy_mgr_conc_next_action action = PM_NOP;
1895 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001896
1897 pm_ctx = policy_mgr_get_context(psoc);
1898 if (!pm_ctx) {
1899 policy_mgr_err("Invalid Context");
1900 return;
1901 }
1902 if (QDF_TIMER_STATE_RUNNING ==
1903 pm_ctx->dbs_opportunistic_timer.state) {
1904 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001905 action = policy_mgr_need_opportunistic_upgrade(psoc);
1906 if (action) {
Krunal Soni4943b902018-01-05 17:36:40 -08001907 qdf_event_reset(&pm_ctx->opportunistic_update_done_evt);
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001908 status = policy_mgr_next_actions(psoc, id, action,
1909 POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC);
1910 if (status != QDF_STATUS_SUCCESS) {
1911 policy_mgr_err("Failed in policy_mgr_next_actions");
1912 return;
1913 }
1914 status = qdf_wait_single_event(
1915 &pm_ctx->opportunistic_update_done_evt,
1916 CONNECTION_UPDATE_TIMEOUT);
1917
1918 if (!QDF_IS_STATUS_SUCCESS(status)) {
1919 policy_mgr_err("wait for event failed");
1920 return;
1921 }
1922 }
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001923 }
1924}
1925
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07001926void policy_mgr_set_hw_mode_change_in_progress(
1927 struct wlan_objmgr_psoc *psoc, enum policy_mgr_hw_mode_change value)
1928{
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001929 struct policy_mgr_psoc_priv_obj *pm_ctx;
1930
1931 pm_ctx = policy_mgr_get_context(psoc);
1932 if (!pm_ctx) {
1933 policy_mgr_err("Invalid Context");
1934 return;
1935 }
1936
1937 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1938 pm_ctx->hw_mode_change_in_progress = value;
1939 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1940
1941 policy_mgr_debug("hw_mode_change_in_progress:%d", value);
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07001942}
1943
1944enum policy_mgr_hw_mode_change policy_mgr_is_hw_mode_change_in_progress(
1945 struct wlan_objmgr_psoc *psoc)
1946{
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001947 enum policy_mgr_hw_mode_change value;
1948 struct policy_mgr_psoc_priv_obj *pm_ctx;
1949
1950 value = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
1951
1952 pm_ctx = policy_mgr_get_context(psoc);
1953 if (!pm_ctx) {
1954 policy_mgr_err("Invalid Context");
1955 return value;
1956 }
1957 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1958 value = pm_ctx->hw_mode_change_in_progress;
1959 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1960
1961 return value;
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07001962}
1963
1964enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index(
1965 struct wlan_objmgr_psoc *psoc, uint32_t hw_mode_index)
1966{
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001967 struct policy_mgr_psoc_priv_obj *pm_ctx;
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001968 struct policy_mgr_hw_mode_params hw_mode;
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001969 enum policy_mgr_hw_mode_change value
1970 = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001971 QDF_STATUS status;
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001972
1973 pm_ctx = policy_mgr_get_context(psoc);
1974 if (!pm_ctx) {
1975 policy_mgr_err("Invalid Context");
1976 return value;
1977 }
1978
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001979 status = policy_mgr_get_hw_mode_from_idx(psoc, hw_mode_index, &hw_mode);
1980 if (status != QDF_STATUS_SUCCESS) {
1981 policy_mgr_err("Failed to get HW mode index");
1982 return value;
1983 }
1984
1985 if (hw_mode.dbs_cap) {
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001986 policy_mgr_info("DBS is requested with HW (%d)",
1987 hw_mode_index);
1988 value = POLICY_MGR_DBS_IN_PROGRESS;
1989 goto ret_value;
1990 }
1991
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001992 if (hw_mode.sbs_cap) {
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001993 policy_mgr_info("SBS is requested with HW (%d)",
1994 hw_mode_index);
1995 value = POLICY_MGR_SBS_IN_PROGRESS;
1996 goto ret_value;
1997 }
1998
1999 value = POLICY_MGR_SMM_IN_PROGRESS;
2000 policy_mgr_info("SMM is requested with HW (%d)", hw_mode_index);
2001
2002ret_value:
2003 return value;
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07002004}
2005
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002006#ifdef MPC_UT_FRAMEWORK
2007QDF_STATUS policy_mgr_update_connection_info_utfw(
2008 struct wlan_objmgr_psoc *psoc,
2009 uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
2010 uint32_t chain_mask, uint32_t type, uint32_t sub_type,
2011 uint32_t channelid, uint32_t mac_id)
2012{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002013 QDF_STATUS status = QDF_STATUS_E_FAILURE;
2014 uint32_t conn_index = 0, found = 0;
2015 struct policy_mgr_psoc_priv_obj *pm_ctx;
2016
2017 pm_ctx = policy_mgr_get_context(psoc);
2018 if (!pm_ctx) {
2019 policy_mgr_err("Invalid Context");
2020 return status;
2021 }
2022
2023 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2024 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2025 if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
2026 /* debug msg */
2027 found = 1;
2028 break;
2029 }
2030 conn_index++;
2031 }
2032 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2033 if (!found) {
2034 /* err msg */
2035 policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list",
2036 vdev_id);
2037 return status;
2038 }
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07002039 policy_mgr_debug("--> updating entry at index[%d]", conn_index);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002040
2041 policy_mgr_update_conc_list(psoc, conn_index,
2042 policy_mgr_get_mode(type, sub_type),
2043 channelid, HW_MODE_20_MHZ,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05302044 mac_id, chain_mask, 0, vdev_id, true, true);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002045
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002046 return QDF_STATUS_SUCCESS;
2047}
2048
2049QDF_STATUS policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc,
2050 uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
2051 uint32_t chain_mask, uint32_t type, uint32_t sub_type,
2052 uint32_t channelid, uint32_t mac_id)
2053{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002054 QDF_STATUS status = QDF_STATUS_E_FAILURE;
2055 uint32_t conn_index = 0;
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05302056 bool update_conn = true;
2057 enum policy_mgr_con_mode mode;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002058
2059 conn_index = policy_mgr_get_connection_count(psoc);
2060 if (MAX_NUMBER_OF_CONC_CONNECTIONS <= conn_index) {
2061 /* err msg */
2062 policy_mgr_err("exceeded max connection limit %d",
2063 MAX_NUMBER_OF_CONC_CONNECTIONS);
2064 return status;
2065 }
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07002066 policy_mgr_debug("--> filling entry at index[%d]", conn_index);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002067
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05302068 mode = policy_mgr_get_mode(type, sub_type);
2069 if (mode == PM_STA_MODE || mode == PM_P2P_CLIENT_MODE)
2070 update_conn = false;
2071
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002072 policy_mgr_update_conc_list(psoc, conn_index,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05302073 mode,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002074 channelid, HW_MODE_20_MHZ,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05302075 mac_id, chain_mask, 0, vdev_id, true,
2076 update_conn);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002077
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002078 return QDF_STATUS_SUCCESS;
2079}
2080
2081QDF_STATUS policy_mgr_decr_connection_count_utfw(struct wlan_objmgr_psoc *psoc,
2082 uint32_t del_all, uint32_t vdev_id)
2083{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002084 QDF_STATUS status;
2085
2086 if (del_all) {
Krunal Sonic54f1a62018-09-05 10:58:05 -07002087 status = policy_mgr_psoc_disable(psoc);
2088 if (!QDF_IS_STATUS_SUCCESS(status)) {
2089 policy_mgr_err("Policy manager initialization failed");
2090 return QDF_STATUS_E_FAILURE;
2091 }
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002092 status = policy_mgr_psoc_enable(psoc);
2093 if (!QDF_IS_STATUS_SUCCESS(status)) {
2094 policy_mgr_err("Policy manager initialization failed");
2095 return QDF_STATUS_E_FAILURE;
2096 }
2097 } else {
2098 policy_mgr_decr_connection_count(psoc, vdev_id);
2099 }
2100
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002101 return QDF_STATUS_SUCCESS;
2102}
2103
2104enum policy_mgr_pcl_type policy_mgr_get_pcl_from_first_conn_table(
2105 enum policy_mgr_con_mode type,
2106 enum policy_mgr_conc_priority_mode sys_pref)
2107{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002108 if ((sys_pref >= PM_MAX_CONC_PRIORITY_MODE) ||
2109 (type >= PM_MAX_NUM_OF_MODE))
2110 return PM_MAX_PCL_TYPE;
2111 return first_connection_pcl_table[type][sys_pref];
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002112}
2113
2114enum policy_mgr_pcl_type policy_mgr_get_pcl_from_second_conn_table(
2115 enum policy_mgr_one_connection_mode idx, enum policy_mgr_con_mode type,
2116 enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable)
2117{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002118 if ((idx >= PM_MAX_ONE_CONNECTION_MODE) ||
2119 (sys_pref >= PM_MAX_CONC_PRIORITY_MODE) ||
2120 (type >= PM_MAX_NUM_OF_MODE))
2121 return PM_MAX_PCL_TYPE;
2122 if (dbs_capable)
2123 return (*second_connection_pcl_dbs_table)[idx][type][sys_pref];
2124 else
2125 return second_connection_pcl_nodbs_table[idx][type][sys_pref];
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002126}
2127
2128enum policy_mgr_pcl_type policy_mgr_get_pcl_from_third_conn_table(
2129 enum policy_mgr_two_connection_mode idx, enum policy_mgr_con_mode type,
2130 enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable)
2131{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002132 if ((idx >= PM_MAX_TWO_CONNECTION_MODE) ||
2133 (sys_pref >= PM_MAX_CONC_PRIORITY_MODE) ||
2134 (type >= PM_MAX_NUM_OF_MODE))
2135 return PM_MAX_PCL_TYPE;
2136 if (dbs_capable)
2137 return (*third_connection_pcl_dbs_table)[idx][type][sys_pref];
2138 else
2139 return third_connection_pcl_nodbs_table[idx][type][sys_pref];
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002140}
2141#endif