blob: 9d16bdd63c258a36f8e727ebe17eae7ba8ceee0f [file] [log] [blame]
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001/*
2 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * DOC: wlan_policy_mgr_get_set_utils.c
30 *
31 * WLAN Concurrenct Connection Management APIs
32 *
33 */
34
35/* Include files */
36
37#include "wlan_policy_mgr_api.h"
38#include "wlan_policy_mgr_i.h"
39#include "qdf_types.h"
40#include "qdf_trace.h"
41#include "wlan_objmgr_global_obj.h"
Ajit Pal Singhc65575e2017-04-17 16:49:01 +053042#include "wlan_objmgr_pdev_obj.h"
43#include "wlan_objmgr_vdev_obj.h"
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -080044
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -080045/* invalid channel id. */
46#define INVALID_CHANNEL_ID 0
47
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -070048void policy_mgr_update_new_hw_mode_index(struct wlan_objmgr_psoc *psoc,
49 uint32_t new_hw_mode_index)
50{
51 struct policy_mgr_psoc_priv_obj *pm_ctx;
52
53 pm_ctx = policy_mgr_get_context(psoc);
54 if (!pm_ctx) {
55 policy_mgr_err("Invalid Context");
56 return;
57 }
58 pm_ctx->new_hw_mode_index = new_hw_mode_index;
59}
60
61void policy_mgr_update_old_hw_mode_index(struct wlan_objmgr_psoc *psoc,
62 uint32_t old_hw_mode_index)
63{
64 struct policy_mgr_psoc_priv_obj *pm_ctx;
65
66 pm_ctx = policy_mgr_get_context(psoc);
67 if (!pm_ctx) {
68 policy_mgr_err("Invalid Context");
69 return;
70 }
71 pm_ctx->old_hw_mode_index = old_hw_mode_index;
72}
73
74void policy_mgr_update_hw_mode_index(struct wlan_objmgr_psoc *psoc,
75 uint32_t new_hw_mode_index)
76{
77 struct policy_mgr_psoc_priv_obj *pm_ctx;
78
79 pm_ctx = policy_mgr_get_context(psoc);
80 if (!pm_ctx) {
81 policy_mgr_err("Invalid Context");
82 return;
83 }
84 if (POLICY_MGR_DEFAULT_HW_MODE_INDEX == pm_ctx->new_hw_mode_index) {
85 pm_ctx->new_hw_mode_index = new_hw_mode_index;
86 } else {
87 pm_ctx->old_hw_mode_index = pm_ctx->new_hw_mode_index;
88 pm_ctx->new_hw_mode_index = new_hw_mode_index;
89 }
90 policy_mgr_debug("Updated: old_hw_mode_index:%d new_hw_mode_index:%d",
91 pm_ctx->old_hw_mode_index, pm_ctx->new_hw_mode_index);
92}
93
94/**
95 * policy_mgr_get_num_of_setbits_from_bitmask() - to get num of
96 * setbits from bitmask
97 * @mask: given bitmask
98 *
99 * This helper function should return number of setbits from bitmask
100 *
101 * Return: number of setbits from bitmask
102 */
103static uint32_t policy_mgr_get_num_of_setbits_from_bitmask(uint32_t mask)
104{
105 uint32_t num_of_setbits = 0;
106
107 while (mask) {
108 mask &= (mask - 1);
109 num_of_setbits++;
110 }
111 return num_of_setbits;
112}
113
114/**
115 * policy_mgr_map_wmi_channel_width_to_hw_mode_bw() - returns
116 * bandwidth in terms of hw_mode_bandwidth
117 * @width: bandwidth in terms of wmi_channel_width
118 *
119 * This function returns the bandwidth in terms of hw_mode_bandwidth.
120 *
121 * Return: BW in terms of hw_mode_bandwidth.
122 */
123static enum hw_mode_bandwidth policy_mgr_map_wmi_channel_width_to_hw_mode_bw(
124 wmi_channel_width width)
125{
126 switch (width) {
127 case WMI_CHAN_WIDTH_20:
128 return HW_MODE_20_MHZ;
129 case WMI_CHAN_WIDTH_40:
130 return HW_MODE_40_MHZ;
131 case WMI_CHAN_WIDTH_80:
132 return HW_MODE_80_MHZ;
133 case WMI_CHAN_WIDTH_160:
134 return HW_MODE_160_MHZ;
135 case WMI_CHAN_WIDTH_80P80:
136 return HW_MODE_80_PLUS_80_MHZ;
137 case WMI_CHAN_WIDTH_5:
138 return HW_MODE_5_MHZ;
139 case WMI_CHAN_WIDTH_10:
140 return HW_MODE_10_MHZ;
141 default:
142 return HW_MODE_BW_NONE;
143 }
144
145 return HW_MODE_BW_NONE;
146}
147
148static void policy_mgr_get_hw_mode_params(WMI_MAC_PHY_CAPABILITIES *caps,
149 struct policy_mgr_mac_ss_bw_info *info)
150{
151 if (!caps) {
152 policy_mgr_err("Invalid capabilities");
153 return;
154 }
155
156 info->mac_tx_stream = policy_mgr_get_num_of_setbits_from_bitmask(
157 QDF_MAX(caps->tx_chain_mask_2G,
158 caps->tx_chain_mask_5G));
159 info->mac_rx_stream = policy_mgr_get_num_of_setbits_from_bitmask(
160 QDF_MAX(caps->rx_chain_mask_2G,
161 caps->rx_chain_mask_5G));
162 info->mac_bw = policy_mgr_map_wmi_channel_width_to_hw_mode_bw(
163 QDF_MAX(caps->max_bw_supported_2G,
164 caps->max_bw_supported_5G));
165}
166
167/**
168 * policy_mgr_set_hw_mode_params() - sets TX-RX stream,
169 * bandwidth and DBS in hw_mode_list
170 * @wma_handle: pointer to wma global structure
171 * @mac0_ss_bw_info: TX-RX streams, BW for MAC0
172 * @mac1_ss_bw_info: TX-RX streams, BW for MAC1
173 * @pos: refers to hw_mode_index
174 * @dbs_mode: dbs_mode for the dbs_hw_mode
175 * @sbs_mode: sbs_mode for the sbs_hw_mode
176 *
177 * This function sets TX-RX stream, bandwidth and DBS mode in
178 * hw_mode_list.
179 *
180 * Return: none
181 */
182static void policy_mgr_set_hw_mode_params(struct wlan_objmgr_psoc *psoc,
183 struct policy_mgr_mac_ss_bw_info mac0_ss_bw_info,
184 struct policy_mgr_mac_ss_bw_info mac1_ss_bw_info,
185 uint32_t pos, uint32_t dbs_mode,
186 uint32_t sbs_mode)
187{
188 struct policy_mgr_psoc_priv_obj *pm_ctx;
189
190 pm_ctx = policy_mgr_get_context(psoc);
191 if (!pm_ctx) {
192 policy_mgr_err("Invalid Context");
193 return;
194 }
195
196 POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_SET(
197 pm_ctx->hw_mode.hw_mode_list[pos],
198 mac0_ss_bw_info.mac_tx_stream);
199 POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_SET(
200 pm_ctx->hw_mode.hw_mode_list[pos],
201 mac0_ss_bw_info.mac_rx_stream);
202 POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_SET(
203 pm_ctx->hw_mode.hw_mode_list[pos],
204 mac0_ss_bw_info.mac_bw);
205 POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_SET(
206 pm_ctx->hw_mode.hw_mode_list[pos],
207 mac1_ss_bw_info.mac_tx_stream);
208 POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_SET(
209 pm_ctx->hw_mode.hw_mode_list[pos],
210 mac1_ss_bw_info.mac_rx_stream);
211 POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_SET(
212 pm_ctx->hw_mode.hw_mode_list[pos],
213 mac1_ss_bw_info.mac_bw);
214 POLICY_MGR_HW_MODE_DBS_MODE_SET(
215 pm_ctx->hw_mode.hw_mode_list[pos],
216 dbs_mode);
217 POLICY_MGR_HW_MODE_AGILE_DFS_SET(
218 pm_ctx->hw_mode.hw_mode_list[pos],
219 HW_MODE_AGILE_DFS_NONE);
220 POLICY_MGR_HW_MODE_SBS_MODE_SET(
221 pm_ctx->hw_mode.hw_mode_list[pos],
222 sbs_mode);
223}
224
225QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc,
226 struct extended_caps *phy_caps)
227{
228 WMI_MAC_PHY_CAPABILITIES *tmp;
229 uint32_t i, hw_config_type, j = 0;
230 uint32_t dbs_mode, sbs_mode;
231 struct policy_mgr_mac_ss_bw_info mac0_ss_bw_info = {0};
232 struct policy_mgr_mac_ss_bw_info mac1_ss_bw_info = {0};
233 struct policy_mgr_psoc_priv_obj *pm_ctx;
234
235 pm_ctx = policy_mgr_get_context(psoc);
236 if (!pm_ctx) {
237 policy_mgr_err("Invalid Context");
238 return QDF_STATUS_E_FAILURE;
239 }
240
241 if (!phy_caps) {
242 policy_mgr_err("Invalid phy capabilities");
243 return QDF_STATUS_E_FAILURE;
244 }
245
246 if (!phy_caps->num_hw_modes.num_hw_modes) {
247 policy_mgr_err("Number of HW modes: %d",
248 phy_caps->num_hw_modes.num_hw_modes);
249 return QDF_STATUS_E_FAILURE;
250 }
251
252 /*
253 * This list was updated as part of service ready event. Re-populate
254 * HW mode list from the device capabilities.
255 */
256 if (pm_ctx->hw_mode.hw_mode_list) {
257 qdf_mem_free(pm_ctx->hw_mode.hw_mode_list);
258 pm_ctx->hw_mode.hw_mode_list = NULL;
259 policy_mgr_err("DBS list is freed");
260 }
261
262 pm_ctx->num_dbs_hw_modes = phy_caps->num_hw_modes.num_hw_modes;
263 pm_ctx->hw_mode.hw_mode_list =
264 qdf_mem_malloc(sizeof(*pm_ctx->hw_mode.hw_mode_list) *
265 pm_ctx->num_dbs_hw_modes);
266 if (!pm_ctx->hw_mode.hw_mode_list) {
267 policy_mgr_err("Memory allocation failed for DBS");
268 return QDF_STATUS_E_FAILURE;
269 }
270
271 policy_mgr_err("Updated HW mode list: Num modes:%d",
272 pm_ctx->num_dbs_hw_modes);
273
274 for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
275 /* Update for MAC0 */
276 tmp = &phy_caps->each_phy_cap_per_hwmode[j++];
277 policy_mgr_get_hw_mode_params(tmp, &mac0_ss_bw_info);
278 hw_config_type =
279 phy_caps->each_hw_mode_cap[i].hw_mode_config_type;
280 dbs_mode = HW_MODE_DBS_NONE;
281 sbs_mode = HW_MODE_SBS_NONE;
282 mac1_ss_bw_info.mac_tx_stream = 0;
283 mac1_ss_bw_info.mac_rx_stream = 0;
284 mac1_ss_bw_info.mac_bw = 0;
285
286 /* SBS and DBS have dual MAC. Upto 2 MACs are considered. */
287 if ((hw_config_type == WMI_HW_MODE_DBS) ||
288 (hw_config_type == WMI_HW_MODE_SBS_PASSIVE) ||
289 (hw_config_type == WMI_HW_MODE_SBS)) {
290 /* Update for MAC1 */
291 tmp = &phy_caps->each_phy_cap_per_hwmode[j++];
292 policy_mgr_get_hw_mode_params(tmp, &mac1_ss_bw_info);
293 if (hw_config_type == WMI_HW_MODE_DBS)
294 dbs_mode = HW_MODE_DBS;
295 if ((hw_config_type == WMI_HW_MODE_SBS_PASSIVE) ||
296 (hw_config_type == WMI_HW_MODE_SBS))
297 sbs_mode = HW_MODE_SBS;
298 }
299
300 /* Updating HW mode list */
301 policy_mgr_set_hw_mode_params(psoc, mac0_ss_bw_info,
302 mac1_ss_bw_info, i, dbs_mode, sbs_mode);
303 }
304 return QDF_STATUS_SUCCESS;
305}
306
307void policy_mgr_init_dbs_hw_mode(struct wlan_objmgr_psoc *psoc,
308 uint32_t num_dbs_hw_modes,
309 uint32_t *ev_wlan_dbs_hw_mode_list)
310{
311 struct policy_mgr_psoc_priv_obj *pm_ctx;
312
313 pm_ctx = policy_mgr_get_context(psoc);
314 if (!pm_ctx) {
315 policy_mgr_err("Invalid Context");
316 return;
317 }
318
319 pm_ctx->num_dbs_hw_modes = num_dbs_hw_modes;
320 pm_ctx->hw_mode.hw_mode_list =
321 qdf_mem_malloc(sizeof(*pm_ctx->hw_mode.hw_mode_list) *
322 pm_ctx->num_dbs_hw_modes);
323 if (!pm_ctx->hw_mode.hw_mode_list) {
324 policy_mgr_err("Memory allocation failed for DBS");
325 return;
326 }
327 qdf_mem_copy(pm_ctx->hw_mode.hw_mode_list,
328 ev_wlan_dbs_hw_mode_list,
329 (sizeof(*pm_ctx->hw_mode.hw_mode_list) *
330 pm_ctx->num_dbs_hw_modes));
331}
332
333void policy_mgr_dump_dbs_hw_mode(struct wlan_objmgr_psoc *psoc)
334{
335 uint32_t i, param;
336 struct policy_mgr_psoc_priv_obj *pm_ctx;
337
338 pm_ctx = policy_mgr_get_context(psoc);
339 if (!pm_ctx) {
340 policy_mgr_err("Invalid Context");
341 return;
342 }
343
344 for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
345 param = pm_ctx->hw_mode.hw_mode_list[i];
346 policy_mgr_err("[%d]-MAC0: tx_ss:%d rx_ss:%d bw_idx:%d",
347 i,
348 POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param),
349 POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param),
350 POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(param));
351 policy_mgr_err("[%d]-MAC1: tx_ss:%d rx_ss:%d bw_idx:%d",
352 i,
353 POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param),
354 POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param),
355 POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(param));
356 policy_mgr_err("[%d] DBS:%d SBS:%d", i,
357 POLICY_MGR_HW_MODE_DBS_MODE_GET(param),
358 POLICY_MGR_HW_MODE_SBS_MODE_GET(param));
359 }
360}
361
362void policy_mgr_init_dbs_config(struct wlan_objmgr_psoc *psoc,
363 uint32_t scan_config, uint32_t fw_config)
364{
365 struct policy_mgr_psoc_priv_obj *pm_ctx;
366
367 pm_ctx = policy_mgr_get_context(psoc);
368 if (!pm_ctx) {
369 policy_mgr_err("Invalid Context");
370 return;
371 }
372 pm_ctx->dual_mac_cfg.cur_scan_config = 0;
373 pm_ctx->dual_mac_cfg.cur_fw_mode_config = 0;
374
375 /* If dual mac features are disabled in the INI, we
376 * need not proceed further
377 */
378 if (policy_mgr_is_dual_mac_disabled_in_ini(psoc)) {
379 policy_mgr_err("Disabling dual mac capabilities");
380 /* All capabilites are initialized to 0. We can return */
381 goto done;
382 }
383
384 /* Initialize concurrent_scan_config_bits with default FW value */
385 WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_SET(
386 pm_ctx->dual_mac_cfg.cur_scan_config,
387 WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_GET(scan_config));
388 WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_SET(
389 pm_ctx->dual_mac_cfg.cur_scan_config,
390 WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_GET(scan_config));
391 WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_SET(
392 pm_ctx->dual_mac_cfg.cur_scan_config,
393 WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_GET(scan_config));
394
395 /* Initialize fw_mode_config_bits with default FW value */
396 WMI_DBS_FW_MODE_CFG_DBS_SET(
397 pm_ctx->dual_mac_cfg.cur_fw_mode_config,
398 WMI_DBS_FW_MODE_CFG_DBS_GET(fw_config));
399 WMI_DBS_FW_MODE_CFG_AGILE_DFS_SET(
400 pm_ctx->dual_mac_cfg.cur_fw_mode_config,
401 WMI_DBS_FW_MODE_CFG_AGILE_DFS_GET(fw_config));
402done:
403 /* Initialize the previous scan/fw mode config */
404 pm_ctx->dual_mac_cfg.prev_scan_config =
405 pm_ctx->dual_mac_cfg.cur_scan_config;
406 pm_ctx->dual_mac_cfg.prev_fw_mode_config =
407 pm_ctx->dual_mac_cfg.cur_fw_mode_config;
408
409 policy_mgr_debug("cur_scan_config:%x cur_fw_mode_config:%x",
410 pm_ctx->dual_mac_cfg.cur_scan_config,
411 pm_ctx->dual_mac_cfg.cur_fw_mode_config);
412}
413
414void policy_mgr_update_dbs_scan_config(struct wlan_objmgr_psoc *psoc)
415{
416 struct policy_mgr_psoc_priv_obj *pm_ctx;
417
418 pm_ctx = policy_mgr_get_context(psoc);
419 if (!pm_ctx) {
420 policy_mgr_err("Invalid Context");
421 return;
422 }
423
424 pm_ctx->dual_mac_cfg.prev_scan_config =
425 pm_ctx->dual_mac_cfg.cur_scan_config;
426 pm_ctx->dual_mac_cfg.cur_scan_config =
427 pm_ctx->dual_mac_cfg.req_scan_config;
428}
429
430void policy_mgr_update_dbs_fw_config(struct wlan_objmgr_psoc *psoc)
431{
432 struct policy_mgr_psoc_priv_obj *pm_ctx;
433
434 pm_ctx = policy_mgr_get_context(psoc);
435 if (!pm_ctx) {
436 policy_mgr_err("Invalid Context");
437 return;
438 }
439
440 pm_ctx->dual_mac_cfg.prev_fw_mode_config =
441 pm_ctx->dual_mac_cfg.cur_fw_mode_config;
442 pm_ctx->dual_mac_cfg.cur_fw_mode_config =
443 pm_ctx->dual_mac_cfg.req_fw_mode_config;
444}
445
446void policy_mgr_update_dbs_req_config(struct wlan_objmgr_psoc *psoc,
447 uint32_t scan_config, uint32_t fw_mode_config)
448{
449 struct policy_mgr_psoc_priv_obj *pm_ctx;
450
451 pm_ctx = policy_mgr_get_context(psoc);
452 if (!pm_ctx) {
453 policy_mgr_err("Invalid Context");
454 return;
455 }
456 pm_ctx->dual_mac_cfg.req_scan_config = scan_config;
457 pm_ctx->dual_mac_cfg.req_fw_mode_config = fw_mode_config;
458}
459
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800460bool policy_mgr_get_dbs_plus_agile_scan_config(struct wlan_objmgr_psoc *psoc)
461{
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800462 uint32_t scan_config;
463 struct policy_mgr_psoc_priv_obj *pm_ctx;
464
465 if (policy_mgr_is_dual_mac_disabled_in_ini(psoc))
466 return false;
467
468
469 pm_ctx = policy_mgr_get_context(psoc);
470 if (!pm_ctx) {
471 policy_mgr_err("Invalid Context");
472 /* We take that it is disabled and proceed */
473 return false;
474 }
475 scan_config = pm_ctx->dual_mac_cfg.cur_scan_config;
476
477 return WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_GET(scan_config);
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800478}
479
480bool policy_mgr_get_single_mac_scan_with_dfs_config(
481 struct wlan_objmgr_psoc *psoc)
482{
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800483 uint32_t scan_config;
484 struct policy_mgr_psoc_priv_obj *pm_ctx;
485
486 if (policy_mgr_is_dual_mac_disabled_in_ini(psoc))
487 return false;
488
489
490 pm_ctx = policy_mgr_get_context(psoc);
491 if (!pm_ctx) {
492 policy_mgr_err("Invalid Context");
493 /* We take that it is disabled and proceed */
494 return false;
495 }
496 scan_config = pm_ctx->dual_mac_cfg.cur_scan_config;
497
498 return WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_GET(scan_config);
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800499}
500
501int8_t policy_mgr_get_num_dbs_hw_modes(struct wlan_objmgr_psoc *psoc)
502{
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800503 struct policy_mgr_psoc_priv_obj *pm_ctx;
504
505 pm_ctx = policy_mgr_get_context(psoc);
506 if (!pm_ctx) {
507 policy_mgr_err("Invalid Context");
508 return -EINVAL;
509 }
510 return pm_ctx->num_dbs_hw_modes;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800511}
512
513bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc)
514{
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800515 uint32_t param, i, found = 0;
516 struct policy_mgr_psoc_priv_obj *pm_ctx;
517
518 pm_ctx = policy_mgr_get_context(psoc);
519 if (!pm_ctx) {
520 policy_mgr_err("Invalid Context");
521 return false;
522 }
523
524 if (!policy_mgr_is_dbs_enable(psoc)) {
525 policy_mgr_notice("DBS is disabled");
526 return false;
527 }
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700528 if (pm_ctx->wma_cbacks.wma_is_service_enabled) {
529 policy_mgr_notice("DBS service bit map: %d",
530 pm_ctx->wma_cbacks.wma_is_service_enabled(
531 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT));
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800532
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700533 /* The agreement with FW is that: To know if the target is DBS
534 * capable, DBS needs to be supported both in the HW mode list
535 * and in the service ready event
536 */
537 if (!(pm_ctx->wma_cbacks.wma_is_service_enabled(
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800538 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT)))
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700539 return false;
540 } else
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800541 return false;
542
543 for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
544 param = pm_ctx->hw_mode.hw_mode_list[i];
545 policy_mgr_notice("HW param: %x", param);
546 if (POLICY_MGR_HW_MODE_DBS_MODE_GET(param)) {
547 policy_mgr_notice("HW (%d) is DBS capable", i);
548 found = 1;
549 break;
550 }
551 }
552
553 if (found)
554 return true;
555
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800556 return false;
557}
558
559bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc)
560{
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800561 uint32_t param, i, found = 0;
562 struct policy_mgr_psoc_priv_obj *pm_ctx;
563
564 pm_ctx = policy_mgr_get_context(psoc);
565 if (!pm_ctx) {
566 policy_mgr_err("Invalid Context");
567 return false;
568 }
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700569 if (pm_ctx->wma_cbacks.wma_is_service_enabled) {
570 policy_mgr_notice("DBS service bit map: %d",
571 pm_ctx->wma_cbacks.wma_is_service_enabled(
572 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT));
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800573
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700574 /* The agreement with FW is that: To know if the target is SBS
575 * capable, SBS needs to be supported both in the HW mode list
576 * and DBS needs to be supported in the service ready event
577 */
578 if (!(pm_ctx->wma_cbacks.wma_is_service_enabled(
579 WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT)))
580 return false;
581 } else
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800582 return false;
583
584 for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
585 param = pm_ctx->hw_mode.hw_mode_list[i];
586 policy_mgr_notice("HW param: %x", param);
587 if (POLICY_MGR_HW_MODE_SBS_MODE_GET(param)) {
588 policy_mgr_notice("HW (%d) is SBS capable", i);
589 found = 1;
590 break;
591 }
592 }
593
594 if (found)
595 return true;
596
Archana Ramachandran878422f2017-03-23 11:34:02 -0700597 return false;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800598}
599
600QDF_STATUS policy_mgr_get_dbs_hw_modes(struct wlan_objmgr_psoc *psoc,
601 bool *one_by_one_dbs, bool *two_by_two_dbs)
602{
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800603 struct policy_mgr_psoc_priv_obj *pm_ctx;
604 uint32_t i;
605 int8_t found_one_by_one = -EINVAL, found_two_by_two = -EINVAL;
606 uint32_t conf1_tx_ss, conf1_rx_ss;
607 uint32_t conf2_tx_ss, conf2_rx_ss;
608
609 *one_by_one_dbs = false;
610 *two_by_two_dbs = false;
611
612 if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
613 policy_mgr_err("HW is not DBS capable");
614 /* Caller will understand that DBS is disabled */
615 return QDF_STATUS_SUCCESS;
616
617 }
618
619 pm_ctx = policy_mgr_get_context(psoc);
620 if (!pm_ctx) {
621 policy_mgr_err("Invalid Context");
622 return QDF_STATUS_E_FAILURE;
623 }
624
625 /* To check 1x1 capability */
626 policy_mgr_get_tx_rx_ss_from_config(HW_MODE_SS_1x1,
627 &conf1_tx_ss, &conf1_rx_ss);
628 /* To check 2x2 capability */
629 policy_mgr_get_tx_rx_ss_from_config(HW_MODE_SS_2x2,
630 &conf2_tx_ss, &conf2_rx_ss);
631
632 for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
633 uint32_t t_conf0_tx_ss, t_conf0_rx_ss;
634 uint32_t t_conf1_tx_ss, t_conf1_rx_ss;
635 uint32_t dbs_mode;
636
637 t_conf0_tx_ss = POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(
638 pm_ctx->hw_mode.hw_mode_list[i]);
639 t_conf0_rx_ss = POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(
640 pm_ctx->hw_mode.hw_mode_list[i]);
641 t_conf1_tx_ss = POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(
642 pm_ctx->hw_mode.hw_mode_list[i]);
643 t_conf1_rx_ss = POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(
644 pm_ctx->hw_mode.hw_mode_list[i]);
645 dbs_mode = POLICY_MGR_HW_MODE_DBS_MODE_GET(
646 pm_ctx->hw_mode.hw_mode_list[i]);
647
648 if (((((t_conf0_tx_ss == conf1_tx_ss) &&
649 (t_conf0_rx_ss == conf1_rx_ss)) ||
650 ((t_conf1_tx_ss == conf1_tx_ss) &&
651 (t_conf1_rx_ss == conf1_rx_ss))) &&
652 (dbs_mode == HW_MODE_DBS)) &&
653 (found_one_by_one < 0)) {
654 found_one_by_one = i;
655 policy_mgr_notice("1x1 hw_mode index %d found", i);
656 /* Once an entry is found, need not check for 1x1
657 * again
658 */
659 continue;
660 }
661
662 if (((((t_conf0_tx_ss == conf2_tx_ss) &&
663 (t_conf0_rx_ss == conf2_rx_ss)) ||
664 ((t_conf1_tx_ss == conf2_tx_ss) &&
665 (t_conf1_rx_ss == conf2_rx_ss))) &&
666 (dbs_mode == HW_MODE_DBS)) &&
667 (found_two_by_two < 0)) {
668 found_two_by_two = i;
669 policy_mgr_notice("2x2 hw_mode index %d found", i);
670 /* Once an entry is found, need not check for 2x2
671 * again
672 */
673 continue;
674 }
675 }
676
677 if (found_one_by_one >= 0)
678 *one_by_one_dbs = true;
679 if (found_two_by_two >= 0)
680 *two_by_two_dbs = true;
681
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800682 return QDF_STATUS_SUCCESS;
683}
684
685QDF_STATUS policy_mgr_get_current_hw_mode(struct wlan_objmgr_psoc *psoc,
686 struct policy_mgr_hw_mode_params *hw_mode)
687{
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800688 QDF_STATUS status;
689 uint32_t old_hw_index = 0, new_hw_index = 0;
690
691 policy_mgr_notice("Get the current hw mode");
692
693 status = policy_mgr_get_old_and_new_hw_index(psoc, &old_hw_index,
694 &new_hw_index);
695 if (QDF_STATUS_SUCCESS != status) {
696 policy_mgr_err("Failed to get HW mode index");
697 return QDF_STATUS_E_FAILURE;
698 }
699
700 if (new_hw_index == POLICY_MGR_DEFAULT_HW_MODE_INDEX) {
701 policy_mgr_err("HW mode is not yet initialized");
702 return QDF_STATUS_E_FAILURE;
703 }
704
705 status = policy_mgr_get_hw_mode_from_idx(psoc, new_hw_index, hw_mode);
706 if (QDF_STATUS_SUCCESS != status) {
707 policy_mgr_err("Failed to get HW mode index");
708 return QDF_STATUS_E_FAILURE;
709 }
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800710 return QDF_STATUS_SUCCESS;
711}
712
713bool policy_mgr_is_current_hwmode_dbs(struct wlan_objmgr_psoc *psoc)
714{
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800715 struct policy_mgr_hw_mode_params hw_mode;
716
717 if (!policy_mgr_is_hw_dbs_capable(psoc))
718 return false;
719 if (QDF_STATUS_SUCCESS !=
720 policy_mgr_get_current_hw_mode(psoc, &hw_mode))
721 return false;
722 if (hw_mode.dbs_cap)
723 return true;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800724 return false;
725}
726
727bool policy_mgr_is_dbs_enable(struct wlan_objmgr_psoc *psoc)
728{
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800729 struct policy_mgr_psoc_priv_obj *pm_ctx;
730
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -0700731 if (policy_mgr_is_dual_mac_disabled_in_ini(psoc)) {
732 policy_mgr_err("DBS is disabled from ini");
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800733 return false;
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -0700734 }
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800735
736 pm_ctx = policy_mgr_get_context(psoc);
737 if (!pm_ctx) {
738 policy_mgr_err("Invalid Context");
739 return false;
740 }
741
742 policy_mgr_debug("DBS=%d",
743 WMI_DBS_FW_MODE_CFG_DBS_GET(
744 pm_ctx->dual_mac_cfg.cur_fw_mode_config));
745
746 if (WMI_DBS_FW_MODE_CFG_DBS_GET(
747 pm_ctx->dual_mac_cfg.cur_fw_mode_config))
748 return true;
749
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800750 return false;
751}
752
753bool policy_mgr_is_hw_dbs_2x2_capable(struct wlan_objmgr_psoc *psoc)
754{
Vikrampal31eb12c2017-04-28 17:44:30 +0530755 struct dbs_nss nss_dbs;
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800756
Vikrampal7e4d4c22017-05-17 09:36:46 +0530757 return ((policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs)) >= HW_MODE_SS_2x2)
758 ? true : false;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800759}
760
761uint32_t policy_mgr_get_connection_count(struct wlan_objmgr_psoc *psoc)
762{
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800763 uint32_t conn_index, count = 0;
764 struct policy_mgr_psoc_priv_obj *pm_ctx;
765
766 pm_ctx = policy_mgr_get_context(psoc);
767 if (!pm_ctx) {
768 policy_mgr_err("Invalid Context");
769 return count;
770 }
771
772 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
773 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
774 conn_index++) {
775 if (pm_conc_connection_list[conn_index].in_use)
776 count++;
777 }
778 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
779
780 return count;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800781}
782
Kabilan Kannan5125d0f2017-05-15 20:28:05 -0700783uint32_t policy_mgr_mode_specific_vdev_id(struct wlan_objmgr_psoc *psoc,
784 enum policy_mgr_con_mode mode)
785{
786 uint32_t conn_index = 0;
787 uint32_t vdev_id = WLAN_INVALID_VDEV_ID;
788 struct policy_mgr_psoc_priv_obj *pm_ctx;
789
790 pm_ctx = policy_mgr_get_context(psoc);
791 if (!pm_ctx) {
792 policy_mgr_err("Invalid Context");
793 return vdev_id;
794 }
795 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
796 /*
797 * Note: This gives you the first vdev id of the mode type in a
798 * sta+sta or sap+sap or p2p + p2p case
799 */
800 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
801 conn_index++) {
802 if ((pm_conc_connection_list[conn_index].mode == mode) &&
803 pm_conc_connection_list[conn_index].in_use) {
804 vdev_id = pm_conc_connection_list[conn_index].vdev_id;
805 break;
806 }
807 }
808 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
809
810 return vdev_id;
811}
812
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800813uint32_t policy_mgr_mode_specific_connection_count(
814 struct wlan_objmgr_psoc *psoc,
815 enum policy_mgr_con_mode mode,
816 uint32_t *list)
817{
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800818 uint32_t conn_index = 0, count = 0;
819 struct policy_mgr_psoc_priv_obj *pm_ctx;
820
821 pm_ctx = policy_mgr_get_context(psoc);
822 if (!pm_ctx) {
823 policy_mgr_err("Invalid Context");
824 return count;
825 }
826 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
827 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
828 conn_index++) {
829 if ((pm_conc_connection_list[conn_index].mode == mode) &&
830 pm_conc_connection_list[conn_index].in_use) {
831 if (list != NULL)
832 list[count] = conn_index;
833 count++;
834 }
835 }
836 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
837
838 return count;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800839}
840
841void policy_mgr_soc_set_dual_mac_cfg_cb(enum set_hw_mode_status status,
842 uint32_t scan_config,
843 uint32_t fw_mode_config)
844{
845 policy_mgr_notice("Status:%d for scan_config:%x fw_mode_config:%x",
846 status, scan_config, fw_mode_config);
847}
848
849void policy_mgr_set_dual_mac_scan_config(struct wlan_objmgr_psoc *psoc,
850 uint8_t dbs_val,
851 uint8_t dbs_plus_agile_scan_val,
852 uint8_t single_mac_scan_with_dbs_val)
853{
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800854 struct policy_mgr_dual_mac_config cfg;
855 QDF_STATUS status;
856 struct policy_mgr_psoc_priv_obj *pm_ctx;
857
858 pm_ctx = policy_mgr_get_context(psoc);
859 if (!pm_ctx) {
860 policy_mgr_err("Invalid Context");
861 return;
862 }
863
864 /* Any non-zero positive value is treated as 1 */
865 if (dbs_val != 0)
866 dbs_val = 1;
867 if (dbs_plus_agile_scan_val != 0)
868 dbs_plus_agile_scan_val = 1;
869 if (single_mac_scan_with_dbs_val != 0)
870 single_mac_scan_with_dbs_val = 1;
871
872 status = policy_mgr_get_updated_scan_config(psoc, &cfg.scan_config,
873 dbs_val,
874 dbs_plus_agile_scan_val,
875 single_mac_scan_with_dbs_val);
876 if (status != QDF_STATUS_SUCCESS) {
877 policy_mgr_err("policy_mgr_get_updated_scan_config failed %d",
878 status);
879 return;
880 }
881
882 status = policy_mgr_get_updated_fw_mode_config(psoc,
883 &cfg.fw_mode_config,
884 policy_mgr_get_dbs_config(psoc),
885 policy_mgr_get_agile_dfs_config(psoc));
886 if (status != QDF_STATUS_SUCCESS) {
887 policy_mgr_err("policy_mgr_get_updated_fw_mode_config failed %d",
888 status);
889 return;
890 }
891
892 cfg.set_dual_mac_cb = (void *)policy_mgr_soc_set_dual_mac_cfg_cb;
893
894 policy_mgr_notice("scan_config:%x fw_mode_config:%x",
895 cfg.scan_config, cfg.fw_mode_config);
896
897 status = pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config(cfg);
898 if (status != QDF_STATUS_SUCCESS)
899 policy_mgr_err("sme_soc_set_dual_mac_config failed %d", status);
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800900}
901
902void policy_mgr_set_dual_mac_fw_mode_config(struct wlan_objmgr_psoc *psoc,
903 uint8_t dbs, uint8_t dfs)
904{
Tushnim Bhattacharyya58a0b192017-03-08 09:56:33 -0800905 struct policy_mgr_dual_mac_config cfg;
906 QDF_STATUS status;
907 struct policy_mgr_psoc_priv_obj *pm_ctx;
908
909 pm_ctx = policy_mgr_get_context(psoc);
910 if (!pm_ctx) {
911 policy_mgr_err("Invalid Context");
912 return;
913 }
914
915 /* Any non-zero positive value is treated as 1 */
916 if (dbs != 0)
917 dbs = 1;
918 if (dfs != 0)
919 dfs = 1;
920
921 status = policy_mgr_get_updated_scan_config(psoc, &cfg.scan_config,
922 policy_mgr_get_dbs_scan_config(psoc),
923 policy_mgr_get_dbs_plus_agile_scan_config(psoc),
924 policy_mgr_get_single_mac_scan_with_dfs_config(psoc));
925 if (status != QDF_STATUS_SUCCESS) {
926 policy_mgr_err("policy_mgr_get_updated_scan_config failed %d",
927 status);
928 return;
929 }
930
931 status = policy_mgr_get_updated_fw_mode_config(psoc,
932 &cfg.fw_mode_config, dbs, dfs);
933 if (status != QDF_STATUS_SUCCESS) {
934 policy_mgr_err("policy_mgr_get_updated_fw_mode_config failed %d",
935 status);
936 return;
937 }
938
939 cfg.set_dual_mac_cb = (void *)policy_mgr_soc_set_dual_mac_cfg_cb;
940
941 policy_mgr_notice("scan_config:%x fw_mode_config:%x",
942 cfg.scan_config, cfg.fw_mode_config);
943
944 status = pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config(cfg);
945 if (status != QDF_STATUS_SUCCESS)
946 policy_mgr_err("sme_soc_set_dual_mac_config failed %d", status);
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800947}
948
949bool policy_mgr_current_concurrency_is_mcc(struct wlan_objmgr_psoc *psoc)
950{
Tushnim Bhattacharyya97670702017-03-08 10:06:58 -0800951 uint32_t num_connections = 0;
952 bool is_mcc = false;
953
954 num_connections = policy_mgr_get_connection_count(psoc);
955
956 switch (num_connections) {
957 case 1:
958 break;
959 case 2:
960 if ((pm_conc_connection_list[0].chan !=
961 pm_conc_connection_list[1].chan) &&
962 (pm_conc_connection_list[0].mac ==
963 pm_conc_connection_list[1].mac)) {
964 is_mcc = true;
965 }
966 break;
967 case 3:
968 if ((pm_conc_connection_list[0].chan !=
969 pm_conc_connection_list[1].chan) ||
970 (pm_conc_connection_list[0].chan !=
971 pm_conc_connection_list[2].chan) ||
972 (pm_conc_connection_list[1].chan !=
973 pm_conc_connection_list[2].chan)){
974 is_mcc = true;
975 }
976 break;
977 default:
978 policy_mgr_err("unexpected num_connections value %d",
979 num_connections);
980 break;
981 }
982
983 return is_mcc;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800984}
985
Archana Ramachandran7abbf562017-03-02 13:14:34 -0800986/**
987 * policy_mgr_set_concurrency_mode() - To set concurrency mode
988 * @psoc: PSOC object data
989 * @mode: device mode
990 *
991 * This routine is called to set the concurrency mode
992 *
993 * Return: NONE
994 */
995void policy_mgr_set_concurrency_mode(struct wlan_objmgr_psoc *psoc,
996 enum tQDF_ADAPTER_MODE mode)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800997{
Archana Ramachandran7abbf562017-03-02 13:14:34 -0800998 struct policy_mgr_psoc_priv_obj *pm_ctx;
999
1000 pm_ctx = policy_mgr_get_context(psoc);
1001 if (!pm_ctx) {
1002 policy_mgr_err("Invalid context");
1003 return;
1004 }
1005
1006 switch (mode) {
1007 case QDF_STA_MODE:
1008 case QDF_P2P_CLIENT_MODE:
1009 case QDF_P2P_GO_MODE:
1010 case QDF_SAP_MODE:
1011 case QDF_IBSS_MODE:
1012 case QDF_MONITOR_MODE:
1013 pm_ctx->concurrency_mode |= (1 << mode);
1014 pm_ctx->no_of_open_sessions[mode]++;
1015 break;
1016 default:
1017 break;
1018 }
1019
1020 policy_mgr_info("concurrency_mode = 0x%x Number of open sessions for mode %d = %d",
1021 pm_ctx->concurrency_mode, mode,
1022 pm_ctx->no_of_open_sessions[mode]);
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001023}
1024
Archana Ramachandran7abbf562017-03-02 13:14:34 -08001025/**
1026 * policy_mgr_clear_concurrency_mode() - To clear concurrency mode
1027 * @psoc: PSOC object data
1028 * @mode: device mode
1029 *
1030 * This routine is called to clear the concurrency mode
1031 *
1032 * Return: NONE
1033 */
1034void policy_mgr_clear_concurrency_mode(struct wlan_objmgr_psoc *psoc,
1035 enum tQDF_ADAPTER_MODE mode)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001036{
Archana Ramachandran7abbf562017-03-02 13:14:34 -08001037 struct policy_mgr_psoc_priv_obj *pm_ctx;
1038
1039 pm_ctx = policy_mgr_get_context(psoc);
1040 if (!pm_ctx) {
1041 policy_mgr_err("Invalid context");
1042 return;
1043 }
1044
1045 switch (mode) {
1046 case QDF_STA_MODE:
1047 case QDF_P2P_CLIENT_MODE:
1048 case QDF_P2P_GO_MODE:
1049 case QDF_SAP_MODE:
1050 case QDF_MONITOR_MODE:
1051 pm_ctx->no_of_open_sessions[mode]--;
1052 if (!(pm_ctx->no_of_open_sessions[mode]))
1053 pm_ctx->concurrency_mode &= (~(1 << mode));
1054 break;
1055 default:
1056 break;
1057 }
1058
1059 policy_mgr_info("concurrency_mode = 0x%x Number of open sessions for mode %d = %d",
1060 pm_ctx->concurrency_mode, mode,
1061 pm_ctx->no_of_open_sessions[mode]);
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001062}
1063
1064void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc,
1065 enum tQDF_ADAPTER_MODE mode,
1066 uint8_t session_id)
1067{
Tushnim Bhattacharyya97670702017-03-08 10:06:58 -08001068 struct policy_mgr_psoc_priv_obj *pm_ctx;
1069
1070 pm_ctx = policy_mgr_get_context(psoc);
1071 if (!pm_ctx) {
1072 policy_mgr_err("Invalid Context");
1073 return;
1074 }
1075
1076 /*
1077 * Need to aquire mutex as entire functionality in this function
1078 * is in critical section
1079 */
1080 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1081 switch (mode) {
1082 case QDF_STA_MODE:
1083 case QDF_P2P_CLIENT_MODE:
1084 case QDF_P2P_GO_MODE:
1085 case QDF_SAP_MODE:
1086 case QDF_IBSS_MODE:
1087 pm_ctx->no_of_active_sessions[mode]++;
1088 break;
1089 default:
1090 break;
1091 }
1092
1093
1094 policy_mgr_notice("No.# of active sessions for mode %d = %d",
1095 mode, pm_ctx->no_of_active_sessions[mode]);
1096 /*
1097 * Get PCL logic makes use of the connection info structure.
1098 * Let us set the PCL to the FW before updating the connection
1099 * info structure about the new connection.
1100 */
1101 if (mode == QDF_STA_MODE) {
1102 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1103 /* Set PCL of STA to the FW */
1104 policy_mgr_pdev_set_pcl(psoc, mode);
1105 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1106 policy_mgr_notice("Set PCL of STA to FW");
1107 }
1108 policy_mgr_incr_connection_count(psoc, session_id);
1109 if ((policy_mgr_mode_specific_connection_count(
1110 psoc, PM_STA_MODE, NULL) > 0) && (mode != QDF_STA_MODE)) {
1111 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1112 policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE);
1113 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1114 }
1115
Kabilan Kannanc81d3752017-02-28 20:28:54 -08001116 /* Notify tdls */
1117 if (pm_ctx->tdls_cbacks.tdls_notify_increment_session)
1118 pm_ctx->tdls_cbacks.tdls_notify_increment_session(psoc);
1119
Tushnim Bhattacharyya97670702017-03-08 10:06:58 -08001120 policy_mgr_dump_current_concurrency(psoc);
1121
1122 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001123}
1124
1125void policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc,
1126 enum tQDF_ADAPTER_MODE mode,
1127 uint8_t session_id)
1128{
Tushnim Bhattacharyya97670702017-03-08 10:06:58 -08001129 struct policy_mgr_psoc_priv_obj *pm_ctx;
1130
1131 pm_ctx = policy_mgr_get_context(psoc);
1132 if (!pm_ctx) {
1133 policy_mgr_err("context is NULL");
1134 return;
1135 }
1136
1137 switch (mode) {
1138 case QDF_STA_MODE:
1139 case QDF_P2P_CLIENT_MODE:
1140 case QDF_P2P_GO_MODE:
1141 case QDF_SAP_MODE:
1142 case QDF_IBSS_MODE:
1143 if (pm_ctx->no_of_active_sessions[mode])
1144 pm_ctx->no_of_active_sessions[mode]--;
1145 break;
1146 default:
1147 break;
1148 }
1149
1150 policy_mgr_notice("No.# of active sessions for mode %d = %d",
1151 mode, pm_ctx->no_of_active_sessions[mode]);
1152
1153 policy_mgr_decr_connection_count(psoc, session_id);
1154
Kabilan Kannanc81d3752017-02-28 20:28:54 -08001155 /* Notify tdls */
1156 if (pm_ctx->tdls_cbacks.tdls_notify_decrement_session)
1157 pm_ctx->tdls_cbacks.tdls_notify_decrement_session(psoc);
Tushnim Bhattacharyya97670702017-03-08 10:06:58 -08001158
1159 policy_mgr_dump_current_concurrency(psoc);
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001160}
1161
1162QDF_STATUS policy_mgr_incr_connection_count(
1163 struct wlan_objmgr_psoc *psoc, uint32_t vdev_id)
1164{
Tushnim Bhattacharyya97670702017-03-08 10:06:58 -08001165 QDF_STATUS status = QDF_STATUS_E_FAILURE;
1166 uint32_t conn_index;
1167 struct policy_mgr_vdev_entry_info conn_table_entry;
1168 enum policy_mgr_chain_mode chain_mask = POLICY_MGR_ONE_ONE;
1169 uint8_t nss_2g = 0, nss_5g = 0;
1170 enum policy_mgr_con_mode mode;
1171 uint8_t chan;
1172 uint32_t nss = 0;
1173 struct policy_mgr_psoc_priv_obj *pm_ctx;
1174
1175 pm_ctx = policy_mgr_get_context(psoc);
1176 if (!pm_ctx) {
1177 policy_mgr_err("context is NULL");
1178 return status;
1179 }
1180
1181 conn_index = policy_mgr_get_connection_count(psoc);
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001182 if (pm_ctx->user_cfg.max_concurrent_active_sessions < conn_index) {
Tushnim Bhattacharyya97670702017-03-08 10:06:58 -08001183 policy_mgr_err("exceeded max connection limit %d",
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001184 pm_ctx->user_cfg.max_concurrent_active_sessions);
Tushnim Bhattacharyya97670702017-03-08 10:06:58 -08001185 return status;
1186 }
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -07001187 if (pm_ctx->wma_cbacks.wma_get_connection_info) {
1188 status = pm_ctx->wma_cbacks.wma_get_connection_info(
Tushnim Bhattacharyya97670702017-03-08 10:06:58 -08001189 vdev_id, &conn_table_entry);
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -07001190 if (QDF_STATUS_SUCCESS != status) {
1191 policy_mgr_err("can't find vdev_id %d in connection table",
Tushnim Bhattacharyya97670702017-03-08 10:06:58 -08001192 vdev_id);
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -07001193 return status;
1194 }
1195 } else {
1196 policy_mgr_err("wma_get_connection_info is NULL");
1197 return QDF_STATUS_E_FAILURE;
Tushnim Bhattacharyya97670702017-03-08 10:06:58 -08001198 }
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -07001199
Tushnim Bhattacharyya97670702017-03-08 10:06:58 -08001200 mode = policy_mgr_get_mode(conn_table_entry.type,
1201 conn_table_entry.sub_type);
Tushnim Bhattacharyyace237d62017-04-05 12:52:36 -07001202 chan = wlan_reg_freq_to_chan(pm_ctx->pdev, conn_table_entry.mhz);
Tushnim Bhattacharyya97670702017-03-08 10:06:58 -08001203 status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g);
1204 if (QDF_IS_STATUS_SUCCESS(status)) {
1205 if ((WLAN_REG_IS_24GHZ_CH(chan) && (nss_2g > 1)) ||
1206 (WLAN_REG_IS_5GHZ_CH(chan) && (nss_5g > 1)))
1207 chain_mask = POLICY_MGR_TWO_TWO;
1208 else
1209 chain_mask = POLICY_MGR_ONE_ONE;
1210 nss = (WLAN_REG_IS_24GHZ_CH(chan)) ? nss_2g : nss_5g;
1211 } else {
1212 policy_mgr_err("Error in getting nss");
1213 }
1214
1215
1216 /* add the entry */
1217 policy_mgr_update_conc_list(psoc, conn_index,
1218 mode,
1219 chan,
1220 policy_mgr_get_bw(conn_table_entry.chan_width),
1221 conn_table_entry.mac_id,
1222 chain_mask,
1223 nss, vdev_id, true);
1224 policy_mgr_notice("Add at idx:%d vdev %d mac=%d",
1225 conn_index, vdev_id,
1226 conn_table_entry.mac_id);
1227
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001228 return QDF_STATUS_SUCCESS;
1229}
1230
1231QDF_STATUS policy_mgr_decr_connection_count(struct wlan_objmgr_psoc *psoc,
1232 uint32_t vdev_id)
1233{
Tushnim Bhattacharyya97670702017-03-08 10:06:58 -08001234 QDF_STATUS status = QDF_STATUS_E_FAILURE;
1235 uint32_t conn_index = 0, next_conn_index = 0;
1236 bool found = false;
1237 struct policy_mgr_psoc_priv_obj *pm_ctx;
1238
1239 pm_ctx = policy_mgr_get_context(psoc);
1240 if (!pm_ctx) {
1241 policy_mgr_err("Invalid Context");
1242 return status;
1243 }
1244
1245 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1246 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
1247 if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
1248 /* debug msg */
1249 found = true;
1250 break;
1251 }
1252 conn_index++;
1253 }
1254 if (!found) {
1255 policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list",
1256 vdev_id);
1257 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1258 return status;
1259 }
1260 next_conn_index = conn_index + 1;
1261 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(next_conn_index)) {
1262 pm_conc_connection_list[conn_index].vdev_id =
1263 pm_conc_connection_list[next_conn_index].vdev_id;
1264 pm_conc_connection_list[conn_index].mode =
1265 pm_conc_connection_list[next_conn_index].mode;
1266 pm_conc_connection_list[conn_index].mac =
1267 pm_conc_connection_list[next_conn_index].mac;
1268 pm_conc_connection_list[conn_index].chan =
1269 pm_conc_connection_list[next_conn_index].chan;
1270 pm_conc_connection_list[conn_index].bw =
1271 pm_conc_connection_list[next_conn_index].bw;
1272 pm_conc_connection_list[conn_index].chain_mask =
1273 pm_conc_connection_list[next_conn_index].chain_mask;
1274 pm_conc_connection_list[conn_index].original_nss =
1275 pm_conc_connection_list[next_conn_index].original_nss;
1276 pm_conc_connection_list[conn_index].in_use =
1277 pm_conc_connection_list[next_conn_index].in_use;
1278 conn_index++;
1279 next_conn_index++;
1280 }
1281
1282 /* clean up the entry */
1283 qdf_mem_zero(&pm_conc_connection_list[next_conn_index - 1],
1284 sizeof(*pm_conc_connection_list));
1285 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1286
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001287 return QDF_STATUS_SUCCESS;
1288}
1289
1290bool policy_mgr_map_concurrency_mode(enum tQDF_ADAPTER_MODE *old_mode,
1291 enum policy_mgr_con_mode *new_mode)
1292{
Tushnim Bhattacharyya97670702017-03-08 10:06:58 -08001293 bool status = true;
1294
1295 switch (*old_mode) {
1296
1297 case QDF_STA_MODE:
1298 *new_mode = PM_STA_MODE;
1299 break;
1300 case QDF_SAP_MODE:
1301 *new_mode = PM_SAP_MODE;
1302 break;
1303 case QDF_P2P_CLIENT_MODE:
1304 *new_mode = PM_P2P_CLIENT_MODE;
1305 break;
1306 case QDF_P2P_GO_MODE:
1307 *new_mode = PM_P2P_GO_MODE;
1308 break;
1309 case QDF_IBSS_MODE:
1310 *new_mode = PM_IBSS_MODE;
1311 break;
1312 default:
1313 *new_mode = PM_MAX_NUM_OF_MODE;
1314 status = false;
1315 break;
1316 }
1317
1318 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001319}
1320
1321bool policy_mgr_is_ibss_conn_exist(struct wlan_objmgr_psoc *psoc,
1322 uint8_t *ibss_channel)
1323{
Tushnim Bhattacharyya97670702017-03-08 10:06:58 -08001324 uint32_t count = 0, index = 0;
1325 uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
1326 bool status = false;
1327 struct policy_mgr_psoc_priv_obj *pm_ctx;
1328
1329 pm_ctx = policy_mgr_get_context(psoc);
1330 if (!pm_ctx) {
1331 policy_mgr_err("Invalid Context");
1332 return status;
1333 }
1334 if (NULL == ibss_channel) {
1335 policy_mgr_err("Null pointer error");
1336 return false;
1337 }
1338 count = policy_mgr_mode_specific_connection_count(
1339 psoc, PM_IBSS_MODE, list);
1340 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1341 if (count == 0) {
1342 /* No IBSS connection */
1343 status = false;
1344 } else if (count == 1) {
1345 *ibss_channel = pm_conc_connection_list[list[index]].chan;
1346 status = true;
1347 } else {
1348 *ibss_channel = pm_conc_connection_list[list[index]].chan;
1349 policy_mgr_notice("Multiple IBSS connections, picking first one");
1350 status = true;
1351 }
1352 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1353
1354 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001355}
1356
Ajit Pal Singhc65575e2017-04-17 16:49:01 +05301357bool policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc,
1358 uint8_t *channel, uint8_t *vdev_id,
1359 enum policy_mgr_con_mode mode)
Archana Ramachandran6199b642017-03-20 13:31:36 -07001360{
Ajit Pal Singhc65575e2017-04-17 16:49:01 +05301361
Archana Ramachandran6199b642017-03-20 13:31:36 -07001362 uint32_t count, index = 0;
1363 uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
1364 bool status = false;
1365 struct policy_mgr_psoc_priv_obj *pm_ctx;
1366
1367 pm_ctx = policy_mgr_get_context(psoc);
1368 if (!pm_ctx) {
1369 policy_mgr_err("Invalid Context");
1370 return false;
1371 }
1372 if (NULL == channel || NULL == vdev_id) {
1373 policy_mgr_err("Null pointer error");
1374 return false;
1375 }
1376
1377 count = policy_mgr_mode_specific_connection_count(
Ajit Pal Singhc65575e2017-04-17 16:49:01 +05301378 psoc, mode, list);
Archana Ramachandran6199b642017-03-20 13:31:36 -07001379 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1380 if (count == 0) {
Ajit Pal Singhc65575e2017-04-17 16:49:01 +05301381 policy_mgr_err("No mode:[%d] connection", mode);
Archana Ramachandran6199b642017-03-20 13:31:36 -07001382 status = false;
1383 } else if (count == 1) {
1384 *channel = pm_conc_connection_list[list[index]].chan;
1385 *vdev_id =
1386 pm_conc_connection_list[list[index]].vdev_id;
1387 status = true;
1388 } else {
1389 /*
1390 * Todo Currently the first SAP connection info is
1391 * returned. Modify this to accommodate SAP+SAP+STA
1392 * and SAP+SAP+P2P
1393 */
1394 *channel = pm_conc_connection_list[list[index]].chan;
1395 *vdev_id =
1396 pm_conc_connection_list[list[index]].vdev_id;
Ajit Pal Singhc65575e2017-04-17 16:49:01 +05301397 policy_mgr_notice("Multiple mode:[%d] connections, picking first one",
1398 mode);
Archana Ramachandran6199b642017-03-20 13:31:36 -07001399 status = true;
1400 }
1401 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1402
1403 return status;
1404}
1405
Ajit Pal Singhc65575e2017-04-17 16:49:01 +05301406bool policy_mgr_get_sap_conn_info(struct wlan_objmgr_psoc *psoc,
1407 uint8_t *channel, uint8_t *vdev_id)
1408{
1409 return policy_mgr_get_mode_specific_conn_info(psoc,
1410 channel,
1411 vdev_id,
1412 PM_SAP_MODE);
1413}
1414
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001415bool policy_mgr_max_concurrent_connections_reached(
1416 struct wlan_objmgr_psoc *psoc)
1417{
Tushnim Bhattacharyya97670702017-03-08 10:06:58 -08001418 uint8_t i = 0, j = 0;
1419 struct policy_mgr_psoc_priv_obj *pm_ctx;
1420
1421 pm_ctx = policy_mgr_get_context(psoc);
1422 if (NULL != pm_ctx) {
1423 for (i = 0; i < QDF_MAX_NO_OF_MODE; i++)
1424 j += pm_ctx->no_of_active_sessions[i];
1425 return j >
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001426 (pm_ctx->user_cfg.
1427 max_concurrent_active_sessions - 1);
Tushnim Bhattacharyya97670702017-03-08 10:06:58 -08001428 }
1429
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001430 return false;
1431}
1432
Tushnim Bhattacharyyad7655ca2017-04-26 12:58:42 -07001433static bool policy_mgr_is_sub_20_mhz_enabled(struct wlan_objmgr_psoc *psoc)
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001434{
Tushnim Bhattacharyyad7655ca2017-04-26 12:58:42 -07001435 struct policy_mgr_psoc_priv_obj *pm_ctx;
1436
1437 pm_ctx = policy_mgr_get_context(psoc);
1438 if (!pm_ctx) {
1439 policy_mgr_err("Invalid Context");
1440 return false;
1441 }
1442
1443 return pm_ctx->user_cfg.sub_20_mhz_enabled;
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001444}
1445
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001446bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc,
1447 enum policy_mgr_con_mode mode,
1448 uint8_t channel, enum hw_mode_bandwidth bw)
1449{
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001450 uint32_t num_connections = 0, count = 0, index = 0;
1451 bool status = false, match = false;
1452 uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
1453 struct policy_mgr_psoc_priv_obj *pm_ctx;
1454 QDF_STATUS ret;
1455 struct policy_mgr_pcl_list pcl;
1456
1457 pm_ctx = policy_mgr_get_context(psoc);
1458 if (!pm_ctx) {
1459 policy_mgr_err("Invalid Context");
1460 return status;
1461 }
1462
1463
1464 qdf_mem_zero(&pcl, sizeof(pcl));
1465 ret = policy_mgr_get_pcl(psoc, mode, pcl.pcl_list, &pcl.pcl_len,
1466 pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list));
1467 if (QDF_IS_STATUS_ERROR(ret)) {
1468 policy_mgr_err("disallow connection:%d", ret);
1469 goto done;
1470 }
1471
1472 /* find the current connection state from pm_conc_connection_list*/
1473 num_connections = policy_mgr_get_connection_count(psoc);
1474
Tushnim Bhattacharyyad7655ca2017-04-26 12:58:42 -07001475 if (num_connections && policy_mgr_is_sub_20_mhz_enabled(psoc)) {
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001476 policy_mgr_err("dont allow concurrency if Sub 20 MHz is enabled");
1477 status = false;
1478 goto done;
1479 }
1480
1481 if (policy_mgr_max_concurrent_connections_reached(psoc)) {
1482 policy_mgr_err("Reached max concurrent connections: %d",
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001483 pm_ctx->user_cfg.max_concurrent_active_sessions);
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001484 goto done;
1485 }
1486
1487 if (channel) {
1488 /* don't allow 3rd home channel on same MAC */
1489 if (!policy_mgr_allow_new_home_channel(psoc,
1490 channel, num_connections))
1491 goto done;
1492
1493 /*
1494 * 1) DFS MCC is not yet supported
1495 * 2) If you already have STA connection on 5G channel then
1496 * don't allow any other persona to make connection on DFS
1497 * channel because STA 5G + DFS MCC is not allowed.
1498 * 3) If STA is on 2G channel and SAP is coming up on
1499 * DFS channel then allow concurrency but make sure it is
1500 * going to DBS and send PCL to firmware indicating that
1501 * don't allow STA to roam to 5G channels.
1502 */
1503 if (!policy_mgr_is_5g_channel_allowed(psoc,
1504 channel, list, PM_P2P_GO_MODE))
1505 goto done;
1506 if (!policy_mgr_is_5g_channel_allowed(psoc,
1507 channel, list, PM_SAP_MODE))
1508 goto done;
1509
1510 if ((PM_P2P_GO_MODE == mode) || (PM_SAP_MODE == mode)) {
Tushnim Bhattacharyyace237d62017-04-05 12:52:36 -07001511 if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel))
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001512 match = policy_mgr_disallow_mcc(psoc, channel);
1513 }
1514 if (true == match) {
1515 policy_mgr_err("No MCC, SAP/GO about to come up on DFS channel");
1516 goto done;
1517 }
1518 }
1519
1520 /*
1521 * Check all IBSS+STA concurrencies
1522 *
1523 * don't allow IBSS + STA MCC
1524 * don't allow IBSS + STA SCC if IBSS is on DFS channel
1525 */
1526 count = policy_mgr_mode_specific_connection_count(psoc,
1527 PM_STA_MODE, list);
1528 if ((PM_IBSS_MODE == mode) &&
1529 (policy_mgr_mode_specific_connection_count(psoc,
1530 PM_IBSS_MODE, list)) && count) {
1531 policy_mgr_err("No 2nd IBSS, we already have STA + IBSS");
1532 goto done;
1533 }
1534 if ((PM_IBSS_MODE == mode) &&
Tushnim Bhattacharyyace237d62017-04-05 12:52:36 -07001535 (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel)) && count) {
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001536 policy_mgr_err("No IBSS + STA SCC/MCC, IBSS is on DFS channel");
1537 goto done;
1538 }
1539 if (PM_IBSS_MODE == mode) {
1540 if (policy_mgr_is_hw_dbs_capable(psoc) == true) {
1541 if (num_connections > 1) {
1542 policy_mgr_err("No IBSS, we have concurrent connections already");
1543 goto done;
1544 }
1545 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1546 if (PM_STA_MODE != pm_conc_connection_list[0].mode) {
1547 policy_mgr_err("No IBSS, we've a non-STA connection");
1548 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1549 goto done;
1550 }
1551 /*
1552 * This logic protects STA and IBSS to come up on same
1553 * band. If requirement changes then this condition
1554 * needs to be removed
1555 */
1556 if (channel &&
1557 (pm_conc_connection_list[0].chan != channel) &&
1558 WLAN_REG_IS_SAME_BAND_CHANNELS(
1559 pm_conc_connection_list[0].chan, channel)) {
1560 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1561 policy_mgr_err("No IBSS + STA MCC");
1562 goto done;
1563 }
1564 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1565 } else if (num_connections) {
1566 policy_mgr_err("No IBSS, we have one connection already");
1567 goto done;
1568 }
1569 }
1570
1571 if ((PM_STA_MODE == mode) &&
1572 (policy_mgr_mode_specific_connection_count(psoc,
1573 PM_IBSS_MODE, list)) && count) {
1574 policy_mgr_err("No 2nd STA, we already have STA + IBSS");
1575 goto done;
1576 }
1577
1578 if ((PM_STA_MODE == mode) &&
1579 (policy_mgr_mode_specific_connection_count(psoc,
1580 PM_IBSS_MODE, list))) {
1581 if (policy_mgr_is_hw_dbs_capable(psoc) == true) {
1582 if (num_connections > 1) {
1583 policy_mgr_err("No 2nd STA, we already have IBSS concurrency");
1584 goto done;
1585 }
1586 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1587 if (channel &&
Tushnim Bhattacharyyace237d62017-04-05 12:52:36 -07001588 (wlan_reg_is_dfs_ch(pm_ctx->pdev,
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001589 pm_conc_connection_list[0].chan))
1590 && (WLAN_REG_IS_5GHZ_CH(channel))) {
1591 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1592 policy_mgr_err("No IBSS + STA SCC/MCC, IBSS is on DFS channel");
1593 goto done;
1594 }
1595 /*
1596 * This logic protects STA and IBSS to come up on same
1597 * band. If requirement changes then this condition
1598 * needs to be removed
1599 */
1600 if ((pm_conc_connection_list[0].chan != channel) &&
1601 WLAN_REG_IS_SAME_BAND_CHANNELS(
1602 pm_conc_connection_list[0].chan, channel)) {
1603 policy_mgr_err("No IBSS + STA MCC");
1604 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1605 goto done;
1606 }
1607 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1608 } else {
1609 policy_mgr_err("No STA, we have IBSS connection already");
1610 goto done;
1611 }
1612 }
1613
1614 /* don't allow two P2P GO on same band */
1615 if (channel && (mode == PM_P2P_GO_MODE) && num_connections) {
1616 index = 0;
1617 count = policy_mgr_mode_specific_connection_count(psoc,
1618 PM_P2P_GO_MODE, list);
1619 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1620 while (index < count) {
1621 if (WLAN_REG_IS_SAME_BAND_CHANNELS(channel,
1622 pm_conc_connection_list[list[index]].chan)) {
1623 policy_mgr_err("Don't allow P2P GO on same band");
1624 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1625 goto done;
1626 }
1627 index++;
1628 }
1629 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1630 }
1631
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001632 status = true;
1633
1634done:
1635 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001636}
1637
Archana Ramachandran107d3782017-03-06 17:07:44 -08001638/**
1639 * policy_mgr_get_concurrency_mode() - return concurrency mode
1640 * @psoc: PSOC object information
1641 *
1642 * This routine is used to retrieve concurrency mode
1643 *
1644 * Return: uint32_t value of concurrency mask
1645 */
1646uint32_t policy_mgr_get_concurrency_mode(struct wlan_objmgr_psoc *psoc)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001647{
Archana Ramachandran107d3782017-03-06 17:07:44 -08001648 struct policy_mgr_psoc_priv_obj *pm_ctx;
1649
1650 pm_ctx = policy_mgr_get_context(psoc);
1651 if (!pm_ctx) {
1652 policy_mgr_err("Invalid context");
1653 return QDF_STA_MASK;
1654 }
1655
1656 policy_mgr_info("concurrency_mode: 0x%x",
1657 pm_ctx->concurrency_mode);
1658
1659 return pm_ctx->concurrency_mode;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001660}
1661
Archana Ramachandran0edce252017-03-06 14:36:29 -08001662/**
1663 * policy_mgr_get_channel_from_scan_result() - to get channel from scan result
1664 * @psoc: PSOC object information
1665 * @roam_profile: pointer to roam profile
1666 * @channel: channel to be filled
1667 *
1668 * This routine gets channel which most likely a candidate to which STA
1669 * will make connection.
1670 *
1671 * Return: QDF_STATUS
1672 */
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001673QDF_STATUS policy_mgr_get_channel_from_scan_result(
1674 struct wlan_objmgr_psoc *psoc,
1675 void *roam_profile, uint8_t *channel)
1676{
Archana Ramachandran0edce252017-03-06 14:36:29 -08001677 QDF_STATUS status;
1678 void *scan_cache = NULL;
1679 struct policy_mgr_psoc_priv_obj *pm_ctx;
1680
1681 pm_ctx = policy_mgr_get_context(psoc);
1682 if (!pm_ctx) {
1683 policy_mgr_err("Invalid context");
1684 return QDF_STATUS_E_INVAL;
1685 }
1686
1687 if (!roam_profile || !channel) {
1688 policy_mgr_err("Invalid input parameters");
1689 return QDF_STATUS_E_INVAL;
1690 }
1691
Archana Ramachandran658a48d2017-03-23 23:30:23 -07001692 if (pm_ctx->sme_cbacks.sme_get_ap_channel_from_scan) {
1693 status = pm_ctx->sme_cbacks.sme_get_ap_channel_from_scan
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001694 (roam_profile, &scan_cache, channel);
1695 if (status != QDF_STATUS_SUCCESS) {
1696 policy_mgr_err("Get AP channel failed");
1697 return status;
1698 }
Archana Ramachandran658a48d2017-03-23 23:30:23 -07001699 } else {
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001700 policy_mgr_err("sme_get_ap_channel_from_scan_cache NULL");
Archana Ramachandran658a48d2017-03-23 23:30:23 -07001701 }
Archana Ramachandran0edce252017-03-06 14:36:29 -08001702
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001703 if (pm_ctx->sme_cbacks.sme_scan_result_purge)
1704 status = pm_ctx->sme_cbacks.sme_scan_result_purge(scan_cache);
1705 else
1706 policy_mgr_err("sme_scan_result_purge NULL");
Archana Ramachandran0edce252017-03-06 14:36:29 -08001707
1708 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001709}
1710
Archana Ramachandran3d9b5cf2017-03-10 18:56:44 -08001711QDF_STATUS policy_mgr_set_user_cfg(struct wlan_objmgr_psoc *psoc,
1712 struct policy_mgr_user_cfg *user_cfg)
1713{
1714
1715 struct policy_mgr_psoc_priv_obj *pm_ctx;
1716
1717 pm_ctx = policy_mgr_get_context(psoc);
1718 if (!pm_ctx) {
1719 policy_mgr_err("Invalid context");
1720 return QDF_STATUS_E_FAILURE;
1721 }
1722 if (NULL == user_cfg) {
1723 policy_mgr_err("Invalid User Config");
1724 return QDF_STATUS_E_FAILURE;
1725 }
1726
1727 pm_ctx->user_cfg = *user_cfg;
1728
1729 return QDF_STATUS_SUCCESS;
1730}
1731
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001732uint8_t policy_mgr_search_and_check_for_session_conc(
1733 struct wlan_objmgr_psoc *psoc,
1734 uint8_t session_id,
1735 void *roam_profile)
1736{
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001737 uint8_t channel = 0;
1738 QDF_STATUS status;
1739 enum policy_mgr_con_mode mode;
1740 bool ret;
Tushnim Bhattacharyya59cbe5c2017-03-24 14:13:52 -07001741 struct policy_mgr_psoc_priv_obj *pm_ctx;
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001742
Tushnim Bhattacharyya59cbe5c2017-03-24 14:13:52 -07001743 pm_ctx = policy_mgr_get_context(psoc);
1744 if (!pm_ctx) {
1745 policy_mgr_err("Invalid Context");
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001746 return channel;
1747 }
1748
Tushnim Bhattacharyya59cbe5c2017-03-24 14:13:52 -07001749 if (pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev) {
1750 mode = pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev(
1751 psoc, session_id);
1752 if (PM_MAX_NUM_OF_MODE == mode) {
1753 policy_mgr_err("Invalid mode");
1754 return channel;
1755 }
1756 } else
1757 return channel;
1758
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001759 status = policy_mgr_get_channel_from_scan_result(psoc,
1760 roam_profile, &channel);
1761 if ((QDF_STATUS_SUCCESS != status) || (channel == 0)) {
1762 policy_mgr_err("%s error %d %d",
1763 __func__, status, channel);
1764 return 0;
1765 }
1766
1767 /* Take care of 160MHz and 80+80Mhz later */
1768 ret = policy_mgr_allow_concurrency(psoc, mode, channel, HW_MODE_20_MHZ);
1769 if (false == ret) {
1770 policy_mgr_err("Connection failed due to conc check fail");
1771 return 0;
1772 }
1773
1774 return channel;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001775}
1776
Archana Ramachandran266613f2017-03-13 16:36:55 -07001777/**
1778 * policy_mgr_is_two_connection_mcc() - Check if MCC scenario
1779 * when there are two connections
1780 *
1781 * If if MCC scenario when there are two connections
1782 *
1783 * Return: true or false
1784 */
1785static bool policy_mgr_is_two_connection_mcc(void)
Archana Ramachandran107d3782017-03-06 17:07:44 -08001786{
Archana Ramachandran266613f2017-03-13 16:36:55 -07001787 return ((pm_conc_connection_list[0].chan !=
1788 pm_conc_connection_list[1].chan) &&
1789 (pm_conc_connection_list[0].mac ==
1790 pm_conc_connection_list[1].mac) &&
1791 (pm_conc_connection_list[0].chan <=
1792 WLAN_REG_MAX_24GHZ_CH_NUM) &&
1793 (pm_conc_connection_list[1].chan <=
1794 WLAN_REG_MAX_24GHZ_CH_NUM)) ? true : false;
1795}
1796
1797/**
1798 * policy_mgr_is_three_connection_mcc() - Check if MCC scenario
1799 * when there are three connections
1800 *
1801 * If if MCC scenario when there are three connections
1802 *
1803 * Return: true or false
1804 */
1805static bool policy_mgr_is_three_connection_mcc(void)
1806{
1807 return (((pm_conc_connection_list[0].chan !=
1808 pm_conc_connection_list[1].chan) ||
1809 (pm_conc_connection_list[0].chan !=
1810 pm_conc_connection_list[2].chan) ||
1811 (pm_conc_connection_list[1].chan !=
1812 pm_conc_connection_list[2].chan)) &&
1813 (pm_conc_connection_list[0].chan <=
1814 WLAN_REG_MAX_24GHZ_CH_NUM) &&
1815 (pm_conc_connection_list[1].chan <=
1816 WLAN_REG_MAX_24GHZ_CH_NUM) &&
1817 (pm_conc_connection_list[2].chan <=
1818 WLAN_REG_MAX_24GHZ_CH_NUM)) ? true : false;
1819}
1820
1821bool policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc)
1822{
1823 uint32_t num_connections = 0;
1824 bool is_24G_mcc = false;
1825
1826 num_connections = policy_mgr_get_connection_count(psoc);
1827
1828 switch (num_connections) {
1829 case 1:
1830 break;
1831 case 2:
1832 if (policy_mgr_is_two_connection_mcc())
1833 is_24G_mcc = true;
1834 break;
1835 case 3:
1836 if (policy_mgr_is_three_connection_mcc())
1837 is_24G_mcc = true;
1838 break;
1839 default:
1840 policy_mgr_err("unexpected num_connections value %d",
1841 num_connections);
1842 break;
1843 }
1844
1845 return is_24G_mcc;
Archana Ramachandran107d3782017-03-06 17:07:44 -08001846}
1847
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001848bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc,
1849 uint8_t session_id, uint8_t channel)
1850{
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001851 enum policy_mgr_con_mode mode;
1852 bool ret;
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001853 struct policy_mgr_psoc_priv_obj *pm_ctx;
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001854
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001855 pm_ctx = policy_mgr_get_context(psoc);
1856 if (!pm_ctx) {
1857 policy_mgr_err("Invalid Context");
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001858 return false;
1859 }
1860
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001861 if (pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev) {
1862 mode = pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev(
1863 psoc, session_id);
1864 if (PM_MAX_NUM_OF_MODE == mode) {
1865 policy_mgr_err("Invalid mode");
1866 return false;
1867 }
1868 } else
1869 return false;
1870
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001871 if (channel == 0) {
1872 policy_mgr_err("Invalid channel number 0");
1873 return false;
1874 }
1875
1876 /* Take care of 160MHz and 80+80Mhz later */
1877 ret = policy_mgr_allow_concurrency(psoc, mode, channel, HW_MODE_20_MHZ);
1878 if (false == ret) {
1879 policy_mgr_err("Connection failed due to conc check fail");
1880 return 0;
1881 }
1882
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001883 return true;
1884}
1885
Archana Ramachandran7abbf562017-03-02 13:14:34 -08001886bool policy_mgr_is_mcc_adaptive_scheduler_enabled(
1887 struct wlan_objmgr_psoc *psoc) {
1888 struct policy_mgr_psoc_priv_obj *pm_ctx;
1889
1890 pm_ctx = policy_mgr_get_context(psoc);
1891 if (!pm_ctx) {
1892 policy_mgr_err("Invalid context");
1893 return false;
1894 }
1895
Archana Ramachandran3d9b5cf2017-03-10 18:56:44 -08001896 return pm_ctx->user_cfg.enable_mcc_adaptive_scheduler ?
1897 true : false;
Archana Ramachandran7abbf562017-03-02 13:14:34 -08001898}
1899
Archana Ramachandran3d9b5cf2017-03-10 18:56:44 -08001900/**
1901 * policy_mgr_change_mcc_go_beacon_interval() - Change MCC beacon interval
1902 * @psoc: PSOC object information
1903 * @vdev_id: vdev id
1904 * @dev_mode: device mode
1905 *
1906 * Updates the beacon parameters of the GO in MCC scenario
1907 *
1908 * Return: Success or Failure depending on the overall function behavior
1909 */
Archana Ramachandran8e3ee362017-03-03 20:02:10 -08001910QDF_STATUS policy_mgr_change_mcc_go_beacon_interval(
1911 struct wlan_objmgr_psoc *psoc,
1912 uint8_t vdev_id, enum tQDF_ADAPTER_MODE dev_mode)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001913{
Archana Ramachandran8e3ee362017-03-03 20:02:10 -08001914 QDF_STATUS status;
Archana Ramachandran7abbf562017-03-02 13:14:34 -08001915 struct policy_mgr_psoc_priv_obj *pm_ctx;
Archana Ramachandran7abbf562017-03-02 13:14:34 -08001916
1917 pm_ctx = policy_mgr_get_context(psoc);
1918 if (!pm_ctx) {
1919 policy_mgr_err("Invalid context");
Archana Ramachandran8e3ee362017-03-03 20:02:10 -08001920 return QDF_STATUS_E_FAILURE;
Archana Ramachandran7abbf562017-03-02 13:14:34 -08001921 }
1922
Archana Ramachandran8e3ee362017-03-03 20:02:10 -08001923 policy_mgr_info("UPDATE Beacon Params");
1924
1925 if (QDF_SAP_MODE == dev_mode) {
Archana Ramachandran658a48d2017-03-23 23:30:23 -07001926 if (pm_ctx->sme_cbacks.sme_change_mcc_beacon_interval
1927 ) {
1928 status = pm_ctx->sme_cbacks.
1929 sme_change_mcc_beacon_interval(vdev_id);
1930 if (status == QDF_STATUS_E_FAILURE) {
1931 policy_mgr_err("Failed to update Beacon Params");
1932 return QDF_STATUS_E_FAILURE;
1933 }
1934 } else {
Archana Ramachandran8e3ee362017-03-03 20:02:10 -08001935 policy_mgr_err("sme_change_mcc_beacon_interval callback is NULL");
1936 return QDF_STATUS_E_FAILURE;
Archana Ramachandran7abbf562017-03-02 13:14:34 -08001937 }
Archana Ramachandran7abbf562017-03-02 13:14:34 -08001938 }
1939
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001940 return QDF_STATUS_SUCCESS;
1941}
1942
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001943struct policy_mgr_conc_connection_info *policy_mgr_get_conn_info(uint32_t *len)
1944{
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001945 struct policy_mgr_conc_connection_info *conn_ptr =
1946 &pm_conc_connection_list[0];
1947 *len = MAX_NUMBER_OF_CONC_CONNECTIONS;
1948
1949 return conn_ptr;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001950}
1951
1952enum policy_mgr_con_mode policy_mgr_convert_device_mode_to_qdf_type(
1953 enum tQDF_ADAPTER_MODE device_mode)
1954{
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08001955 enum policy_mgr_con_mode mode = PM_MAX_NUM_OF_MODE;
1956 switch (device_mode) {
1957 case QDF_STA_MODE:
1958 mode = PM_STA_MODE;
1959 break;
1960 case QDF_P2P_CLIENT_MODE:
1961 mode = PM_P2P_CLIENT_MODE;
1962 break;
1963 case QDF_P2P_GO_MODE:
1964 mode = PM_P2P_GO_MODE;
1965 break;
1966 case QDF_SAP_MODE:
1967 mode = PM_SAP_MODE;
1968 break;
1969 case QDF_IBSS_MODE:
1970 mode = PM_IBSS_MODE;
1971 break;
1972 default:
1973 policy_mgr_err("Unsupported mode (%d)",
1974 device_mode);
1975 }
1976
1977 return mode;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001978}
1979
Archana Ramachandran107d3782017-03-06 17:07:44 -08001980/**
1981 * policy_mgr_concurrent_open_sessions_running() - Checks for
1982 * concurrent open session
1983 * @psoc: PSOC object information
1984 *
1985 * Checks if more than one open session is running for all the allowed modes
1986 * in the driver
1987 *
1988 * Return: True if more than one open session exists, False otherwise
1989 */
1990bool policy_mgr_concurrent_open_sessions_running(
1991 struct wlan_objmgr_psoc *psoc)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001992{
Archana Ramachandran107d3782017-03-06 17:07:44 -08001993 uint8_t i = 0;
1994 uint8_t j = 0;
1995 struct policy_mgr_psoc_priv_obj *pm_ctx;
1996
1997 pm_ctx = policy_mgr_get_context(psoc);
1998 if (!pm_ctx) {
1999 policy_mgr_err("Invalid context");
2000 return false;
2001 }
2002
2003 for (i = 0; i < QDF_MAX_NO_OF_MODE; i++)
2004 j += pm_ctx->no_of_open_sessions[i];
2005
2006 return j > 1;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002007}
2008
Archana Ramachandran107d3782017-03-06 17:07:44 -08002009/**
2010 * policy_mgr_concurrent_beaconing_sessions_running() - Checks
2011 * for concurrent beaconing entities
2012 * @psoc: PSOC object information
2013 *
2014 * Checks if multiple beaconing sessions are running i.e., if SAP or GO or IBSS
2015 * are beaconing together
2016 *
2017 * Return: True if multiple entities are beaconing together, False otherwise
2018 */
2019bool policy_mgr_concurrent_beaconing_sessions_running(
2020 struct wlan_objmgr_psoc *psoc)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002021{
Archana Ramachandran107d3782017-03-06 17:07:44 -08002022 return (policy_mgr_mode_specific_connection_count(
2023 psoc, QDF_SAP_MODE, NULL) +
2024 policy_mgr_mode_specific_connection_count(
2025 psoc, QDF_P2P_GO_MODE, NULL) +
2026 policy_mgr_mode_specific_connection_count(
2027 psoc, QDF_IBSS_MODE, NULL) > 1) ?
2028 true : false;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002029}
2030
2031
2032void policy_mgr_clear_concurrent_session_count(struct wlan_objmgr_psoc *psoc)
2033{
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08002034 uint8_t i = 0;
2035 struct policy_mgr_psoc_priv_obj *pm_ctx;
2036
2037 pm_ctx = policy_mgr_get_context(psoc);
2038 if (NULL != pm_ctx) {
2039 for (i = 0; i < QDF_MAX_NO_OF_MODE; i++)
2040 pm_ctx->no_of_active_sessions[i] = 0;
2041 }
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002042}
2043
2044bool policy_mgr_is_multiple_active_sta_sessions(struct wlan_objmgr_psoc *psoc)
2045{
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08002046 return policy_mgr_mode_specific_connection_count(
2047 psoc, PM_STA_MODE, NULL) > 1;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002048}
2049
Archana Ramachandran0edce252017-03-06 14:36:29 -08002050/**
2051 * policy_mgr_is_sta_active_connection_exists() - Check if a STA
2052 * connection is active
2053 * @psoc: PSOC object information
2054 *
2055 * Checks if there is atleast one active STA connection in the driver
2056 *
2057 * Return: True if an active STA session is present, False otherwise
2058 */
2059bool policy_mgr_is_sta_active_connection_exists(
2060 struct wlan_objmgr_psoc *psoc)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002061{
Archana Ramachandran0edce252017-03-06 14:36:29 -08002062 return (!policy_mgr_mode_specific_connection_count(
2063 psoc, QDF_STA_MODE, NULL)) ? false : true;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002064}
2065
2066bool policy_mgr_is_any_nondfs_chnl_present(struct wlan_objmgr_psoc *psoc,
2067 uint8_t *channel)
2068{
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08002069 bool status = false;
2070 uint32_t conn_index = 0;
2071 struct policy_mgr_psoc_priv_obj *pm_ctx;
2072
2073 pm_ctx = policy_mgr_get_context(psoc);
2074 if (!pm_ctx) {
2075 policy_mgr_err("Invalid Context");
2076 return false;
2077 }
2078 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2079 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
2080 conn_index++) {
2081 if (pm_conc_connection_list[conn_index].in_use &&
Tushnim Bhattacharyyace237d62017-04-05 12:52:36 -07002082 !wlan_reg_is_dfs_ch(pm_ctx->pdev,
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08002083 pm_conc_connection_list[conn_index].chan)) {
2084 *channel = pm_conc_connection_list[conn_index].chan;
2085 status = true;
2086 }
2087 }
2088 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2089
2090 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002091}
2092
2093bool policy_mgr_is_any_dfs_beaconing_session_present(
2094 struct wlan_objmgr_psoc *psoc, uint8_t *channel)
2095{
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08002096 struct policy_mgr_conc_connection_info *conn_info;
2097 bool status = false;
2098 uint32_t conn_index = 0;
2099 struct policy_mgr_psoc_priv_obj *pm_ctx;
2100
2101 pm_ctx = policy_mgr_get_context(psoc);
2102 if (!pm_ctx) {
2103 policy_mgr_err("Invalid Context");
2104 return false;
2105 }
2106 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2107 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
2108 conn_index++) {
2109 conn_info = &pm_conc_connection_list[conn_index];
2110 if (conn_info->in_use &&
Tushnim Bhattacharyyace237d62017-04-05 12:52:36 -07002111 wlan_reg_is_dfs_ch(pm_ctx->pdev, conn_info->chan) &&
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08002112 (PM_SAP_MODE == conn_info->mode ||
2113 PM_P2P_GO_MODE == conn_info->mode)) {
2114 *channel = pm_conc_connection_list[conn_index].chan;
2115 status = true;
2116 }
2117 }
2118 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2119
2120 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002121}
2122
2123QDF_STATUS policy_mgr_get_nss_for_vdev(struct wlan_objmgr_psoc *psoc,
2124 enum policy_mgr_con_mode mode,
2125 uint8_t *nss_2g, uint8_t *nss_5g)
2126{
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08002127 enum tQDF_ADAPTER_MODE dev_mode;
2128 struct policy_mgr_psoc_priv_obj *pm_ctx;
2129
2130 switch (mode) {
2131 case PM_STA_MODE:
2132 dev_mode = QDF_STA_MODE;
2133 break;
2134 case PM_SAP_MODE:
2135 dev_mode = QDF_SAP_MODE;
2136 break;
2137 case PM_P2P_CLIENT_MODE:
2138 dev_mode = QDF_P2P_CLIENT_MODE;
2139 break;
2140 case PM_P2P_GO_MODE:
2141 dev_mode = QDF_P2P_GO_MODE;
2142 break;
2143 case PM_IBSS_MODE:
2144 dev_mode = QDF_IBSS_MODE;
2145 break;
2146 default:
2147 policy_mgr_err("Invalid mode to get allowed NSS value");
2148 return QDF_STATUS_E_FAILURE;
2149 };
2150
2151 pm_ctx = policy_mgr_get_context(psoc);
2152 if (!pm_ctx) {
2153 policy_mgr_err("Invalid Context");
2154 return QDF_STATUS_E_FAILURE;
2155 }
2156
Archana Ramachandran658a48d2017-03-23 23:30:23 -07002157 if (pm_ctx->sme_cbacks.sme_get_nss_for_vdev) {
2158 pm_ctx->sme_cbacks.sme_get_nss_for_vdev(
2159 dev_mode, nss_2g, nss_5g);
2160
2161 } else {
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08002162 policy_mgr_err("sme_get_nss_for_vdev callback is NULL");
2163 return QDF_STATUS_E_FAILURE;
2164 }
2165
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002166 return QDF_STATUS_SUCCESS;
2167}
2168
2169void policy_mgr_dump_connection_status_info(struct wlan_objmgr_psoc *psoc)
2170{
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08002171 uint32_t i;
2172 struct policy_mgr_psoc_priv_obj *pm_ctx;
2173
2174 pm_ctx = policy_mgr_get_context(psoc);
2175 if (!pm_ctx) {
2176 policy_mgr_err("Invalid Context");
2177 return;
2178 }
2179
2180 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2181 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
2182 policy_mgr_debug("%d: use:%d vdev:%d mode:%d mac:%d chan:%d orig chainmask:%d orig nss:%d bw:%d",
2183 i, pm_conc_connection_list[i].in_use,
2184 pm_conc_connection_list[i].vdev_id,
2185 pm_conc_connection_list[i].mode,
2186 pm_conc_connection_list[i].mac,
2187 pm_conc_connection_list[i].chan,
2188 pm_conc_connection_list[i].chain_mask,
2189 pm_conc_connection_list[i].original_nss,
2190 pm_conc_connection_list[i].bw);
2191 }
2192 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002193}
2194
2195bool policy_mgr_is_any_mode_active_on_band_along_with_session(
2196 struct wlan_objmgr_psoc *psoc,
2197 uint8_t session_id,
2198 enum policy_mgr_band band)
2199{
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08002200 uint32_t i;
2201 bool status = false;
2202 struct policy_mgr_psoc_priv_obj *pm_ctx;
2203
2204 pm_ctx = policy_mgr_get_context(psoc);
2205 if (!pm_ctx) {
2206 policy_mgr_err("Invalid Context");
2207 status = false;
2208 goto send_status;
2209 }
2210
2211 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2212 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
2213 switch (band) {
2214 case POLICY_MGR_BAND_24:
2215 if ((pm_conc_connection_list[i].vdev_id != session_id)
2216 && (pm_conc_connection_list[i].in_use) &&
2217 (WLAN_REG_IS_24GHZ_CH(
2218 pm_conc_connection_list[i].chan))) {
2219 status = true;
2220 goto release_mutex_and_send_status;
2221 }
2222 break;
2223 case POLICY_MGR_BAND_5:
2224 if ((pm_conc_connection_list[i].vdev_id != session_id)
2225 && (pm_conc_connection_list[i].in_use) &&
2226 (WLAN_REG_IS_5GHZ_CH(
2227 pm_conc_connection_list[i].chan))) {
2228 status = true;
2229 goto release_mutex_and_send_status;
2230 }
2231 break;
2232 default:
2233 policy_mgr_err("Invalidband option:%d", band);
2234 status = false;
2235 goto release_mutex_and_send_status;
2236 }
2237 }
2238release_mutex_and_send_status:
2239 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2240send_status:
2241 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002242}
2243
Nitesh Shah3ab43842017-04-26 20:02:34 +05302244QDF_STATUS policy_mgr_get_chan_by_session_id(struct wlan_objmgr_psoc *psoc,
2245 uint8_t session_id, uint8_t *chan)
2246{
2247 uint32_t i;
2248 struct policy_mgr_psoc_priv_obj *pm_ctx;
2249
2250 pm_ctx = policy_mgr_get_context(psoc);
2251 if (!pm_ctx) {
2252 policy_mgr_err("Invalid Context");
2253 return QDF_STATUS_E_FAILURE;
2254 }
2255
2256 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2257 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
2258 if ((pm_conc_connection_list[i].vdev_id == session_id) &&
2259 (pm_conc_connection_list[i].in_use)) {
2260 *chan = pm_conc_connection_list[i].chan;
2261 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2262 return QDF_STATUS_SUCCESS;
2263 }
2264 }
2265 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2266
2267 return QDF_STATUS_E_FAILURE;
2268}
2269
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002270QDF_STATUS policy_mgr_get_mac_id_by_session_id(struct wlan_objmgr_psoc *psoc,
2271 uint8_t session_id, uint8_t *mac_id)
2272{
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08002273 uint32_t i;
2274 struct policy_mgr_psoc_priv_obj *pm_ctx;
2275
2276 pm_ctx = policy_mgr_get_context(psoc);
2277 if (!pm_ctx) {
2278 policy_mgr_err("Invalid Context");
2279 return QDF_STATUS_E_FAILURE;
2280 }
2281
2282 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2283 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
2284 if ((pm_conc_connection_list[i].vdev_id == session_id) &&
2285 (pm_conc_connection_list[i].in_use)) {
2286 *mac_id = pm_conc_connection_list[i].mac;
2287 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2288 return QDF_STATUS_SUCCESS;
2289 }
2290 }
2291 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2292
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002293 return QDF_STATUS_E_FAILURE;
2294}
2295
2296QDF_STATUS policy_mgr_get_mcc_session_id_on_mac(struct wlan_objmgr_psoc *psoc,
2297 uint8_t mac_id, uint8_t session_id,
2298 uint8_t *mcc_session_id)
2299{
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08002300 uint32_t i;
Nitesh Shah3ab43842017-04-26 20:02:34 +05302301 QDF_STATUS status;
2302 uint8_t chan;
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08002303 struct policy_mgr_psoc_priv_obj *pm_ctx;
2304
2305 pm_ctx = policy_mgr_get_context(psoc);
2306 if (!pm_ctx) {
2307 policy_mgr_err("Invalid Context");
2308 return QDF_STATUS_E_FAILURE;
2309 }
2310
Nitesh Shah3ab43842017-04-26 20:02:34 +05302311 status = policy_mgr_get_chan_by_session_id(psoc, session_id, &chan);
2312 if (QDF_IS_STATUS_ERROR(status)) {
2313 policy_mgr_err("Failed to get channel for session id:%d",
2314 session_id);
2315 return QDF_STATUS_E_FAILURE;
2316 }
2317
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08002318 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2319 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
2320 if (pm_conc_connection_list[i].mac != mac_id)
2321 continue;
2322 if (pm_conc_connection_list[i].vdev_id == session_id)
2323 continue;
2324 /* Inter band or intra band MCC */
2325 if ((pm_conc_connection_list[i].chan != chan) &&
2326 (pm_conc_connection_list[i].in_use)) {
2327 *mcc_session_id = pm_conc_connection_list[i].vdev_id;
2328 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2329 return QDF_STATUS_SUCCESS;
2330 }
2331 }
2332 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2333
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002334 return QDF_STATUS_E_FAILURE;
2335}
2336
2337uint8_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc,
2338 uint8_t session_id)
2339{
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08002340 uint8_t mac_id, mcc_session_id;
2341 QDF_STATUS status;
2342 uint8_t chan;
2343 struct policy_mgr_psoc_priv_obj *pm_ctx;
2344
2345 pm_ctx = policy_mgr_get_context(psoc);
2346 if (!pm_ctx) {
2347 policy_mgr_err("Invalid Context");
2348 return INVALID_CHANNEL_ID;
2349 }
2350
2351 status = policy_mgr_get_mac_id_by_session_id(psoc, session_id, &mac_id);
2352 if (QDF_IS_STATUS_ERROR(status)) {
2353 policy_mgr_err("failed to get MAC ID");
2354 return INVALID_CHANNEL_ID;
2355 }
2356
2357 status = policy_mgr_get_mcc_session_id_on_mac(psoc, mac_id, session_id,
2358 &mcc_session_id);
2359 if (QDF_IS_STATUS_ERROR(status)) {
2360 policy_mgr_err("failed to get MCC session ID");
2361 return INVALID_CHANNEL_ID;
2362 }
2363
Nitesh Shah3ab43842017-04-26 20:02:34 +05302364 status = policy_mgr_get_chan_by_session_id(psoc, mcc_session_id,
2365 &chan);
2366 if (QDF_IS_STATUS_ERROR(status)) {
2367 policy_mgr_err("Failed to get channel for MCC session ID:%d",
2368 mcc_session_id);
2369 return INVALID_CHANNEL_ID;
2370 }
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08002371
2372 return chan;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002373}
2374
2375void policy_mgr_set_do_hw_mode_change_flag(struct wlan_objmgr_psoc *psoc,
2376 bool flag)
2377{
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08002378 struct policy_mgr_psoc_priv_obj *pm_ctx;
2379
2380 pm_ctx = policy_mgr_get_context(psoc);
2381 if (!pm_ctx) {
2382 policy_mgr_err("Invalid Context");
2383 return;
2384 }
2385
2386 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2387 pm_ctx->do_hw_mode_change = flag;
2388 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2389
2390 policy_mgr_debug("hw_mode_change_channel:%d", flag);
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002391}
2392
2393bool policy_mgr_is_hw_mode_change_after_vdev_up(struct wlan_objmgr_psoc *psoc)
2394{
Tushnim Bhattacharyya482d82b2017-03-08 10:26:14 -08002395 bool flag;
2396 struct policy_mgr_psoc_priv_obj *pm_ctx;
2397
2398 pm_ctx = policy_mgr_get_context(psoc);
2399 if (!pm_ctx) {
2400 policy_mgr_err("Invalid Context");
2401 return INVALID_CHANNEL_ID;
2402 }
2403
2404 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2405 flag = pm_ctx->do_hw_mode_change;
2406 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2407
2408 return flag;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002409}
Ajit Pal Singhc65575e2017-04-17 16:49:01 +05302410
Ajit Pal Singhc0af3e82017-05-24 11:58:09 +05302411bool policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev *vdev)
Ajit Pal Singhc65575e2017-04-17 16:49:01 +05302412{
Ajit Pal Singhc0af3e82017-05-24 11:58:09 +05302413 bool roffchan;
2414
2415 if (!vdev) {
2416 policy_mgr_err("Invalid parameter");
2417 return false;
2418 }
2419
2420 wlan_vdev_obj_lock(vdev);
2421 roffchan = wlan_vdev_mlme_cap_get(vdev, WLAN_VDEV_C_RESTRICT_OFFCHAN);
2422 wlan_vdev_obj_unlock(vdev);
2423
2424 policy_mgr_debug("Restrict offchannel:%s",
2425 roffchan ? "set" : "clear");
2426
2427 return roffchan;
Ajit Pal Singhc65575e2017-04-17 16:49:01 +05302428}
2429
2430QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc,
2431 uint8_t channel, bool *ok)
2432{
2433 uint8_t operating_channel = 0, vdev_id = 0;
2434 struct wlan_objmgr_vdev *vdev;
2435
2436 if (!channel || !ok) {
2437 policy_mgr_err("Invalid parameter");
2438 return QDF_STATUS_E_INVAL;
2439 }
2440
2441 if (policy_mgr_get_mode_specific_conn_info(psoc,
2442 &operating_channel,
2443 &vdev_id,
2444 PM_SAP_MODE))
2445 policy_mgr_debug("SAP mode active");
2446 else if (policy_mgr_get_mode_specific_conn_info(psoc,
2447 &operating_channel,
2448 &vdev_id,
2449 PM_P2P_GO_MODE))
2450 policy_mgr_debug("P2P_GO_MODE mode active");
2451 else {
2452 *ok = true;
2453 return QDF_STATUS_SUCCESS;
2454 }
2455
2456 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
2457 WLAN_POLICY_MGR_ID);
2458 if (!vdev) {
2459 policy_mgr_err("vdev is NULL");
2460 return QDF_STATUS_E_INVAL;
2461 }
2462
2463 /**
2464 * If channel passed is same as AP/GO operating channel, then
2465 * return true.
2466 * If channel is different from operating channel but in same band.
2467 * return false.
2468 * If operating channel in different band.
2469 * return true.
2470 */
2471 /* TODO: To be enhanced for SBS */
Ajit Pal Singhc0af3e82017-05-24 11:58:09 +05302472 if (policy_mgr_is_dnsc_set(vdev)) {
Ajit Pal Singhc65575e2017-04-17 16:49:01 +05302473 if (operating_channel == channel)
2474 *ok = true;
2475 else if (WLAN_REG_IS_SAME_BAND_CHANNELS(operating_channel,
2476 channel))
2477 *ok = false;
2478 else
2479 *ok = true;
2480 } else {
2481 *ok = true;
2482 }
2483 wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID);
2484 return QDF_STATUS_SUCCESS;
2485}
Vikrampal31eb12c2017-04-28 17:44:30 +05302486
Vikrampal7e4d4c22017-05-17 09:36:46 +05302487uint32_t policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc,
2488 struct dbs_nss *nss_dbs)
Vikrampal31eb12c2017-04-28 17:44:30 +05302489{
2490 int i, param;
2491 uint32_t dbs, tx_chain0, rx_chain0, tx_chain1, rx_chain1;
2492 uint32_t min_mac0_rf_chains, min_mac1_rf_chains;
Vikrampal7e4d4c22017-05-17 09:36:46 +05302493 uint32_t max_rf_chains, final_max_rf_chains = HW_MODE_SS_0x0;
Vikrampal31eb12c2017-04-28 17:44:30 +05302494 struct policy_mgr_psoc_priv_obj *pm_ctx;
2495
2496 pm_ctx = policy_mgr_get_context(psoc);
2497 if (!pm_ctx)
2498 policy_mgr_err("Invalid Context");
2499
2500 for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
2501 param = pm_ctx->hw_mode.hw_mode_list[i];
2502 dbs = POLICY_MGR_HW_MODE_DBS_MODE_GET(param);
2503
2504 if (dbs) {
2505 tx_chain0
2506 = POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param);
2507 rx_chain0
2508 = POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param);
2509
2510 tx_chain1
2511 = POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param);
2512 rx_chain1
2513 = POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param);
2514
2515 min_mac0_rf_chains = QDF_MIN(tx_chain0, rx_chain0);
2516 min_mac1_rf_chains = QDF_MIN(tx_chain1, rx_chain1);
2517
Vikrampal7e4d4c22017-05-17 09:36:46 +05302518 max_rf_chains
2519 = QDF_MAX(min_mac0_rf_chains, min_mac1_rf_chains);
Vikrampal31eb12c2017-04-28 17:44:30 +05302520
Vikrampal7e4d4c22017-05-17 09:36:46 +05302521 if (final_max_rf_chains < max_rf_chains) {
2522 final_max_rf_chains
2523 = (max_rf_chains == 2)
2524 ? HW_MODE_SS_2x2 : HW_MODE_SS_1x1;
Vikrampal31eb12c2017-04-28 17:44:30 +05302525
Vikrampal7e4d4c22017-05-17 09:36:46 +05302526 nss_dbs->mac0_ss
2527 = (min_mac0_rf_chains == 2)
2528 ? HW_MODE_SS_2x2 : HW_MODE_SS_1x1;
2529
2530 nss_dbs->mac1_ss
2531 = (min_mac1_rf_chains == 2)
2532 ? HW_MODE_SS_2x2 : HW_MODE_SS_1x1;
2533 }
Vikrampal31eb12c2017-04-28 17:44:30 +05302534 } else {
2535 continue;
2536 }
2537 }
2538
Vikrampal7e4d4c22017-05-17 09:36:46 +05302539 return final_max_rf_chains;
Vikrampal31eb12c2017-04-28 17:44:30 +05302540}