diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index 63398c7e656b..cf67ee2f81d3 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -1584,6 +1584,29 @@ enum hdd_dot11_mode {
#define CFG_ROAM_RSSI_DIFF_MAX (30)
#define CFG_ROAM_RSSI_DIFF_DEFAULT (5)
+/*
+ *
+ * rssi_abs_thresh - The min RSSI of the candidate AP to consider roam
+ * @Min: -96
+ * @Max: 0
+ * @Default: 0
+ *
+ * The RSSI value of the candidate AP should be higher than rssi_abs_thresh
+ * to roam to the AP. 0 means no absolute minimum RSSI is required.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ *
+ */
+#define CFG_ROAM_RSSI_ABS_THRESHOLD_NAME "rssi_abs_thresh"
+#define CFG_ROAM_RSSI_ABS_THRESHOLD_MIN (-96)
+#define CFG_ROAM_RSSI_ABS_THRESHOLD_MAX (0)
+#define CFG_ROAM_RSSI_ABS_THRESHOLD_DEFAULT (0)
+
/*
*
* gRoamScanNProbes - Sets the number of probes to be sent for firmware roaming
@@ -13651,6 +13674,7 @@ struct hdd_config {
#endif
bool isFastTransitionEnabled;
uint8_t RoamRssiDiff;
+ int32_t rssi_abs_thresh;
bool isWESModeEnabled;
uint32_t pmkid_modes;
bool isRoamOffloadScanEnabled;
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index d82d5c064b47..b6838767bae6 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -1116,6 +1116,13 @@ struct reg_table_entry g_registry_table[] = {
CFG_ROAM_RSSI_DIFF_MAX,
cb_notify_set_roam_rssi_diff, 0),
+ REG_VARIABLE(CFG_ROAM_RSSI_ABS_THRESHOLD_NAME, WLAN_PARAM_SignedInteger,
+ struct hdd_config, rssi_abs_thresh,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_ROAM_RSSI_ABS_THRESHOLD_DEFAULT,
+ CFG_ROAM_RSSI_ABS_THRESHOLD_MIN,
+ CFG_ROAM_RSSI_ABS_THRESHOLD_MAX),
+
REG_DYNAMIC_VARIABLE(CFG_ENABLE_WES_MODE_NAME, WLAN_PARAM_Integer,
struct hdd_config, isWESModeEnabled,
VAR_FLAGS_OPTIONAL |
@@ -6276,6 +6283,8 @@ void hdd_cfg_print(struct hdd_context *hdd_ctx)
hdd_mawc_cfg_log(hdd_ctx);
hdd_debug("Name = [RoamRssiDiff] Value = [%u] ",
hdd_ctx->config->RoamRssiDiff);
+ hdd_debug("Name = [%s] Value = [%u] ", CFG_ROAM_RSSI_ABS_THRESHOLD_NAME,
+ hdd_ctx->config->rssi_abs_thresh);
hdd_debug("Name = [isWESModeEnabled] Value = [%u] ",
hdd_ctx->config->isWESModeEnabled);
hdd_debug("Name = [pmkidModes] Value = [0x%x] ",
@@ -8646,6 +8655,7 @@ QDF_STATUS hdd_set_sme_config(struct hdd_context *hdd_ctx)
smeConfig->csrConfig.isFastTransitionEnabled =
pConfig->isFastTransitionEnabled;
smeConfig->csrConfig.RoamRssiDiff = pConfig->RoamRssiDiff;
+ smeConfig->csrConfig.rssi_abs_thresh = pConfig->rssi_abs_thresh;
smeConfig->csrConfig.isWESModeEnabled = pConfig->isWESModeEnabled;
smeConfig->csrConfig.isRoamOffloadScanEnabled =
pConfig->isRoamOffloadScanEnabled;
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 3c041f586141..a08a4ff649b5 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -3213,6 +3213,7 @@ typedef struct sSirRoamOffloadScanReq {
uint8_t OpportunisticScanThresholdDiff;
uint8_t RoamRescanRssiDiff;
uint8_t RoamRssiDiff;
+ int32_t rssi_abs_thresh;
uint8_t ChannelCacheType;
uint8_t Command;
uint8_t reason;
diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h
index 075513fa2246..20f64a80e752 100644
--- a/core/sme/inc/csr_api.h
+++ b/core/sme/inc/csr_api.h
@@ -1212,6 +1212,7 @@ typedef struct tagCsrConfigParam {
struct mawc_params csr_mawc_config;
uint8_t isFastTransitionEnabled;
uint8_t RoamRssiDiff;
+ int32_t rssi_abs_thresh;
bool isWESModeEnabled;
tCsrNeighborRoamConfigParams neighborRoamConfig;
/*
diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h
index beb18a1d2cca..6c1c5dd2c74f 100644
--- a/core/sme/inc/csr_internal.h
+++ b/core/sme/inc/csr_internal.h
@@ -532,6 +532,7 @@ struct csr_config {
#endif
uint8_t isFastTransitionEnabled;
uint8_t RoamRssiDiff;
+ int32_t rssi_abs_thresh;
bool nRoamPrefer5GHz;
bool nRoamIntraBand;
bool isWESModeEnabled;
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index 8d7b51b4bc14..d76acc6c6340 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -2657,6 +2657,8 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac,
pMac->roam.configParam.isFastTransitionEnabled =
pParam->isFastTransitionEnabled;
pMac->roam.configParam.RoamRssiDiff = pParam->RoamRssiDiff;
+ pMac->roam.configParam.rssi_abs_thresh =
+ pParam->rssi_abs_thresh;
pMac->roam.configParam.nRoamPrefer5GHz =
pParam->nRoamPrefer5GHz;
pMac->roam.configParam.nRoamIntraBand = pParam->nRoamIntraBand;
@@ -3030,6 +3032,7 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
sizeof(tCsr11rConfigParams));
pParam->isFastTransitionEnabled = cfg_params->isFastTransitionEnabled;
pParam->RoamRssiDiff = cfg_params->RoamRssiDiff;
+ pParam->rssi_abs_thresh = cfg_params->rssi_abs_thresh;
pParam->nRoamPrefer5GHz = cfg_params->nRoamPrefer5GHz;
pParam->nRoamIntraBand = cfg_params->nRoamIntraBand;
pParam->isWESModeEnabled = cfg_params->isWESModeEnabled;
@@ -17775,6 +17778,7 @@ csr_create_roam_scan_offload_request(tpAniSirGlobal mac_ctx,
req_buf->RoamRescanRssiDiff =
roam_info->cfgParams.nRoamRescanRssiDiff;
req_buf->RoamRssiDiff = mac_ctx->roam.configParam.RoamRssiDiff;
+ req_buf->rssi_abs_thresh = mac_ctx->roam.configParam.rssi_abs_thresh;
req_buf->reason = reason;
req_buf->NeighborScanTimerPeriod =
roam_info->cfgParams.neighborScanPeriod;
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index 792c24580d0e..aeeec582ec07 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -1316,6 +1316,10 @@ static void wma_roam_scan_fill_ap_profile(tSirRoamOffloadScanReq *roam_req,
profile->rsn_mcastmgmtcipherset =
profile->rsn_mcastcipherset;
profile->rssi_threshold = roam_req->RoamRssiDiff;
+ if (roam_req->rssi_abs_thresh)
+ profile->rssi_abs_thresh =
+ roam_req->rssi_abs_thresh -
+ WMA_NOISE_FLOOR_DBM_DEFAULT;
#ifdef WLAN_FEATURE_11W
if (roam_req->ConnectedNetwork.mfp_enabled)
profile->flags |= WMI_AP_PROFILE_FLAG_PMF;