From cd0a9fdcd8a5d673fd613f6bcec52dbbc13f06ae Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Tue, 29 Jan 2019 17:56:37 +0530 Subject: [PATCH] qcacmn: Move scan req modification logic to scan core to ucfg Move the scan req modification logic to scan core from ucfg layer. Change-Id: I92d7bc6ed41761fd6cd4a602ab3c5852e8121dd8 CRs-Fixed: 2393496 --- umac/scan/core/src/wlan_scan_manager.c | 530 ++++++++++++++++- umac/scan/dispatcher/src/wlan_scan_ucfg_api.c | 539 +----------------- 2 files changed, 532 insertions(+), 537 deletions(-) diff --git a/umac/scan/core/src/wlan_scan_manager.c b/umac/scan/core/src/wlan_scan_manager.c index aa92842b1a20..63398f079959 100644 --- a/umac/scan/core/src/wlan_scan_manager.c +++ b/umac/scan/core/src/wlan_scan_manager.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -26,9 +26,15 @@ #include "wlan_scan_main.h" #include "wlan_scan_manager.h" #include "wlan_utility.h" +#include #ifdef FEATURE_WLAN_SCAN_PNO #include #endif +#ifdef WLAN_POLICY_MGR_ENABLE +#include +#include +#endif + QDF_STATUS scm_scan_free_scan_request_mem(struct scan_start_request *req) @@ -405,6 +411,519 @@ bool scm_is_scan_allowed(struct wlan_objmgr_vdev *vdev) return true; } +#ifdef WLAN_POLICY_MGR_ENABLE +/** + * scm_update_dbs_scan_ctrl_ext_flag() - update dbs scan ctrl flags + * @req: pointer to scan request + * + * This function sets scan_ctrl_flags_ext value depending on the type of + * scan and the channel lists. + * + * Non-DBS scan is requested if any of the below case is met: + * 1. HW is DBS incapable + * 2. A high accuracy scan request is sent by kernel. + * + * DBS scan is enabled for these conditions: + * 1. A low power or low span scan request is sent by kernel. + * For remaining cases DBS is enabled by default. + * Return: void + */ +static void +scm_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req) +{ + struct wlan_objmgr_psoc *psoc; + uint32_t scan_dbs_policy = SCAN_DBS_POLICY_DEFAULT; + + psoc = wlan_vdev_get_psoc(req->vdev); + + if (!policy_mgr_is_hw_dbs_capable(psoc)) { + scm_debug("dbs disabled, going for non-dbs scan"); + scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS; + goto end; + } + + if (req->scan_req.scan_policy_high_accuracy) { + scm_debug("high accuracy scan received, going for non-dbs scan"); + scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS; + goto end; + } + if ((req->scan_req.scan_policy_low_power) || + (req->scan_req.scan_policy_low_span)) { + scm_debug("low power/span scan received, going for dbs scan"); + scan_dbs_policy = SCAN_DBS_POLICY_IGNORE_DUTY; + goto end; + } + +end: + req->scan_req.scan_ctrl_flags_ext |= + ((scan_dbs_policy << SCAN_FLAG_EXT_DBS_SCAN_POLICY_BIT) + & SCAN_FLAG_EXT_DBS_SCAN_POLICY_MASK); + scm_debug("scan_ctrl_flags_ext: 0x%x", + req->scan_req.scan_ctrl_flags_ext); +} + +/** + * scm_update_passive_dwell_time() - update dwell passive time + * @vdev: vdev object + * @req: scan request + * + * Return: None + */ +static void +scm_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev, + struct scan_start_request *req) +{ + struct wlan_objmgr_psoc *psoc; + + psoc = wlan_vdev_get_psoc(vdev); + if (!psoc) + return; + + if (policy_mgr_is_sta_connected_2g(psoc) && + !policy_mgr_is_hw_dbs_capable(psoc) && + ucfg_scan_get_bt_activity(psoc)) + req->scan_req.dwell_time_passive = + PASSIVE_DWELL_TIME_BT_A2DP_ENABLED; +} + +static const struct probe_time_dwell_time + scan_probe_time_dwell_time_map[SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE] = { + {28, 11}, /* 0 SSID */ + {28, 20}, /* 1 SSID */ + {28, 20}, /* 2 SSID */ + {28, 20}, /* 3 SSID */ + {28, 20}, /* 4 SSID */ + {28, 20}, /* 5 SSID */ + {28, 20}, /* 6 SSID */ + {28, 11}, /* 7 SSID */ + {28, 11}, /* 8 SSID */ + {28, 11}, /* 9 SSID */ + {28, 8} /* 10 SSID */ +}; + +/** + * scm_scan_get_burst_duration() - get burst duration depending on max chan + * and miracast. + * @max_ch_time: max channel time + * @miracast_enabled: if miracast is enabled + * + * Return: burst_duration + */ +static inline +int scm_scan_get_burst_duration(int max_ch_time, bool miracast_enabled) +{ + int burst_duration = 0; + + if (miracast_enabled) { + /* + * When miracast is running, burst + * duration needs to be minimum to avoid + * any stutter or glitch in miracast + * during station scan + */ + if (max_ch_time <= SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION) + burst_duration = max_ch_time; + else + burst_duration = SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION; + } else { + /* + * If miracast is not running, accommodate max + * stations to make the scans faster + */ + burst_duration = SCAN_GO_BURST_SCAN_MAX_NUM_OFFCHANNELS * + max_ch_time; + + if (burst_duration > SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION) { + uint8_t channels = SCAN_P2P_SCAN_MAX_BURST_DURATION / + max_ch_time; + + if (channels) + burst_duration = channels * max_ch_time; + else + burst_duration = + SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION; + } + } + return burst_duration; +} + +/** + * scm_req_update_concurrency_params() - update scan req params depending on + * concurrent mode present. + * @vdev: vdev object pointer + * @req: scan request + * @scan_obj: scan object + * + * Return: void + */ +static void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev, + struct scan_start_request *req, + struct wlan_scan_obj *scan_obj) +{ + bool ap_present, go_present, sta_active, p2p_cli_present, ndi_present; + struct wlan_objmgr_psoc *psoc; + + psoc = wlan_vdev_get_psoc(vdev); + + if (!psoc) + return; + + ap_present = policy_mgr_mode_specific_connection_count( + psoc, PM_SAP_MODE, NULL); + go_present = policy_mgr_mode_specific_connection_count( + psoc, PM_P2P_GO_MODE, NULL); + p2p_cli_present = policy_mgr_mode_specific_connection_count( + psoc, PM_P2P_CLIENT_MODE, NULL); + sta_active = policy_mgr_mode_specific_connection_count( + psoc, PM_STA_MODE, NULL); + ndi_present = policy_mgr_mode_specific_connection_count( + psoc, PM_NDI_MODE, NULL); + + if (policy_mgr_get_connection_count(psoc)) { + if (req->scan_req.scan_f_passive) + req->scan_req.dwell_time_passive = + scan_obj->scan_def.conc_passive_dwell; + else + req->scan_req.dwell_time_active = + scan_obj->scan_def.conc_active_dwell; + req->scan_req.max_rest_time = + scan_obj->scan_def.conc_max_rest_time; + req->scan_req.min_rest_time = + scan_obj->scan_def.conc_min_rest_time; + req->scan_req.idle_time = scan_obj->scan_def.conc_idle_time; + } + + if (wlan_vdev_is_up(req->vdev) != QDF_STATUS_SUCCESS) + req->scan_req.adaptive_dwell_time_mode = + scan_obj->scan_def.adaptive_dwell_time_mode_nc; + /* + * If AP is active set min rest time same as max rest time, so that + * firmware spends more time on home channel which will increase the + * probability of sending beacon at TBTT + */ + if (ap_present || go_present) { + req->scan_req.dwell_time_active_2g = 0; + req->scan_req.min_rest_time = req->scan_req.max_rest_time; + } + + /* + * If scan req for SAP (ACS Sacn) use dwell_time_active_def as dwell + * time for 2g channels instead of dwell_time_active_2g + */ + if (vdev->vdev_mlme.vdev_opmode == QDF_SAP_MODE) + req->scan_req.dwell_time_active_2g = 0; + + if (req->scan_req.p2p_scan_type == SCAN_NON_P2P_DEFAULT) { + /* + * Decide burst_duration and dwell_time_active based on + * what type of devices are active. + */ + do { + if (ap_present && go_present && sta_active) { + if (req->scan_req.dwell_time_active <= + SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION) + req->scan_req.burst_duration = + req->scan_req.dwell_time_active; + else + req->scan_req.burst_duration = + SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION; + + break; + } + + if (scan_obj->miracast_enabled && + policy_mgr_is_mcc_in_24G(psoc)) + req->scan_req.max_rest_time = + scan_obj->scan_def.sta_miracast_mcc_rest_time; + + if (go_present) { + /* + * Background scan while GO is sending beacons. + * Every off-channel transition has overhead of + * 2 beacon intervals for NOA. Maximize number + * of channels in every transition by using + * burst scan. + */ + req->scan_req.burst_duration = + scm_scan_get_burst_duration( + req->scan_req.dwell_time_active, + scan_obj->miracast_enabled); + break; + } + if ((sta_active || p2p_cli_present) && + !req->scan_req.burst_duration) { + /* + * Typical background scan. + * Disable burst scan for now. + */ + req->scan_req.burst_duration = 0; + break; + } + + if (ndi_present) { + req->scan_req.burst_duration = + scm_scan_get_burst_duration( + req->scan_req.dwell_time_active, + scan_obj->miracast_enabled); + break; + } + } while (0); + + if (ap_present) { + uint8_t ssid_num; + + ssid_num = req->scan_req.num_ssids * + req->scan_req.num_bssid; + req->scan_req.repeat_probe_time = + scan_probe_time_dwell_time_map[ + QDF_MIN(ssid_num, + SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE + - 1)].probe_time; + req->scan_req.n_probes = + (req->scan_req.repeat_probe_time > 0) ? + req->scan_req.dwell_time_active / + req->scan_req.repeat_probe_time : 0; + } + } + + if (ap_present) { + uint8_t ap_chan; + struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); + + ap_chan = policy_mgr_get_channel(psoc, PM_SAP_MODE, NULL); + /* + * P2P/STA scan while SoftAP is sending beacons. + * Max duration of CTS2self is 32 ms, which limits the + * dwell time. If DBS is supported and if SAP is on 2G channel + * then keep passive dwell time default. + */ + req->scan_req.dwell_time_active = + QDF_MIN(req->scan_req.dwell_time_active, + (SCAN_CTS_DURATION_MS_MAX - + SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME)); + if (!policy_mgr_is_hw_dbs_capable(psoc) || + (policy_mgr_is_hw_dbs_capable(psoc) && + WLAN_CHAN_IS_5GHZ(ap_chan))) { + req->scan_req.dwell_time_passive = + req->scan_req.dwell_time_active; + } + req->scan_req.burst_duration = 0; + if (utils_is_dfs_ch(pdev, ap_chan)) + req->scan_req.burst_duration = + SCAN_BURST_SCAN_MAX_NUM_OFFCHANNELS * + req->scan_req.dwell_time_active; + } +} + +#else +static inline +void scm_req_update_concurrency_params(struct wlan_objmgr_vdev *vdev, + struct scan_start_request *req, + struct wlan_scan_obj *scan_obj) +{ +} + +static inline void +scm_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev, + struct scan_start_request *req) +{ +} + +static inline void +scm_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req) +{ +} +#endif + +/** + * scm_update_channel_list() - update scan req params depending on dfs inis + * and initial scan request. + * @req: scan request + * @scan_obj: scan object + * + * Return: void + */ +static void +scm_update_channel_list(struct scan_start_request *req, + struct wlan_scan_obj *scan_obj) +{ + uint8_t i; + uint8_t num_scan_channels = 0; + struct scan_vdev_obj *scan_vdev_obj; + struct wlan_objmgr_pdev *pdev; + bool first_scan_done = true; + + pdev = wlan_vdev_get_pdev(req->vdev); + + scan_vdev_obj = wlan_get_vdev_scan_obj(req->vdev); + if (!scan_vdev_obj) { + scm_err("null scan_vdev_obj"); + return; + } + + if (!scan_vdev_obj->first_scan_done) { + first_scan_done = false; + scan_vdev_obj->first_scan_done = true; + } + + /* + * No need to update channels if req is passive scan and single channel + * ie ROC, Preauth etc + */ + if (req->scan_req.scan_f_passive && + req->scan_req.chan_list.num_chan == 1) + return; + + /* do this only for STA and P2P-CLI mode */ + if (!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) && + !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE)) + return; + + if (scan_obj->scan_def.allow_dfs_chan_in_scan && + (scan_obj->scan_def.allow_dfs_chan_in_first_scan || + first_scan_done)) + return; + + for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { + if (wlan_reg_is_dfs_ch(pdev, wlan_reg_freq_to_chan(pdev, + req->scan_req.chan_list.chan[i].freq))) + continue; + req->scan_req.chan_list.chan[num_scan_channels++] = + req->scan_req.chan_list.chan[i]; + } + req->scan_req.chan_list.num_chan = num_scan_channels; +} + +/** + * scm_scan_req_update_params() - update scan req params depending on modes + * and scan type. + * @vdev: vdev object pointer + * @req: scan request + * @scan_obj: scan object + * + * Return: void + */ +static void +scm_scan_req_update_params(struct wlan_objmgr_vdev *vdev, + struct scan_start_request *req, + struct wlan_scan_obj *scan_obj) +{ + struct chan_list *custom_chan_list; + struct wlan_objmgr_pdev *pdev; + uint8_t pdev_id; + + /* Ensure correct number of probes are sent on active channel */ + if (!req->scan_req.repeat_probe_time) + req->scan_req.repeat_probe_time = + req->scan_req.dwell_time_active / SCAN_NPROBES_DEFAULT; + + if (req->scan_req.scan_f_passive) + req->scan_req.scan_ctrl_flags_ext |= + SCAN_FLAG_EXT_FILTER_PUBLIC_ACTION_FRAME; + + if (!req->scan_req.n_probes) + req->scan_req.n_probes = (req->scan_req.repeat_probe_time > 0) ? + req->scan_req.dwell_time_active / + req->scan_req.repeat_probe_time : 0; + + if (req->scan_req.p2p_scan_type == SCAN_NON_P2P_DEFAULT) { + req->scan_req.scan_f_cck_rates = true; + if (!req->scan_req.num_ssids) + req->scan_req.scan_f_bcast_probe = true; + req->scan_req.scan_f_add_ds_ie_in_probe = true; + req->scan_req.scan_f_filter_prb_req = true; + req->scan_req.scan_f_add_tpc_ie_in_probe = true; + } else { + req->scan_req.adaptive_dwell_time_mode = SCAN_DWELL_MODE_STATIC; + req->scan_req.dwell_time_active_2g = 0; + if (req->scan_req.p2p_scan_type == SCAN_P2P_LISTEN) { + req->scan_req.repeat_probe_time = 0; + } else { + req->scan_req.scan_f_filter_prb_req = true; + if (!req->scan_req.num_ssids) + req->scan_req.scan_f_bcast_probe = true; + + req->scan_req.dwell_time_active += + P2P_SEARCH_DWELL_TIME_INC; + /* + * 3 channels with default max dwell time 40 ms. + * Cap limit will be set by + * P2P_SCAN_MAX_BURST_DURATION. Burst duration + * should be such that no channel is scanned less + * than the dwell time in normal scenarios. + */ + if (req->scan_req.chan_list.num_chan == + WLAN_P2P_SOCIAL_CHANNELS && + !scan_obj->miracast_enabled) + req->scan_req.repeat_probe_time = + req->scan_req.dwell_time_active / 5; + else + req->scan_req.repeat_probe_time = + req->scan_req.dwell_time_active / 3; + + req->scan_req.burst_duration = + BURST_SCAN_MAX_NUM_OFFCHANNELS * + req->scan_req.dwell_time_active; + if (req->scan_req.burst_duration > + P2P_SCAN_MAX_BURST_DURATION) { + uint8_t channels = + P2P_SCAN_MAX_BURST_DURATION / + req->scan_req.dwell_time_active; + if (channels) + req->scan_req.burst_duration = + channels * + req->scan_req.dwell_time_active; + else + req->scan_req.burst_duration = + P2P_SCAN_MAX_BURST_DURATION; + } + req->scan_req.scan_ev_bss_chan = false; + } + } + + if (!req->scan_req.scan_f_passive) + scm_update_passive_dwell_time(vdev, req); + scm_update_dbs_scan_ctrl_ext_flag(req); + + /* + * No need to update conncurrency parmas if req is passive scan on + * single channel ie ROC, Preauth etc + */ + if (!(req->scan_req.scan_f_passive && + req->scan_req.chan_list.num_chan == 1)) + scm_req_update_concurrency_params(vdev, req, scan_obj); + + /* + * Set wide band flag if enabled. This will cause + * phymode TLV being sent to FW. + */ + pdev = wlan_vdev_get_pdev(vdev); + pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + if (ucfg_scan_get_wide_band_scan(pdev)) + req->scan_req.scan_f_wide_band = true; + else + req->scan_req.scan_f_wide_band = false; + + /* + * Overwrite scan channles with custom scan channel + * list if configured. + */ + custom_chan_list = &scan_obj->pdev_info[pdev_id].custom_chan_list; + if (custom_chan_list->num_chan) + qdf_mem_copy(&req->scan_req.chan_list, custom_chan_list, + sizeof(struct chan_list)); + else if (!req->scan_req.chan_list.num_chan) + ucfg_scan_init_chanlist_params(req, 0, NULL, NULL); + + scm_update_channel_list(req, scan_obj); + scm_debug("dwell time: active %d, passive %d, repeat_probe_time %d n_probes %d flags_ext %x, wide_bw_scan: %d", + req->scan_req.dwell_time_active, + req->scan_req.dwell_time_passive, + req->scan_req.repeat_probe_time, req->scan_req.n_probes, + req->scan_req.scan_ctrl_flags_ext, + req->scan_req.scan_f_wide_band); +} + QDF_STATUS scm_scan_start_req(struct scheduler_msg *msg) { @@ -413,6 +932,7 @@ scm_scan_start_req(struct scheduler_msg *msg) struct scan_start_request *req = NULL; struct wlan_scan_obj *scan_obj; QDF_STATUS status = QDF_STATUS_SUCCESS; + uint8_t idx; if (!msg) { scm_err("msg received is NULL"); @@ -440,6 +960,14 @@ scm_scan_start_req(struct scheduler_msg *msg) goto err; } + scm_scan_req_update_params(req->vdev, req, scan_obj); + scm_info("request to scan %d channels", + req->scan_req.chan_list.num_chan); + for (idx = 0; idx < req->scan_req.chan_list.num_chan; idx++) + scm_debug("chan[%d]: freq:%d, phymode:%d", idx, + req->scan_req.chan_list.chan[idx].freq, + req->scan_req.chan_list.chan[idx].phymode); + cmd.cmd_type = WLAN_SER_CMD_SCAN; cmd.cmd_id = req->scan_req.scan_id; cmd.cmd_cb = (wlan_serialization_cmd_callback) diff --git a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c index 8f53de6efba3..48b363327708 100644 --- a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c @@ -35,7 +35,6 @@ #include #endif #ifdef WLAN_POLICY_MGR_ENABLE -#include #include #include #endif @@ -401,327 +400,9 @@ wlan_pno_global_deinit(struct pno_def_config *pno_def) #endif -#ifdef WLAN_POLICY_MGR_ENABLE -/** - * ucfg_scan_update_dbs_scan_ctrl_ext_flag() - update dbs scan ctrl flags - * @req: pointer to scan request - * - * This function sets scan_ctrl_flags_ext value depending on the type of - * scan and the channel lists. - * - * Non-DBS scan is requested if any of the below case is met: - * 1. HW is DBS incapable - * 2. A high accuracy scan request is sent by kernel. - * - * DBS scan is enabled for these conditions: - * 1. A low power or low span scan request is sent by kernel. - * For remaining cases DBS is enabled by default. - * Return: void - */ -static void -ucfg_scan_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req) -{ - struct wlan_objmgr_psoc *psoc; - uint32_t scan_dbs_policy = SCAN_DBS_POLICY_DEFAULT; - - psoc = wlan_vdev_get_psoc(req->vdev); - - if (!policy_mgr_is_hw_dbs_capable(psoc)) { - scm_debug("dbs disabled, going for non-dbs scan"); - scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS; - goto end; - } - - if (req->scan_req.scan_policy_high_accuracy) { - scm_debug("high accuracy scan received, going for non-dbs scan"); - scan_dbs_policy = SCAN_DBS_POLICY_FORCE_NONDBS; - goto end; - } - if ((req->scan_req.scan_policy_low_power) || - (req->scan_req.scan_policy_low_span)) { - scm_debug("low power/span scan received, going for dbs scan"); - scan_dbs_policy = SCAN_DBS_POLICY_IGNORE_DUTY; - goto end; - } - -end: - req->scan_req.scan_ctrl_flags_ext |= - ((scan_dbs_policy << SCAN_FLAG_EXT_DBS_SCAN_POLICY_BIT) - & SCAN_FLAG_EXT_DBS_SCAN_POLICY_MASK); - scm_debug("scan_ctrl_flags_ext: 0x%x", - req->scan_req.scan_ctrl_flags_ext); -} - -/** - * ucfg_update_passive_dwell_time() - update dwell passive time - * @vdev: vdev object - * @req: scan request - * - * Return: None - */ -static void -ucfg_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev, - struct scan_start_request *req) -{ - struct wlan_objmgr_psoc *psoc; - - psoc = wlan_vdev_get_psoc(vdev); - if (!psoc) - return; - - if (policy_mgr_is_sta_connected_2g(psoc) && - !policy_mgr_is_hw_dbs_capable(psoc) && - ucfg_scan_get_bt_activity(psoc)) - req->scan_req.dwell_time_passive = - PASSIVE_DWELL_TIME_BT_A2DP_ENABLED; -} - -static const struct probe_time_dwell_time - scan_probe_time_dwell_time_map[SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE] = { - {28, 11}, /* 0 SSID */ - {28, 20}, /* 1 SSID */ - {28, 20}, /* 2 SSID */ - {28, 20}, /* 3 SSID */ - {28, 20}, /* 4 SSID */ - {28, 20}, /* 5 SSID */ - {28, 20}, /* 6 SSID */ - {28, 11}, /* 7 SSID */ - {28, 11}, /* 8 SSID */ - {28, 11}, /* 9 SSID */ - {28, 8} /* 10 SSID */ -}; - -/** - * ucfg_scan_get_burst_duration() - get burst duration depending on max chan - * and miracast. - * @max_ch_time: max channel time - * @miracast_enabled: if miracast is enabled - * - * Return: burst_duration - */ -static inline -int ucfg_scan_get_burst_duration(int max_ch_time, - bool miracast_enabled) -{ - int burst_duration = 0; - - if (miracast_enabled) { - /* - * When miracast is running, burst - * duration needs to be minimum to avoid - * any stutter or glitch in miracast - * during station scan - */ - if (max_ch_time <= SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION) - burst_duration = max_ch_time; - else - burst_duration = SCAN_GO_MIN_ACTIVE_SCAN_BURST_DURATION; - } else { - /* - * If miracast is not running, accommodate max - * stations to make the scans faster - */ - burst_duration = SCAN_GO_BURST_SCAN_MAX_NUM_OFFCHANNELS * - max_ch_time; - - if (burst_duration > SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION) { - uint8_t channels = SCAN_P2P_SCAN_MAX_BURST_DURATION / - max_ch_time; - - if (channels) - burst_duration = channels * max_ch_time; - else - burst_duration = - SCAN_GO_MAX_ACTIVE_SCAN_BURST_DURATION; - } - } - return burst_duration; -} - -/** - * ucfg_scan_req_update_params() - update scan req params depending on - * concurrent mode present. - * @vdev: vdev object pointer - * @req: scan request - * @scan_obj: scan object - * - * Return: void - */ -static void ucfg_scan_req_update_concurrency_params( - struct wlan_objmgr_vdev *vdev, struct scan_start_request *req, - struct wlan_scan_obj *scan_obj) -{ - bool ap_present, go_present, sta_active, p2p_cli_present, ndi_present; - struct wlan_objmgr_psoc *psoc; - - psoc = wlan_vdev_get_psoc(vdev); - - if (!psoc) - return; - - ap_present = policy_mgr_mode_specific_connection_count( - psoc, PM_SAP_MODE, NULL); - go_present = policy_mgr_mode_specific_connection_count( - psoc, PM_P2P_GO_MODE, NULL); - p2p_cli_present = policy_mgr_mode_specific_connection_count( - psoc, PM_P2P_CLIENT_MODE, NULL); - sta_active = policy_mgr_mode_specific_connection_count( - psoc, PM_STA_MODE, NULL); - ndi_present = policy_mgr_mode_specific_connection_count( - psoc, PM_NDI_MODE, NULL); - - if (policy_mgr_get_connection_count(psoc)) { - if (req->scan_req.scan_f_passive) - req->scan_req.dwell_time_passive = - scan_obj->scan_def.conc_passive_dwell; - else - req->scan_req.dwell_time_active = - scan_obj->scan_def.conc_active_dwell; - req->scan_req.max_rest_time = - scan_obj->scan_def.conc_max_rest_time; - req->scan_req.min_rest_time = - scan_obj->scan_def.conc_min_rest_time; - req->scan_req.idle_time = scan_obj->scan_def.conc_idle_time; - } - - if (wlan_vdev_is_up(req->vdev) != QDF_STATUS_SUCCESS) - req->scan_req.adaptive_dwell_time_mode = - scan_obj->scan_def.adaptive_dwell_time_mode_nc; - /* - * If AP is active set min rest time same as max rest time, so that - * firmware spends more time on home channel which will increase the - * probability of sending beacon at TBTT - */ - if (ap_present || go_present) { - req->scan_req.dwell_time_active_2g = 0; - req->scan_req.min_rest_time = req->scan_req.max_rest_time; - } - - /* - * If scan req for SAP (ACS Sacn) use dwell_time_active_def as dwell - * time for 2g channels instead of dwell_time_active_2g - */ - if (vdev->vdev_mlme.vdev_opmode == QDF_SAP_MODE) { - req->scan_req.dwell_time_active_2g = 0; - } - - if (req->scan_req.p2p_scan_type == SCAN_NON_P2P_DEFAULT) { - /* - * Decide burst_duration and dwell_time_active based on - * what type of devices are active. - */ - do { - if (ap_present && go_present && sta_active) { - if (req->scan_req.dwell_time_active <= - SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION) - req->scan_req.burst_duration = - req->scan_req.dwell_time_active; - else - req->scan_req.burst_duration = - SCAN_3PORT_CONC_SCAN_MAX_BURST_DURATION; - - break; - } - - if (scan_obj->miracast_enabled && - policy_mgr_is_mcc_in_24G(psoc)) - req->scan_req.max_rest_time = - scan_obj->scan_def.sta_miracast_mcc_rest_time; - - if (go_present) { - /* - * Background scan while GO is sending beacons. - * Every off-channel transition has overhead of - * 2 beacon intervals for NOA. Maximize number - * of channels in every transition by using - * burst scan. - */ - req->scan_req.burst_duration = - ucfg_scan_get_burst_duration( - req->scan_req.dwell_time_active, - scan_obj->miracast_enabled); - break; - } - if ((sta_active || p2p_cli_present) && - !req->scan_req.burst_duration) { - /* Typical background scan. - * Disable burst scan for now. - */ - req->scan_req.burst_duration = 0; - break; - } - - if (ndi_present) { - req->scan_req.burst_duration = - ucfg_scan_get_burst_duration( - req->scan_req.dwell_time_active, - scan_obj->miracast_enabled); - break; - } - } while (0); - - if (ap_present) { - uint8_t ssid_num; - ssid_num = req->scan_req.num_ssids * - req->scan_req.num_bssid; - req->scan_req.repeat_probe_time = - scan_probe_time_dwell_time_map[ - QDF_MIN(ssid_num, - SCAN_DWELL_TIME_PROBE_TIME_MAP_SIZE - - 1)].probe_time; - req->scan_req.n_probes = - (req->scan_req.repeat_probe_time > 0) ? - req->scan_req.dwell_time_active / - req->scan_req.repeat_probe_time : 0; - } - } - - if (ap_present) { - uint8_t ap_chan; - struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); - - ap_chan = policy_mgr_get_channel(psoc, PM_SAP_MODE, NULL); - /* - * P2P/STA scan while SoftAP is sending beacons. - * Max duration of CTS2self is 32 ms, which limits the - * dwell time. If DBS is supported and if SAP is on 2G channel - * then keep passive dwell time default. - */ - req->scan_req.dwell_time_active = - QDF_MIN(req->scan_req.dwell_time_active, - (SCAN_CTS_DURATION_MS_MAX - - SCAN_ROAM_SCAN_CHANNEL_SWITCH_TIME)); - if (!policy_mgr_is_hw_dbs_capable(psoc) || - (policy_mgr_is_hw_dbs_capable(psoc) && - WLAN_CHAN_IS_5GHZ(ap_chan))) { - req->scan_req.dwell_time_passive = - req->scan_req.dwell_time_active; - } - req->scan_req.burst_duration = 0; - if (utils_is_dfs_ch(pdev, ap_chan)) - req->scan_req.burst_duration = - SCAN_BURST_SCAN_MAX_NUM_OFFCHANNELS * - req->scan_req.dwell_time_active; - } -} - -#else -static inline void ucfg_scan_req_update_concurrency_params( - struct wlan_objmgr_vdev *vdev, struct scan_start_request *req, - struct wlan_scan_obj *scan_obj) -{ -} -static inline void -ucfg_update_passive_dwell_time(struct wlan_objmgr_vdev *vdev, - struct scan_start_request *req) {} -static inline void -ucfg_scan_update_dbs_scan_ctrl_ext_flag( - struct scan_start_request *req) {} -#endif - QDF_STATUS ucfg_scan_set_custom_scan_chan_list(struct wlan_objmgr_pdev *pdev, - struct chan_list *chan_list) + struct chan_list *chan_list) { uint8_t pdev_id; struct wlan_scan_obj *scan_obj; @@ -739,202 +420,11 @@ ucfg_scan_set_custom_scan_chan_list(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } -/** - * ucfg_update_channel_list() - update scan req params depending on dfs inis - * and initial scan request. - * @req: scan request - * @scan_obj: scan object - * - * Return: void - */ -static void -ucfg_update_channel_list(struct scan_start_request *req, - struct wlan_scan_obj *scan_obj) -{ - uint8_t i; - uint8_t num_scan_channels = 0; - struct scan_vdev_obj *scan_vdev_obj; - struct wlan_objmgr_pdev *pdev; - bool first_scan_done = true; - - pdev = wlan_vdev_get_pdev(req->vdev); - - scan_vdev_obj = wlan_get_vdev_scan_obj(req->vdev); - if (!scan_vdev_obj) { - scm_err("null scan_vdev_obj"); - return; - } - - if (!scan_vdev_obj->first_scan_done) { - first_scan_done = false; - scan_vdev_obj->first_scan_done = true; - } - - /* - * No need to update channels if req is passive scan and single channel - * ie ROC, Preauth etc - */ - if (req->scan_req.scan_f_passive && - req->scan_req.chan_list.num_chan == 1) - return; - - /* do this only for STA and P2P-CLI mode */ - if (!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) && - !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE)) - return; - - if (scan_obj->scan_def.allow_dfs_chan_in_scan && - (scan_obj->scan_def.allow_dfs_chan_in_first_scan || - first_scan_done)) - return; - - for (i = 0; i < req->scan_req.chan_list.num_chan; i++) { - if (wlan_reg_is_dfs_ch(pdev, wlan_reg_freq_to_chan(pdev, - req->scan_req.chan_list. - chan[i].freq))) - continue; - req->scan_req.chan_list.chan[num_scan_channels++] = - req->scan_req.chan_list.chan[i]; - } - req->scan_req.chan_list.num_chan = num_scan_channels; -} - -/** - * ucfg_scan_req_update_params() - update scan req params depending on modes - * and scan type. - * @vdev: vdev object pointer - * @req: scan request - * @scan_obj: scan object - * - * Return: void - */ -static void -ucfg_scan_req_update_params(struct wlan_objmgr_vdev *vdev, - struct scan_start_request *req, struct wlan_scan_obj *scan_obj) -{ - struct chan_list *custom_chan_list; - struct wlan_objmgr_pdev *pdev; - uint8_t pdev_id; - - /* Ensure correct number of probes are sent on active channel */ - if (!req->scan_req.repeat_probe_time) - req->scan_req.repeat_probe_time = - req->scan_req.dwell_time_active / SCAN_NPROBES_DEFAULT; - - if (req->scan_req.scan_f_passive) - req->scan_req.scan_ctrl_flags_ext |= - SCAN_FLAG_EXT_FILTER_PUBLIC_ACTION_FRAME; - - if (!req->scan_req.n_probes) - req->scan_req.n_probes = (req->scan_req.repeat_probe_time > 0) ? - req->scan_req.dwell_time_active / - req->scan_req.repeat_probe_time : 0; - - if (req->scan_req.p2p_scan_type == SCAN_NON_P2P_DEFAULT) { - req->scan_req.scan_f_cck_rates = true; - if (!req->scan_req.num_ssids) - req->scan_req.scan_f_bcast_probe = true; - req->scan_req.scan_f_add_ds_ie_in_probe = true; - req->scan_req.scan_f_filter_prb_req = true; - req->scan_req.scan_f_add_tpc_ie_in_probe = true; - } else { - req->scan_req.adaptive_dwell_time_mode = SCAN_DWELL_MODE_STATIC; - req->scan_req.dwell_time_active_2g = 0; - if (req->scan_req.p2p_scan_type == SCAN_P2P_LISTEN) { - req->scan_req.repeat_probe_time = 0; - } else { - req->scan_req.scan_f_filter_prb_req = true; - if (!req->scan_req.num_ssids) - req->scan_req.scan_f_bcast_probe = true; - - req->scan_req.dwell_time_active += - P2P_SEARCH_DWELL_TIME_INC; - /* - * 3 channels with default max dwell time 40 ms. - * Cap limit will be set by - * P2P_SCAN_MAX_BURST_DURATION. Burst duration - * should be such that no channel is scanned less - * than the dwell time in normal scenarios. - */ - if (req->scan_req.chan_list.num_chan == - WLAN_P2P_SOCIAL_CHANNELS && - !scan_obj->miracast_enabled) - req->scan_req.repeat_probe_time = - req->scan_req.dwell_time_active / 5; - else - req->scan_req.repeat_probe_time = - req->scan_req.dwell_time_active / 3; - - req->scan_req.burst_duration = - BURST_SCAN_MAX_NUM_OFFCHANNELS * - req->scan_req.dwell_time_active; - if (req->scan_req.burst_duration > - P2P_SCAN_MAX_BURST_DURATION) { - uint8_t channels = - P2P_SCAN_MAX_BURST_DURATION / - req->scan_req.dwell_time_active; - if (channels) - req->scan_req.burst_duration = - channels * - req->scan_req.dwell_time_active; - else - req->scan_req.burst_duration = - P2P_SCAN_MAX_BURST_DURATION; - } - req->scan_req.scan_ev_bss_chan = false; - } - } - - if (!req->scan_req.scan_f_passive) - ucfg_update_passive_dwell_time(vdev, req); - ucfg_scan_update_dbs_scan_ctrl_ext_flag(req); - - /* - * No need to update conncurrency parmas if req is passive scan on - * single channel ie ROC, Preauth etc - */ - if (!(req->scan_req.scan_f_passive && - req->scan_req.chan_list.num_chan == 1)) - ucfg_scan_req_update_concurrency_params(vdev, req, scan_obj); - - /* Set wide band flag if enabled. This will cause - * phymode TLV being sent to FW. - */ - pdev = wlan_vdev_get_pdev(vdev); - pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); - if (ucfg_scan_get_wide_band_scan(pdev)) - req->scan_req.scan_f_wide_band = true; - else - req->scan_req.scan_f_wide_band = false; - - /* Overwrite scan channles with custom scan channel - * list if configured. - */ - custom_chan_list = &scan_obj->pdev_info[pdev_id].custom_chan_list; - if (custom_chan_list->num_chan) - qdf_mem_copy(&req->scan_req.chan_list, custom_chan_list, - sizeof(struct chan_list)); - else if (!req->scan_req.chan_list.num_chan) - ucfg_scan_init_chanlist_params(req, 0, NULL, NULL); - - ucfg_update_channel_list(req, scan_obj); - scm_debug("dwell time: active %d, passive %d, repeat_probe_time %d " - "n_probes %d flags_ext %x, wide_bw_scan: %d", - req->scan_req.dwell_time_active, - req->scan_req.dwell_time_passive, - req->scan_req.repeat_probe_time, req->scan_req.n_probes, - req->scan_req.scan_ctrl_flags_ext, - req->scan_req.scan_f_wide_band); -} - QDF_STATUS ucfg_scan_start(struct scan_start_request *req) { struct scheduler_msg msg = {0}; QDF_STATUS status; - struct wlan_scan_obj *scan_obj; - struct wlan_objmgr_pdev *pdev; - uint8_t idx; if (!req || !req->vdev) { scm_err("req or vdev within req is NULL"); @@ -943,31 +433,15 @@ ucfg_scan_start(struct scan_start_request *req) return QDF_STATUS_E_NULL_VALUE; } - pdev = wlan_vdev_get_pdev(req->vdev); - if (!pdev) { - scm_err("Failed to get pdev object"); - scm_scan_free_scan_request_mem(req); - return QDF_STATUS_E_NULL_VALUE; - } - if (!scm_is_scan_allowed(req->vdev)) { scm_err("scan disabled, rejecting the scan req"); scm_scan_free_scan_request_mem(req); return QDF_STATUS_E_AGAIN; } - scan_obj = wlan_pdev_get_scan_obj(pdev); - if (!scan_obj) { - scm_err("Failed to get scan object"); - scm_scan_free_scan_request_mem(req); - return QDF_STATUS_E_NULL_VALUE; - } - scm_debug("reqid: %d, scanid: %d, vdevid: %d", - req->scan_req.scan_req_id, req->scan_req.scan_id, - req->scan_req.vdev_id); - - ucfg_scan_req_update_params(req->vdev, req, scan_obj); + req->scan_req.scan_req_id, req->scan_req.scan_id, + req->scan_req.vdev_id); /* Try to get vdev reference. Return if reference could * not be taken. Reference will be released once scan @@ -980,13 +454,6 @@ ucfg_scan_start(struct scan_start_request *req) return status; } - scm_info("request to scan %d channels", - req->scan_req.chan_list.num_chan); - for (idx = 0; idx < req->scan_req.chan_list.num_chan; idx++) - scm_debug("chan[%d]: freq:%d, phymode:%d", idx, - req->scan_req.chan_list.chan[idx].freq, - req->scan_req.chan_list.chan[idx].phymode); - msg.bodyptr = req; msg.callback = scm_scan_start_req; msg.flush_callback = scm_scan_start_flush_callback;