diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index 60ea427ab4bb..7356586be11e 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -2155,6 +2155,31 @@ enum hdd_dot11_mode {
#define CFG_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G_MAX (86)
#define CFG_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G_DEFAULT (40)
+/*
+ *
+ * ho_delay_for_rx - Delay Hand-off (In msec) by this duration to receive
+ * pending rx frames from current BSS
+ * @Min: 0
+ * @Max: 200
+ * @Default: 0
+ *
+ * For LFR 3.0 roaming scenario, once roam candidate is found, firmware
+ * waits for minimum this much duration to receive pending rx frames from
+ * current BSS before switching to new channel for handoff to new AP.
+ *
+ * Related: None
+ *
+ * Supported Feature: Roaming
+ *
+ * Usage: External
+ *
+ *
+ */
+#define CFG_ROAM_HO_DELAY_FOR_RX_NAME "ho_delay_for_rx"
+#define CFG_ROAM_HO_DELAY_FOR_RX_MIN (0)
+#define CFG_ROAM_HO_DELAY_FOR_RX_MAX (200)
+#define CFG_ROAM_HO_DELAY_FOR_RX_DEFAULT (0)
+
/*
*
* roamscan_adaptive_dwell_mode - Sets dwell time adaptive mode
@@ -14521,6 +14546,7 @@ struct hdd_config {
uint32_t roam_dense_min_aps;
int8_t roam_bg_scan_bad_rssi_thresh;
uint8_t roam_bad_rssi_thresh_offset_2g;
+ uint32_t ho_delay_for_rx;
uint32_t roam_bg_scan_client_bitmap;
bool enable_edca_params;
uint32_t edca_vo_cwmin;
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index 0ba8b0ecc0e8..c1ae8fb4aa59 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -3860,6 +3860,14 @@ struct reg_table_entry g_registry_table[] = {
CFG_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G_MIN,
CFG_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G_MAX),
+ REG_VARIABLE(CFG_ROAM_HO_DELAY_FOR_RX_NAME,
+ WLAN_PARAM_Integer, struct hdd_config,
+ ho_delay_for_rx,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_ROAM_HO_DELAY_FOR_RX_DEFAULT,
+ CFG_ROAM_HO_DELAY_FOR_RX_MIN,
+ CFG_ROAM_HO_DELAY_FOR_RX_MAX),
+
REG_VARIABLE(CFG_ENABLE_FATAL_EVENT_TRIGGER, WLAN_PARAM_Integer,
struct hdd_config, enable_fatal_event,
VAR_FLAGS_OPTIONAL |
@@ -6842,6 +6850,9 @@ void hdd_cfg_print(struct hdd_context *hdd_ctx)
hdd_debug("Name = [%s] Value = [%u]",
CFG_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G_NAME,
hdd_ctx->config->roam_bad_rssi_thresh_offset_2g);
+ hdd_debug("Name = [%s] Value = [%u]",
+ CFG_ROAM_HO_DELAY_FOR_RX_NAME,
+ hdd_ctx->config->ho_delay_for_rx);
hdd_debug("Name = [%s] Value = [%u]",
CFG_MIN_REST_TIME_NAME,
hdd_ctx->config->min_rest_time_conc);
@@ -8796,6 +8807,8 @@ QDF_STATUS hdd_set_sme_config(struct hdd_context *hdd_ctx)
hdd_ctx->config->roam_bg_scan_client_bitmap;
smeConfig->csrConfig.roam_bad_rssi_thresh_offset_2g =
hdd_ctx->config->roam_bad_rssi_thresh_offset_2g;
+ smeConfig->csrConfig.ho_delay_for_rx =
+ hdd_ctx->config->ho_delay_for_rx;
smeConfig->csrConfig.obss_width_interval =
hdd_ctx->config->obss_width_trigger_interval;
smeConfig->csrConfig.obss_active_dwelltime =
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 2bb54e6e6ae2..ae6d226996ee 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -2941,6 +2941,7 @@ typedef struct sSirRoamOffloadScanReq {
uint32_t btm_max_attempt_cnt;
uint32_t btm_sticky_time;
struct wmi_11k_offload_params offload_11k_params;
+ uint32_t ho_delay_for_rx;
} tSirRoamOffloadScanReq, *tpSirRoamOffloadScanReq;
typedef struct sSirRoamOffloadScanRsp {
diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h
index 1bad3a459ca0..ec8dc9672612 100644
--- a/core/sme/inc/csr_api.h
+++ b/core/sme/inc/csr_api.h
@@ -1211,6 +1211,7 @@ typedef struct tagCsrConfigParam {
bool enable_vht20_mcs9;
uint8_t max_amsdu_num;
uint8_t nSelect5GHzMargin;
+ uint32_t ho_delay_for_rx;
uint8_t isCoalesingInIBSSAllowed;
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
uint8_t cc_switch_mode;
diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h
index 11b357acc44e..011cefaa5807 100644
--- a/core/sme/inc/csr_internal.h
+++ b/core/sme/inc/csr_internal.h
@@ -537,6 +537,7 @@ struct csr_config {
bool enableHeartBeatOffload;
uint8_t max_amsdu_num;
uint8_t nSelect5GHzMargin;
+ uint32_t ho_delay_for_rx;
uint8_t isCoalesingInIBSSAllowed;
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
uint8_t cc_switch_mode;
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index b98c07c4882f..1ed3754393b4 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -2938,6 +2938,8 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac,
pParam->max_amsdu_num;
pMac->roam.configParam.nSelect5GHzMargin =
pParam->nSelect5GHzMargin;
+ pMac->roam.configParam.ho_delay_for_rx =
+ pParam->ho_delay_for_rx;
pMac->roam.configParam.isCoalesingInIBSSAllowed =
pParam->isCoalesingInIBSSAllowed;
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
@@ -3279,6 +3281,7 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
pParam->disable_high_ht_mcs_2x2 = cfg_params->disable_high_ht_mcs_2x2;
pParam->max_amsdu_num = cfg_params->max_amsdu_num;
pParam->nSelect5GHzMargin = cfg_params->nSelect5GHzMargin;
+ pParam->ho_delay_for_rx = cfg_params->ho_delay_for_rx;
pParam->isCoalesingInIBSSAllowed = cfg_params->isCoalesingInIBSSAllowed;
pParam->allowDFSChannelRoam = cfg_params->allowDFSChannelRoam;
pParam->nInitialDwellTime = cfg_params->nInitialDwellTime;
@@ -17792,6 +17795,7 @@ csr_update_roam_scan_offload_request(tpAniSirGlobal mac_ctx,
req_buf->Prefer5GHz = mac_ctx->roam.configParam.nRoamPrefer5GHz;
req_buf->RoamRssiCatGap = mac_ctx->roam.configParam.bCatRssiOffset;
req_buf->Select5GHzMargin = mac_ctx->roam.configParam.nSelect5GHzMargin;
+ req_buf->ho_delay_for_rx = mac_ctx->roam.configParam.ho_delay_for_rx;
if (wlan_cfg_get_int(mac_ctx, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT,
(uint32_t *) &req_buf->ReassocFailureTimeout)
!= eSIR_SUCCESS) {
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index 4f1e19e3dc22..d9b74e3538a9 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -337,6 +337,8 @@ QDF_STATUS wma_roam_scan_offload_mode(tp_wma_handle wma_handle,
params->is_roam_req_valid = 1;
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
params->roam_offload_enabled = roam_req->RoamOffloadEnabled;
+ params->roam_offload_params.ho_delay_for_rx =
+ roam_req->ho_delay_for_rx;
params->prefer_5ghz = roam_req->Prefer5GHz;
params->roam_rssi_cat_gap = roam_req->RoamRssiCatGap;
params->select_5ghz_margin = roam_req->Select5GHzMargin;
@@ -367,10 +369,10 @@ QDF_STATUS wma_roam_scan_offload_mode(tp_wma_handle wma_handle,
wma_roam_scan_fill_fils_params(wma_handle, params, roam_req);
}
- WMA_LOGD(FL("qos_caps: %d, qos_enabled: %d, roam_scan_mode: %d"),
+ WMA_LOGD(FL("qos_caps: %d, qos_enabled: %d, ho_delay_for_rx: %d, roam_scan_mode: %d"),
params->roam_offload_params.qos_caps,
params->roam_offload_params.qos_enabled,
- params->mode);
+ params->roam_offload_params.ho_delay_for_rx, params->mode);
status = wmi_unified_roam_scan_offload_mode_cmd(wma_handle->wmi_handle,
scan_cmd_fp, params);