blob: ac2ddf75df79b3e90bc66d4a125bd398c7950d5d [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"
Tushnim Bhattacharyya89036a72018-10-01 14:50:15 -070034#include "qdf_platform.h"
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -080035
36enum policy_mgr_conc_next_action (*policy_mgr_get_current_pref_hw_mode_ptr)
37 (struct wlan_objmgr_psoc *psoc);
38
39void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index,
40 uint32_t new_hw_mode_index,
41 uint32_t num_vdev_mac_entries,
42 struct policy_mgr_vdev_mac_map *vdev_mac_map,
43 struct wlan_objmgr_psoc *context)
44{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -080045 QDF_STATUS status;
46 struct policy_mgr_hw_mode_params hw_mode;
47 uint32_t i;
Yeshwanth Sriram Guntuka6a3be162018-02-23 12:14:46 +053048 struct policy_mgr_psoc_priv_obj *pm_ctx;
49
50 pm_ctx = policy_mgr_get_context(context);
51 if (!pm_ctx) {
52 policy_mgr_err("Invalid context");
53 return;
54 }
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -080055
56 if (!vdev_mac_map) {
57 policy_mgr_err("vdev_mac_map is NULL");
58 return;
59 }
60
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -070061 policy_mgr_debug("old_hw_mode_index=%d, new_hw_mode_index=%d",
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -080062 old_hw_mode_index, new_hw_mode_index);
63
64 for (i = 0; i < num_vdev_mac_entries; i++)
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -070065 policy_mgr_debug("vdev_id:%d mac_id:%d",
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -080066 vdev_mac_map[i].vdev_id,
67 vdev_mac_map[i].mac_id);
68
69 status = policy_mgr_get_hw_mode_from_idx(context,
70 new_hw_mode_index, &hw_mode);
71 if (status != QDF_STATUS_SUCCESS) {
72 policy_mgr_err("Get HW mode failed: %d", status);
73 return;
74 }
75
Liangwei Donge57b6b72018-05-21 04:51:47 -040076 policy_mgr_debug("MAC0: TxSS:%d, RxSS:%d, Bw:%d band_cap:%d",
77 hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss,
78 hw_mode.mac0_bw, hw_mode.mac0_band_cap);
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -070079 policy_mgr_debug("MAC1: TxSS:%d, RxSS:%d, Bw:%d",
Liangwei Donge57b6b72018-05-21 04:51:47 -040080 hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss,
81 hw_mode.mac1_bw);
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -070082 policy_mgr_debug("DBS:%d, Agile DFS:%d, SBS:%d",
Liangwei Donge57b6b72018-05-21 04:51:47 -040083 hw_mode.dbs_cap, hw_mode.agile_dfs_cap,
84 hw_mode.sbs_cap);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -080085
86 /* update pm_conc_connection_list */
87 policy_mgr_update_hw_mode_conn_info(context, num_vdev_mac_entries,
88 vdev_mac_map,
89 hw_mode);
90
Yeshwanth Sriram Guntuka6a3be162018-02-23 12:14:46 +053091 if (pm_ctx->mode_change_cb)
92 pm_ctx->mode_change_cb();
93
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -080094 return;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -080095}
96
Tushnim Bhattacharyyac304f892018-08-01 19:15:55 -070097QDF_STATUS policy_mgr_check_n_start_opportunistic_timer(
98 struct wlan_objmgr_psoc *psoc)
99{
100 struct policy_mgr_psoc_priv_obj *pm_ctx;
101 QDF_STATUS status = QDF_STATUS_E_FAILURE;
102
103 pm_ctx = policy_mgr_get_context(psoc);
104 if (!pm_ctx) {
105 policy_mgr_err("PM ctx not valid. Oppurtunistic timer cannot start");
106 return QDF_STATUS_E_FAILURE;
107 }
108 if (policy_mgr_need_opportunistic_upgrade(psoc)) {
109 /* let's start the timer */
110 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
111 status = qdf_mc_timer_start(
112 &pm_ctx->dbs_opportunistic_timer,
113 DBS_OPPORTUNISTIC_TIME * 1000);
114 if (!QDF_IS_STATUS_SUCCESS(status))
115 policy_mgr_err("Failed to start dbs opportunistic timer");
116 }
117 return status;
118}
119
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800120QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc,
121 uint32_t session_id,
122 enum hw_mode_ss_config mac0_ss,
123 enum hw_mode_bandwidth mac0_bw,
124 enum hw_mode_ss_config mac1_ss,
125 enum hw_mode_bandwidth mac1_bw,
Liangwei Dong9ace8a92018-05-21 05:39:04 -0400126 enum hw_mode_mac_band_cap mac0_band_cap,
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800127 enum hw_mode_dbs_capab dbs,
128 enum hw_mode_agile_dfs_capab dfs,
129 enum hw_mode_sbs_capab sbs,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800130 enum policy_mgr_conn_update_reason reason,
131 uint8_t next_action)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800132{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800133 int8_t hw_mode_index;
134 struct policy_mgr_hw_mode msg;
135 QDF_STATUS status;
136 struct policy_mgr_psoc_priv_obj *pm_ctx;
137
138 pm_ctx = policy_mgr_get_context(psoc);
139 if (!pm_ctx) {
140 policy_mgr_err("Invalid context");
141 return QDF_STATUS_E_FAILURE;
142 }
143
144 /*
145 * if HW is not capable of doing 2x2 or ini config disabled 2x2, don't
146 * allow to request FW for 2x2
147 */
Tushnim Bhattacharyya68f709d2017-03-23 18:00:04 -0700148 if ((HW_MODE_SS_2x2 == mac0_ss) && (!pm_ctx->user_cfg.enable2x2)) {
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -0700149 policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac0");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800150 mac0_ss = HW_MODE_SS_1x1;
151 }
Tushnim Bhattacharyya68f709d2017-03-23 18:00:04 -0700152 if ((HW_MODE_SS_2x2 == mac1_ss) && (!pm_ctx->user_cfg.enable2x2)) {
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -0700153 policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac1");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800154 mac1_ss = HW_MODE_SS_1x1;
155 }
156
157 hw_mode_index = policy_mgr_get_hw_mode_idx_from_dbs_hw_list(psoc,
Liangwei Dong9ace8a92018-05-21 05:39:04 -0400158 mac0_ss, mac0_bw, mac1_ss, mac1_bw, mac0_band_cap,
159 dbs, dfs, sbs);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800160 if (hw_mode_index < 0) {
161 policy_mgr_err("Invalid HW mode index obtained");
162 return QDF_STATUS_E_FAILURE;
163 }
164
165 msg.hw_mode_index = hw_mode_index;
166 msg.set_hw_mode_cb = (void *)policy_mgr_pdev_set_hw_mode_cb;
167 msg.reason = reason;
168 msg.session_id = session_id;
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -0800169 msg.next_action = next_action;
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -0700170 msg.context = psoc;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800171
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -0700172 policy_mgr_debug("set hw mode to sme: hw_mode_index: %d session:%d reason:%d",
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800173 msg.hw_mode_index, msg.session_id, msg.reason);
174
175 status = pm_ctx->sme_cbacks.sme_pdev_set_hw_mode(msg);
176 if (status != QDF_STATUS_SUCCESS) {
177 policy_mgr_err("Failed to set hw mode to SME");
178 return status;
179 }
180
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800181 return QDF_STATUS_SUCCESS;
182}
183
184enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade(
185 struct wlan_objmgr_psoc *psoc)
186{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800187 uint32_t conn_index;
188 enum policy_mgr_conc_next_action upgrade = PM_NOP;
189 uint8_t mac = 0;
190 struct policy_mgr_hw_mode_params hw_mode;
191 QDF_STATUS status = QDF_STATUS_E_FAILURE;
192 struct policy_mgr_psoc_priv_obj *pm_ctx;
193
194 pm_ctx = policy_mgr_get_context(psoc);
195 if (!pm_ctx) {
196 policy_mgr_err("Invalid Context");
197 goto done;
198 }
199
200 if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
201 policy_mgr_err("driver isn't dbs capable, no further action needed");
202 goto done;
203 }
204
205 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
206 if (!QDF_IS_STATUS_SUCCESS(status)) {
207 policy_mgr_err("policy_mgr_get_current_hw_mode failed");
208 goto done;
209 }
210 if (!hw_mode.dbs_cap) {
Yeshwanth Sriram Guntukad540cd02018-08-23 18:25:28 +0530211 policy_mgr_debug("current HW mode is non-DBS capable");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800212 goto done;
213 }
214
215 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
216 /* Are both mac's still in use */
217 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
218 conn_index++) {
219 policy_mgr_debug("index:%d mac:%d in_use:%d chan:%d org_nss:%d",
220 conn_index,
221 pm_conc_connection_list[conn_index].mac,
222 pm_conc_connection_list[conn_index].in_use,
223 pm_conc_connection_list[conn_index].chan,
224 pm_conc_connection_list[conn_index].original_nss);
225 if ((pm_conc_connection_list[conn_index].mac == 0) &&
226 pm_conc_connection_list[conn_index].in_use) {
227 mac |= POLICY_MGR_MAC0;
228 if (POLICY_MGR_MAC0_AND_MAC1 == mac) {
229 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
230 goto done;
231 }
232 } else if ((pm_conc_connection_list[conn_index].mac == 1) &&
233 pm_conc_connection_list[conn_index].in_use) {
234 mac |= POLICY_MGR_MAC1;
Archana Ramachandran944f1fd2017-06-02 16:48:17 -0700235 if (policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
236 WLAN_REG_IS_24GHZ_CH(
237 pm_conc_connection_list[conn_index].chan)
238 ) {
239 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
240 policy_mgr_debug("2X2 DBS capable with 2.4 GHZ connection");
241 goto done;
242 }
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800243 if (POLICY_MGR_MAC0_AND_MAC1 == mac) {
244 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
245 goto done;
246 }
247 }
248 }
249 /* Let's request for single MAC mode */
250 upgrade = PM_SINGLE_MAC;
251 /* Is there any connection had an initial connection with 2x2 */
252 for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
253 conn_index++) {
254 if ((pm_conc_connection_list[conn_index].original_nss == 2) &&
255 pm_conc_connection_list[conn_index].in_use) {
256 upgrade = PM_SINGLE_MAC_UPGRADE;
257 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
258 goto done;
259 }
260 }
261 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
262
263done:
264 return upgrade;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800265}
266
267QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc,
268 uint32_t vdev_id)
269{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800270 QDF_STATUS status = QDF_STATUS_E_FAILURE;
271 uint32_t conn_index = 0;
272 bool found = false;
273 struct policy_mgr_vdev_entry_info conn_table_entry;
274 enum policy_mgr_chain_mode chain_mask = POLICY_MGR_ONE_ONE;
275 uint8_t nss_2g, nss_5g;
276 enum policy_mgr_con_mode mode;
277 uint8_t chan;
278 uint32_t nss = 0;
279 struct policy_mgr_psoc_priv_obj *pm_ctx;
280
281 pm_ctx = policy_mgr_get_context(psoc);
282 if (!pm_ctx) {
283 policy_mgr_err("Invalid Context");
284 return status;
285 }
286
287 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
288 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
289 if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
290 /* debug msg */
291 found = true;
292 break;
293 }
294 conn_index++;
295 }
296 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
297 if (!found) {
298 /* err msg */
299 policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list",
300 vdev_id);
301 return status;
302 }
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700303 if (pm_ctx->wma_cbacks.wma_get_connection_info) {
304 status = pm_ctx->wma_cbacks.wma_get_connection_info(
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800305 vdev_id, &conn_table_entry);
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700306 if (QDF_STATUS_SUCCESS != status) {
307 policy_mgr_err("can't find vdev_id %d in connection table",
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800308 vdev_id);
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700309 return status;
310 }
311 } else {
312 policy_mgr_err("wma_get_connection_info is NULL");
313 return QDF_STATUS_E_FAILURE;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800314 }
Tushnim Bhattacharyya00ccf112017-03-28 10:45:08 -0700315
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800316 mode = policy_mgr_get_mode(conn_table_entry.type,
317 conn_table_entry.sub_type);
Tushnim Bhattacharyyace237d62017-04-05 12:52:36 -0700318 chan = wlan_reg_freq_to_chan(pm_ctx->pdev, conn_table_entry.mhz);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800319 status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g);
320 if (QDF_IS_STATUS_SUCCESS(status)) {
321 if ((WLAN_REG_IS_24GHZ_CH(chan) && (nss_2g > 1)) ||
322 (WLAN_REG_IS_5GHZ_CH(chan) && (nss_5g > 1)))
323 chain_mask = POLICY_MGR_TWO_TWO;
324 else
325 chain_mask = POLICY_MGR_ONE_ONE;
326 nss = (WLAN_REG_IS_24GHZ_CH(chan)) ? nss_2g : nss_5g;
327 } else {
328 policy_mgr_err("Error in getting nss");
329 }
330
331 policy_mgr_debug("update PM connection table for vdev:%d", vdev_id);
332
333 /* add the entry */
334 policy_mgr_update_conc_list(psoc, conn_index,
335 mode,
336 chan,
337 policy_mgr_get_bw(conn_table_entry.chan_width),
338 conn_table_entry.mac_id,
339 chain_mask,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +0530340 nss, vdev_id, true, true);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800341
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800342 return QDF_STATUS_SUCCESS;
343}
344
345QDF_STATUS policy_mgr_update_and_wait_for_connection_update(
346 struct wlan_objmgr_psoc *psoc,
347 uint8_t session_id,
348 uint8_t channel,
349 enum policy_mgr_conn_update_reason reason)
350{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800351 QDF_STATUS status;
352
353 policy_mgr_debug("session:%d channel:%d reason:%d",
354 session_id, channel, reason);
355
356 status = policy_mgr_reset_connection_update(psoc);
357 if (QDF_IS_STATUS_ERROR(status))
358 policy_mgr_err("clearing event failed");
359
360 status = policy_mgr_current_connections_update(psoc,
361 session_id, channel, reason);
362 if (QDF_STATUS_E_FAILURE == status) {
363 policy_mgr_err("connections update failed");
364 return QDF_STATUS_E_FAILURE;
365 }
366
367 /* Wait only when status is success */
368 if (QDF_IS_STATUS_SUCCESS(status)) {
369 status = policy_mgr_wait_for_connection_update(psoc);
370 if (QDF_IS_STATUS_ERROR(status)) {
371 policy_mgr_err("qdf wait for event failed");
372 return QDF_STATUS_E_FAILURE;
373 }
374 }
375
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800376 return QDF_STATUS_SUCCESS;
377}
378
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530379/**
380 * policy_mgr_is_dbs_allowed_for_concurrency() - If dbs is allowed for current
381 * concurreny
382 * @new_conn_mode: new connection mode
383 *
384 * When a new connection is about to come up, check if dbs is allowed for
385 * STA+STA or STA+P2P
386 *
387 * Return: true if dbs is allowed for STA+STA or STA+P2P else false
388 */
Bala Venkatesh28477d32018-05-07 21:35:55 +0530389bool policy_mgr_is_dbs_allowed_for_concurrency(
390 struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE new_conn_mode)
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530391{
392 struct policy_mgr_psoc_priv_obj *pm_ctx;
393 uint32_t count, dbs_for_sta_sta, dbs_for_sta_p2p;
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530394 bool ret = true;
395
396 pm_ctx = policy_mgr_get_context(psoc);
397 if (!pm_ctx) {
398 policy_mgr_err("Invalid context");
399 return ret;
400 }
401
402 count = policy_mgr_get_connection_count(psoc);
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530403
404 if (count != 1 || new_conn_mode == QDF_MAX_NO_OF_MODE)
405 return ret;
406
407 dbs_for_sta_sta = PM_CHANNEL_SELECT_LOGIC_STA_STA_GET(pm_ctx->user_cfg.
408 channel_select_logic_conc);
409 dbs_for_sta_p2p = PM_CHANNEL_SELECT_LOGIC_STA_P2P_GET(pm_ctx->user_cfg.
410 channel_select_logic_conc);
411
412 switch (pm_conc_connection_list[0].mode) {
413 case PM_STA_MODE:
414 switch (new_conn_mode) {
415 case QDF_STA_MODE:
416 if (!dbs_for_sta_sta)
417 return false;
418 break;
419 case QDF_P2P_DEVICE_MODE:
420 case QDF_P2P_CLIENT_MODE:
421 case QDF_P2P_GO_MODE:
422 if (!dbs_for_sta_p2p)
423 return false;
424 break;
425 default:
426 break;
427 }
428 break;
429 case PM_P2P_CLIENT_MODE:
430 case PM_P2P_GO_MODE:
431 switch (new_conn_mode) {
432 case QDF_STA_MODE:
433 if (!dbs_for_sta_p2p)
434 return false;
435 break;
436 default:
437 break;
438 }
439 break;
440 default:
441 break;
442 }
443
444 return ret;
445}
446
gaurank kathpalia9ba5f5e2018-10-04 01:36:09 +0530447bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc,
Krunal Soni637eba52018-06-14 17:55:15 -0700448 uint8_t channel)
449{
450 uint8_t i, pm_chnl;
451 struct policy_mgr_psoc_priv_obj *pm_ctx;
452
453 pm_ctx = policy_mgr_get_context(psoc);
454 if (!pm_ctx) {
455 policy_mgr_err("Invalid Context");
456 return false;
457 }
458
459 /*
460 * check given channel against already existing connections'
461 * channels. if they differ then channels are in different bands
462 */
463 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
464 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
465 pm_chnl = pm_conc_connection_list[i].chan;
466 if (pm_conc_connection_list[i].in_use)
467 if (!WLAN_REG_IS_SAME_BAND_CHANNELS(channel, pm_chnl)) {
468 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
469 policy_mgr_debug("channel is in diff band");
470 return true;
471 }
472 }
473 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
474
475 return false;
476}
477
478bool policy_mgr_is_hwmode_set_for_given_chnl(struct wlan_objmgr_psoc *psoc,
479 uint8_t channel)
480{
481 enum policy_mgr_band band;
482 bool is_hwmode_dbs, is_2x2_dbs;
483
484 if (policy_mgr_is_hw_dbs_capable(psoc) == false)
485 return true;
486
487 if (WLAN_REG_IS_24GHZ_CH(channel))
488 band = POLICY_MGR_BAND_24;
489 else
490 band = POLICY_MGR_BAND_5;
491
492 is_hwmode_dbs = policy_mgr_is_current_hwmode_dbs(psoc);
493 is_2x2_dbs = policy_mgr_is_hw_dbs_2x2_capable(psoc);
494 /*
495 * If HW supports 2x2 chains in DBS HW mode and if DBS HW mode is not
496 * yet set then this is the right time to block the connection.
497 */
498 if ((band == POLICY_MGR_BAND_24) && is_2x2_dbs && !is_hwmode_dbs) {
499 policy_mgr_err("HW mode is not yet in DBS!!!!!");
500 return false;
501 }
502
503 /*
504 * If HW supports 1x1 chains DBS HW mode and if first connection is
505 * 2G or 5G band and if second connection is coming up in diffrent
506 * band than the first connection and if current HW mode is not yet
507 * set in DBS then this is the right time to block the connection.
508 */
509 if (policy_mgr_is_chnl_in_diff_band(psoc, channel) && !is_hwmode_dbs) {
510 policy_mgr_err("Given channel & existing conn is diff band & HW mode is not yet in DBS !!!!");
511 return false;
512 }
513
514 return true;
515}
516
Liangwei Dongecbf1132018-05-25 05:24:12 -0400517/**
518 * policy_mgr_pri_id_to_con_mode() - convert policy_mgr_pri_id to
519 * policy_mgr_con_mode
520 * @pri_id: policy_mgr_pri_id
521 *
522 * The help function converts policy_mgr_pri_id type to policy_mgr_con_mode
523 * type.
524 *
525 * Return: policy_mgr_con_mode type.
526 */
527static
528enum policy_mgr_con_mode policy_mgr_pri_id_to_con_mode(
529 enum policy_mgr_pri_id pri_id)
530{
531 switch (pri_id) {
532 case PM_STA_PRI_ID:
533 return PM_STA_MODE;
534 case PM_SAP_PRI_ID:
535 return PM_SAP_MODE;
536 case PM_P2P_GO_PRI_ID:
537 return PM_P2P_GO_MODE;
538 case PM_P2P_CLI_PRI_ID:
539 return PM_P2P_CLIENT_MODE;
540 default:
541 return PM_MAX_NUM_OF_MODE;
542 }
543}
544
545enum policy_mgr_conc_next_action
546policy_mgr_get_preferred_dbs_action_table(
547 struct wlan_objmgr_psoc *psoc,
548 uint32_t vdev_id,
549 uint8_t channel,
550 enum policy_mgr_conn_update_reason reason)
551{
552 struct policy_mgr_psoc_priv_obj *pm_ctx;
553 enum policy_mgr_con_mode pri_conn_mode = PM_MAX_NUM_OF_MODE;
554 enum policy_mgr_con_mode new_conn_mode = PM_MAX_NUM_OF_MODE;
555 enum QDF_OPMODE new_conn_op_mode = QDF_MAX_NO_OF_MODE;
556 bool band_pref_5g = true;
557 bool vdev_priority_enabled = false;
558 bool dbs_2x2_5g_1x1_2g_supported;
559 bool dbs_2x2_2g_1x1_5g_supported;
560 uint32_t vdev_pri_list, vdev_pri_id;
561 uint8_t chan_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
562 uint8_t vdev_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1];
563 uint32_t vdev_count = 0;
564 uint32_t i;
565 bool found;
566
567 pm_ctx = policy_mgr_get_context(psoc);
568 if (!pm_ctx) {
569 policy_mgr_err("Invalid context");
570 return PM_NOP;
571 }
572 dbs_2x2_5g_1x1_2g_supported =
573 policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc);
574 dbs_2x2_2g_1x1_5g_supported =
575 policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc);
576 policy_mgr_debug("target support DBS1 %d DBS2 %d",
577 dbs_2x2_5g_1x1_2g_supported,
578 dbs_2x2_2g_1x1_5g_supported);
579 /*
580 * If both DBS1 and DBS2 not supported, this should be Legacy Single
581 * DBS mode HW. The policy_mgr_psoc_enable has setup the correct
582 * action tables.
583 */
584 if (!dbs_2x2_5g_1x1_2g_supported && !dbs_2x2_2g_1x1_5g_supported)
585 return PM_NOP;
586 if (!dbs_2x2_5g_1x1_2g_supported) {
587 band_pref_5g = false;
588 policy_mgr_debug("target only supports DBS2!");
589 goto DONE;
590 }
591 if (!dbs_2x2_2g_1x1_5g_supported) {
592 policy_mgr_debug("target only supports DBS1!");
593 goto DONE;
594 }
595 if (PM_GET_BAND_PREFERRED(pm_ctx->user_cfg.dbs_selection_policy) == 1)
596 band_pref_5g = false;
597
598 if (PM_GET_VDEV_PRIORITY_ENABLED(
599 pm_ctx->user_cfg.dbs_selection_policy) == 1 &&
600 pm_ctx->user_cfg.vdev_priority_list)
601 vdev_priority_enabled = true;
602
603 if (!vdev_priority_enabled)
604 goto DONE;
605
606 if (vdev_id != INVALID_VDEV_ID && channel) {
607 if (pm_ctx->hdd_cbacks.hdd_get_device_mode)
608 new_conn_op_mode = pm_ctx->hdd_cbacks.
609 hdd_get_device_mode(vdev_id);
610
611 new_conn_mode = policy_mgr_convert_device_mode_to_qdf_type(
612 new_conn_op_mode);
613 if (new_conn_mode == PM_MAX_NUM_OF_MODE)
614 policy_mgr_debug("new vdev %d op_mode %d chan %d reason %d: not prioritized",
615 vdev_id, new_conn_op_mode,
616 channel, reason);
617 else
618 policy_mgr_debug("new vdev %d op_mode %d chan %d : reason %d",
619 vdev_id, new_conn_op_mode, channel,
620 reason);
621 }
622 vdev_pri_list = pm_ctx->user_cfg.vdev_priority_list;
623 while (vdev_pri_list) {
624 vdev_pri_id = vdev_pri_list & 0xF;
625 pri_conn_mode = policy_mgr_pri_id_to_con_mode(vdev_pri_id);
626 if (pri_conn_mode == PM_MAX_NUM_OF_MODE) {
627 policy_mgr_debug("vdev_pri_id %d prioritization not supported",
628 vdev_pri_id);
629 goto NEXT;
630 }
631 vdev_count = policy_mgr_get_mode_specific_conn_info(
632 psoc, chan_list, vdev_list, pri_conn_mode);
633 /**
634 * Take care of duplication case, the vdev id may
635 * exist in the conn list already with old chan.
636 * Replace with new chan before make decision.
637 */
638 found = false;
639 for (i = 0; i < vdev_count; i++) {
640 policy_mgr_debug("[%d] vdev %d chan %d conn_mode %d",
641 i, vdev_list[i], chan_list[i],
642 pri_conn_mode);
643
644 if (new_conn_mode == pri_conn_mode &&
645 vdev_list[i] == vdev_id) {
646 chan_list[i] = channel;
647 found = true;
648 }
649 }
650 /**
651 * The new coming vdev should be added to the list to
652 * make decision if it is prioritized.
653 */
654 if (!found && new_conn_mode == pri_conn_mode) {
655 chan_list[vdev_count] = channel;
656 vdev_list[vdev_count++] = vdev_id;
657 }
658 /**
659 * if more than one vdev has same priority, keep "band_pref_5g"
660 * value as default band preference setting.
661 */
662 if (vdev_count > 1)
663 break;
664 /**
665 * select the only active vdev (or new coming vdev) chan as
666 * preferred band.
667 */
668 if (vdev_count > 0) {
669 band_pref_5g = WLAN_REG_IS_5GHZ_CH(chan_list[0]);
670 break;
671 }
672NEXT:
673 vdev_pri_list >>= 4;
674 }
675DONE:
676 policy_mgr_debug("band_pref_5g %d", band_pref_5g);
677 if (band_pref_5g)
678 return PM_DBS1;
679 else
680 return PM_DBS2;
681}
682
683/**
684 * policy_mgr_get_second_conn_action_table() - get second conn action table
685 * @psoc: Pointer to psoc
686 * @vdev_id: vdev Id
687 * @channel: channel of vdev.
688 * @reason: reason of request
689 *
690 * Get the action table based on current HW Caps and INI user preference.
691 * This function will be called by policy_mgr_current_connections_update during
692 * DBS action decision.
693 *
694 * return : action table address
695 */
696static policy_mgr_next_action_two_connection_table_type *
697policy_mgr_get_second_conn_action_table(
698 struct wlan_objmgr_psoc *psoc,
699 uint32_t vdev_id,
700 uint8_t channel,
701 enum policy_mgr_conn_update_reason reason)
702{
703 enum policy_mgr_conc_next_action preferred_action;
704
705 if (!policy_mgr_is_2x2_1x1_dbs_capable(psoc))
706 return next_action_two_connection_table;
707
708 preferred_action = policy_mgr_get_preferred_dbs_action_table(
709 psoc, vdev_id, channel, reason);
710 switch (preferred_action) {
711 case PM_DBS2:
712 return next_action_two_connection_2x2_2g_1x1_5g_table;
713 default:
714 return next_action_two_connection_table;
715 }
716}
717
718/**
719 * policy_mgr_get_third_conn_action_table() - get third connection action table
720 * @psoc: Pointer to psoc
721 * @vdev_id: vdev Id
722 * @channel: channel of vdev.
723 * @reason: reason of request
724 *
725 * Get the action table based on current HW Caps and INI user preference.
726 * This function will be called by policy_mgr_current_connections_update during
727 * DBS action decision.
728 *
729 * return : action table address
730 */
731static policy_mgr_next_action_three_connection_table_type *
732policy_mgr_get_third_conn_action_table(
733 struct wlan_objmgr_psoc *psoc,
734 uint32_t vdev_id,
735 uint8_t channel,
736 enum policy_mgr_conn_update_reason reason)
737{
738 enum policy_mgr_conc_next_action preferred_action;
739
740 if (!policy_mgr_is_2x2_1x1_dbs_capable(psoc))
741 return next_action_three_connection_table;
742
743 preferred_action = policy_mgr_get_preferred_dbs_action_table(
744 psoc, vdev_id, channel, reason);
745 switch (preferred_action) {
746 case PM_DBS2:
747 return next_action_three_connection_2x2_2g_1x1_5g_table;
748 default:
749 return next_action_three_connection_table;
750 }
751}
752
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800753QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc,
754 uint32_t session_id,
755 uint8_t channel,
756 enum policy_mgr_conn_update_reason reason)
757{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800758 enum policy_mgr_conc_next_action next_action = PM_NOP;
759 uint32_t num_connections = 0;
760 enum policy_mgr_one_connection_mode second_index = 0;
761 enum policy_mgr_two_connection_mode third_index = 0;
Liangwei Dongecbf1132018-05-25 05:24:12 -0400762 policy_mgr_next_action_two_connection_table_type *second_conn_table;
763 policy_mgr_next_action_three_connection_table_type *third_conn_table;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800764 enum policy_mgr_band band;
765 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Bala Venkatesh28477d32018-05-07 21:35:55 +0530766 struct policy_mgr_psoc_priv_obj *pm_ctx;
767 enum QDF_OPMODE new_conn_mode = QDF_MAX_NO_OF_MODE;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800768
769 if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
770 policy_mgr_err("driver isn't dbs capable, no further action needed");
771 return QDF_STATUS_E_NOSUPPORT;
772 }
773 if (WLAN_REG_IS_24GHZ_CH(channel))
774 band = POLICY_MGR_BAND_24;
775 else
776 band = POLICY_MGR_BAND_5;
777
778 num_connections = policy_mgr_get_connection_count(psoc);
779
780 policy_mgr_debug("num_connections=%d channel=%d",
781 num_connections, channel);
782
783 switch (num_connections) {
784 case 0:
785 if (band == POLICY_MGR_BAND_24)
786 if (policy_mgr_is_hw_dbs_2x2_capable(psoc))
787 next_action = PM_DBS;
788 else
789 next_action = PM_NOP;
790 else
791 next_action = PM_NOP;
792 break;
793 case 1:
794 second_index =
795 policy_mgr_get_second_connection_pcl_table_index(psoc);
796 if (PM_MAX_ONE_CONNECTION_MODE == second_index) {
797 policy_mgr_err(
798 "couldn't find index for 2nd connection next action table");
799 goto done;
800 }
Liangwei Dongecbf1132018-05-25 05:24:12 -0400801 second_conn_table = policy_mgr_get_second_conn_action_table(
802 psoc, session_id, channel, reason);
803 next_action = (*second_conn_table)[second_index][band];
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800804 break;
805 case 2:
806 third_index =
807 policy_mgr_get_third_connection_pcl_table_index(psoc);
808 if (PM_MAX_TWO_CONNECTION_MODE == third_index) {
809 policy_mgr_err(
810 "couldn't find index for 3rd connection next action table");
811 goto done;
812 }
Liangwei Dongecbf1132018-05-25 05:24:12 -0400813 third_conn_table = policy_mgr_get_third_conn_action_table(
814 psoc, session_id, channel, reason);
815 next_action = (*third_conn_table)[third_index][band];
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800816 break;
817 default:
818 policy_mgr_err("unexpected num_connections value %d",
819 num_connections);
820 break;
821 }
822
Bala Venkatesh28477d32018-05-07 21:35:55 +0530823 pm_ctx = policy_mgr_get_context(psoc);
824 if (!pm_ctx) {
825 policy_mgr_err("Invalid context");
826 goto done;
827 }
828
829 if (pm_ctx->hdd_cbacks.hdd_get_device_mode)
830 new_conn_mode = pm_ctx->hdd_cbacks.
831 hdd_get_device_mode(session_id);
832
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530833 /*
834 * Based on channel_select_logic_conc ini, hw mode is set
835 * when second connection is about to come up that results
836 * in STA+STA and STA+P2P concurrency.
837 * 1) If MCC is set and if current hw mode is dbs, hw mode
838 * should be set to single mac for above concurrency.
839 * 2) If MCC is set and if current hw mode is not dbs, hw
840 * mode change is not required.
841 */
842 if (policy_mgr_is_current_hwmode_dbs(psoc) &&
Bala Venkatesh28477d32018-05-07 21:35:55 +0530843 !policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode))
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530844 next_action = PM_SINGLE_MAC;
845 else if (!policy_mgr_is_current_hwmode_dbs(psoc) &&
Bala Venkatesh28477d32018-05-07 21:35:55 +0530846 !policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode))
Yeshwanth Sriram Guntuka71e5ae62018-02-12 13:30:23 +0530847 next_action = PM_NOP;
848
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800849 if (PM_NOP != next_action)
850 status = policy_mgr_next_actions(psoc, session_id,
851 next_action, reason);
852 else
853 status = QDF_STATUS_E_NOSUPPORT;
854
855 policy_mgr_debug(
856 "idx2=%d idx3=%d next_action=%d, band=%d status=%d reason=%d session_id=%d",
857 second_index, third_index, next_action, band, status,
858 reason, session_id);
859
860done:
861 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800862}
863
Liangwei Dong18300132018-05-25 01:25:24 -0400864/**
865 * policy_mgr_validate_dbs_switch() - Check DBS action valid or not
866 * @psoc: Pointer to psoc
867 * @session_id: vdev id
868 * @action: action requested
869 * @reason: reason of hw mode change
870 *
871 * This routine will check the current hw mode with requested action.
872 * If we are already in the mode, the caller will do nothing.
873 * This will be called by policy_mgr_next_actions to check the action needed
874 * or not.
875 *
876 * return : QDF_STATUS_SUCCESS, action is allowed.
877 * QDF_STATUS_E_ALREADY, action is not needed.
878 * QDF_STATUS_E_FAILURE, error happens.
879 * QDF_STATUS_E_NOSUPPORT, the requested mode not supported.
880 */
881static
882QDF_STATUS policy_mgr_validate_dbs_switch(
883 struct wlan_objmgr_psoc *psoc,
884 uint32_t session_id,
885 enum policy_mgr_conc_next_action action,
886 enum policy_mgr_conn_update_reason reason)
887{
888 QDF_STATUS status;
889 struct policy_mgr_hw_mode_params hw_mode;
890
891 /* check for the current HW index to see if really need any action */
892 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
893 if (!QDF_IS_STATUS_SUCCESS(status)) {
894 policy_mgr_err("policy_mgr_get_current_hw_mode failed");
895 return status;
896 }
897
898 if (hw_mode.sbs_cap) {
899 if ((action == PM_SBS) || (action == PM_SBS_DOWNGRADE)) {
900 if (!policy_mgr_is_hw_sbs_capable(psoc)) {
901 /* No action */
902 policy_mgr_notice("firmware is not sbs capable");
903 return QDF_STATUS_E_NOSUPPORT;
904 }
905 /* current mode is already SBS nothing to be
906 * done
907 */
908 policy_mgr_notice("current mode is already SBS");
909 return QDF_STATUS_E_ALREADY;
910 } else {
911 return QDF_STATUS_SUCCESS;
912 }
913 }
914
915 if (!hw_mode.dbs_cap) {
916 if (action == PM_SINGLE_MAC ||
917 action == PM_SINGLE_MAC_UPGRADE) {
918 policy_mgr_notice("current mode is already single MAC");
919 return QDF_STATUS_E_ALREADY;
920 } else {
921 return QDF_STATUS_SUCCESS;
922 }
923 }
924 /**
925 * If already in DBS, no need to request DBS again (HL, Napier).
926 * For dual DBS HW, in case DBS1 -> DBS2 or DBS2 -> DBS1
927 * switching, we need to check the current DBS mode is same as
928 * requested or not.
929 */
930 if (policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc) ||
931 policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc)) {
932 policy_mgr_info("curr dbs action %d new action %d",
933 hw_mode.action_type, action);
934 if (hw_mode.action_type == PM_DBS1 &&
935 ((action == PM_DBS1 ||
936 action == PM_DBS1_DOWNGRADE))) {
937 policy_mgr_err("driver is already in DBS_5G_2x2_24G_1x1 (%d), no further action %d needed",
938 hw_mode.action_type, action);
939 return QDF_STATUS_E_ALREADY;
940 } else if (hw_mode.action_type == PM_DBS2 &&
941 ((action == PM_DBS2 ||
942 action == PM_DBS2_DOWNGRADE))) {
943 policy_mgr_err("driver is already in DBS_24G_2x2_5G_1x1 (%d), no further action %d needed",
944 hw_mode.action_type, action);
945 return QDF_STATUS_E_ALREADY;
946 }
947 } else if ((action == PM_DBS_DOWNGRADE) || (action == PM_DBS) ||
948 (action == PM_DBS_UPGRADE)) {
949 policy_mgr_err("driver is already in %s mode, no further action needed",
950 (hw_mode.dbs_cap) ? "dbs" : "non dbs");
951 return QDF_STATUS_E_ALREADY;
952 }
953 return QDF_STATUS_SUCCESS;
954}
955
956QDF_STATUS policy_mgr_next_actions(
957 struct wlan_objmgr_psoc *psoc,
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -0800958 uint32_t session_id,
959 enum policy_mgr_conc_next_action action,
960 enum policy_mgr_conn_update_reason reason)
961{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800962 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Varun Reddy Yeturue23b6bc2018-01-08 13:18:41 -0800963 struct dbs_nss nss_dbs = {0};
Liangwei Dong18300132018-05-25 01:25:24 -0400964 struct policy_mgr_hw_mode_params hw_mode;
965 enum policy_mgr_conc_next_action next_action;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800966
967 if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
968 policy_mgr_err("driver isn't dbs capable, no further action needed");
969 return QDF_STATUS_E_NOSUPPORT;
970 }
971
972 /* check for the current HW index to see if really need any action */
973 status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
974 if (!QDF_IS_STATUS_SUCCESS(status)) {
975 policy_mgr_err("policy_mgr_get_current_hw_mode failed");
976 return status;
977 }
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800978
Liangwei Dong18300132018-05-25 01:25:24 -0400979 /* check for the current HW index to see if really need any action */
980 status = policy_mgr_validate_dbs_switch(psoc, session_id, action,
981 reason);
982 if (!QDF_IS_STATUS_SUCCESS(status)) {
983 policy_mgr_err(" not take action %d reason %d session %d status %d",
984 action, reason, session_id, status);
985 return status;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -0800986 }
987
988 switch (action) {
989 case PM_DBS_DOWNGRADE:
990 /*
991 * check if we have a beaconing entity that is using 2x2. If yes,
992 * update the beacon template & notify FW. Once FW confirms
993 * beacon updated, send down the HW mode change req
994 */
995 status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
996 PM_DBS, reason, session_id);
997 break;
998 case PM_DBS:
Vikrampal31eb12c2017-04-28 17:44:30 +0530999 (void)policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs);
1000
1001 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1002 nss_dbs.mac0_ss,
1003 HW_MODE_80_MHZ,
1004 nss_dbs.mac1_ss,
1005 HW_MODE_40_MHZ,
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001006 HW_MODE_MAC_BAND_NONE,
Vikrampal31eb12c2017-04-28 17:44:30 +05301007 HW_MODE_DBS,
1008 HW_MODE_AGILE_DFS_NONE,
1009 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -08001010 reason, PM_NOP);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001011 break;
1012 case PM_SINGLE_MAC_UPGRADE:
1013 /*
1014 * change the HW mode first before the NSS upgrade
1015 */
1016 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1017 HW_MODE_SS_2x2,
1018 HW_MODE_80_MHZ,
1019 HW_MODE_SS_0x0, HW_MODE_BW_NONE,
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001020 HW_MODE_MAC_BAND_NONE,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001021 HW_MODE_DBS_NONE,
1022 HW_MODE_AGILE_DFS_NONE,
1023 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -08001024 reason, PM_UPGRADE);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001025 break;
1026 case PM_SINGLE_MAC:
1027 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1028 HW_MODE_SS_2x2,
1029 HW_MODE_80_MHZ,
1030 HW_MODE_SS_0x0, HW_MODE_BW_NONE,
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001031 HW_MODE_MAC_BAND_NONE,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001032 HW_MODE_DBS_NONE,
1033 HW_MODE_AGILE_DFS_NONE,
1034 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -08001035 reason, PM_NOP);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001036 break;
1037 case PM_DBS_UPGRADE:
1038 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1039 HW_MODE_SS_2x2,
1040 HW_MODE_80_MHZ,
1041 HW_MODE_SS_2x2, HW_MODE_80_MHZ,
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001042 HW_MODE_MAC_BAND_NONE,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001043 HW_MODE_DBS,
1044 HW_MODE_AGILE_DFS_NONE,
1045 HW_MODE_SBS_NONE,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -08001046 reason, PM_UPGRADE);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001047 break;
1048 case PM_SBS_DOWNGRADE:
1049 status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
1050 PM_SBS, reason, session_id);
1051 break;
1052 case PM_SBS:
1053 status = policy_mgr_pdev_set_hw_mode(psoc, session_id,
1054 HW_MODE_SS_1x1,
1055 HW_MODE_80_MHZ,
1056 HW_MODE_SS_1x1, HW_MODE_80_MHZ,
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001057 HW_MODE_MAC_BAND_NONE,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001058 HW_MODE_DBS,
1059 HW_MODE_AGILE_DFS_NONE,
1060 HW_MODE_SBS,
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -08001061 reason, PM_NOP);
1062 break;
1063 case PM_DOWNGRADE:
1064 /*
1065 * check if we have a beaconing entity that advertised 2x2
1066 * intially. If yes, update the beacon template & notify FW.
1067 */
1068 status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_1,
Liangwei Donga590ecd2018-05-25 00:56:38 -04001069 PM_NOP, POLICY_MGR_ANY, reason);
Tushnim Bhattacharyya94206562017-11-15 15:30:07 -08001070 break;
1071 case PM_UPGRADE:
1072 /*
1073 * check if we have a beaconing entity that advertised 2x2
1074 * intially. If yes, update the beacon template & notify FW.
1075 */
1076 status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_2,
Liangwei Donga590ecd2018-05-25 00:56:38 -04001077 PM_NOP, POLICY_MGR_ANY, reason);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001078 break;
Liangwei Dong18300132018-05-25 01:25:24 -04001079 case PM_DBS1_DOWNGRADE:
1080 status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
1081 PM_DBS1, reason,
1082 session_id);
1083 break;
1084 case PM_DBS2_DOWNGRADE:
1085 status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
1086 PM_DBS2, reason,
1087 session_id);
1088 break;
1089 case PM_DBS1:
1090 /*
1091 * PM_DBS1 (2x2 5G + 1x1 2G) will support 5G 2x2. If previous
1092 * mode is DBS, that should be 2x2 2G + 1x1 5G mode and
1093 * the 5G band was downgraded to 1x1. So, we need to
1094 * upgrade 5G vdevs after hw mode change.
1095 */
1096 if (hw_mode.dbs_cap)
1097 next_action = PM_UPGRADE_5G;
1098 else
1099 next_action = PM_NOP;
1100 status = policy_mgr_pdev_set_hw_mode(
1101 psoc, session_id,
1102 HW_MODE_SS_2x2,
1103 HW_MODE_80_MHZ,
1104 HW_MODE_SS_1x1, HW_MODE_40_MHZ,
1105 HW_MODE_MAC_BAND_5G,
1106 HW_MODE_DBS,
1107 HW_MODE_AGILE_DFS_NONE,
1108 HW_MODE_SBS_NONE,
1109 reason, next_action);
1110 break;
1111 case PM_DBS2:
1112 /*
1113 * PM_DBS2 (2x2 2G + 1x1 5G) will support 2G 2x2. If previous
1114 * mode is DBS, that should be 2x2 5G + 1x1 2G mode and
1115 * the 2G band was downgraded to 1x1. So, we need to
1116 * upgrade 5G vdevs after hw mode change.
1117 */
1118 if (hw_mode.dbs_cap)
1119 next_action = PM_UPGRADE_2G;
1120 else
1121 next_action = PM_NOP;
1122 status = policy_mgr_pdev_set_hw_mode(
1123 psoc, session_id,
1124 HW_MODE_SS_2x2,
1125 HW_MODE_40_MHZ,
1126 HW_MODE_SS_1x1, HW_MODE_40_MHZ,
1127 HW_MODE_MAC_BAND_2G,
1128 HW_MODE_DBS,
1129 HW_MODE_AGILE_DFS_NONE,
1130 HW_MODE_SBS_NONE,
1131 reason, next_action);
1132 break;
1133 case PM_UPGRADE_5G:
1134 status = policy_mgr_nss_update(
1135 psoc, POLICY_MGR_RX_NSS_2,
1136 PM_NOP, POLICY_MGR_BAND_5, reason);
1137 break;
1138 case PM_UPGRADE_2G:
1139 status = policy_mgr_nss_update(
1140 psoc, POLICY_MGR_RX_NSS_2,
1141 PM_NOP, POLICY_MGR_BAND_24, reason);
1142 break;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001143 default:
1144 policy_mgr_err("unexpected action value %d", action);
1145 status = QDF_STATUS_E_FAILURE;
1146 break;
1147 }
1148
1149 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001150}
1151
1152QDF_STATUS policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc,
1153 uint8_t session_id, uint8_t channel)
1154{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001155 QDF_STATUS status;
1156
1157 if (!policy_mgr_check_for_session_conc(psoc, session_id, channel)) {
1158 policy_mgr_err("Conc not allowed for the session %d",
1159 session_id);
1160 return QDF_STATUS_E_FAILURE;
1161 }
1162
1163 status = policy_mgr_reset_connection_update(psoc);
1164 if (!QDF_IS_STATUS_SUCCESS(status))
1165 policy_mgr_err("clearing event failed");
1166
1167 status = policy_mgr_current_connections_update(psoc, session_id,
1168 channel,
1169 POLICY_MGR_UPDATE_REASON_NORMAL_STA);
1170 if (QDF_STATUS_E_FAILURE == status) {
1171 policy_mgr_err("connections update failed");
1172 return status;
1173 }
1174
1175 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001176}
1177
1178#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301179void policy_mgr_update_user_config_sap_chan(
1180 struct wlan_objmgr_psoc *psoc, uint32_t channel)
1181{
1182 struct policy_mgr_psoc_priv_obj *pm_ctx;
1183
1184 pm_ctx = policy_mgr_get_context(psoc);
1185 if (!pm_ctx) {
1186 policy_mgr_err("Invalid pm context and failed to update the user config sap channel");
1187 return;
1188 }
1189 pm_ctx->user_config_sap_channel = channel;
1190}
1191
Archana Ramachandran544ce172017-03-14 15:12:09 -07001192/**
1193 * policy_mgr_is_restart_sap_allowed() - Check if restart SAP
1194 * allowed during SCC -> MCC switch
1195 * @psoc: PSOC object data
1196 * @mcc_to_scc_switch: MCC to SCC switch enabled user config
1197 *
1198 * Check if restart SAP allowed during SCC->MCC switch
1199 *
1200 * Restart: true or false
1201 */
1202static bool policy_mgr_is_restart_sap_allowed(
1203 struct wlan_objmgr_psoc *psoc,
1204 uint32_t mcc_to_scc_switch)
1205{
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301206 uint32_t sta_ap_bit_mask = QDF_STA_MASK | QDF_SAP_MASK;
1207 uint32_t sta_go_bit_mask = QDF_STA_MASK | QDF_P2P_GO_MASK;
1208
Archana Ramachandran544ce172017-03-14 15:12:09 -07001209 if ((mcc_to_scc_switch == QDF_MCC_TO_SCC_SWITCH_DISABLE) ||
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001210 !policy_mgr_concurrent_open_sessions_running(psoc) ||
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301211 !(((policy_mgr_get_concurrency_mode(psoc) & sta_ap_bit_mask)
1212 == sta_ap_bit_mask) ||
Tushnim Bhattacharyyab7f83962018-06-14 17:56:38 -07001213 ((mcc_to_scc_switch ==
1214 QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) &&
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301215 ((policy_mgr_get_concurrency_mode(psoc) & sta_go_bit_mask)
Tushnim Bhattacharyyab7f83962018-06-14 17:56:38 -07001216 == sta_go_bit_mask)))) {
Abhinav Kumar77cb42a2018-06-15 16:46:30 +05301217 policy_mgr_debug("MCC switch disabled or not concurrent STA/SAP, STA/GO");
Archana Ramachandran544ce172017-03-14 15:12:09 -07001218 return false;
1219 }
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001220
Archana Ramachandran544ce172017-03-14 15:12:09 -07001221 return true;
1222}
1223
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -07001224bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc,
1225 uint8_t channel)
1226{
1227 struct policy_mgr_psoc_priv_obj *pm_ctx;
1228 bool is_safe = true;
1229 uint8_t j;
1230
1231 pm_ctx = policy_mgr_get_context(psoc);
1232 if (!pm_ctx) {
1233 policy_mgr_err("Invalid context");
1234 return is_safe;
1235 }
1236
1237
1238 if (pm_ctx->unsafe_channel_count == 0) {
1239 policy_mgr_debug("There are no unsafe channels");
1240 return is_safe;
1241 }
1242
1243 for (j = 0; j < pm_ctx->unsafe_channel_count; j++) {
1244 if (channel == pm_ctx->unsafe_channel_list[j]) {
1245 is_safe = false;
1246 policy_mgr_warn("CH %d is not safe", channel);
1247 break;
1248 }
1249 }
1250
1251 return is_safe;
1252}
1253
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301254bool policy_mgr_is_sap_restart_required_after_sta_disconnect(
1255 struct wlan_objmgr_psoc *psoc, uint8_t *intf_ch)
1256{
1257 struct policy_mgr_psoc_priv_obj *pm_ctx;
1258 uint8_t sap_chan = policy_mgr_mode_specific_get_channel(psoc,
1259 PM_SAP_MODE);
1260 bool sta_sap_scc_on_dfs_chan =
1261 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
1262
1263 *intf_ch = 0;
1264
1265 pm_ctx = policy_mgr_get_context(psoc);
1266 if (!pm_ctx) {
1267 policy_mgr_err("Invalid pm context");
1268 return false;
1269 }
1270
1271 policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sap_chan %u",
1272 sta_sap_scc_on_dfs_chan, sap_chan);
1273
Jianmin Zhu7f6bdd32018-06-29 10:39:30 +08001274 if ((!sta_sap_scc_on_dfs_chan ||
1275 !(sap_chan && WLAN_REG_IS_5GHZ_CH(sap_chan) &&
1276 (wlan_reg_get_channel_state(pm_ctx->pdev, sap_chan) ==
1277 CHANNEL_STATE_DFS))) &&
1278 (!policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) ||
1279 policy_mgr_is_safe_channel(psoc, sap_chan))) {
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301280 return false;
1281 }
1282
1283 *intf_ch = pm_ctx->user_config_sap_channel;
1284 policy_mgr_debug("Standalone SAP is not allowed on DFS channel, Move it to channel %u",
1285 *intf_ch);
1286
1287 return true;
1288}
1289
Tushnim Bhattacharyya89036a72018-10-01 14:50:15 -07001290static void __policy_mgr_check_sta_ap_concurrent_ch_intf(void *data)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001291{
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001292 struct wlan_objmgr_psoc *psoc;
1293 struct policy_mgr_psoc_priv_obj *pm_ctx = NULL;
1294 struct sta_ap_intf_check_work_ctx *work_info = NULL;
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301295 uint32_t mcc_to_scc_switch, cc_count = 0, i;
Archana Ramachandran544ce172017-03-14 15:12:09 -07001296 QDF_STATUS status;
1297 uint8_t channel, sec_ch;
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301298 uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS];
1299 uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS];
Archana Ramachandran544ce172017-03-14 15:12:09 -07001300
Tushnim Bhattacharyya89036a72018-10-01 14:50:15 -07001301 if (qdf_is_module_state_transitioning()) {
1302 policy_mgr_err("Module transition in progress");
1303 goto end;
1304 }
1305
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001306 work_info = (struct sta_ap_intf_check_work_ctx *) data;
1307 if (!work_info) {
1308 policy_mgr_err("Invalid work_info");
1309 goto end;
1310 }
1311
1312 psoc = work_info->psoc;
1313 if (!psoc) {
1314 policy_mgr_err("Invalid psoc");
1315 goto end;
1316 }
1317
Archana Ramachandran544ce172017-03-14 15:12:09 -07001318 pm_ctx = policy_mgr_get_context(psoc);
1319 if (!pm_ctx) {
1320 policy_mgr_err("Invalid context");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001321 goto end;
Archana Ramachandran544ce172017-03-14 15:12:09 -07001322 }
1323 mcc_to_scc_switch =
Krunal Sonid36b2072018-09-26 17:02:14 -07001324 policy_mgr_get_mcc_to_scc_switch_mode(psoc);
Archana Ramachandran544ce172017-03-14 15:12:09 -07001325
1326 policy_mgr_info("Concurrent open sessions running: %d",
1327 policy_mgr_concurrent_open_sessions_running(psoc));
1328
1329 if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch))
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001330 goto end;
Archana Ramachandran6199b642017-03-20 13:31:36 -07001331
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301332 cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
1333 &operating_channel[cc_count],
1334 &vdev_id[cc_count],
1335 PM_SAP_MODE);
1336 policy_mgr_debug("Number of concurrent SAP: %d", cc_count);
Tushnim Bhattacharyya1acaac72018-10-08 12:47:26 -07001337 if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS)
1338 cc_count = cc_count +
1339 policy_mgr_get_mode_specific_conn_info
1340 (psoc,
1341 &operating_channel[cc_count],
1342 &vdev_id[cc_count],
1343 PM_P2P_GO_MODE);
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301344 policy_mgr_debug("Number of beaconing entities (SAP + GO):%d",
1345 cc_count);
1346 if (!cc_count) {
Ajit Pal Singhc1246b12017-06-16 11:36:12 +05301347 policy_mgr_err("Could not retrieve SAP/GO operating channel&vdevid");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001348 goto end;
Archana Ramachandran6199b642017-03-20 13:31:36 -07001349 }
1350
Bala Venkatesh378064b2018-06-11 15:06:53 +05301351 policy_mgr_debug("wait if channel switch is already in progress");
1352 status = qdf_wait_single_event(
1353 &pm_ctx->channel_switch_complete_evt,
1354 CHANNEL_SWITCH_COMPLETE_TIMEOUT);
1355
1356 if (!QDF_IS_STATUS_SUCCESS(status)) {
1357 policy_mgr_err("wait for event failed, still continue with channel switch");
1358 }
Archana Ramachandran631fd9f2017-03-19 18:51:30 -07001359 if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) {
1360 policy_mgr_err("SAP restart get channel callback in NULL");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001361 goto end;
Archana Ramachandran631fd9f2017-03-19 18:51:30 -07001362 }
Tushnim Bhattacharyya1acaac72018-10-08 12:47:26 -07001363 if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS)
1364 for (i = 0; i < cc_count; i++) {
1365 status = pm_ctx->hdd_cbacks.
1366 wlan_hdd_get_channel_for_sap_restart
1367 (psoc,
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301368 vdev_id[i], &channel, &sec_ch);
Tushnim Bhattacharyya1acaac72018-10-08 12:47:26 -07001369 if (status == QDF_STATUS_SUCCESS) {
1370 policy_mgr_info("SAP restarts due to MCC->SCC switch, old chan :%d new chan: %d"
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301371 , operating_channel[i], channel);
Tushnim Bhattacharyya1acaac72018-10-08 12:47:26 -07001372 break;
1373 }
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301374 }
Rachit Kankanea07e4b92017-09-15 19:38:49 +05301375 if (status != QDF_STATUS_SUCCESS)
1376 policy_mgr_err("Failed to switch SAP channel");
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001377end:
1378 if (work_info) {
1379 qdf_mem_free(work_info);
1380 if (pm_ctx)
1381 pm_ctx->sta_ap_intf_check_work_info = NULL;
1382 }
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001383}
1384
Tushnim Bhattacharyya89036a72018-10-01 14:50:15 -07001385void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data)
1386{
1387 qdf_ssr_protect(__func__);
1388 __policy_mgr_check_sta_ap_concurrent_ch_intf(data);
1389 qdf_ssr_unprotect(__func__);
1390}
1391
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -07001392static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc,
1393 uint8_t sta_channel)
1394{
1395 struct policy_mgr_psoc_priv_obj *pm_ctx;
1396
1397 pm_ctx = policy_mgr_get_context(psoc);
1398 if (!pm_ctx) {
1399 policy_mgr_err("Invalid context");
1400 return false;
1401 }
1402
Ganesh Kondabattini8a611c62017-11-21 15:01:31 +05301403 if ((wlan_reg_is_dfs_ch(pm_ctx->pdev, sta_channel) &&
1404 (!policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc))) ||
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -07001405 wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev, sta_channel) ||
Ganesh Kondabattini8a611c62017-11-21 15:01:31 +05301406 !policy_mgr_is_safe_channel(psoc, sta_channel)) {
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -07001407 if (policy_mgr_is_hw_dbs_capable(psoc))
1408 return true;
1409 else
1410 return false;
Ganesh Kondabattini8a611c62017-11-21 15:01:31 +05301411 }
Tushnim Bhattacharyya08a83392017-06-28 13:28:49 -07001412 else
1413 return true;
1414}
1415
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001416QDF_STATUS policy_mgr_valid_sap_conc_channel_check(
1417 struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch)
1418{
1419 uint8_t channel = *con_ch;
1420 uint8_t temp_channel = 0;
1421 struct policy_mgr_psoc_priv_obj *pm_ctx;
Bala Venkatesh7c96e542018-06-07 19:32:27 +05301422 bool sta_sap_scc_on_dfs_chan;
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001423
1424 pm_ctx = policy_mgr_get_context(psoc);
1425 if (!pm_ctx) {
1426 policy_mgr_err("Invalid context");
1427 return QDF_STATUS_E_FAILURE;
1428 }
1429
1430 /*
1431 * if force SCC is set, Check if conc channel is DFS
1432 * or passive or part of LTE avoided channel list.
1433 * In that case move SAP to other band if DBS is supported,
1434 * return otherwise
1435 */
1436 if (!policy_mgr_is_force_scc(psoc))
1437 return QDF_STATUS_SUCCESS;
1438
1439 /*
1440 * if interference is 0, check if it is DBS case. If DBS case
1441 * return from here. If SCC, check further if SAP can move to
1442 * STA's channel.
1443 */
1444 if (!channel &&
1445 (sap_ch != policy_mgr_mode_specific_get_channel(
1446 psoc, PM_STA_MODE)))
1447 return QDF_STATUS_SUCCESS;
1448 else if (!channel)
1449 channel = sap_ch;
1450
Bala Venkatesh7c96e542018-06-07 19:32:27 +05301451 sta_sap_scc_on_dfs_chan =
1452 policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc);
1453
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001454 if (policy_mgr_valid_sta_channel_check(psoc, channel)) {
1455 if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) ||
Abhinav Kumar93b3c7f2018-08-23 21:46:44 +05301456 wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev, channel) ||
Zhu Jianmin5ac66ef2018-06-11 19:03:39 +08001457 !(policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) ||
Abhinav Kumar93b3c7f2018-08-23 21:46:44 +05301458 policy_mgr_is_safe_channel(psoc, channel)) ||
1459 (!reg_is_etsi13_srd_chan_allowed_master_mode(pm_ctx->pdev)
1460 && reg_is_etsi13_srd_chan(pm_ctx->pdev, channel))) {
Liangwei Dongbd8b24b2018-09-05 23:13:52 -04001461 if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) &&
1462 sta_sap_scc_on_dfs_chan) {
1463 policy_mgr_debug("STA SAP SCC is allowed on DFS channel");
1464 goto update_chan;
1465 }
1466
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001467 if (policy_mgr_is_hw_dbs_capable(psoc)) {
1468 temp_channel =
1469 policy_mgr_get_alternate_channel_for_sap(psoc);
1470 policy_mgr_debug("temp_channel is %d",
1471 temp_channel);
1472 if (temp_channel) {
1473 channel = temp_channel;
1474 } else {
1475 if (WLAN_REG_IS_5GHZ_CH(channel))
1476 channel = PM_24_GHZ_CHANNEL_6;
1477 else
1478 channel = PM_5_GHZ_CHANNEL_36;
1479 }
1480 if (!policy_mgr_is_safe_channel(
1481 psoc, channel)) {
1482 policy_mgr_warn(
1483 "Can't have concurrency on %d as it is not safe",
1484 channel);
1485 return QDF_STATUS_E_FAILURE;
1486 }
1487 } else {
1488 policy_mgr_warn("Can't have concurrency on %d",
1489 channel);
1490 return QDF_STATUS_E_FAILURE;
1491 }
1492 }
1493 }
1494
Bala Venkatesh7c96e542018-06-07 19:32:27 +05301495update_chan:
Tushnim Bhattacharyyaa2c3b622017-08-03 16:58:38 -07001496 if (channel != sap_ch)
1497 *con_ch = channel;
1498
1499 return QDF_STATUS_SUCCESS;
1500}
1501
Archana Ramachandran107d3782017-03-06 17:07:44 -08001502/**
1503 * policy_mgr_check_concurrent_intf_and_restart_sap() - Check
1504 * concurrent change intf
1505 * @psoc: PSOC object information
1506 * @operation_channel: operation channel
Archana Ramachandran544ce172017-03-14 15:12:09 -07001507 * @vdev_id: vdev id of SAP
Archana Ramachandran107d3782017-03-06 17:07:44 -08001508 *
1509 * Checks the concurrent change interface and restarts SAP
1510 *
1511 * Return: None
1512 */
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001513void policy_mgr_check_concurrent_intf_and_restart_sap(
Archana Ramachandran6199b642017-03-20 13:31:36 -07001514 struct wlan_objmgr_psoc *psoc)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001515{
Archana Ramachandran266613f2017-03-13 16:36:55 -07001516 struct policy_mgr_psoc_priv_obj *pm_ctx;
1517 uint32_t mcc_to_scc_switch;
Tushnim Bhattacharyyaf8417d12018-05-08 15:31:21 -07001518 uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
1519 uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
1520 uint32_t cc_count = 0;
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301521 bool restart_sap = false;
1522 uint8_t sap_ch;
Archana Ramachandran266613f2017-03-13 16:36:55 -07001523
1524 pm_ctx = policy_mgr_get_context(psoc);
1525 if (!pm_ctx) {
1526 policy_mgr_err("Invalid context");
1527 return;
1528 }
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301529 if (policy_mgr_get_connection_count(psoc) == 1) {
1530 /*
1531 * If STA+SAP sessions are on DFS channel and STA+SAP SCC is
1532 * enabled on DFS channel then move the SAP out of DFS channel
1533 * as soon as STA gets disconnect.
Jianmin Zhu7f6bdd32018-06-29 10:39:30 +08001534 * If STA+SAP sessions are on unsafe channel and STA+SAP SCC is
1535 * enabled on unsafe channel then move the SAP to safe channel
1536 * as soon as STA disconnected.
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301537 */
1538 if (policy_mgr_is_sap_restart_required_after_sta_disconnect(
1539 psoc, &sap_ch)) {
1540 policy_mgr_debug("move the SAP to configured channel %u",
1541 sap_ch);
1542 restart_sap = true;
1543 goto sap_restart;
1544 }
1545 }
Archana Ramachandran266613f2017-03-13 16:36:55 -07001546
Tushnim Bhattacharyyaf8417d12018-05-08 15:31:21 -07001547 /*
1548 * force SCC with STA+STA+SAP will need some additional logic
1549 */
1550 cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
1551 &operating_channel[cc_count],
1552 &vdev_id[cc_count], PM_STA_MODE);
1553 if (!cc_count) {
Yeshwanth Sriram Guntukad540cd02018-08-23 18:25:28 +05301554 policy_mgr_debug("Could not get STA operating channel&vdevid");
Archana Ramachandran6199b642017-03-20 13:31:36 -07001555 return;
1556 }
1557
Archana Ramachandran266613f2017-03-13 16:36:55 -07001558 mcc_to_scc_switch =
Krunal Sonid36b2072018-09-26 17:02:14 -07001559 policy_mgr_get_mcc_to_scc_switch_mode(psoc);
Archana Ramachandran266613f2017-03-13 16:36:55 -07001560 policy_mgr_info("MCC to SCC switch: %d chan: %d",
Tushnim Bhattacharyyaf8417d12018-05-08 15:31:21 -07001561 mcc_to_scc_switch, operating_channel[0]);
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001562
1563 if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch)) {
1564 policy_mgr_debug(
1565 "No action taken at check_concurrent_intf_and_restart_sap");
1566 return;
1567 }
1568
Bala Venkatesh3b3f16f2018-06-27 12:50:10 +05301569sap_restart:
1570 /*
1571 * If sta_sap_scc_on_dfs_chan is true then standalone SAP is not
1572 * allowed on DFS channel. SAP is allowed on DFS channel only when STA
1573 * is already connected on that channel.
1574 * In following condition restart_sap will be true if
1575 * sta_sap_scc_on_dfs_chan is true and SAP is on DFS channel.
1576 * This scenario can come if STA+SAP are operating on DFS channel and
1577 * STA gets disconnected.
1578 */
1579 if (restart_sap ||
1580 ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) &&
1581 policy_mgr_valid_sta_channel_check(psoc, operating_channel[0]) &&
1582 !pm_ctx->sta_ap_intf_check_work_info)) {
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001583 struct sta_ap_intf_check_work_ctx *work_info;
1584 work_info = qdf_mem_malloc(
1585 sizeof(struct sta_ap_intf_check_work_ctx));
1586 pm_ctx->sta_ap_intf_check_work_info = work_info;
1587 if (work_info) {
1588 work_info->psoc = psoc;
1589 qdf_create_work(0, &pm_ctx->sta_ap_intf_check_work,
Archana Ramachandran6199b642017-03-20 13:31:36 -07001590 policy_mgr_check_sta_ap_concurrent_ch_intf,
Tushnim Bhattacharyya8d185eb2017-06-30 17:40:49 -07001591 work_info);
1592 qdf_sched_work(0, &pm_ctx->sta_ap_intf_check_work);
1593 policy_mgr_info(
1594 "Checking for Concurrent Change interference");
1595 }
Archana Ramachandran266613f2017-03-13 16:36:55 -07001596 }
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001597}
1598#endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */
1599
1600#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Archana Ramachandran0edce252017-03-06 14:36:29 -08001601/**
1602 * policy_mgr_change_sap_channel_with_csa() - Move SAP channel using (E)CSA
1603 * @psoc: PSOC object information
1604 * @vdev_id: Vdev id
1605 * @channel: Channel to change
1606 * @ch_width: channel width to change
Min Liuc5b10432018-01-19 18:01:44 +08001607 * @forced: Force to switch channel, ignore SCC/MCC check
Archana Ramachandran0edce252017-03-06 14:36:29 -08001608 *
1609 * Invoke the callback function to change SAP channel using (E)CSA
1610 *
1611 * Return: None
1612 */
1613void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc,
1614 uint8_t vdev_id, uint32_t channel,
Min Liuc5b10432018-01-19 18:01:44 +08001615 uint32_t ch_width,
1616 bool forced)
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001617{
Archana Ramachandran0edce252017-03-06 14:36:29 -08001618 struct policy_mgr_psoc_priv_obj *pm_ctx;
1619
1620 pm_ctx = policy_mgr_get_context(psoc);
1621 if (!pm_ctx) {
1622 policy_mgr_err("Invalid context");
1623 return;
1624 }
1625
Archana Ramachandran544ce172017-03-14 15:12:09 -07001626 if (pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb) {
Archana Ramachandran0edce252017-03-06 14:36:29 -08001627 policy_mgr_info("SAP change change without restart");
Archana Ramachandran631fd9f2017-03-19 18:51:30 -07001628 pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb(psoc,
Min Liuc5b10432018-01-19 18:01:44 +08001629 vdev_id, channel, ch_width, forced);
Archana Ramachandran0edce252017-03-06 14:36:29 -08001630 }
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001631}
1632#endif
1633
1634QDF_STATUS policy_mgr_wait_for_connection_update(struct wlan_objmgr_psoc *psoc)
1635{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001636 QDF_STATUS status;
1637 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1638
1639 policy_mgr_context = policy_mgr_get_context(psoc);
1640 if (!policy_mgr_context) {
1641 policy_mgr_err("Invalid context");
1642 return QDF_STATUS_E_FAILURE;
1643 }
1644
1645 status = qdf_wait_single_event(
1646 &policy_mgr_context->connection_update_done_evt,
1647 CONNECTION_UPDATE_TIMEOUT);
1648
1649 if (!QDF_IS_STATUS_SUCCESS(status)) {
1650 policy_mgr_err("wait for event failed");
1651 return QDF_STATUS_E_FAILURE;
1652 }
1653
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001654 return QDF_STATUS_SUCCESS;
1655}
1656
1657QDF_STATUS policy_mgr_reset_connection_update(struct wlan_objmgr_psoc *psoc)
1658{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001659 QDF_STATUS status;
1660 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1661
1662 policy_mgr_context = policy_mgr_get_context(psoc);
1663 if (!policy_mgr_context) {
1664 policy_mgr_err("Invalid context");
1665 return QDF_STATUS_E_FAILURE;
1666 }
1667
1668 status = qdf_event_reset(
1669 &policy_mgr_context->connection_update_done_evt);
1670
1671 if (!QDF_IS_STATUS_SUCCESS(status)) {
1672 policy_mgr_err("clear event failed");
1673 return QDF_STATUS_E_FAILURE;
1674 }
1675
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001676 return QDF_STATUS_SUCCESS;
1677}
1678
1679QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc)
1680{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001681 QDF_STATUS status;
1682 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1683
1684 policy_mgr_context = policy_mgr_get_context(psoc);
1685 if (!policy_mgr_context) {
1686 policy_mgr_err("Invalid context");
1687 return QDF_STATUS_E_FAILURE;
1688 }
1689
1690 status = qdf_event_set(&policy_mgr_context->connection_update_done_evt);
1691
1692 if (!QDF_IS_STATUS_SUCCESS(status)) {
1693 policy_mgr_err("set event failed");
1694 return QDF_STATUS_E_FAILURE;
1695 }
1696
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001697 return QDF_STATUS_SUCCESS;
1698}
1699
Bala Venkatesh378064b2018-06-11 15:06:53 +05301700QDF_STATUS policy_mgr_set_chan_switch_complete_evt(
1701 struct wlan_objmgr_psoc *psoc)
1702{
1703 QDF_STATUS status;
1704 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1705
1706 policy_mgr_context = policy_mgr_get_context(psoc);
1707
1708 if (!policy_mgr_context) {
1709 policy_mgr_err("Invalid context");
1710 return QDF_STATUS_E_FAILURE;
1711 }
1712 status = qdf_event_set(
1713 &policy_mgr_context->channel_switch_complete_evt);
1714
1715 if (!QDF_IS_STATUS_SUCCESS(status)) {
1716 policy_mgr_err("set event failed");
1717 return QDF_STATUS_E_FAILURE;
1718 }
1719
1720 return QDF_STATUS_SUCCESS;
1721}
1722
1723QDF_STATUS policy_mgr_reset_chan_switch_complete_evt(
1724 struct wlan_objmgr_psoc *psoc)
1725{
1726 QDF_STATUS status;
1727 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1728
1729 policy_mgr_context = policy_mgr_get_context(psoc);
1730
1731 if (!policy_mgr_context) {
1732 policy_mgr_err("Invalid context");
1733 return QDF_STATUS_E_FAILURE;
1734 }
1735 status = qdf_event_reset(
1736 &policy_mgr_context->channel_switch_complete_evt);
1737
1738 if (!QDF_IS_STATUS_SUCCESS(status)) {
1739 policy_mgr_err("reset event failed");
1740 return QDF_STATUS_E_FAILURE;
1741 }
1742
1743 return QDF_STATUS_SUCCESS;
1744}
1745
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001746QDF_STATUS policy_mgr_set_opportunistic_update(struct wlan_objmgr_psoc *psoc)
1747{
1748 QDF_STATUS status;
1749 struct policy_mgr_psoc_priv_obj *policy_mgr_context;
1750
1751 policy_mgr_context = policy_mgr_get_context(psoc);
1752 if (!policy_mgr_context) {
1753 policy_mgr_err("Invalid context");
1754 return QDF_STATUS_E_FAILURE;
1755 }
1756
1757 status = qdf_event_set(
1758 &policy_mgr_context->opportunistic_update_done_evt);
1759
1760 if (!QDF_IS_STATUS_SUCCESS(status)) {
1761 policy_mgr_err("set event failed");
1762 return QDF_STATUS_E_FAILURE;
1763 }
1764
1765 return QDF_STATUS_SUCCESS;
1766}
1767
Himanshu Agarwal70a52d92018-05-04 14:37:48 +05301768QDF_STATUS policy_mgr_stop_opportunistic_timer(struct wlan_objmgr_psoc *psoc)
1769{
1770 struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
1771
1772 policy_mgr_ctx = policy_mgr_get_context(psoc);
1773 if (!policy_mgr_ctx) {
1774 policy_mgr_err("Invalid context");
1775 return QDF_STATUS_E_FAILURE;
1776 }
1777
1778 if (policy_mgr_ctx->dbs_opportunistic_timer.state !=
1779 QDF_TIMER_STATE_RUNNING)
1780 return QDF_STATUS_SUCCESS;
1781
1782 qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer);
1783 return QDF_STATUS_SUCCESS;
1784}
1785
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001786QDF_STATUS policy_mgr_restart_opportunistic_timer(
1787 struct wlan_objmgr_psoc *psoc, bool check_state)
1788{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001789 QDF_STATUS status = QDF_STATUS_E_FAILURE;
1790 struct policy_mgr_psoc_priv_obj *policy_mgr_ctx;
1791
1792 policy_mgr_ctx = policy_mgr_get_context(psoc);
1793 if (!policy_mgr_ctx) {
1794 policy_mgr_err("Invalid context");
1795 return status;
1796 }
1797
1798 if (check_state &&
1799 QDF_TIMER_STATE_RUNNING !=
1800 policy_mgr_ctx->dbs_opportunistic_timer.state)
1801 return status;
1802
1803 qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer);
1804
1805 status = qdf_mc_timer_start(
1806 &policy_mgr_ctx->dbs_opportunistic_timer,
1807 DBS_OPPORTUNISTIC_TIME * 1000);
1808
1809 if (!QDF_IS_STATUS_SUCCESS(status)) {
1810 policy_mgr_err("failed to start opportunistic timer");
1811 return status;
1812 }
1813
1814 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001815}
1816
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001817QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch(
1818 struct wlan_objmgr_psoc *psoc, uint8_t session_id)
1819{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001820 QDF_STATUS status = QDF_STATUS_E_FAILURE, qdf_status;
1821 enum policy_mgr_conc_next_action action;
1822
1823 if (!policy_mgr_is_hw_dbs_capable(psoc)) {
1824 policy_mgr_err("PM/DBS is disabled");
1825 return status;
1826 }
1827
1828 action = (*policy_mgr_get_current_pref_hw_mode_ptr)(psoc);
1829 if ((action != PM_DBS_DOWNGRADE) &&
1830 (action != PM_SINGLE_MAC_UPGRADE)) {
1831 policy_mgr_err("Invalid action: %d", action);
1832 status = QDF_STATUS_SUCCESS;
1833 goto done;
1834 }
1835
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001836 policy_mgr_debug("action:%d session id:%d", action, session_id);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001837
1838 /* Opportunistic timer is started, PM will check if MCC upgrade can be
1839 * done on timer expiry. This avoids any possible ping pong effect
1840 * as well.
1841 */
1842 if (action == PM_SINGLE_MAC_UPGRADE) {
1843 qdf_status = policy_mgr_restart_opportunistic_timer(
1844 psoc, false);
1845 if (QDF_IS_STATUS_SUCCESS(qdf_status))
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001846 policy_mgr_debug("opportunistic timer for MCC upgrade");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001847 goto done;
1848 }
1849
1850 /* For DBS, we want to move right away to DBS mode */
1851 status = policy_mgr_next_actions(psoc, session_id, action,
1852 POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH);
1853 if (!QDF_IS_STATUS_SUCCESS(status)) {
1854 policy_mgr_err("no set hw mode command was issued");
1855 goto done;
1856 }
1857done:
1858 /* success must be returned only when a set hw mode was done */
1859 return status;
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001860}
1861
1862void policy_mgr_checkn_update_hw_mode_single_mac_mode(
1863 struct wlan_objmgr_psoc *psoc, uint8_t channel)
1864{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001865 uint8_t i;
1866 struct policy_mgr_psoc_priv_obj *pm_ctx;
1867
1868 pm_ctx = policy_mgr_get_context(psoc);
1869 if (!pm_ctx) {
1870 policy_mgr_err("Invalid Context");
1871 return;
1872 }
1873
gaurank kathpaliaafa4e1b2018-07-05 15:04:46 +05301874 if (QDF_TIMER_STATE_RUNNING ==
1875 pm_ctx->dbs_opportunistic_timer.state)
1876 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
1877
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001878 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1879 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
Tushnim Bhattacharyyac304f892018-08-01 19:15:55 -07001880 if (pm_conc_connection_list[i].in_use) {
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001881 if (!WLAN_REG_IS_SAME_BAND_CHANNELS(channel,
1882 pm_conc_connection_list[i].chan)) {
1883 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07001884 policy_mgr_debug("DBS required");
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001885 return;
1886 }
Tushnim Bhattacharyyac304f892018-08-01 19:15:55 -07001887 if (policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
1888 (WLAN_REG_IS_24GHZ_CH(channel) ||
1889 WLAN_REG_IS_24GHZ_CH
1890 (pm_conc_connection_list[i].chan))) {
1891 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1892 policy_mgr_debug("DBS required");
1893 return;
1894 }
1895 }
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001896 }
1897 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08001898 pm_dbs_opportunistic_timer_handler((void *)psoc);
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08001899}
1900
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001901void policy_mgr_check_and_stop_opportunistic_timer(
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001902 struct wlan_objmgr_psoc *psoc, uint8_t id)
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001903{
1904 struct policy_mgr_psoc_priv_obj *pm_ctx;
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001905 enum policy_mgr_conc_next_action action = PM_NOP;
1906 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001907
1908 pm_ctx = policy_mgr_get_context(psoc);
1909 if (!pm_ctx) {
1910 policy_mgr_err("Invalid Context");
1911 return;
1912 }
1913 if (QDF_TIMER_STATE_RUNNING ==
1914 pm_ctx->dbs_opportunistic_timer.state) {
1915 qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer);
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001916 action = policy_mgr_need_opportunistic_upgrade(psoc);
1917 if (action) {
Krunal Soni4943b902018-01-05 17:36:40 -08001918 qdf_event_reset(&pm_ctx->opportunistic_update_done_evt);
Tushnim Bhattacharyya3b9ff372017-12-27 13:57:24 -08001919 status = policy_mgr_next_actions(psoc, id, action,
1920 POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC);
1921 if (status != QDF_STATUS_SUCCESS) {
1922 policy_mgr_err("Failed in policy_mgr_next_actions");
1923 return;
1924 }
1925 status = qdf_wait_single_event(
1926 &pm_ctx->opportunistic_update_done_evt,
1927 CONNECTION_UPDATE_TIMEOUT);
1928
1929 if (!QDF_IS_STATUS_SUCCESS(status)) {
1930 policy_mgr_err("wait for event failed");
1931 return;
1932 }
1933 }
Tushnim Bhattacharyyabdda5822017-10-25 16:33:06 -07001934 }
1935}
1936
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07001937void policy_mgr_set_hw_mode_change_in_progress(
1938 struct wlan_objmgr_psoc *psoc, enum policy_mgr_hw_mode_change value)
1939{
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001940 struct policy_mgr_psoc_priv_obj *pm_ctx;
1941
1942 pm_ctx = policy_mgr_get_context(psoc);
1943 if (!pm_ctx) {
1944 policy_mgr_err("Invalid Context");
1945 return;
1946 }
1947
1948 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1949 pm_ctx->hw_mode_change_in_progress = value;
1950 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1951
1952 policy_mgr_debug("hw_mode_change_in_progress:%d", value);
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07001953}
1954
1955enum policy_mgr_hw_mode_change policy_mgr_is_hw_mode_change_in_progress(
1956 struct wlan_objmgr_psoc *psoc)
1957{
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001958 enum policy_mgr_hw_mode_change value;
1959 struct policy_mgr_psoc_priv_obj *pm_ctx;
1960
1961 value = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
1962
1963 pm_ctx = policy_mgr_get_context(psoc);
1964 if (!pm_ctx) {
1965 policy_mgr_err("Invalid Context");
1966 return value;
1967 }
1968 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
1969 value = pm_ctx->hw_mode_change_in_progress;
1970 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
1971
1972 return value;
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07001973}
1974
1975enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index(
1976 struct wlan_objmgr_psoc *psoc, uint32_t hw_mode_index)
1977{
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001978 struct policy_mgr_psoc_priv_obj *pm_ctx;
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001979 struct policy_mgr_hw_mode_params hw_mode;
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001980 enum policy_mgr_hw_mode_change value
1981 = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001982 QDF_STATUS status;
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001983
1984 pm_ctx = policy_mgr_get_context(psoc);
1985 if (!pm_ctx) {
1986 policy_mgr_err("Invalid Context");
1987 return value;
1988 }
1989
Liangwei Dong9ace8a92018-05-21 05:39:04 -04001990 status = policy_mgr_get_hw_mode_from_idx(psoc, hw_mode_index, &hw_mode);
1991 if (status != QDF_STATUS_SUCCESS) {
1992 policy_mgr_err("Failed to get HW mode index");
1993 return value;
1994 }
1995
1996 if (hw_mode.dbs_cap) {
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07001997 policy_mgr_info("DBS is requested with HW (%d)",
1998 hw_mode_index);
1999 value = POLICY_MGR_DBS_IN_PROGRESS;
2000 goto ret_value;
2001 }
2002
Liangwei Dong9ace8a92018-05-21 05:39:04 -04002003 if (hw_mode.sbs_cap) {
Tushnim Bhattacharyya7051ad02017-03-23 11:16:40 -07002004 policy_mgr_info("SBS is requested with HW (%d)",
2005 hw_mode_index);
2006 value = POLICY_MGR_SBS_IN_PROGRESS;
2007 goto ret_value;
2008 }
2009
2010 value = POLICY_MGR_SMM_IN_PROGRESS;
2011 policy_mgr_info("SMM is requested with HW (%d)", hw_mode_index);
2012
2013ret_value:
2014 return value;
Tushnim Bhattacharyyae9c1e422017-03-13 10:27:10 -07002015}
2016
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002017#ifdef MPC_UT_FRAMEWORK
2018QDF_STATUS policy_mgr_update_connection_info_utfw(
2019 struct wlan_objmgr_psoc *psoc,
2020 uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
2021 uint32_t chain_mask, uint32_t type, uint32_t sub_type,
2022 uint32_t channelid, uint32_t mac_id)
2023{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002024 QDF_STATUS status = QDF_STATUS_E_FAILURE;
2025 uint32_t conn_index = 0, found = 0;
2026 struct policy_mgr_psoc_priv_obj *pm_ctx;
2027
2028 pm_ctx = policy_mgr_get_context(psoc);
2029 if (!pm_ctx) {
2030 policy_mgr_err("Invalid Context");
2031 return status;
2032 }
2033
2034 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
2035 while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
2036 if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) {
2037 /* debug msg */
2038 found = 1;
2039 break;
2040 }
2041 conn_index++;
2042 }
2043 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
2044 if (!found) {
2045 /* err msg */
2046 policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list",
2047 vdev_id);
2048 return status;
2049 }
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07002050 policy_mgr_debug("--> updating entry at index[%d]", conn_index);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002051
2052 policy_mgr_update_conc_list(psoc, conn_index,
2053 policy_mgr_get_mode(type, sub_type),
2054 channelid, HW_MODE_20_MHZ,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05302055 mac_id, chain_mask, 0, vdev_id, true, true);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002056
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002057 return QDF_STATUS_SUCCESS;
2058}
2059
2060QDF_STATUS policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc,
2061 uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
2062 uint32_t chain_mask, uint32_t type, uint32_t sub_type,
2063 uint32_t channelid, uint32_t mac_id)
2064{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002065 QDF_STATUS status = QDF_STATUS_E_FAILURE;
2066 uint32_t conn_index = 0;
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05302067 bool update_conn = true;
2068 enum policy_mgr_con_mode mode;
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002069
2070 conn_index = policy_mgr_get_connection_count(psoc);
2071 if (MAX_NUMBER_OF_CONC_CONNECTIONS <= conn_index) {
2072 /* err msg */
2073 policy_mgr_err("exceeded max connection limit %d",
2074 MAX_NUMBER_OF_CONC_CONNECTIONS);
2075 return status;
2076 }
Tushnim Bhattacharyya8b60ebb2017-08-17 14:53:07 -07002077 policy_mgr_debug("--> filling entry at index[%d]", conn_index);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002078
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05302079 mode = policy_mgr_get_mode(type, sub_type);
2080 if (mode == PM_STA_MODE || mode == PM_P2P_CLIENT_MODE)
2081 update_conn = false;
2082
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002083 policy_mgr_update_conc_list(psoc, conn_index,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05302084 mode,
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002085 channelid, HW_MODE_20_MHZ,
Yeshwanth Sriram Guntuka28542952018-06-13 11:43:46 +05302086 mac_id, chain_mask, 0, vdev_id, true,
2087 update_conn);
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002088
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002089 return QDF_STATUS_SUCCESS;
2090}
2091
2092QDF_STATUS policy_mgr_decr_connection_count_utfw(struct wlan_objmgr_psoc *psoc,
2093 uint32_t del_all, uint32_t vdev_id)
2094{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002095 QDF_STATUS status;
2096
2097 if (del_all) {
Krunal Sonic54f1a62018-09-05 10:58:05 -07002098 status = policy_mgr_psoc_disable(psoc);
2099 if (!QDF_IS_STATUS_SUCCESS(status)) {
2100 policy_mgr_err("Policy manager initialization failed");
2101 return QDF_STATUS_E_FAILURE;
2102 }
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002103 status = policy_mgr_psoc_enable(psoc);
2104 if (!QDF_IS_STATUS_SUCCESS(status)) {
2105 policy_mgr_err("Policy manager initialization failed");
2106 return QDF_STATUS_E_FAILURE;
2107 }
2108 } else {
2109 policy_mgr_decr_connection_count(psoc, vdev_id);
2110 }
2111
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002112 return QDF_STATUS_SUCCESS;
2113}
2114
2115enum policy_mgr_pcl_type policy_mgr_get_pcl_from_first_conn_table(
2116 enum policy_mgr_con_mode type,
2117 enum policy_mgr_conc_priority_mode sys_pref)
2118{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002119 if ((sys_pref >= PM_MAX_CONC_PRIORITY_MODE) ||
2120 (type >= PM_MAX_NUM_OF_MODE))
2121 return PM_MAX_PCL_TYPE;
2122 return first_connection_pcl_table[type][sys_pref];
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002123}
2124
2125enum policy_mgr_pcl_type policy_mgr_get_pcl_from_second_conn_table(
2126 enum policy_mgr_one_connection_mode idx, enum policy_mgr_con_mode type,
2127 enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable)
2128{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002129 if ((idx >= PM_MAX_ONE_CONNECTION_MODE) ||
2130 (sys_pref >= PM_MAX_CONC_PRIORITY_MODE) ||
2131 (type >= PM_MAX_NUM_OF_MODE))
2132 return PM_MAX_PCL_TYPE;
2133 if (dbs_capable)
2134 return (*second_connection_pcl_dbs_table)[idx][type][sys_pref];
2135 else
2136 return second_connection_pcl_nodbs_table[idx][type][sys_pref];
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002137}
2138
2139enum policy_mgr_pcl_type policy_mgr_get_pcl_from_third_conn_table(
2140 enum policy_mgr_two_connection_mode idx, enum policy_mgr_con_mode type,
2141 enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable)
2142{
Tushnim Bhattacharyya5ae4c432017-03-08 09:15:15 -08002143 if ((idx >= PM_MAX_TWO_CONNECTION_MODE) ||
2144 (sys_pref >= PM_MAX_CONC_PRIORITY_MODE) ||
2145 (type >= PM_MAX_NUM_OF_MODE))
2146 return PM_MAX_PCL_TYPE;
2147 if (dbs_capable)
2148 return (*third_connection_pcl_dbs_table)[idx][type][sys_pref];
2149 else
2150 return third_connection_pcl_nodbs_table[idx][type][sys_pref];
Tushnim Bhattacharyya6a8f07f2017-02-15 16:59:48 -08002151}
2152#endif