diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index fbc147a6de..fe912809f8 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -4827,6 +4827,52 @@ enum dot11p_mode { #define CFG_RX_WAKELOCK_TIMEOUT_MIN (0) #define CFG_RX_WAKELOCK_TIMEOUT_MAX (100) +/* + * + * g_max_sched_scan_plan_int - pno sched max scan plan interval. + * @Min: 1 + * @Max: 7200 + * @Default: 3600 + * + * This ini is used to set max sched scan plan interval for pno scan + * (value in seconds). + * + * Related: gPNOScanSupport + * + * Supported Feature: PNO scan + * + * Usage: External + * + * + */ +#define CFG_MAX_SCHED_SCAN_PLAN_INT_NAME "g_max_sched_scan_plan_int" +#define CFG_MAX_SCHED_SCAN_PLAN_INT_MIN (1) +#define CFG_MAX_SCHED_SCAN_PLAN_INT_MAX (7200) +#define CFG_MAX_SCHED_SCAN_PLAN_INT_DEFAULT (3600) + +/* + * + * g_max_sched_scan_plan_iterations - pno sched max scan plan iterations. + * @Min: 1 + * @Max: 100 + * @Default: 10 + * + * This ini is used to set max sched scan plan iterations for pno scan + * (value in seconds). + * + * Related: gPNOScanSupport + * + * Supported Feature: PNO scan + * + * Usage: External + * + * + */ +#define CFG_MAX_SCHED_SCAN_PLAN_ITRNS_NAME "g_max_sched_scan_plan_iterations" +#define CFG_MAX_SCHED_SCAN_PLAN_ITRNS_MIN (1) +#define CFG_MAX_SCHED_SCAN_PLAN_ITRNS_MAX (100) +#define CFG_MAX_SCHED_SCAN_PLAN_ITRNS_DEFAULT (10) + /*--------------------------------------------------------------------------- Type declarations -------------------------------------------------------------------------*/ @@ -5503,6 +5549,8 @@ struct hdd_config { uint8_t sap_max_inactivity_override; bool fw_timeout_crash; uint32_t rx_wakelock_timeout; + uint32_t max_sched_scan_plan_interval; + uint32_t max_sched_scan_plan_iterations; }; #define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var)) diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index 8a828643f2..e92e511819 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -4075,7 +4075,19 @@ REG_TABLE_ENTRY g_registry_table[] = { VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, CFG_RX_WAKELOCK_TIMEOUT_DEFAULT, CFG_RX_WAKELOCK_TIMEOUT_MIN, - CFG_RX_WAKELOCK_TIMEOUT_MAX) + CFG_RX_WAKELOCK_TIMEOUT_MAX), + REG_VARIABLE(CFG_MAX_SCHED_SCAN_PLAN_INT_NAME, WLAN_PARAM_Integer, + struct hdd_config, max_sched_scan_plan_interval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_SCHED_SCAN_PLAN_INT_DEFAULT, + CFG_MAX_SCHED_SCAN_PLAN_INT_MIN, + CFG_MAX_SCHED_SCAN_PLAN_INT_MAX), + REG_VARIABLE(CFG_MAX_SCHED_SCAN_PLAN_ITRNS_NAME, WLAN_PARAM_Integer, + struct hdd_config, max_sched_scan_plan_iterations, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_SCHED_SCAN_PLAN_ITRNS_DEFAULT, + CFG_MAX_SCHED_SCAN_PLAN_ITRNS_MIN, + CFG_MAX_SCHED_SCAN_PLAN_ITRNS_MAX), }; /** diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 81e1b45f0e..bf4b33a674 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -8684,6 +8684,41 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { #endif }; +#if ((LINUX_VERSION_CODE > KERNEL_VERSION(4, 4, 0)) || \ + defined(CFG80211_MULTI_SCAN_PLAN_BACKPORT)) && \ + defined(FEATURE_WLAN_SCAN_PNO) +/** + * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy + * @wiphy: pointer to wiphy + * @config: pointer to config + * + * Return: None + */ +static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy, + struct hdd_config *config) +{ + if (config->configPNOScanSupport) { + wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; + wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS; + wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS; + wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH; + wiphy->max_sched_scan_plans = SIR_PNO_MAX_PLAN_REQUEST; + if (config->max_sched_scan_plan_interval) + wiphy->max_sched_scan_plan_interval = + config->max_sched_scan_plan_interval; + if (config->max_sched_scan_plan_iterations) + wiphy->max_sched_scan_plan_iterations = + config->max_sched_scan_plan_iterations; + } +} +#else +static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy, + struct hdd_config *config) +{ +} +#endif + + /** * hdd_cfg80211_wiphy_alloc() - Allocate wiphy context * @priv_size: Size of the hdd context. @@ -8830,17 +8865,7 @@ int wlan_hdd_cfg80211_init(struct device *dev, wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS); #endif -#ifdef FEATURE_WLAN_SCAN_PNO - if (pCfg->configPNOScanSupport) { - wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; - wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS; - wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS; - wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) || defined(WITH_BACKPORTS) - wiphy->max_sched_scan_plans = SIR_PNO_MAX_PLAN_REQUEST; -#endif - } -#endif /*FEATURE_WLAN_SCAN_PNO */ + hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg); #if defined QCA_WIFI_FTM if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE) { diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c index 3e75abaaa8..7d8abfae0f 100644 --- a/core/hdd/src/wlan_hdd_scan.c +++ b/core/hdd/src/wlan_hdd_scan.c @@ -2298,6 +2298,70 @@ static QDF_STATUS wlan_hdd_is_pno_allowed(hdd_adapter_t *adapter) } +#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) || \ + defined(CFG80211_MULTI_SCAN_PLAN_BACKPORT)) && \ + defined(FEATURE_WLAN_SCAN_PNO) +/** + * hdd_config_sched_scan_plan() - configures the sched scan plans + * from the framework. + * @pno_req: pointer to PNO scan request + * @request: pointer to scan request from framework + * + * Return: None + */ +static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req, + struct cfg80211_sched_scan_request *request, + hdd_context_t *hdd_ctx) +{ + /* + * As of now max 2 scan plans were supported by firmware + * if number of scan plan supported by firmware increased below logic + * must change. + */ + if (request->n_scan_plans == SIR_PNO_MAX_PLAN_REQUEST) { + pno_req->fast_scan_period = + request->scan_plans[0].interval * MSEC_PER_SEC; + pno_req->fast_scan_max_cycles = + request->scan_plans[0].iterations; + pno_req->slow_scan_period = + request->scan_plans[1].interval * MSEC_PER_SEC; + hdd_notice("Base scan interval: %d sec, scan cycles: %d, slow scan interval %d", + request->scan_plans[0].interval, + request->scan_plans[0].iterations, + request->scan_plans[1].interval); + } else if (request->n_scan_plans == 1) { + pno_req->fast_scan_period = + request->scan_plans[0].interval * MSEC_PER_SEC; + /* + * if only one scan plan is configured from framework + * then both fast and slow scan should be configured with the + * same value that is why fast scan cycles are hardcoded to one + */ + pno_req->fast_scan_max_cycles = 1; + pno_req->slow_scan_period = + request->scan_plans[0].interval * MSEC_PER_SEC; + } else { + hdd_err("Invalid number of scan plans %d !!", + request->n_scan_plans); + } +} +#else +static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req, + struct cfg80211_sched_scan_request *request, + hdd_context_t *hdd_ctx) +{ + pno_req->fast_scan_period = request->interval; + pno_req->fast_scan_max_cycles = + hdd_ctx->config->configPNOScanTimerRepeatValue; + pno_req->slow_scan_period = + hdd_ctx->config->pno_slow_scan_multiplier * + pno_req->fast_scan_period; + hdd_notice("Base scan interval: %d sec PNOScanTimerRepeatValue: %d", + (request->interval / 1000), + hdd_ctx->config->configPNOScanTimerRepeatValue); +} +#endif + /** * __wlan_hdd_cfg80211_sched_scan_start() - cfg80211 scheduled scan(pno) start * @wiphy: Pointer to wiphy @@ -2524,27 +2588,7 @@ static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy, * switches slow_scan_period. This is less frequent scans and firmware * shall be in slow_scan_period mode until next PNO Start. */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) || defined(WITH_BACKPORTS) - if (WARN_ON(request->n_scan_plans > SIR_PNO_MAX_PLAN_REQUEST)) { - ret = -EINVAL; - goto error; - } - - /* TBD: only one sched_scan plan we can support now, so we only - * retrieve the first plan and ignore the rest of them. - * If there are more than 1 sched_pan request we can support, the - * PnoRequet structure will also need to be revised. - */ - pPnoRequest->fast_scan_period = request->scan_plans[0].interval * - MSEC_PER_SEC; -#else - pPnoRequest->fast_scan_period = request->interval; -#endif - pPnoRequest->fast_scan_max_cycles = - config->configPNOScanTimerRepeatValue; - pPnoRequest->slow_scan_period = - config->pno_slow_scan_multiplier * - pPnoRequest->fast_scan_period; + hdd_config_sched_scan_plan(pPnoRequest, request, pHddCtx); hdd_info("Base scan interval: %d sec PNOScanTimerRepeatValue: %d", (pPnoRequest->fast_scan_period / 1000), diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 9f7fbd7daf..598b0a6e68 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -2825,7 +2825,7 @@ typedef struct sAniIbssRouteTable { /* Set PNO */ -#define SIR_PNO_MAX_PLAN_REQUEST 1 +#define SIR_PNO_MAX_PLAN_REQUEST 2 #define SIR_PNO_MAX_NETW_CHANNELS 26 #define SIR_PNO_MAX_NETW_CHANNELS_EX 60 #define SIR_PNO_MAX_SUPP_NETWORKS 16