diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index 5375635c7c70..07f28b07388b 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -10456,6 +10456,70 @@ enum hdd_external_acs_freq_band {
#define CFG_ITO_REPEAT_COUNT_MIN (0)
#define CFG_ITO_REPEAT_COUNT_MAX (5)
#define CFG_ITO_REPEAT_COUNT_DEFAULT (0)
+/*
+ *
+ * groam_disallow_duration -disallow duration before roaming
+ * @Min: 0
+ * @Max: 3600
+ * @Default: 30
+ *
+ * This ini is used to configure how long LCA[Last Connected AP] AP will
+ * be disallowed before it can be a roaming candidate again, in units of
+ * seconds.
+ *
+ * Related: LFR
+ *
+ * Usage: Internal
+ *
+ *
+ */
+#define CFG_ROAM_DISALLOW_DURATION_NAME "groam_disallow_duration"
+#define CFG_ROAM_DISALLOW_DURATION_MIN (0)
+#define CFG_ROAM_DISALLOW_DURATION_MAX (3600)
+#define CFG_ROAM_DISALLOW_DURATION_DEFAULT (30)
+
+/*
+ *
+ * grssi_channel_penalization - RSSI penalization
+ * @Min: 0
+ * @Max: 15
+ * @Default: 5
+ *
+ * This ini is used to configure RSSI that will be penalized if candidate(s)
+ * are found to be in the same channel as disallowed AP's, in units of db.
+ *
+ * Related: LFR
+ *
+ * Usage: Internal
+ *
+ *
+ */
+#define CFG_ROAM_RSSI_CHANNEL_PENALIZATION_NAME "grssi_channel_penalization"
+#define CFG_ROAM_RSSI_CHANNEL_PENALIZATION_MIN (0)
+#define CFG_ROAM_RSSI_CHANNEL_PENALIZATION_MAX (15)
+#define CFG_ROAM_RSSI_CHANNEL_PENALIZATION_DEFAULT (5)
+
+/*
+ *
+ * groam_num_disallowed_aps - Max number of AP's to maintain in LCA list
+ * @Min: 0
+ * @Max: 8
+ * @Default: 3
+ *
+ * This ini is used to set the maximum number of AP's to be maintained
+ * in LCA [Last Connected AP] list.
+ *
+ * Related: LFR
+ *
+ * Usage: Internal
+ *
+ *
+ */
+#define CFG_ROAM_NUM_DISALLOWED_APS_NAME "groam_num_disallowed_aps"
+#define CFG_ROAM_NUM_DISALLOWED_APS_MIN (0)
+#define CFG_ROAM_NUM_DISALLOWED_APS_MAX (8)
+#define CFG_ROAM_NUM_DISALLOWED_APS_DEFAULT (3)
+
/*
* Type declarations
*/
@@ -11200,6 +11264,11 @@ struct hdd_config {
uint16_t num_11b_tx_chains;
uint16_t num_11ag_tx_chains;
uint8_t ito_repeat_count;
+
+ /* LCA(Last connected AP) disallow configs */
+ uint32_t disallow_duration;
+ uint32_t rssi_channel_penalization;
+ uint32_t num_disallowed_aps;
};
#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 e84b0c9691e7..6e69b7206480 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -4463,6 +4463,27 @@ struct reg_table_entry g_registry_table[] = {
CFG_ITO_REPEAT_COUNT_MIN,
CFG_ITO_REPEAT_COUNT_MAX),
+ REG_VARIABLE(CFG_ROAM_DISALLOW_DURATION_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, disallow_duration,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_ROAM_DISALLOW_DURATION_DEFAULT,
+ CFG_ROAM_DISALLOW_DURATION_MIN,
+ CFG_ROAM_DISALLOW_DURATION_MAX),
+
+ REG_VARIABLE(CFG_ROAM_RSSI_CHANNEL_PENALIZATION_NAME,
+ WLAN_PARAM_Integer, struct hdd_config,
+ rssi_channel_penalization,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_ROAM_RSSI_CHANNEL_PENALIZATION_DEFAULT,
+ CFG_ROAM_RSSI_CHANNEL_PENALIZATION_MIN,
+ CFG_ROAM_RSSI_CHANNEL_PENALIZATION_MAX),
+
+ REG_VARIABLE(CFG_ROAM_NUM_DISALLOWED_APS_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, num_disallowed_aps,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_ROAM_NUM_DISALLOWED_APS_DEFAULT,
+ CFG_ROAM_NUM_DISALLOWED_APS_MIN,
+ CFG_ROAM_NUM_DISALLOWED_APS_MAX),
};
@@ -6004,6 +6025,15 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
hdd_debug("Name = [%s] value = [%u]",
CFG_ITO_REPEAT_COUNT_NAME,
pHddCtx->config->ito_repeat_count);
+ hdd_debug("Name = [%s] Value = [%u]",
+ CFG_ROAM_DISALLOW_DURATION_NAME,
+ pHddCtx->config->disallow_duration);
+ hdd_debug("Name = [%s] Value = [%u]",
+ CFG_ROAM_RSSI_CHANNEL_PENALIZATION_NAME,
+ pHddCtx->config->rssi_channel_penalization);
+ hdd_debug("Name = [%s] Value = [%u]",
+ CFG_ROAM_NUM_DISALLOWED_APS_NAME,
+ pHddCtx->config->num_disallowed_aps);
}
@@ -7626,6 +7656,13 @@ QDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx)
smeConfig->csrConfig.pkt_err_disconn_th =
pHddCtx->config->pkt_err_disconn_th;
+ smeConfig->csrConfig.disallow_duration =
+ pHddCtx->config->disallow_duration;
+ smeConfig->csrConfig.rssi_channel_penalization =
+ pHddCtx->config->rssi_channel_penalization;
+ smeConfig->csrConfig.num_disallowed_aps =
+ pHddCtx->config->num_disallowed_aps;
+
smeConfig->csrConfig.is_force_1x1 =
pHddCtx->config->is_force_1x1;
smeConfig->csrConfig.num_11b_tx_chains =
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index bfe2ce0a94f7..1dc99e34558b 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -2983,6 +2983,20 @@ struct pmkid_mode_bits {
uint32_t unused:30;
};
+/**
+ * struct lca_disallow_config_params - LCA[Last Connected AP]
+ * disallow config params
+ * @disallow_duration: LCA AP disallowed duration
+ * @rssi_channel_penalization: RSSI channel Penalization
+ * @num_disallowed_aps: Maximum number of AP's in LCA list
+ *
+ */
+struct lca_disallow_config_params{
+ uint32_t disallow_duration;
+ uint32_t rssi_channel_penalization;
+ uint32_t num_disallowed_aps;
+};
+
typedef struct sSirRoamOffloadScanReq {
uint16_t message_type;
uint16_t length;
@@ -3040,6 +3054,7 @@ typedef struct sSirRoamOffloadScanReq {
int8_t early_stop_scan_max_threshold;
enum wmi_dwelltime_adaptive_mode roamscan_adaptive_dwell_mode;
tSirAddie assoc_ie;
+ struct lca_disallow_config_params lca_config_params;
} tSirRoamOffloadScanReq, *tpSirRoamOffloadScanReq;
typedef struct sSirRoamOffloadScanRsp {
diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h
index 837a4e39b79e..14eb6e80e8a3 100644
--- a/core/sme/inc/csr_api.h
+++ b/core/sme/inc/csr_api.h
@@ -1319,6 +1319,9 @@ typedef struct tagCsrConfigParam {
bool is_force_1x1;
uint16_t num_11b_tx_chains;
uint16_t num_11ag_tx_chains;
+ uint32_t disallow_duration;
+ uint32_t rssi_channel_penalization;
+ uint32_t num_disallowed_aps;
} tCsrConfigParam;
/* Tush */
diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h
index e4ee1c6ac2f5..f0edfd7305dc 100644
--- a/core/sme/inc/csr_internal.h
+++ b/core/sme/inc/csr_internal.h
@@ -624,6 +624,9 @@ typedef struct tagCsrConfig {
bool is_force_1x1;
uint16_t num_11b_tx_chains;
uint16_t num_11ag_tx_chains;
+ uint32_t disallow_duration;
+ uint32_t rssi_channel_penalization;
+ uint32_t num_disallowed_aps;
} tCsrConfig;
typedef struct tagCsrChannelPowerInfo {
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index 77d89deb2c20..34e6256b8413 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -2788,6 +2788,12 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac,
pParam->qcn_ie_support;
pMac->roam.configParam.fils_max_chan_guard_time =
pParam->fils_max_chan_guard_time;
+ pMac->roam.configParam.disallow_duration =
+ pParam->disallow_duration;
+ pMac->roam.configParam.rssi_channel_penalization =
+ pParam->rssi_channel_penalization;
+ pMac->roam.configParam.num_disallowed_aps =
+ pParam->num_disallowed_aps;
csr_update_he_config_param(pMac, pParam);
}
@@ -3027,6 +3033,12 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
pMac->roam.configParam.qcn_ie_support;
pParam->fils_max_chan_guard_time =
pMac->roam.configParam.fils_max_chan_guard_time;
+ pParam->disallow_duration =
+ pMac->roam.configParam.disallow_duration;
+ pParam->rssi_channel_penalization =
+ pMac->roam.configParam.rssi_channel_penalization;
+ pParam->num_disallowed_aps =
+ pMac->roam.configParam.num_disallowed_aps;
csr_get_he_config_param(pParam, pMac);
@@ -17211,15 +17223,26 @@ csr_create_roam_scan_offload_request(tpAniSirGlobal mac_ctx,
mac_ctx->roam.configParam.early_stop_scan_min_threshold;
req_buf->early_stop_scan_max_threshold =
mac_ctx->roam.configParam.early_stop_scan_max_threshold;
- QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
- FL("HomeAwayTime=%d EarlyStopFeature Enable=%d, MinThresh=%d, MaxThresh=%d PMK len=%d"),
- req_buf->HomeAwayTime, req_buf->early_stop_scan_enable,
- req_buf->early_stop_scan_min_threshold,
- req_buf->early_stop_scan_max_threshold,
- req_buf->pmk_len);
req_buf->roamscan_adaptive_dwell_mode =
mac_ctx->roam.configParam.roamscan_adaptive_dwell_mode;
+ req_buf->lca_config_params.disallow_duration =
+ mac_ctx->roam.configParam.disallow_duration;
+ req_buf->lca_config_params.rssi_channel_penalization =
+ mac_ctx->roam.configParam.rssi_channel_penalization;
+ req_buf->lca_config_params.num_disallowed_aps =
+ mac_ctx->roam.configParam.num_disallowed_aps;
+
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+ FL("HomeAwayTime=%d EarlyStopFeature Enable=%d, MinThresh=%d, MaxThresh=%d PMK len=%d disallow_dur=%d rssi_chan_pen=%d num_disallowed_aps=%d"),
+ req_buf->HomeAwayTime,
+ req_buf->early_stop_scan_enable,
+ req_buf->early_stop_scan_min_threshold,
+ req_buf->early_stop_scan_max_threshold,
+ req_buf->pmk_len,
+ req_buf->lca_config_params.disallow_duration,
+ req_buf->lca_config_params.rssi_channel_penalization,
+ req_buf->lca_config_params.num_disallowed_aps);
req_buf->RoamOffloadEnabled = csr_roamIsRoamOffloadEnabled(mac_ctx);
req_buf->RoamKeyMgmtOffloadEnabled = session->RoamKeyMgmtOffloadEnabled;
req_buf->pmkid_modes = session->pmkid_modes;
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index ce4fb7e60f7a..65276c1cf9ec 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -1582,6 +1582,7 @@ static QDF_STATUS wma_roam_scan_filter(tp_wma_handle wma_handle,
uint32_t op_bitmap = 0;
struct roam_ext_params *roam_params;
struct roam_scan_filter_params *params;
+ struct lca_disallow_config_params *lca_config_params;
params = qdf_mem_malloc(sizeof(struct roam_scan_filter_params));
if (params == NULL) {
@@ -1590,6 +1591,7 @@ static QDF_STATUS wma_roam_scan_filter(tp_wma_handle wma_handle,
}
roam_params = &roam_req->roam_params;
+ lca_config_params = &roam_req->lca_config_params;
if (roam_req->Command != ROAM_SCAN_OFFLOAD_STOP) {
switch (roam_req->reason) {
case REASON_ROAM_SET_BLACKLIST_BSSID:
@@ -1607,6 +1609,16 @@ static QDF_STATUS wma_roam_scan_filter(tp_wma_handle wma_handle,
num_bssid_preferred_list =
roam_params->num_bssid_favored;
break;
+ case REASON_CTX_INIT:
+ if (roam_req->Command == ROAM_SCAN_OFFLOAD_START) {
+ params->lca_disallow_config_present = true;
+ op_bitmap |= ROAM_FILTER_OP_BITMAP_LCA_DISALLOW;
+ } else {
+ WMA_LOGD("%s : Roam Filter need not be sent", __func__);
+ qdf_mem_free(params);
+ return QDF_STATUS_SUCCESS;
+ }
+ break;
default:
WMA_LOGD("%s : Roam Filter need not be sent", __func__);
qdf_mem_free(params);
@@ -1648,6 +1660,14 @@ static QDF_STATUS wma_roam_scan_filter(tp_wma_handle wma_handle,
qdf_mem_copy(params->bssid_favored_factor,
roam_params->bssid_favored_factor, MAX_BSSID_FAVORED);
+ if (params->lca_disallow_config_present) {
+ params->disallow_duration
+ = lca_config_params->disallow_duration;
+ params->rssi_channel_penalization
+ = lca_config_params->rssi_channel_penalization;
+ params->num_disallowed_aps
+ = lca_config_params->num_disallowed_aps;
+ }
status = wmi_unified_roam_scan_filter_cmd(wma_handle->wmi_handle,
params);