diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c
index 7f58af2a99..0e42dbddff 100644
--- a/components/mlme/core/src/wlan_mlme_main.c
+++ b/components/mlme/core/src/wlan_mlme_main.c
@@ -432,6 +432,8 @@ static void mlme_init_generic_cfg(struct wlan_objmgr_psoc *psoc,
cfg_get(psoc, CFG_REMOVE_TIME_STAMP_SYNC_CMD);
gen->enable_change_channel_bandwidth =
cfg_get(psoc, CFG_CHANGE_CHANNEL_BANDWIDTH);
+ gen->disable_4way_hs_offload =
+ cfg_get(psoc, CFG_DISABLE_4WAY_HS_OFFLOAD);
}
static void mlme_init_edca_ani_cfg(struct wlan_mlme_edca_params *edca_params)
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_generic.h b/components/mlme/dispatcher/inc/cfg_mlme_generic.h
index 51101831b2..2adc345ff2 100644
--- a/components/mlme/dispatcher/inc/cfg_mlme_generic.h
+++ b/components/mlme/dispatcher/inc/cfg_mlme_generic.h
@@ -625,6 +625,28 @@
CFG_CHANGE_CHANNEL_BANDWIDTH_DEFAULT, \
"enable change channel bw")
+/*
+ *
+ * disable_4way_hs_offload - Enable/Disable 4 way handshake offload to firmware
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * 0 4-way HS to be handled in firmware
+ * 1 4-way HS to be handled in supplicant
+ *
+ * Related: None
+ *
+ * Supported Feature: STA Roaming
+ *
+ * Usage: External
+ *
+ *
+ */
+#define CFG_DISABLE_4WAY_HS_OFFLOAD CFG_INI_BOOL("disable_4way_hs_offload", \
+ 0, \
+ "Enable/disable 4 way handshake offload to firmware")
+
#define CFG_GENERIC_ALL \
CFG(CFG_ENABLE_DEBUG_PACKET_LOG) \
CFG(CFG_PMF_SA_QUERY_MAX_RETRIES) \
@@ -642,6 +664,7 @@
CFG(CFG_ENABLE_LPASS_SUPPORT) \
CFG(CFG_ENABLE_SELF_RECOVERY) \
CFG(CFG_ENABLE_DEAUTH_TO_DISASSOC_MAP) \
+ CFG(CFG_DISABLE_4WAY_HS_OFFLOAD) \
CFG(CFG_SAP_DOT11MC) \
CFG(CFG_ENABLE_FATAL_EVENT_TRIGGER) \
CFG(CFG_SUB_20_CHANNEL_WIDTH) \
diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h
index 4abca04e36..ddb42e2933 100644
--- a/components/mlme/dispatcher/inc/wlan_mlme_api.h
+++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h
@@ -2214,4 +2214,14 @@ wlan_mlme_get_wps_uuid(struct wlan_mlme_wps_params *wps_params, uint8_t *data);
QDF_STATUS
wlan_mlme_get_self_gen_frm_pwr(struct wlan_objmgr_psoc *psoc,
uint32_t *value);
+
+/*
+ * wlan_mlme_get_4way_hs_offload() - get 4-way hs offload to fw cfg
+ * @psoc: pointer to psoc object
+ * @val: Pointer to the value which will be filled for the caller
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS
+wlan_mlme_get_4way_hs_offload(struct wlan_objmgr_psoc *psoc, bool *value);
#endif /* _WLAN_MLME_API_H_ */
diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
index a1520520b3..5c9cbe4f11 100644
--- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
+++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
@@ -1063,6 +1063,7 @@ struct wlan_mlme_chainmask {
* @data_stall_recovery_fw_support: whether FW supports Data stall recovery.
* @enable_change_channel_bandwidth: enable/disable change channel bw in mission
* mode
+ * @disable_4way_hs_offload: enable/disable 4 way handshake offload to firmware
*/
struct wlan_mlme_generic {
enum band_info band_capability;
@@ -1093,6 +1094,7 @@ struct wlan_mlme_generic {
bool enable_remove_time_stamp_sync_cmd;
bool data_stall_recovery_fw_support;
bool enable_change_channel_bandwidth;
+ bool disable_4way_hs_offload;
};
/*
diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c
index a1644a35eb..ac1b57998e 100644
--- a/components/mlme/dispatcher/src/wlan_mlme_api.c
+++ b/components/mlme/dispatcher/src/wlan_mlme_api.c
@@ -3415,3 +3415,20 @@ QDF_STATUS wlan_mlme_ibss_power_save_setup(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_SUCCESS;
}
+
+QDF_STATUS
+wlan_mlme_get_4way_hs_offload(struct wlan_objmgr_psoc *psoc, bool *value)
+{
+ struct wlan_mlme_psoc_obj *mlme_obj;
+
+ mlme_obj = mlme_get_psoc_obj(psoc);
+ if (!mlme_obj) {
+ *value = cfg_default(CFG_DISABLE_4WAY_HS_OFFLOAD);
+ mlme_legacy_err("Failed to get MLME Obj");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ *value = mlme_obj->cfg.gen.disable_4way_hs_offload;
+
+ return QDF_STATUS_SUCCESS;
+}
diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c
index 60fd27539d..85ab667d87 100644
--- a/core/wma/src/wma_utils.c
+++ b/core/wma/src/wma_utils.c
@@ -62,6 +62,7 @@
#include
#include
#include "host_diag_core_log.h"
+#include
/* MCS Based rate table */
/* HT MCS parameters with Nss = 1 */
@@ -4460,11 +4461,22 @@ static void wma_set_roam_offload_flag(tp_wma_handle wma, uint8_t vdev_id,
{
QDF_STATUS status;
uint32_t flag = 0;
+ bool disable_4way_hs_offload;
- if (is_set)
+ if (is_set) {
flag = WMI_ROAM_FW_OFFLOAD_ENABLE_FLAG |
WMI_ROAM_BMISS_FINAL_SCAN_ENABLE_FLAG;
+ wlan_mlme_get_4way_hs_offload(wma->psoc,
+ &disable_4way_hs_offload);
+ /*
+ * If 4-way HS offload is disabled then let supplicant handle
+ * 4way HS and firmware will still do LFR3.0 till reassoc phase.
+ */
+ if (disable_4way_hs_offload)
+ flag |= WMI_VDEV_PARAM_SKIP_ROAM_EAPOL_4WAY_HANDSHAKE;
+ }
+
WMA_LOGD("%s: vdev_id:%d, is_set:%d, flag:%d, roam_offload_enabled:%d",
__func__, vdev_id, is_set, flag,
wma->interfaces[vdev_id].roam_offload_enabled);