Browse Source

qcacld-3.0: Add support for adaptive dwell scan time

Dwell time can be modify based on channel congestion per scan
request.
Add changes to enable firmware to use scan control flag and
select dwell time optimization algorithm based on ini values.

Change-Id: Iea3de57c1b7d087442e4b8984b4184d24bb8c930
CRs-Fixed: 994443
Gupta, Kapil 9 years ago
parent
commit
96c7f2f620

+ 126 - 0
core/hdd/inc/wlan_hdd_cfg.h

@@ -3116,6 +3116,123 @@ enum dot11p_mode {
 #define CFG_ENABLE_DP_TRACE_MAX		(1)
 #define CFG_ENABLE_DP_TRACE_DEFAULT	(1)
 
+/*
+ * This parameter will globally disable/enable the adaptive dwell config.
+ * Scan dwell time optimization
+ * Following parameters will set different values of attributes for dwell
+ * time optimization thus reducing total scan time.
+ */
+
+/*
+ * This parameter will globally disable/enable the adaptive dwell config.
+ * Acceptable values for this:
+ * 0: Config is disabled
+ * 1: Config is enabled
+ */
+#define CFG_ADAPTIVE_DWELL_MODE_ENABLED_NAME      "adaptive_dwell_mode_enabled"
+#define CFG_ADAPTIVE_DWELL_MODE_ENABLED_MIN       (0)
+#define CFG_ADAPTIVE_DWELL_MODE_ENABLED_MAX       (1)
+#define CFG_ADAPTIVE_DWELL_MODE_ENABLED_DEFAULT   (0)
+
+/*
+ * This parameter will set default adaptive mode, will be used if any of the
+ * scan dwell mode is set to default.
+ * For uses : see enum wmi_dwelltime_adaptive_mode
+ */
+#define CFG_GLOBAL_ADAPTIVE_DWELL_MODE_NAME       "global_adapt_dwelltime_mode"
+#define CFG_GLOBAL_ADAPTIVE_DWELL_MODE_MIN        (0)
+#define CFG_GLOBAL_ADAPTIVE_DWELL_MODE_MAX        (4)
+#define CFG_GLOBAL_ADAPTIVE_DWELL_MODE_DEFAULT    (0)
+
+/*
+ * This parameter will set the weight to calculate the average low pass
+ * filter for channel congestion.
+ * Acceptable values for this: 0-100 (In %)
+ */
+#define CFG_ADAPT_DWELL_LPF_WEIGHT_NAME       "adapt_dwell_lpf_weight"
+#define CFG_ADAPT_DWELL_LPF_WEIGHT_MIN        (0)
+#define CFG_ADAPT_DWELL_LPF_WEIGHT_MAX        (100)
+#define CFG_ADAPT_DWELL_LPF_WEIGHT_DEFAULT    (80)
+
+/*
+ * This parameter will set interval to monitor wifi activity
+ * in passive scan in msec.
+ * Acceptable values for this: 0-25
+ */
+#define CFG_ADAPT_DWELL_PASMON_INTVAL_NAME     "adapt_dwell_passive_mon_intval"
+#define CFG_ADAPT_DWELL_PASMON_INTVAL_MIN      (0)
+#define CFG_ADAPT_DWELL_PASMON_INTVAL_MAX      (10)
+#define CFG_ADAPT_DWELL_PASMON_INTVAL_DEFAULT  (25)
+
+/*
+ * This parameter will set % of wifi activity used in passive scan 0-100.
+ * Acceptable values for this: 0-100 (in %)
+ */
+#define CFG_ADAPT_DWELL_WIFI_THRESH_NAME       "adapt_dwell_wifi_act_threshold"
+#define CFG_ADAPT_DWELL_WIFI_THRESH_MIN        (0)
+#define CFG_ADAPT_DWELL_WIFI_THRESH_MAX        (100)
+#define CFG_ADAPT_DWELL_WIFI_THRESH_DEFAULT    (10)
+
+/*
+ * This parameter will set the algo used in dwell time optimization during
+ * host scan. see enum wmi_dwelltime_adaptive_mode.
+ * Acceptable values for this:
+ * 0: Default (Use firmware default mode)
+ * 1: Conservative optimization
+ * 2: Moderate optimization
+ * 3: Aggressive optimization
+ * 4: Static
+ */
+#define CFG_ADAPTIVE_SCAN_DWELL_MODE_NAME        "hostscan_adaptive_dwell_mode"
+#define CFG_ADAPTIVE_SCAN_DWELL_MODE_MIN         (0)
+#define CFG_ADAPTIVE_SCAN_DWELL_MODE_MAX         (4)
+#define CFG_ADAPTIVE_SCAN_DWELL_MODE_DEFAULT     (0)
+
+/*
+ * This parameter will set the algo used in dwell time optimization during
+ * roam scan. see enum wmi_dwelltime_adaptive_mode.
+ * Acceptable values for this:
+ * 0: Default (Use firmware default mode)
+ * 1: Conservative optimization
+ * 2: Moderate optimization
+ * 3: Aggressive optimization
+ * 4: Static
+ */
+#define CFG_ADAPTIVE_ROAMSCAN_DWELL_MODE_NAME    "roamscan_adaptive_dwell_mode"
+#define CFG_ADAPTIVE_ROAMSCAN_DWELL_MODE_MIN     (0)
+#define CFG_ADAPTIVE_ROAMSCAN_DWELL_MODE_MAX     (4)
+#define CFG_ADAPTIVE_ROAMSCAN_DWELL_MODE_DEFAULT (0)
+
+/*
+ * This parameter will set the algo used in dwell time optimization during
+ * ext scan. see enum wmi_dwelltime_adaptive_mode.
+ * Acceptable values for this:
+ * 0: Default (Use firmware default mode)
+ * 1: Conservative optimization
+ * 2: Moderate optimization
+ * 3: Aggressive optimization
+ * 4: Static
+ */
+#define CFG_ADAPTIVE_EXTSCAN_DWELL_MODE_NAME     "extscan_adaptive_dwell_mode"
+#define CFG_ADAPTIVE_EXTSCAN_DWELL_MODE_MIN      (0)
+#define CFG_ADAPTIVE_EXTSCAN_DWELL_MODE_MAX      (4)
+#define CFG_ADAPTIVE_EXTSCAN_DWELL_MODE_DEFAULT  (0)
+
+/*
+ * This parameter will set the algo used in dwell time optimization during
+ * pno scan. see enum wmi_dwelltime_adaptive_mode.
+ * Acceptable values for this:
+ * 0: Default (Use firmware default mode)
+ * 1: Conservative optimization
+ * 2: Moderate optimization
+ * 3: Aggressive optimization
+ * 4: Static
+ */
+#define CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_NAME     "pnoscan_adaptive_dwell_mode"
+#define CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_MIN      (0)
+#define CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_MAX      (4)
+#define CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_DEFAULT  (0)
+
 /*---------------------------------------------------------------------------
    Type declarations
    -------------------------------------------------------------------------*/
@@ -3736,6 +3853,15 @@ struct hdd_config {
 	bool enable_fatal_event;
 	bool bpf_enabled;
 	bool enable_dp_trace;
+	bool adaptive_dwell_mode_enabled;
+	enum wmi_dwelltime_adaptive_mode scan_adaptive_dwell_mode;
+	enum wmi_dwelltime_adaptive_mode roamscan_adaptive_dwell_mode;
+	enum wmi_dwelltime_adaptive_mode extscan_adaptive_dwell_mode;
+	enum wmi_dwelltime_adaptive_mode pnoscan_adaptive_dwell_mode;
+	enum wmi_dwelltime_adaptive_mode global_adapt_dwelltime_mode;
+	uint8_t adapt_dwell_lpf_weight;
+	uint8_t adapt_dwell_passive_mon_intval;
+	uint8_t adapt_dwell_wifi_act_threshold;
 };
 
 #define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))

+ 97 - 1
core/hdd/src/wlan_hdd_cfg.c

@@ -3646,6 +3646,14 @@ REG_TABLE_ENTRY g_registry_table[] = {
 		     CFG_CHANNEL_PREDICTION_FULL_SCAN_MS_DEFAULT,
 		     CFG_CHANNEL_PREDICTION_FULL_SCAN_MS_MIN,
 		     CFG_CHANNEL_PREDICTION_FULL_SCAN_MS_MAX),
+
+	REG_VARIABLE(CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_NAME,
+		     WLAN_PARAM_Integer,
+		     struct hdd_config, pnoscan_adaptive_dwell_mode,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_DEFAULT,
+		     CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_MIN,
+		     CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_MAX),
 #endif
 
 	REG_VARIABLE(CFG_TX_CHAIN_MASK_CCK, WLAN_PARAM_Integer,
@@ -3904,6 +3912,62 @@ REG_TABLE_ENTRY g_registry_table[] = {
 		CFG_ENABLE_DP_TRACE_DEFAULT,
 		CFG_ENABLE_DP_TRACE_MIN,
 		CFG_ENABLE_DP_TRACE_MAX),
+
+	REG_VARIABLE(CFG_ADAPTIVE_SCAN_DWELL_MODE_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, scan_adaptive_dwell_mode,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ADAPTIVE_SCAN_DWELL_MODE_DEFAULT,
+		CFG_ADAPTIVE_SCAN_DWELL_MODE_MIN,
+		CFG_ADAPTIVE_SCAN_DWELL_MODE_MAX),
+
+	REG_VARIABLE(CFG_ADAPTIVE_ROAMSCAN_DWELL_MODE_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, roamscan_adaptive_dwell_mode,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ADAPTIVE_ROAMSCAN_DWELL_MODE_DEFAULT,
+		CFG_ADAPTIVE_ROAMSCAN_DWELL_MODE_MIN,
+		CFG_ADAPTIVE_ROAMSCAN_DWELL_MODE_MAX),
+
+	REG_VARIABLE(CFG_ADAPTIVE_EXTSCAN_DWELL_MODE_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, extscan_adaptive_dwell_mode,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ADAPTIVE_EXTSCAN_DWELL_MODE_DEFAULT,
+		CFG_ADAPTIVE_EXTSCAN_DWELL_MODE_MIN,
+		CFG_ADAPTIVE_EXTSCAN_DWELL_MODE_MAX),
+
+	REG_VARIABLE(CFG_ADAPTIVE_DWELL_MODE_ENABLED_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, adaptive_dwell_mode_enabled,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ADAPTIVE_DWELL_MODE_ENABLED_DEFAULT,
+		CFG_ADAPTIVE_DWELL_MODE_ENABLED_MIN,
+		CFG_ADAPTIVE_DWELL_MODE_ENABLED_MAX),
+
+	REG_VARIABLE(CFG_GLOBAL_ADAPTIVE_DWELL_MODE_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, global_adapt_dwelltime_mode,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_GLOBAL_ADAPTIVE_DWELL_MODE_DEFAULT,
+		CFG_GLOBAL_ADAPTIVE_DWELL_MODE_MIN,
+		CFG_GLOBAL_ADAPTIVE_DWELL_MODE_MAX),
+
+	REG_VARIABLE(CFG_ADAPT_DWELL_LPF_WEIGHT_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, adapt_dwell_lpf_weight,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ADAPT_DWELL_LPF_WEIGHT_DEFAULT,
+		CFG_ADAPT_DWELL_LPF_WEIGHT_MIN,
+		CFG_ADAPT_DWELL_LPF_WEIGHT_MAX),
+
+	REG_VARIABLE(CFG_ADAPT_DWELL_PASMON_INTVAL_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, adapt_dwell_passive_mon_intval,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ADAPT_DWELL_PASMON_INTVAL_DEFAULT,
+		CFG_ADAPT_DWELL_PASMON_INTVAL_MIN,
+		CFG_ADAPT_DWELL_PASMON_INTVAL_MAX),
+
+	REG_VARIABLE(CFG_ADAPT_DWELL_WIFI_THRESH_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, adapt_dwell_wifi_act_threshold,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_ADAPT_DWELL_WIFI_THRESH_DEFAULT,
+		CFG_ADAPT_DWELL_WIFI_THRESH_MIN,
+		CFG_ADAPT_DWELL_WIFI_THRESH_MAX),
 };
 
 
@@ -5462,6 +5526,9 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
 	hddLog(LOGE, "Name = [%s] Value = [%u]",
 			CFG_CHANNEL_PREDICTION_FULL_SCAN_MS_NAME,
 			pHddCtx->config->channel_prediction_full_scan);
+	hddLog(LOGE, "Name = [%s] Value = [%u]",
+			CFG_ADAPTIVE_PNOSCAN_DWELL_MODE_NAME,
+			pHddCtx->config->pnoscan_adaptive_dwell_mode);
 #endif
 	hddLog(LOGE, "Name = [%s] Value = [%d]",
 		  CFG_EARLY_STOP_SCAN_ENABLE,
@@ -5507,7 +5574,6 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
 		CFG_IDLE_TIME_NAME,
 		pHddCtx->config->idle_time_conc);
 
-
 	hdd_info("Name = [%s] Value = [%u]",
 		CFG_ENABLE_EDCA_INI_NAME,
 		pHddCtx->config->enable_edca_params);
@@ -5553,6 +5619,30 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
 	hdd_info("Name = [%s] Value = [%u]",
 		CFG_ENABLE_DP_TRACE,
 		pHddCtx->config->enable_dp_trace);
+	hdd_info("Name = [%s] Value = [%u]",
+		CFG_ADAPTIVE_SCAN_DWELL_MODE_NAME,
+		pHddCtx->config->scan_adaptive_dwell_mode);
+	hdd_info("Name = [%s] Value = [%u]",
+		CFG_ADAPTIVE_ROAMSCAN_DWELL_MODE_NAME,
+		pHddCtx->config->roamscan_adaptive_dwell_mode);
+	hdd_info("Name = [%s] Value = [%u]",
+		CFG_ADAPTIVE_EXTSCAN_DWELL_MODE_NAME,
+		pHddCtx->config->extscan_adaptive_dwell_mode);
+	hdd_info("Name = [%s] Value = [%u]",
+		CFG_ADAPTIVE_DWELL_MODE_ENABLED_NAME,
+		pHddCtx->config->adaptive_dwell_mode_enabled);
+	hdd_info("Name = [%s] Value = [%u]",
+		CFG_GLOBAL_ADAPTIVE_DWELL_MODE_NAME,
+		pHddCtx->config->global_adapt_dwelltime_mode);
+	hdd_info("Name = [%s] Value = [%u]",
+		CFG_ADAPT_DWELL_LPF_WEIGHT_NAME,
+		pHddCtx->config->adapt_dwell_lpf_weight);
+	hdd_info("Name = [%s] Value = [%u]",
+		CFG_ADAPT_DWELL_PASMON_INTVAL_NAME,
+		pHddCtx->config->adapt_dwell_passive_mon_intval);
+	hdd_info("Name = [%s] Value = [%u]",
+		CFG_ADAPT_DWELL_WIFI_THRESH_NAME,
+		pHddCtx->config->adapt_dwell_wifi_act_threshold);
 }
 
 
@@ -6735,6 +6825,8 @@ void hdd_set_pno_channel_prediction_config(
 		hdd_ctx->config->stationary_thresh;
 	sme_config->csrConfig.channel_prediction_full_scan =
 		hdd_ctx->config->channel_prediction_full_scan;
+	sme_config->csrConfig.pnoscan_adaptive_dwell_mode =
+		hdd_ctx->config->pnoscan_adaptive_dwell_mode;
 }
 #endif
 /**
@@ -7062,6 +7154,10 @@ QDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx)
 			pConfig->ignore_peer_ht_opmode;
 	smeConfig->csrConfig.enable_fatal_event =
 			pConfig->enable_fatal_event;
+	smeConfig->csrConfig.scan_adaptive_dwell_mode =
+			pHddCtx->config->scan_adaptive_dwell_mode;
+	smeConfig->csrConfig.roamscan_adaptive_dwell_mode =
+			pHddCtx->config->roamscan_adaptive_dwell_mode;
 
 	smeConfig->csrConfig.enable_edca_params =
 			pConfig->enable_edca_params;

+ 3 - 0
core/hdd/src/wlan_hdd_ext_scan.c

@@ -3231,6 +3231,9 @@ __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
 			hdd_extscan_map_usr_drv_config_flags(
 				nla_get_u32(tb[PARAM_CONFIG_FLAGS]));
 
+	pReqMsg->extscan_adaptive_dwell_mode =
+		pHddCtx->config->extscan_adaptive_dwell_mode;
+
 	hddLog(LOG1, FL("Configuration flags: %u"),
 				pReqMsg->configuration_flags);
 

+ 39 - 0
core/hdd/src/wlan_hdd_main.c

@@ -6325,6 +6325,42 @@ out:
 	return ret;
 }
 
+/**
+ * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config
+ * @hdd_ctx: HDD context
+ *
+ * This function sends the adaptive dwell time config configuration to the
+ * firmware via WMA
+ *
+ * Return: 0 - success, < 0 - failure
+ */
+static int hdd_adaptive_dwelltime_init(hdd_context_t *hdd_ctx)
+{
+	QDF_STATUS status;
+	struct adaptive_dwelltime_params dwelltime_params;
+
+	dwelltime_params.is_enabled =
+			hdd_ctx->config->adaptive_dwell_mode_enabled;
+	dwelltime_params.dwelltime_mode =
+			hdd_ctx->config->global_adapt_dwelltime_mode;
+	dwelltime_params.lpf_weight =
+			hdd_ctx->config->adapt_dwell_lpf_weight;
+	dwelltime_params.passive_mon_intval =
+			hdd_ctx->config->adapt_dwell_passive_mon_intval;
+	dwelltime_params.wifi_act_threshold =
+			hdd_ctx->config->adapt_dwell_wifi_act_threshold;
+
+	status = sme_set_adaptive_dwelltime_config(hdd_ctx->hHal,
+						   &dwelltime_params);
+
+	hdd_debug("Sending Adaptive Dwelltime Configuration to fw");
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		hdd_err("Failed to send Adaptive Dwelltime configuration!");
+		return -EAGAIN;
+	}
+	return 0;
+}
+
 /**
  * hdd_wlan_startup() - HDD init function
  * @dev:	Pointer to the underlying device
@@ -6509,6 +6545,9 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc)
 	if (0 != hdd_lro_init(hdd_ctx))
 		hdd_err("Unable to initialize LRO in fw");
 
+	if (0 != hdd_adaptive_dwelltime_init(hdd_ctx))
+		hdd_err("Unable to send adaptive dwelltime setting to FW");
+
 	hddtxlimit.txPower2g = hdd_ctx->config->TxPower2g;
 	hddtxlimit.txPower5g = hdd_ctx->config->TxPower5g;
 	status = sme_txpower_limit(hdd_ctx->hHal, &hddtxlimit);

+ 26 - 0
core/mac/inc/sir_api.h

@@ -46,6 +46,7 @@
 #include "ani_system_defs.h"
 #include "sir_params.h"
 #include "cds_regdomain.h"
+#include "wmi_unified_param.h"
 
 #define OFFSET_OF(structType, fldName)   (&((structType *)0)->fldName)
 
@@ -761,6 +762,7 @@ typedef struct sSirSmeScanReq {
 	 * WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME) is used.
 	 */
 	uint32_t maxChannelTime;
+	enum wmi_dwelltime_adaptive_mode scan_adaptive_dwell_mode;
 	/**
 	 * returnAfterFirstMatch can take following values:
 	 * 0x00 - Return SCAN_RSP message after complete channel scan
@@ -2778,6 +2780,7 @@ typedef struct sSirPNOScanReq {
 	bool pno_channel_prediction;
 	uint8_t top_k_num_of_channels;
 	uint8_t stationary_thresh;
+	enum wmi_dwelltime_adaptive_mode pnoscan_adaptive_dwell_mode;
 	uint32_t channel_prediction_full_scan;
 #endif
 } tSirPNOScanReq, *tpSirPNOScanReq;
@@ -2952,6 +2955,7 @@ typedef struct sSirRoamOffloadScanReq {
 	uint8_t early_stop_scan_enable;
 	int8_t early_stop_scan_min_threshold;
 	int8_t early_stop_scan_max_threshold;
+	enum wmi_dwelltime_adaptive_mode roamscan_adaptive_dwell_mode;
 } tSirRoamOffloadScanReq, *tpSirRoamOffloadScanReq;
 
 typedef struct sSirRoamOffloadScanRsp {
@@ -3577,6 +3581,7 @@ typedef struct sSirScanOffloadReq {
 	/*in units of milliseconds, ignored when not connected*/
 	uint32_t idle_time;
 	tSirP2pScanType p2pScanType;
+	enum wmi_dwelltime_adaptive_mode scan_adaptive_dwell_mode;
 	uint16_t uIEFieldLen;
 	uint16_t uIEFieldOffset;
 	tSirChannelList channelList;
@@ -4422,6 +4427,7 @@ typedef struct {
 	uint32_t min_dwell_time_passive;
 	uint32_t max_dwell_time_passive;
 	uint32_t configuration_flags;
+	enum wmi_dwelltime_adaptive_mode extscan_adaptive_dwell_mode;
 	tSirWifiScanBucketSpec buckets[WLAN_EXTSCAN_MAX_BUCKETS];
 } tSirWifiScanCmdReqParams, *tpSirWifiScanCmdReqParams;
 
@@ -5624,6 +5630,26 @@ struct beacon_filter_param {
 	uint32_t   ie_map[SIR_BCN_FLT_MAX_ELEMS_IE_LIST];
 };
 
+/**
+ * struct adaptive_dwelltime_params - the adaptive dwelltime params
+ * @vdev_id: vdev id
+ * @is_enabled: Adaptive dwell time is enabled/disabled
+ * @dwelltime_mode: global default adaptive dwell mode
+ * @lpf_weight: weight to calculate the average low pass
+ * filter for channel congestion
+ * @passive_mon_intval: intval to monitor wifi activity in passive scan in msec
+ * @wifi_act_threshold: % of wifi activity used in passive scan 0-100
+ *
+ */
+struct adaptive_dwelltime_params {
+	uint32_t  vdev_id;
+	bool      is_enabled;
+	uint8_t   dwelltime_mode;
+	uint8_t   lpf_weight;
+	uint8_t   passive_mon_intval;
+	uint8_t   wifi_act_threshold;
+};
+
 /**
  * struct csa_offload_params - CSA offload request parameters
  * @channel: channel

+ 1 - 0
core/mac/src/include/sir_params.h

@@ -609,6 +609,7 @@ typedef struct sSirMbMsgP2p {
 #define SIR_HAL_BPF_SET_INSTRUCTIONS_REQ    (SIR_HAL_ITC_MSG_TYPES_BEGIN + 342)
 
 #define SIR_HAL_SET_WISA_PARAMS             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 343)
+#define SIR_HAL_SET_ADAPT_DWELLTIME_PARAMS  (SIR_HAL_ITC_MSG_TYPES_BEGIN + 344)
 #define SIR_HAL_MSG_TYPES_END                (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
 
 /* CFG message types */

+ 4 - 0
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -1300,6 +1300,8 @@ static QDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac,
 	pScanOffloadReq->restTime = pScanReq->restTime;
 	pScanOffloadReq->min_rest_time = pScanReq->min_rest_time;
 	pScanOffloadReq->idle_time = pScanReq->idle_time;
+	pScanOffloadReq->scan_adaptive_dwell_mode =
+			pScanReq->scan_adaptive_dwell_mode;
 
 	/* for normal scan, the value for p2pScanType should be 0
 	   always */
@@ -1309,6 +1311,8 @@ static QDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac,
 	pScanOffloadReq->sessionId = pScanReq->sessionId;
 	pScanOffloadReq->scan_id = pScanReq->scan_id;
 	pScanOffloadReq->scan_requestor_id = USER_SCAN_REQUESTOR_ID;
+	pScanOffloadReq->scan_adaptive_dwell_mode =
+			pScanReq->scan_adaptive_dwell_mode;
 
 	if (pScanOffloadReq->sessionId >= pMac->lim.maxBssId)
 		lim_log(pMac, LOGE, FL("Invalid pe sessionID : %d"),

+ 4 - 0
core/sme/inc/csr_api.h

@@ -278,6 +278,7 @@ typedef struct tagCsrScanRequest {
 	uint32_t idle_time;
 	uint32_t uIEFieldLen;
 	uint8_t *pIEField;
+	enum wmi_dwelltime_adaptive_mode scan_adaptive_dwell_mode;
 	eCsrRequestType requestType; /* 11d scan or full scan */
 	bool p2pSearch;
 	bool skipDfsChnlInP2pSearch;
@@ -1203,6 +1204,7 @@ typedef struct tagCsrConfigParam {
 	bool pno_channel_prediction;
 	uint8_t top_k_num_of_channels;
 	uint8_t stationary_thresh;
+	enum wmi_dwelltime_adaptive_mode pnoscan_adaptive_dwell_mode;
 	uint32_t channel_prediction_full_scan;
 #endif
 	bool early_stop_scan_enable;
@@ -1244,6 +1246,8 @@ typedef struct tagCsrConfigParam {
 	uint32_t edca_bk_aifs;
 	uint32_t edca_be_aifs;
 	bool enable_fatal_event;
+	enum wmi_dwelltime_adaptive_mode scan_adaptive_dwell_mode;
+	enum wmi_dwelltime_adaptive_mode roamscan_adaptive_dwell_mode;
 } tCsrConfigParam;
 
 /* Tush */

+ 3 - 0
core/sme/inc/csr_internal.h

@@ -640,6 +640,7 @@ typedef struct tagCsrConfig {
 	bool pno_channel_prediction;
 	uint8_t top_k_num_of_channels;
 	uint8_t stationary_thresh;
+	enum wmi_dwelltime_adaptive_mode pnoscan_adaptive_dwell_mode;
 	uint32_t channel_prediction_full_scan;
 #endif
 	bool early_stop_scan_enable;
@@ -663,6 +664,8 @@ typedef struct tagCsrConfig {
 	uint32_t edca_bk_aifs;
 	uint32_t edca_be_aifs;
 	bool enable_fatal_event;
+	enum wmi_dwelltime_adaptive_mode scan_adaptive_dwell_mode;
+	enum wmi_dwelltime_adaptive_mode roamscan_adaptive_dwell_mode;
 } tCsrConfig;
 
 typedef struct tagCsrChannelPowerInfo {

+ 2 - 0
core/sme/inc/sme_api.h

@@ -1128,4 +1128,6 @@ QDF_STATUS sme_set_bpf_instructions(tHalHandle hal,
 				struct sir_bpf_set_offload *);
 
 QDF_STATUS sme_create_mon_session(tHalHandle hal_handle, uint8_t *bssid);
+QDF_STATUS sme_set_adaptive_dwelltime_config(tHalHandle hal,
+			struct adaptive_dwelltime_params *dwelltime_params);
 #endif /* #if !defined( __SME_API_H ) */

+ 45 - 0
core/sme/src/common/sme_api.c

@@ -7187,6 +7187,8 @@ void sme_update_roam_pno_channel_prediction_config(
 			csr_config->stationary_thresh;
 		mac_ctx->roam.configParam.channel_prediction_full_scan =
 			csr_config->channel_prediction_full_scan;
+		mac_ctx->roam.configParam.pnoscan_adaptive_dwell_mode =
+			csr_config->pnoscan_adaptive_dwell_mode;
 	} else if (copy_from_to == ROAM_CONFIG_TO_SME_CONFIG) {
 		csr_config->pno_channel_prediction =
 			mac_ctx->roam.configParam.pno_channel_prediction;
@@ -7196,6 +7198,8 @@ void sme_update_roam_pno_channel_prediction_config(
 			mac_ctx->roam.configParam.stationary_thresh;
 		csr_config->channel_prediction_full_scan =
 			mac_ctx->roam.configParam.channel_prediction_full_scan;
+		csr_config->pnoscan_adaptive_dwell_mode =
+			mac_ctx->roam.configParam.pnoscan_adaptive_dwell_mode;
 	}
 
 }
@@ -15765,3 +15769,44 @@ QDF_STATUS sme_create_mon_session(tHalHandle hal_handle, tSirMacAddr bss_id)
 	}
 	return status;
 }
+
+
+/**
+ * sme_set_adaptive_dwelltime_config() - Update Adaptive dwelltime configuration
+ * @hal: The handle returned by macOpen
+ * @params: adaptive_dwelltime_params config
+ *
+ * Return: QDF_STATUS if adaptive dwell time update
+ * configuration sucsess else failure status
+ */
+QDF_STATUS sme_set_adaptive_dwelltime_config(tHalHandle hal,
+			struct adaptive_dwelltime_params *params)
+{
+	cds_msg_t message;
+	QDF_STATUS status;
+	struct adaptive_dwelltime_params *dwelltime_params;
+
+	dwelltime_params = qdf_mem_malloc(sizeof(*dwelltime_params));
+	if (NULL == dwelltime_params) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: fail to alloc dwelltime_params", __func__);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	dwelltime_params->is_enabled = params->is_enabled;
+	dwelltime_params->dwelltime_mode = params->dwelltime_mode;
+	dwelltime_params->lpf_weight = params->lpf_weight;
+	dwelltime_params->passive_mon_intval = params->passive_mon_intval;
+	dwelltime_params->wifi_act_threshold = params->wifi_act_threshold;
+
+	message.type = WMA_SET_ADAPT_DWELLTIME_CONF_PARAMS;
+	message.bodyptr = dwelltime_params;
+	status = cds_mq_post_message(QDF_MODULE_ID_WMA, &message);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+			"%s: Not able to post msg to WMA!", __func__);
+
+		qdf_mem_free(dwelltime_params);
+	}
+	return status;
+}

+ 6 - 0
core/sme/src/common/sme_power_save.c

@@ -710,6 +710,8 @@ void sme_set_pno_channel_prediction(tpSirPNOScanReq request_buf,
 		mac_ctx->roam.configParam.stationary_thresh;
 	request_buf->channel_prediction_full_scan =
 		mac_ctx->roam.configParam.channel_prediction_full_scan;
+	request_buf->pnoscan_adaptive_dwell_mode =
+		mac_ctx->roam.configParam.pnoscan_adaptive_dwell_mode;
 	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
 			FL("channel_prediction: %d, top_k_num_of_channels: %d"),
 			request_buf->pno_channel_prediction,
@@ -799,6 +801,8 @@ QDF_STATUS sme_set_ps_preferred_network_list(tHalHandle hal_ctx,
 			mac_ctx->roam.configParam.nPassiveMaxChnTimeConc;
 		request_buf->passive_min_time =
 			mac_ctx->roam.configParam.nPassiveMinChnTimeConc;
+		request_buf->pnoscan_adaptive_dwell_mode =
+			mac_ctx->roam.configParam.pnoscan_adaptive_dwell_mode;
 	} else {
 		request_buf->active_max_time =
 			mac_ctx->roam.configParam.nActiveMaxChnTime;
@@ -808,6 +812,8 @@ QDF_STATUS sme_set_ps_preferred_network_list(tHalHandle hal_ctx,
 			mac_ctx->roam.configParam.nPassiveMaxChnTime;
 		request_buf->passive_min_time =
 			mac_ctx->roam.configParam.nPassiveMinChnTime;
+		request_buf->pnoscan_adaptive_dwell_mode =
+			mac_ctx->roam.configParam.pnoscan_adaptive_dwell_mode;
 	}
 
 	msg.type = WMA_SET_PNO_REQ;

+ 11 - 0
core/sme/src/csr/csr_api_roam.c

@@ -2338,6 +2338,11 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac,
 		pMac->roam.configParam.roam_params.traffic_threshold =
 			pParam->roam_dense_traffic_thresh;
 
+		pMac->roam.configParam.scan_adaptive_dwell_mode =
+			pParam->scan_adaptive_dwell_mode;
+		pMac->roam.configParam.roamscan_adaptive_dwell_mode =
+			pParam->roamscan_adaptive_dwell_mode;
+
 		/* update p2p offload status */
 		pMac->pnoOffload = pParam->pnoOffload;
 
@@ -2534,6 +2539,10 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
 	pParam->roam_dense_traffic_thresh =
 			cfg_params->roam_params.traffic_threshold;
 
+	pParam->scan_adaptive_dwell_mode =
+			cfg_params->scan_adaptive_dwell_mode;
+	pParam->roamscan_adaptive_dwell_mode =
+			cfg_params->roamscan_adaptive_dwell_mode;
 	pParam->conc_custom_rule1 = cfg_params->conc_custom_rule1;
 	pParam->conc_custom_rule2 = cfg_params->conc_custom_rule2;
 	pParam->is_sta_connection_in_5gz_enabled =
@@ -16699,6 +16708,8 @@ csr_create_roam_scan_offload_request(tpAniSirGlobal mac_ctx,
 		  req_buf->early_stop_scan_enable,
 		  req_buf->early_stop_scan_min_threshold,
 		  req_buf->early_stop_scan_max_threshold);
+	req_buf->roamscan_adaptive_dwell_mode =
+		mac_ctx->roam.configParam.roamscan_adaptive_dwell_mode;
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 	req_buf->RoamOffloadEnabled = csr_roamIsRoamOffloadEnabled(mac_ctx);
 	req_buf->RoamKeyMgmtOffloadEnabled = session->RoamKeyMgmtOffloadEnabled;

+ 2 - 0
core/sme/src/csr/csr_api_scan.c

@@ -604,6 +604,7 @@ QDF_STATUS csr_scan_request(tpAniSirGlobal pMac, uint16_t sessionId,
 		sms_log(pMac, LOG1, FL("updating dwell time for first scan %u"),
 			scan_req->maxChnTime);
 	}
+	scan_req->scan_adaptive_dwell_mode = cfg_prm->scan_adaptive_dwell_mode;
 
 	status = csr_scan_copy_request(pMac, &scan_cmd->u.scanCmd.u.scanRequest,
 				       scan_req);
@@ -4999,6 +5000,7 @@ QDF_STATUS csr_send_mb_scan_req(tpAniSirGlobal pMac, uint16_t sessionId,
 		}
 	}
 	pMsg->scanType = scanType;
+	pMsg->scan_adaptive_dwell_mode = pScanReq->scan_adaptive_dwell_mode;
 
 	pMsg->numSsid = (pScanReq->SSIDs.numOfSSIDs < SIR_SCAN_MAX_NUM_SSID) ?
 			 pScanReq->SSIDs.numOfSSIDs : SIR_SCAN_MAX_NUM_SSID;

+ 2 - 0
core/wma/inc/wma_api.h

@@ -231,6 +231,8 @@ QDF_STATUS wma_remove_beacon_filter(WMA_HANDLE wma,
 
 QDF_STATUS wma_add_beacon_filter(WMA_HANDLE wma,
 				struct beacon_filter_param *filter_params);
+QDF_STATUS wma_send_adapt_dwelltime_params(WMA_HANDLE handle,
+			struct adaptive_dwelltime_params *dwelltime_params);
 #ifdef FEATURE_GREEN_AP
 void wma_setup_egap_support(struct wma_tgt_cfg *tgt_cfg, WMA_HANDLE handle);
 void wma_register_egap_event_handle(WMA_HANDLE handle);

+ 1 - 0
core/wma/inc/wma_types.h

@@ -468,6 +468,7 @@
 #define WMA_SET_EGAP_CONF_PARAMS             SIR_HAL_SET_EGAP_CONF_PARAMS
 #define WMA_ADD_BCN_FILTER_CMDID             SIR_HAL_ADD_BCN_FILTER_CMDID
 #define WMA_REMOVE_BCN_FILTER_CMDID          SIR_HAL_REMOVE_BCN_FILTER_CMDID
+#define WMA_SET_ADAPT_DWELLTIME_CONF_PARAMS  SIR_HAL_SET_ADAPT_DWELLTIME_PARAMS
 
 #define WDA_BPF_GET_CAPABILITIES_REQ          SIR_HAL_BPF_GET_CAPABILITIES_REQ
 #define WDA_BPF_SET_INSTRUCTIONS_REQ          SIR_HAL_BPF_SET_INSTRUCTIONS_REQ

+ 27 - 0
core/wma/src/wma_features.c

@@ -1174,6 +1174,33 @@ QDF_STATUS wma_remove_beacon_filter(WMA_HANDLE handle,
 	return QDF_STATUS_SUCCESS;
 }
 
+/**
+ * wma_send_adapt_dwelltime_params() - send adaptive dwelltime configuration
+ * params to firmware
+ * @wma_handle:	 wma handler
+ * @dwelltime_params: pointer to dwelltime_params
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF failure reason code for failure
+ */
+QDF_STATUS wma_send_adapt_dwelltime_params(WMA_HANDLE handle,
+			struct adaptive_dwelltime_params *dwelltime_params)
+{
+	tp_wma_handle wma_handle = (tp_wma_handle) handle;
+	struct wmi_adaptive_dwelltime_params wmi_param = {0};
+	int32_t err;
+
+	wmi_param.is_enabled = dwelltime_params->is_enabled;
+	wmi_param.dwelltime_mode = dwelltime_params->dwelltime_mode;
+	wmi_param.lpf_weight = dwelltime_params->lpf_weight;
+	wmi_param.passive_mon_intval = dwelltime_params->passive_mon_intval;
+	wmi_param.wifi_act_threshold = dwelltime_params->wifi_act_threshold;
+	err = wmi_unified_send_adapt_dwelltime_params_cmd(wma_handle->
+					wmi_handle, &wmi_param);
+	if (err)
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
 
 #ifdef FEATURE_GREEN_AP
 

+ 5 - 0
core/wma/src/wma_main.c

@@ -5316,6 +5316,11 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg)
 			(struct egap_conf_params *)msg->bodyptr);
 		qdf_mem_free(msg->bodyptr);
 		break;
+	case WMA_SET_ADAPT_DWELLTIME_CONF_PARAMS:
+		wma_send_adapt_dwelltime_params(wma_handle,
+			(struct adaptive_dwelltime_params *)msg->bodyptr);
+		qdf_mem_free(msg->bodyptr);
+		break;
 	case WMA_HT40_OBSS_SCAN_IND:
 		wma_send_ht40_obss_scanind(wma_handle,
 			(struct obss_ht40_scanind *)msg->bodyptr);

+ 10 - 0
core/wma/src/wma_scan_roam.c

@@ -267,6 +267,9 @@ QDF_STATUS wma_get_buf_start_scan_cmd(tp_wma_handle wma_handle,
 	else
 		WMA_LOGD("OFDM_RATES not included in 11B mode");
 
+	WMI_SCAN_SET_DWELL_MODE(cmd->scan_ctrl_flags,
+			scan_req->scan_adaptive_dwell_mode);
+
 	/* Do not combine multiple channels in a single burst. Come back
 	 * to home channel for data traffic after every foreign channel.
 	 * By default, prefer throughput performance over scan cycle time.
@@ -1273,6 +1276,9 @@ void wma_roam_scan_fill_scan_params(tp_wma_handle wma_handle,
 					WMI_SCAN_FLAG_FORCE_ACTIVE_ON_DFS;
 			}
 		}
+		WMI_SCAN_SET_DWELL_MODE(scan_params->scan_ctrl_flags,
+				roam_req->roamscan_adaptive_dwell_mode);
+
 	} else {
 		/* roam_req = NULL during initial or pre-assoc invocation */
 		scan_params->dwell_time_active =
@@ -2754,6 +2760,7 @@ QDF_STATUS wma_pno_start(tp_wma_handle wma, tpSirPNOScanReq pno)
 	params->active_max_time = pno->active_max_time;
 	params->passive_min_time = pno->passive_min_time;
 	params->passive_max_time = pno->passive_max_time;
+	params->pnoscan_adaptive_dwell_mode = pno->pnoscan_adaptive_dwell_mode;
 #ifdef FEATURE_WLAN_SCAN_PNO
 	params->pno_channel_prediction = pno->pno_channel_prediction;
 	params->top_k_num_of_channels = pno->top_k_num_of_channels;
@@ -4464,6 +4471,7 @@ QDF_STATUS wma_get_buf_extscan_start_cmd(tp_wma_handle wma_handle,
 			       WMI_SCAN_ADD_OFDM_RATES |
 			       WMI_SCAN_ADD_SPOOFED_MAC_IN_PROBE_REQ |
 			       WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ;
+
 	cmd->scan_priority = WMI_SCAN_PRIORITY_HIGH;
 	cmd->num_ssids = 0;
 	cmd->num_bssid = 0;
@@ -4622,6 +4630,8 @@ QDF_STATUS wma_start_extscan(tp_wma_handle wma,
 	params->max_dwell_time_active = pstart->max_dwell_time_active;
 	params->max_dwell_time_passive = pstart->max_dwell_time_passive;
 	params->configuration_flags = pstart->configuration_flags;
+	params->extscan_adaptive_dwell_mode =
+			pstart->extscan_adaptive_dwell_mode;
 	for (i = 0; i < WMI_WLAN_EXTSCAN_MAX_BUCKETS; i++) {
 		params->buckets[i].bucket = pstart->buckets[i].bucket;
 		params->buckets[i].band =