qcacld-3.0: Add interface to get / set eLNA bypass

Add interface to get / set eLNA bypass from / to firmware

Change-Id: Idf5d6a838d2596767a1fb00040457af721fba69d
CRs-Fixed: 2498525
diff --git a/Kbuild b/Kbuild
index 8755980..d9bcd08 100644
--- a/Kbuild
+++ b/Kbuild
@@ -929,12 +929,25 @@
 endif
 
 ######## FWOL ##########
-FWOL_DIR := components/fw_offload
-FWOL_INC := -I$(WLAN_ROOT)/$(FWOL_DIR)/core/inc \
-		-I$(WLAN_ROOT)/$(FWOL_DIR)/dispatcher/inc
+FWOL_CORE_INC := components/fw_offload/core/inc
+FWOL_CORE_SRC := components/fw_offload/core/src
+FWOL_DISPATCHER_INC := components/fw_offload/dispatcher/inc
+FWOL_DISPATCHER_SRC := components/fw_offload/dispatcher/src
+FWOL_TARGET_IF_INC := components/target_if/fw_offload/inc
+FWOL_TARGET_IF_SRC := components/target_if/fw_offload/src
+FWOL_OS_IF_INC := os_if/fw_offload/inc
+FWOL_OS_IF_SRC := os_if/fw_offload/src
 
-FWOL_OBJS :=	$(FWOL_DIR)/core/src/wlan_fw_offload_main.o \
-		$(FWOL_DIR)/dispatcher/src/wlan_fwol_ucfg_api.o
+FWOL_INC := -I$(WLAN_ROOT)/$(FWOL_CORE_INC) \
+	    -I$(WLAN_ROOT)/$(FWOL_DISPATCHER_INC) \
+	    -I$(WLAN_ROOT)/$(FWOL_TARGET_IF_INC) \
+	    -I$(WLAN_ROOT)/$(FWOL_OS_IF_INC)
+
+FWOL_OBJS :=	$(FWOL_CORE_SRC)/wlan_fw_offload_main.o \
+		$(FWOL_DISPATCHER_SRC)/wlan_fwol_ucfg_api.o \
+		$(FWOL_DISPATCHER_SRC)/wlan_fwol_tgt_api.o \
+		$(FWOL_TARGET_IF_SRC)/target_if_fwol.o \
+		$(FWOL_OS_IF_SRC)/os_if_fwol.o
 
 ######## SM FRAMEWORK  ##############
 UMAC_SM_DIR := umac/cmn_services/sm_engine
@@ -1244,6 +1257,11 @@
 WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_bcn_tlv.o
 endif
 
+ifeq ($(CONFIG_WLAN_FW_OFFLOAD), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_fwol_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_fwol_tlv.o
+endif
+
 ########### FWLOG ###########
 FWLOG_DIR := $(WLAN_COMMON_ROOT)/utils/fwlog
 
@@ -1980,7 +1998,9 @@
 OBJS +=		$(UMAC_SM_OBJS)
 OBJS +=		$(UMAC_MLME_OBJS)
 OBJS +=		$(MLME_OBJS)
+ifeq ($(CONFIG_WLAN_FW_OFFLOAD), y)
 OBJS +=		$(FWOL_OBJS)
+endif
 OBJS +=		$(BLM_OBJS)
 
 ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
@@ -2080,6 +2100,8 @@
 cppflags-$(CONFIG_FEATURE_FW_LOG_PARSING) += -DFEATURE_FW_LOG_PARSING
 cppflags-$(CONFIG_FEATURE_OEM_DATA) += -DFEATURE_OEM_DATA
 cppflags-$(CONFIG_FEATURE_MOTION_DETECTION) += -DWLAN_FEATURE_MOTION_DETECTION
+cppflags-$(CONFIG_WLAN_FW_OFFLOAD) += -DWLAN_FW_OFFLOAD
+cppflags-$(CONFIG_WLAN_FEATURE_ELNA) += -DWLAN_FEATURE_ELNA
 
 cppflags-$(CONFIG_PLD_SDIO_CNSS_FLAG) += -DCONFIG_PLD_SDIO_CNSS
 cppflags-$(CONFIG_PLD_PCIE_CNSS_FLAG) += -DCONFIG_PLD_PCIE_CNSS
diff --git a/components/fw_offload/core/inc/wlan_fw_offload_main.h b/components/fw_offload/core/inc/wlan_fw_offload_main.h
index 365b53d..0386ba8 100644
--- a/components/fw_offload/core/inc/wlan_fw_offload_main.h
+++ b/components/fw_offload/core/inc/wlan_fw_offload_main.h
@@ -26,8 +26,10 @@
 #include <wlan_objmgr_psoc_obj.h>
 #include <wlan_objmgr_global_obj.h>
 #include <wlan_cmn.h>
+#include <scheduler_api.h>
 
 #include "cfg_ucfg_api.h"
+#include "wlan_fwol_public_structs.h"
 
 #define fwol_alert(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_FWOL, params)
 #define fwol_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_FWOL, params)
@@ -47,6 +49,17 @@
 	QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_FWOL, params)
 
 /**
+ * enum wlan_fwol_southbound_event - fw offload south bound event type
+ * @WLAN_FWOL_EVT_GET_ELNA_BYPASS_RESPONSE: get eLNA bypass response
+ */
+enum wlan_fwol_southbound_event {
+	WLAN_FWOL_EVT_INVALID = 0,
+	WLAN_FWOL_EVT_GET_ELNA_BYPASS_RESPONSE,
+	WLAN_FWOL_EVT_LAST,
+	WLAN_FWOL_EVT_MAX = WLAN_FWOL_EVT_LAST - 1
+};
+
+/**
  * struct wlan_fwol_three_antenna_btc - Three antenna BTC config items
  * @btc_mode: Config BTC mode
  * @antenna_isolation: Antenna isolation
@@ -244,9 +257,31 @@
 /**
  * struct wlan_fwol_psoc_obj - FW offload psoc priv object
  * @cfg:     cfg items
+ * @cbs:     callback functions
+ * @tx_ops: tx operations for target interface
+ * @rx_ops: rx operations for target interface
  */
 struct wlan_fwol_psoc_obj {
 	struct wlan_fwol_cfg cfg;
+	struct wlan_fwol_callbacks cbs;
+	struct wlan_fwol_tx_ops tx_ops;
+	struct wlan_fwol_rx_ops rx_ops;
+};
+
+/**
+ * struct wlan_fwol_rx_event - event from south bound
+ * @psoc: psoc handle
+ * @event_id: event ID
+ * @get_elna_bypass_response: get eLNA bypass response
+ */
+struct wlan_fwol_rx_event {
+	struct wlan_objmgr_psoc *psoc;
+	enum wlan_fwol_southbound_event event_id;
+	union {
+#ifdef WLAN_FEATURE_ELNA
+		struct get_elna_bypass_response get_elna_bypass_response;
+#endif
+	};
 };
 
 /**
@@ -277,6 +312,22 @@
  */
 QDF_STATUS fwol_cfg_on_psoc_disable(struct wlan_objmgr_psoc *psoc);
 
+/**
+ * fwol_process_event() - API to process event from south bound
+ * @msg: south bound message
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS fwol_process_event(struct scheduler_msg *msg);
+
+/*
+ * fwol_release_rx_event() - Release fw offload RX event
+ * @event: fw offload RX event
+ *
+ * Return: none
+ */
+void fwol_release_rx_event(struct wlan_fwol_rx_event *event);
+
 /*
  * fwol_init_neighbor_report_cfg() - Populate default neighbor report CFG values
  * @psoc: pointer to the psoc object
diff --git a/components/fw_offload/core/src/wlan_fw_offload_main.c b/components/fw_offload/core/src/wlan_fw_offload_main.c
index 1e1f79c..16fcd33 100644
--- a/components/fw_offload/core/src/wlan_fw_offload_main.c
+++ b/components/fw_offload/core/src/wlan_fw_offload_main.c
@@ -543,3 +543,97 @@
 	/* Clear the CFG structure */
 	return QDF_STATUS_SUCCESS;
 }
+
+#ifdef WLAN_FEATURE_ELNA
+/**
+ * fwol_process_get_elna_bypass_resp() - Process get eLNA bypass response
+ * @event: response event
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+fwol_process_get_elna_bypass_resp(struct wlan_fwol_rx_event *event)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_fwol_psoc_obj *fwol_obj;
+	struct wlan_fwol_callbacks *cbs;
+	struct get_elna_bypass_response *resp;
+
+	if (!event) {
+		fwol_err("Event buffer is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	psoc = event->psoc;
+	if (!psoc) {
+		fwol_err("psoc is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL Obj");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	cbs = &fwol_obj->cbs;
+	if (cbs->get_elna_bypass_callback) {
+		resp = &event->get_elna_bypass_response;
+		cbs->get_elna_bypass_callback(cbs->get_elna_bypass_context,
+					      resp);
+	} else {
+		fwol_err("NULL pointer for callback");
+		status = QDF_STATUS_E_IO;
+	}
+
+	return status;
+}
+#else
+static QDF_STATUS
+fwol_process_get_elna_bypass_resp(struct wlan_fwol_rx_event *event)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* WLAN_FEATURE_ELNA */
+
+QDF_STATUS fwol_process_event(struct scheduler_msg *msg)
+{
+	QDF_STATUS status;
+	struct wlan_fwol_rx_event *event;
+
+	fwol_debug("msg type %d", msg->type);
+
+	if (!(msg->bodyptr)) {
+		fwol_err("Invalid message body");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	event = msg->bodyptr;
+	msg->bodyptr = NULL;
+
+	switch (msg->type) {
+	case WLAN_FWOL_EVT_GET_ELNA_BYPASS_RESPONSE:
+		status = fwol_process_get_elna_bypass_resp(event);
+		break;
+	default:
+		status = QDF_STATUS_E_INVAL;
+		break;
+	}
+
+	fwol_release_rx_event(event);
+
+	return status;
+}
+
+void fwol_release_rx_event(struct wlan_fwol_rx_event *event)
+{
+	if (!event) {
+		fwol_err("event is NULL");
+		return;
+	}
+
+	if (event->psoc)
+		wlan_objmgr_psoc_release_ref(event->psoc, WLAN_FWOL_SB_ID);
+	qdf_mem_free(event);
+}
diff --git a/components/fw_offload/dispatcher/inc/cfg_fwol.h b/components/fw_offload/dispatcher/inc/cfg_fwol.h
index 3e39ac4..245d3d7 100644
--- a/components/fw_offload/dispatcher/inc/cfg_fwol.h
+++ b/components/fw_offload/dispatcher/inc/cfg_fwol.h
@@ -29,6 +29,7 @@
 #include "cfg_neighbor_roam.h"
 #include "cfg_adaptive_dwelltime.h"
 
+#ifdef WLAN_FW_OFFLOAD
 #define CFG_FWOL_ALL \
 	CFG_ADAPTIVE_DWELLTIME_ALL \
 	CFG_11K_ALL \
@@ -36,6 +37,9 @@
 	CFG_FWOL_GENERIC_ALL \
 	CFG_IE_WHITELIST \
 	CFG_THERMAL_TEMP_ALL
+#else
+#define CFG_FWOL_ALL
+#endif
 
 #endif /* __CFG_FWOL_H */
 
diff --git a/components/fw_offload/dispatcher/inc/wlan_fwol_public_structs.h b/components/fw_offload/dispatcher/inc/wlan_fwol_public_structs.h
new file mode 100644
index 0000000..ea0863b
--- /dev/null
+++ b/components/fw_offload/dispatcher/inc/wlan_fwol_public_structs.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: contains fw offload structure definations
+ */
+
+#ifndef _WLAN_FWOL_PUBLIC_STRUCTS_H_
+#define _WLAN_FWOL_PUBLIC_STRUCTS_H_
+
+#include "wlan_objmgr_psoc_obj.h"
+
+#ifdef WLAN_FEATURE_ELNA
+/**
+ * struct set_elna_bypass_request - set eLNA bypass request
+ * @vdev_id: vdev id
+ * @en_dis: 0 - disable eLNA bypass
+ *          1 - enable eLNA bypass
+ */
+struct set_elna_bypass_request {
+	uint8_t vdev_id;
+	uint8_t en_dis;
+};
+
+/**
+ * struct get_elna_bypass_request - get eLNA bypass request
+ * @vdev_id: vdev id
+ */
+struct get_elna_bypass_request {
+	uint8_t vdev_id;
+};
+
+/**
+ * struct get_elna_bypass_response - get eLNA bypass response
+ * @vdev_id: vdev id
+ * @en_dis: 0 - disable eLNA bypass
+ *          1 - enable eLNA bypass
+ */
+struct get_elna_bypass_response {
+	uint8_t vdev_id;
+	uint8_t en_dis;
+};
+#endif
+
+/**
+ * struct wlan_fwol_callbacks - fw offload callbacks
+ * @get_elna_bypass_callback: callback for get eLNA bypass
+ * @get_elna_bypass_context: context for get eLNA bypass
+ */
+struct wlan_fwol_callbacks {
+#ifdef WLAN_FEATURE_ELNA
+	void (*get_elna_bypass_callback)(void *context,
+				     struct get_elna_bypass_response *response);
+	void *get_elna_bypass_context;
+#endif
+};
+
+/**
+ * struct wlan_fwol_tx_ops - structure of tx func pointers
+ * @set_elna_bypass: set eLNA bypass
+ * @get_elna_bypass: get eLNA bypass
+ * @reg_evt_handler: register event handler
+ * @unreg_evt_handler: unregister event handler
+ */
+struct wlan_fwol_tx_ops {
+#ifdef WLAN_FEATURE_ELNA
+	QDF_STATUS (*set_elna_bypass)(struct wlan_objmgr_psoc *psoc,
+				      struct set_elna_bypass_request *req);
+	QDF_STATUS (*get_elna_bypass)(struct wlan_objmgr_psoc *psoc,
+				      struct get_elna_bypass_request *req);
+#endif
+	QDF_STATUS (*reg_evt_handler)(struct wlan_objmgr_psoc *psoc,
+				      void *arg);
+	QDF_STATUS (*unreg_evt_handler)(struct wlan_objmgr_psoc *psoc,
+					void *arg);
+};
+
+/**
+ * struct wlan_fwol_rx_ops - structure of rx func pointers
+ * @get_elna_bypass_resp: get eLNA bypass response
+ */
+struct wlan_fwol_rx_ops {
+#ifdef WLAN_FEATURE_ELNA
+	QDF_STATUS (*get_elna_bypass_resp)(struct wlan_objmgr_psoc *psoc,
+					 struct get_elna_bypass_response *resp);
+#endif
+};
+
+#endif /* _WLAN_FWOL_PUBLIC_STRUCTS_H_ */
+
diff --git a/components/fw_offload/dispatcher/inc/wlan_fwol_tgt_api.h b/components/fw_offload/dispatcher/inc/wlan_fwol_tgt_api.h
new file mode 100644
index 0000000..4bf88b2
--- /dev/null
+++ b/components/fw_offload/dispatcher/inc/wlan_fwol_tgt_api.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: fw offload south bound interface declaration
+ */
+#ifndef _WLAN_FWOL_TGT_API_H
+#define _WLAN_FWOL_TGT_API_H
+
+#include "wlan_fwol_public_structs.h"
+
+/**
+ * tgt_fwol_register_ev_handler() - register south bound event handler
+ * @psoc: psoc handle
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS tgt_fwol_register_ev_handler(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * tgt_fwol_unregister_ev_handler() - unregister south bound event handler
+ * @psoc: psoc handle
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS tgt_fwol_unregister_ev_handler(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * tgt_fwol_register_rx_ops() - register fw offload rx operations
+ * @rx_ops: fps to rx operations
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS tgt_fwol_register_rx_ops(struct wlan_fwol_rx_ops *rx_ops);
+#endif /* _WLAN_FWOL_TGT_API_H */
diff --git a/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h b/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h
index bccd02a..c835073 100644
--- a/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h
+++ b/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h
@@ -26,7 +26,9 @@
 #include <wlan_objmgr_global_obj.h>
 #include <wlan_cmn.h>
 #include "wlan_fw_offload_main.h"
+#include "wlan_fwol_public_structs.h"
 
+#ifdef WLAN_FW_OFFLOAD
 /**
  * ucfg_fwol_psoc_open() - FWOL component Open
  * @psoc: pointer to psoc object
@@ -523,4 +525,321 @@
 {
 	return fwol_set_adaptive_dwelltime_config(dwelltime_params);
 }
+
+#ifdef WLAN_FEATURE_ELNA
+/**
+ * ucfg_fwol_set_elna_bypass() - send set eLNA bypass request
+ * @vdev: vdev handle
+ * @req: set eLNA bypass request
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_fwol_set_elna_bypass(struct wlan_objmgr_vdev *vdev,
+				     struct set_elna_bypass_request *req);
+
+/**
+ * ucfg_fwol_get_elna_bypass() - send get eLNA bypass request
+ * @vdev: vdev handle
+ * @req: get eLNA bypass request
+ * @callback: get eLNA bypass response callback
+ * @context: request manager context
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_fwol_get_elna_bypass(struct wlan_objmgr_vdev *vdev,
+				     struct get_elna_bypass_request *req,
+				     void (*callback)(void *context,
+				     struct get_elna_bypass_response *response),
+				     void *context);
+#endif /* WLAN_FEATURE_ELNA */
+#else
+static inline QDF_STATUS ucfg_fwol_psoc_open(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void ucfg_fwol_psoc_close(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline QDF_STATUS ucfg_fwol_init(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void ucfg_fwol_deinit(void)
+{
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_coex_config_params(struct wlan_objmgr_psoc *psoc,
+				 struct wlan_fwol_coex_config *coex_config)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_thermal_temp(struct wlan_objmgr_psoc *psoc,
+			   struct wlan_fwol_thermal_temp *thermal_temp)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_neighbor_report_cfg(struct wlan_objmgr_psoc *psoc,
+				  struct wlan_fwol_neighbor_report_cfg
+				  *fwol_neighbor_report_cfg)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_is_neighbor_report_req_supported(struct wlan_objmgr_psoc *psoc,
+					   bool *neighbor_report_req)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_ie_whitelist(struct wlan_objmgr_psoc *psoc, bool *ie_whitelist)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_set_ie_whitelist(struct wlan_objmgr_psoc *psoc, bool ie_whitelist)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_all_whitelist_params(struct wlan_objmgr_psoc *psoc,
+				   struct wlan_fwol_ie_whitelist *whitelist)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_ani_enabled(struct wlan_objmgr_psoc *psoc,
+			  bool *ani_enabled)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_get_enable_rts_sifsbursting(struct wlan_objmgr_psoc *psoc,
+				 bool *enable_rts_sifsbursting)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_get_max_mpdus_inampdu(struct wlan_objmgr_psoc *psoc,
+			   uint8_t *max_mpdus_inampdu)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_get_arp_ac_category(struct wlan_objmgr_psoc *psoc,
+			 uint32_t *arp_ac_category)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_get_enable_phy_reg_retention(struct wlan_objmgr_psoc *psoc,
+				  uint8_t *enable_phy_reg_retention)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_get_upper_brssi_thresh(struct wlan_objmgr_psoc *psoc,
+			    uint16_t *upper_brssi_thresh)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_get_lower_brssi_thresh(struct wlan_objmgr_psoc *psoc,
+			    uint16_t *lower_brssi_thresh)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_get_enable_dtim_1chrx(struct wlan_objmgr_psoc *psoc,
+			   bool *enable_dtim_1chrx)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_get_alternative_chainmask_enabled(struct wlan_objmgr_psoc *psoc,
+				       bool *alternative_chainmask_enabled)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_get_smart_chainmask_enabled(struct wlan_objmgr_psoc *psoc,
+				 bool *smart_chainmask_enabled)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_rts_profile(struct wlan_objmgr_psoc *psoc,
+			  uint16_t *get_rts_profile)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_enable_fw_log_level(struct wlan_objmgr_psoc *psoc,
+				  uint16_t *enable_fw_log_level)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_enable_fw_log_type(struct wlan_objmgr_psoc *psoc,
+				 uint16_t *enable_fw_log_type)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_enable_fw_module_log_level(
+				struct wlan_objmgr_psoc *psoc,
+				uint8_t **enable_fw_module_log_level,
+				uint8_t *enable_fw_module_log_level_num)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_tsf_gpio_pin(struct wlan_objmgr_psoc *psoc,
+			   uint32_t *tsf_gpio_pin)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_tsf_ptp_options(struct wlan_objmgr_psoc *psoc,
+			      uint32_t *tsf_ptp_options)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_lprx_enable(struct wlan_objmgr_psoc *psoc,
+			  bool *lprx_enable)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline bool ucfg_fwol_get_sae_enable(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline bool ucfg_fwol_get_gcmp_enable(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_enable_tx_sch_delay(struct wlan_objmgr_psoc *psoc,
+				  uint8_t *enable_tx_sch_delay)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_enable_secondary_rate(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *enable_secondary_rate)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_all_adaptive_dwelltime_params(
+			struct wlan_objmgr_psoc *psoc,
+			struct adaptive_dwelltime_params *dwelltime_params)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_adaptive_dwell_mode_enabled(struct wlan_objmgr_psoc *psoc,
+					  bool *adaptive_dwell_mode_enabled)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_global_adapt_dwelltime_mode(struct wlan_objmgr_psoc *psoc,
+					  uint8_t *global_adapt_dwelltime_mode)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_adapt_dwell_lpf_weight(struct wlan_objmgr_psoc *psoc,
+				     uint8_t *adapt_dwell_lpf_weight)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_adapt_dwell_passive_mon_intval(
+				struct wlan_objmgr_psoc *psoc,
+				uint8_t *adapt_dwell_passive_mon_intval)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_adapt_dwell_wifi_act_threshold(
+				struct wlan_objmgr_psoc *psoc,
+				uint8_t *adapt_dwell_wifi_act_threshold)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_init_adapt_dwelltime_in_cfg(
+			struct wlan_objmgr_psoc *psoc,
+			struct adaptive_dwelltime_params *dwelltime_params)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_set_adaptive_dwelltime_config(
+			struct adaptive_dwelltime_params *dwelltime_params)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+#ifdef FEATURE_WLAN_RA_FILTERING
+static inline QDF_STATUS
+ucfg_fwol_set_is_rate_limit_enabled(struct wlan_objmgr_psoc *psoc,
+				    bool is_rate_limit_enabled)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_is_rate_limit_enabled(struct wlan_objmgr_psoc *psoc,
+				    bool *is_rate_limit_enabled)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* FEATURE_WLAN_RA_FILTERING */
+
+#endif /* WLAN_FW_OFFLOAD */
+
 #endif /* _WLAN_FWOL_UCFG_API_H_ */
diff --git a/components/fw_offload/dispatcher/src/wlan_fwol_tgt_api.c b/components/fw_offload/dispatcher/src/wlan_fwol_tgt_api.c
new file mode 100644
index 0000000..8778fc6
--- /dev/null
+++ b/components/fw_offload/dispatcher/src/wlan_fwol_tgt_api.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: This file contains fw offload south bound interface definitions
+ */
+
+#include "scheduler_api.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_objmgr_global_obj.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "wlan_fwol_public_structs.h"
+#include "wlan_fwol_ucfg_api.h"
+#include "wlan_fwol_tgt_api.h"
+#include "wlan_fw_offload_main.h"
+
+QDF_STATUS tgt_fwol_register_ev_handler(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+	struct wlan_fwol_tx_ops *tx_ops;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (!psoc) {
+		fwol_err("NULL psoc handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL Obj");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	tx_ops = &fwol_obj->tx_ops;
+	if (tx_ops->reg_evt_handler) {
+		status = tx_ops->reg_evt_handler(psoc, NULL);
+		fwol_debug("reg_evt_handler, status:%d", status);
+	} else {
+		fwol_alert("No reg_evt_handler");
+	}
+
+	return status;
+}
+
+QDF_STATUS tgt_fwol_unregister_ev_handler(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+	struct wlan_fwol_tx_ops *tx_ops;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (!psoc) {
+		fwol_err("NNULL psoc handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL Obj");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	tx_ops = &fwol_obj->tx_ops;
+	if (tx_ops->unreg_evt_handler) {
+		status = tx_ops->unreg_evt_handler(psoc, NULL);
+		fwol_debug("unreg_evt_handler, status:%d", status);
+	} else {
+		fwol_alert("No unreg_evt_handler");
+	}
+
+	return status;
+}
+
+/**
+ * fwol_flush_callback() - fw offload message flush callback
+ * @msg: fw offload message
+ *
+ * Return: QDF_STATUS_SUCCESS on success.
+ */
+__attribute__((unused))
+static QDF_STATUS fwol_flush_callback(struct scheduler_msg *msg)
+{
+	struct wlan_fwol_rx_event *event;
+
+	if (!msg) {
+		fwol_err("NULL pointer for eLNA message");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	event = msg->bodyptr;
+	msg->bodyptr = NULL;
+	fwol_release_rx_event(event);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_ELNA
+/**
+ * tgt_fwol_get_elna_bypass_resp() - handler for get eLNA bypass response
+ * @psoc: psoc handle
+ * @resp: status for last channel config
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+tgt_fwol_get_elna_bypass_resp(struct wlan_objmgr_psoc *psoc,
+			      struct get_elna_bypass_response *resp)
+{
+	QDF_STATUS status;
+	struct scheduler_msg msg = {0};
+	struct wlan_fwol_rx_event *event;
+
+	event = qdf_mem_malloc(sizeof(*event));
+	if (!event)
+		return QDF_STATUS_E_NOMEM;
+
+	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_FWOL_SB_ID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		fwol_err("Failed to get psoc ref");
+		fwol_release_rx_event(event);
+		return status;
+	}
+
+	event->psoc = psoc;
+	event->event_id = WLAN_FWOL_EVT_GET_ELNA_BYPASS_RESPONSE;
+	event->get_elna_bypass_response = *resp;
+	msg.type = WLAN_FWOL_EVT_GET_ELNA_BYPASS_RESPONSE;
+	msg.bodyptr = event;
+	msg.callback = fwol_process_event;
+	msg.flush_callback = fwol_flush_callback;
+	status = scheduler_post_message(QDF_MODULE_ID_FWOL,
+					QDF_MODULE_ID_FWOL,
+					QDF_MODULE_ID_TARGET_IF, &msg);
+
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return QDF_STATUS_SUCCESS;
+
+	fwol_err("failed to send WLAN_FWOL_GET_ELNA_BYPASS_RESPONSE msg");
+	fwol_flush_callback(&msg);
+
+	return status;
+}
+
+static void tgt_fwol_register_elna_rx_ops(struct wlan_fwol_rx_ops *rx_ops)
+{
+	rx_ops->get_elna_bypass_resp = tgt_fwol_get_elna_bypass_resp;
+}
+#else
+static void tgt_fwol_register_elna_rx_ops(struct wlan_fwol_rx_ops *rx_ops)
+{
+}
+#endif /* WLAN_FEATURE_ELNA */
+
+QDF_STATUS tgt_fwol_register_rx_ops(struct wlan_fwol_rx_ops *rx_ops)
+{
+	tgt_fwol_register_elna_rx_ops(rx_ops);
+
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c b/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c
index 019fb5f..961f1f0 100644
--- a/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c
+++ b/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c
@@ -20,7 +20,11 @@
  */
 
 #include "wlan_fw_offload_main.h"
+#include "wlan_fwol_public_structs.h"
 #include "wlan_fwol_ucfg_api.h"
+#include "wlan_fwol_tgt_api.h"
+#include "target_if_fwol.h"
+#include "wlan_objmgr_vdev_obj.h"
 
 QDF_STATUS ucfg_fwol_psoc_open(struct wlan_objmgr_psoc *psoc)
 {
@@ -30,12 +34,16 @@
 	if (QDF_IS_STATUS_ERROR(status))
 		fwol_err("Failed to initialize FWOL CFG");
 
+	tgt_fwol_register_ev_handler(psoc);
+
 	return status;
 }
 
 void ucfg_fwol_psoc_close(struct wlan_objmgr_psoc *psoc)
 {
 	/* Clear the FWOL CFG Structure */
+
+	tgt_fwol_unregister_ev_handler(psoc);
 }
 
 /**
@@ -66,6 +74,9 @@
 		qdf_mem_free(fwol_obj);
 	}
 
+	tgt_fwol_register_rx_ops(&fwol_obj->rx_ops);
+	target_if_fwol_register_tx_ops(&fwol_obj->tx_ops);
+
 	return status;
 }
 
@@ -832,3 +843,71 @@
 			fwol_obj->cfg.dwelltime_params.wifi_act_threshold;
 	return QDF_STATUS_SUCCESS;
 }
+
+#ifdef WLAN_FEATURE_ELNA
+QDF_STATUS ucfg_fwol_set_elna_bypass(struct wlan_objmgr_vdev *vdev,
+				     struct set_elna_bypass_request *req)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_fwol_psoc_obj *fwol_obj;
+	struct wlan_fwol_tx_ops *tx_ops;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		fwol_err("NULL pointer for psoc");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL Obj");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	tx_ops = &fwol_obj->tx_ops;
+	if (tx_ops->set_elna_bypass)
+		status = tx_ops->set_elna_bypass(psoc, req);
+	else
+		status = QDF_STATUS_E_IO;
+
+	return status;
+}
+
+QDF_STATUS ucfg_fwol_get_elna_bypass(struct wlan_objmgr_vdev *vdev,
+				     struct get_elna_bypass_request *req,
+				     void (*callback)(void *context,
+				     struct get_elna_bypass_response *response),
+				     void *context)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_fwol_psoc_obj *fwol_obj;
+	struct wlan_fwol_tx_ops *tx_ops;
+	struct wlan_fwol_callbacks *cbs;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		fwol_err("NULL pointer for psoc");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL Obj");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	cbs = &fwol_obj->cbs;
+	cbs->get_elna_bypass_callback = callback;
+	cbs->get_elna_bypass_context = context;
+
+	tx_ops = &fwol_obj->tx_ops;
+	if (tx_ops->get_elna_bypass)
+		status = tx_ops->get_elna_bypass(psoc, req);
+	else
+		status = QDF_STATUS_E_IO;
+
+	return status;
+}
+#endif /* WLAN_FEATURE_ELNA */
diff --git a/components/target_if/fw_offload/inc/target_if_fwol.h b/components/target_if/fw_offload/inc/target_if_fwol.h
new file mode 100644
index 0000000..7a6ab16
--- /dev/null
+++ b/components/target_if/fw_offload/inc/target_if_fwol.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: target interface APIs for fw offload
+ *
+ */
+
+#ifndef __TARGET_IF_FWOL_H__
+#define __TARGET_IF_FWOL_H__
+
+/**
+ * target_if_fwol_register_event_handler() - register fw offload event handler
+ * @psoc: psoc object
+ * @arg: argument passed to lmac
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS target_if_fwol_register_event_handler(struct wlan_objmgr_psoc *psoc,
+						 void *arg);
+
+/**
+ * target_if_fwol_unregister_event_handler() - unregister fw offload event
+ * handler
+ * @psoc: psoc object
+ * @arg: argument passed to lmac
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+target_if_fwol_unregister_event_handler(struct wlan_objmgr_psoc *psoc,
+					void *arg);
+
+/**
+ * target_if_fwol_register_tx_ops() - register fw offload tx ops callback
+ * functions
+ * @tx_ops: fw offload tx operations
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS target_if_fwol_register_tx_ops(struct wlan_fwol_tx_ops *tx_ops);
+
+#endif /* __TARGET_IF_FWOL_H__ */
diff --git a/components/target_if/fw_offload/src/target_if_fwol.c b/components/target_if/fw_offload/src/target_if_fwol.c
new file mode 100644
index 0000000..276f250
--- /dev/null
+++ b/components/target_if/fw_offload/src/target_if_fwol.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: target interface APIs for fw offload
+ *
+ */
+
+#include "qdf_mem.h"
+#include "target_if.h"
+#include "qdf_status.h"
+#include "wmi_unified_api.h"
+#include "wmi_unified_priv.h"
+#include "wmi_unified_param.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_utility.h"
+#include "wlan_defs.h"
+#include "wlan_fwol_public_structs.h"
+#include "wlan_fw_offload_main.h"
+#include "target_if_fwol.h"
+
+#ifdef WLAN_FEATURE_ELNA
+/**
+ * target_if_fwol_set_elna_bypass() - send set eLNA bypass request to FW
+ * @psoc: pointer to PSOC object
+ * @req: set eLNA bypass request
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+target_if_fwol_set_elna_bypass(struct wlan_objmgr_psoc *psoc,
+			       struct set_elna_bypass_request *req)
+{
+	QDF_STATUS status;
+
+	status = wmi_unified_send_set_elna_bypass_cmd(
+					    get_wmi_unified_hdl_from_psoc(psoc),
+					    req);
+	if (status)
+		target_if_err("Failed to set eLNA bypass %d", status);
+
+	return status;
+}
+
+/**
+ * target_if_fwol_get_elna_bypass() - send get eLNA bypass request to FW
+ * @psoc: pointer to PSOC object
+ * @req: get eLNA bypass request
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+target_if_fwol_get_elna_bypass(struct wlan_objmgr_psoc *psoc,
+			       struct get_elna_bypass_request *req)
+{
+	QDF_STATUS status;
+
+	status = wmi_unified_send_get_elna_bypass_cmd(
+					    get_wmi_unified_hdl_from_psoc(psoc),
+					    req);
+	if (status)
+		target_if_err("Failed to set eLNA bypass %d", status);
+
+	return status;
+}
+
+/**
+ * target_if_fwol_get_elna_bypass_resp() - handler for get eLNA bypass response
+ * @scn: scn handle
+ * @event_buf: pointer to the event buffer
+ * @len: length of the buffer
+ *
+ * Return: 0 on success
+ */
+static int target_if_fwol_get_elna_bypass_resp(ol_scn_t scn, uint8_t *event_buf,
+					       uint32_t len)
+{
+	QDF_STATUS status;
+	struct get_elna_bypass_response resp;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_fwol_psoc_obj *fwol_obj;
+	struct wlan_fwol_rx_ops *rx_ops;
+
+	target_if_debug("scn:%pK, data:%pK, datalen:%d", scn, event_buf, len);
+	if (!scn || !event_buf) {
+		target_if_err("scn: 0x%pK, data: 0x%pK", scn, event_buf);
+		return -EINVAL;
+	}
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("null psoc");
+		return -EINVAL;
+	}
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		target_if_err("Failed to get FWOL Obj");
+		return -EINVAL;
+	}
+
+	rx_ops = &fwol_obj->rx_ops;
+	if (rx_ops->get_elna_bypass_resp) {
+		status = wmi_extract_get_elna_bypass_resp(
+					    get_wmi_unified_hdl_from_psoc(psoc),
+					    event_buf, &resp);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			target_if_err("Failed to extract eLNA bypass");
+			return -EINVAL;
+		}
+		status = rx_ops->get_elna_bypass_resp(psoc, &resp);
+		if (status != QDF_STATUS_SUCCESS) {
+			target_if_err("get_elna_bypass_resp failed.");
+			return -EINVAL;
+		}
+	} else {
+		target_if_fatal("No get_elna_bypass_resp callback");
+		return -EINVAL;
+	}
+
+	return 0;
+};
+
+static void
+target_if_fwol_register_elna_event_handler(struct wlan_objmgr_psoc *psoc,
+					   void *arg)
+{
+	int rc;
+
+	rc = wmi_unified_register_event(get_wmi_unified_hdl_from_psoc(psoc),
+					wmi_get_elna_bypass_event_id,
+					target_if_fwol_get_elna_bypass_resp);
+	if (rc)
+		target_if_err("Failed to register get eLNA bypass event cb");
+}
+
+static void
+target_if_fwol_unregister_elna_event_handler(struct wlan_objmgr_psoc *psoc,
+					     void *arg)
+{
+	int rc;
+
+	rc = wmi_unified_unregister_event_handler(
+					    get_wmi_unified_hdl_from_psoc(psoc),
+					    wmi_get_elna_bypass_event_id);
+	if (rc)
+		target_if_err("Failed to unregister get eLNA bypass event cb");
+}
+
+static void
+target_if_fwol_register_elna_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
+{
+	tx_ops->set_elna_bypass = target_if_fwol_set_elna_bypass;
+	tx_ops->get_elna_bypass = target_if_fwol_get_elna_bypass;
+}
+#else
+static void
+target_if_fwol_register_elna_event_handler(struct wlan_objmgr_psoc *psoc,
+					   void *arg)
+{
+}
+
+static void
+target_if_fwol_unregister_elna_event_handler(struct wlan_objmgr_psoc *psoc,
+					     void *arg)
+{
+}
+
+static void
+target_if_fwol_register_elna_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
+{
+}
+#endif /* WLAN_FEATURE_ELNA */
+
+QDF_STATUS target_if_fwol_register_event_handler(struct wlan_objmgr_psoc *psoc,
+						 void *arg)
+{
+	target_if_fwol_register_elna_event_handler(psoc, arg);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+target_if_fwol_unregister_event_handler(struct wlan_objmgr_psoc *psoc,
+					void *arg)
+{
+	target_if_fwol_unregister_elna_event_handler(psoc, arg);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS target_if_fwol_register_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
+{
+	target_if_fwol_register_elna_tx_ops(tx_ops);
+
+	tx_ops->reg_evt_handler = target_if_fwol_register_event_handler;
+	tx_ops->unreg_evt_handler = target_if_fwol_unregister_event_handler;
+
+	return QDF_STATUS_SUCCESS;
+}
+
diff --git a/configs/default_defconfig b/configs/default_defconfig
index 3bd13e7..14e8155 100644
--- a/configs/default_defconfig
+++ b/configs/default_defconfig
@@ -905,6 +905,14 @@
 #Enable OEM DATA feature
 CONFIG_FEATURE_OEM_DATA := y
 
+#Enable FW Offload
+CONFIG_WLAN_FW_OFFLOAD := y
+
+#Enable eLNA bypass feature
+ifeq ($(CONFIG_WLAN_FW_OFFLOAD), y)
+CONFIG_WLAN_FEATURE_ELNA := y
+endif
+
 ifeq (y,$(findstring y,$(CONFIG_ARCH_MSM) $(CONFIG_ARCH_QCOM)))
 CONFIG_WLAN_FEATURE_DP_BUS_BANDWIDTH := y
 endif
diff --git a/configs/genoa.common b/configs/genoa.common
index 384fedc..8e7a575 100644
--- a/configs/genoa.common
+++ b/configs/genoa.common
@@ -221,4 +221,8 @@
 endif
 
 CONFIG_SAP_DHCP_FW_IND := n
+
+#Enable FW Offload
+CONFIG_WLAN_FW_OFFLOAD := y
+
 ###################################
diff --git a/configs/qca6174_defconfig b/configs/qca6174_defconfig
index 10dee88..1731a86 100644
--- a/configs/qca6174_defconfig
+++ b/configs/qca6174_defconfig
@@ -716,3 +716,7 @@
 endif
 
 CONFIG_SAP_DHCP_FW_IND := y
+
+#Enable FW Offload
+CONFIG_WLAN_FW_OFFLOAD := y
+
diff --git a/configs/qca6390_defconfig b/configs/qca6390_defconfig
index dede872..5fe7ac5 100644
--- a/configs/qca6390_defconfig
+++ b/configs/qca6390_defconfig
@@ -750,3 +750,7 @@
 
 CONFIG_FOURTH_CONNECTION := y
 CONFIG_SAP_DHCP_FW_IND := y
+
+#Enable FW Offload
+CONFIG_WLAN_FW_OFFLOAD := y
+
diff --git a/configs/qcs40x.snoc.perf_defconfig b/configs/qcs40x.snoc.perf_defconfig
index 44c853c..ce77021 100644
--- a/configs/qcs40x.snoc.perf_defconfig
+++ b/configs/qcs40x.snoc.perf_defconfig
@@ -172,6 +172,9 @@
 endif
 endif
 
+#Enable FW Offload
+CONFIG_WLAN_FW_OFFLOAD := y
+
 CONFIG_ENABLE_SIZE_OPTIMIZE := y
 
 # configure log buffer size
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index c72b652..94ccdb8 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -141,6 +141,7 @@
 #include "wlan_blm_ucfg_api.h"
 #include "wlan_hdd_hw_capability.h"
 #include "wlan_hdd_oemdata.h"
+#include "os_if_fwol.h"
 
 #define g_mode_rates_size (12)
 #define a_mode_rates_size (8)
@@ -6108,6 +6109,7 @@
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_ENABLE] = {.type = NLA_U8 },
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] = {.type = NLA_U8},
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_GTX] = {.type = NLA_U8},
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_ELNA_BYPASS] = {.type = NLA_U8},
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY] = {.type = NLA_U32 },
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY_IE_LIST] = {
 		.type = NLA_BINARY,
@@ -7270,6 +7272,32 @@
 	return qdf_status_to_os_return(status);
 }
 
+#ifdef WLAN_FEATURE_ELNA
+/**
+ * hdd_set_elna_bypass() - Set eLNA bypass
+ * @adapter: Pointer to HDD adapter
+ * @attr: Pointer to struct nlattr
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int hdd_set_elna_bypass(struct hdd_adapter *adapter,
+			       const struct nlattr *attr)
+{
+	int ret;
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = hdd_objmgr_get_vdev(adapter);
+	if (!vdev)
+		return -EINVAL;
+
+	ret = os_if_fwol_set_elna_bypass(vdev, attr);
+
+	hdd_objmgr_put_vdev(vdev);
+
+	return ret;
+}
+#endif
+
 /**
  * typedef independent_setter_fn - independent attribute handler
  * @adapter: The adapter being configured
@@ -7356,8 +7384,135 @@
 	 hdd_config_gtx},
 	{QCA_WLAN_VENDOR_ATTR_DISCONNECT_IES,
 	 hdd_config_disconnect_ies},
+#ifdef WLAN_FEATURE_ELNA
+	{QCA_WLAN_VENDOR_ATTR_CONFIG_ELNA_BYPASS,
+	 hdd_set_elna_bypass},
+#endif
 };
 
+#ifdef WLAN_FEATURE_ELNA
+/**
+ * hdd_get_elna_bypass() - Get eLNA bypass
+ * @adapter: Pointer to HDD adapter
+ * @skb: sk buffer to hold nl80211 attributes
+ * @attr: Pointer to struct nlattr
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int hdd_get_elna_bypass(struct hdd_adapter *adapter,
+			       struct sk_buff *skb,
+			       const struct nlattr *attr)
+{
+	int ret;
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = hdd_objmgr_get_vdev(adapter);
+	if (!vdev)
+		return -EINVAL;
+
+	ret = os_if_fwol_get_elna_bypass(vdev, skb, attr);
+
+	hdd_objmgr_put_vdev(vdev);
+
+	return ret;
+}
+#endif
+
+/**
+ * typedef config_getter_fn - get configuration handler
+ * @adapter: The adapter being configured
+ * @skb: sk buffer to hold nl80211 attributes
+ * @attr: The nl80211 attribute being applied
+ *
+ * Defines the signature of functions in the attribute vtable
+ *
+ * Return: 0 if the attribute was handled successfully, otherwise an errno
+ */
+typedef int (*config_getter_fn)(struct hdd_adapter *adapter,
+				struct sk_buff *skb,
+				const struct nlattr *attr);
+
+/**
+ * struct config_getters
+ * @id: vendor attribute which this entry handles
+ * @cb: callback function to invoke to process the attribute when present
+ */
+struct config_getters {
+	uint32_t id;
+	size_t max_attr_len;
+	config_getter_fn cb;
+};
+
+/* vtable for config getters */
+static const struct config_getters config_getters[] = {
+#ifdef WLAN_FEATURE_ELNA
+	{QCA_WLAN_VENDOR_ATTR_CONFIG_ELNA_BYPASS,
+	 sizeof(uint8_t),
+	 hdd_get_elna_bypass},
+#endif
+};
+
+/**
+ * hdd_get_configuration() - Handle get configuration
+ * @adapter: adapter upon which the vendor command was received
+ * @tb: parsed attribute array
+ *
+ * This is a table-driven function which dispatches attributes
+ * in a QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_CONFIGURATION
+ * vendor command.
+ *
+ * Return: 0 if there were no issues, otherwise errno of the last issue
+ */
+static int hdd_get_configuration(struct hdd_adapter *adapter,
+				 struct nlattr **tb)
+{
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+	uint32_t i, id;
+	unsigned long nl_buf_len = NLMSG_HDRLEN;
+	struct sk_buff *skb;
+	struct nlattr *attr;
+	config_getter_fn cb;
+	int errno = 0;
+
+	for (i = 0; i < QDF_ARRAY_SIZE(config_getters); i++) {
+		id = config_getters[i].id;
+		attr = tb[id];
+		if (!attr)
+			continue;
+
+		nl_buf_len += NLA_HDRLEN +
+			      NLA_ALIGN(config_getters[i].max_attr_len);
+	}
+
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
+	if (!skb) {
+		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < QDF_ARRAY_SIZE(config_getters); i++) {
+		id = config_getters[i].id;
+		attr = tb[id];
+		if (!attr)
+			continue;
+
+		cb = config_getters[i].cb;
+		errno = cb(adapter, skb, attr);
+		if (errno)
+			break;
+	}
+
+	if (errno) {
+		hdd_err("Failed to get wifi configuration, errno = %d", errno);
+		kfree_skb(skb);
+		return -EINVAL;
+	}
+
+	cfg80211_vendor_cmd_reply(skb);
+
+	return errno;
+}
+
 /**
  * hdd_set_independent_configuration() - Handle independent attributes
  * @adapter: adapter upon which the vendor command was received
@@ -7537,6 +7692,88 @@
 }
 
 /**
+ * __wlan_hdd_cfg80211_wifi_configuration_get() - Wifi configuration
+ * vendor command
+ * @wiphy: wiphy device pointer
+ * @wdev: wireless device pointer
+ * @data: Vendor command data buffer
+ * @data_len: Buffer length
+ *
+ * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
+ *
+ * Return: Error code.
+ */
+static int
+__wlan_hdd_cfg80211_wifi_configuration_get(struct wiphy *wiphy,
+					   struct wireless_dev *wdev,
+					   const void *data,
+					   int data_len)
+{
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx  = wiphy_priv(wiphy);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1];
+	int errno;
+	int ret;
+
+	hdd_enter_dev(dev);
+
+	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+		hdd_err("Command not allowed in FTM mode");
+		return -EPERM;
+	}
+
+	errno = wlan_hdd_validate_context(hdd_ctx);
+	if (errno)
+		return errno;
+
+	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_CONFIG_MAX, data,
+				    data_len, wlan_hdd_wifi_config_policy)) {
+		hdd_err("invalid attr");
+		return -EINVAL;
+	}
+
+	ret = hdd_get_configuration(adapter, tb);
+	if (ret)
+		errno = ret;
+
+	return errno;
+}
+
+/**
+ * wlan_hdd_cfg80211_wifi_configuration_get() - Wifi configuration
+ * vendor command
+ *
+ * @wiphy: wiphy device pointer
+ * @wdev: wireless device pointer
+ * @data: Vendor command data buffer
+ * @data_len: Buffer length
+ *
+ * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
+ *
+ * Return: EOK or other error codes.
+ */
+static int wlan_hdd_cfg80211_wifi_configuration_get(struct wiphy *wiphy,
+						    struct wireless_dev *wdev,
+						    const void *data,
+						    int data_len)
+{
+	int errno;
+	struct osif_vdev_sync *vdev_sync;
+
+	errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
+	if (errno)
+		return errno;
+
+	errno = __wlan_hdd_cfg80211_wifi_configuration_get(wiphy, wdev,
+							   data, data_len);
+
+	osif_vdev_sync_op_stop(vdev_sync);
+
+	return errno;
+}
+
+/**
  * __wlan_hdd_cfg80211_set_wifi_test_config() - Wifi test configuration
  * vendor command
  *
@@ -13500,6 +13737,14 @@
 	},
 	{
 		.info.vendor_id = QCA_NL80211_VENDOR_ID,
+		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_CONFIGURATION,
+		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+			WIPHY_VENDOR_CMD_NEED_NETDEV |
+			WIPHY_VENDOR_CMD_NEED_RUNNING,
+		.doit = wlan_hdd_cfg80211_wifi_configuration_get
+	},
+	{
+		.info.vendor_id = QCA_NL80211_VENDOR_ID,
 		.info.subcmd =
 			QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION,
 		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
diff --git a/os_if/fw_offload/inc/os_if_fwol.h b/os_if/fw_offload/inc/os_if_fwol.h
new file mode 100644
index 0000000..ec8a08f
--- /dev/null
+++ b/os_if/fw_offload/inc/os_if_fwol.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: os_if_fwol.h
+ *
+ * This Header file provide declaration for OS interface API
+ */
+
+#ifndef __OS_IF_FWOL_H__
+#define __OS_IF_FWOL_H__
+
+#include "wlan_objmgr_vdev_obj.h"
+
+#ifdef WLAN_FEATURE_ELNA
+/**
+ * os_if_fwol_set_elna_bypass() - Set eLNA bypass
+ * @vdev: Pointer to vdev
+ * @attr: Pointer to struct nlattr
+ *
+ * Return: 0 on success; error number otherwise
+ */
+int os_if_fwol_set_elna_bypass(struct wlan_objmgr_vdev *vdev,
+			       const struct nlattr *attr);
+
+/**
+ * os_if_fwol_get_elna_bypass() - Get eLNA bypass
+ * @vdev: Pointer to vdev
+ * @skb: sk buffer to hold nl80211 attributes
+ * @attr: Pointer to struct nlattr
+ *
+ * Return: 0 on success; error number otherwise
+ */
+int os_if_fwol_get_elna_bypass(struct wlan_objmgr_vdev *vdev,
+			       struct sk_buff *skb,
+			       const struct nlattr *attr);
+#else
+static inline int os_if_fwol_set_elna_bypass(struct wlan_objmgr_vdev *vdev,
+					     const struct nlattr *attr)
+{
+	return 0;
+}
+
+static inline int os_if_fwol_get_elna_bypass(struct wlan_objmgr_vdev *vdev,
+					     struct sk_buff *skb,
+					     const struct nlattr *attr)
+{
+	return 0;
+}
+#endif /* WLAN_FEATURE_ELNA */
+
+#endif /* __OS_IF_FWOL_H__ */
diff --git a/os_if/fw_offload/src/os_if_fwol.c b/os_if/fw_offload/src/os_if_fwol.c
new file mode 100644
index 0000000..bcb4c7d
--- /dev/null
+++ b/os_if/fw_offload/src/os_if_fwol.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: defines driver functions interfacing with linux kernel
+ */
+
+#include "wlan_cfg80211.h"
+#include "wlan_osif_request_manager.h"
+#include "wlan_fwol_public_structs.h"
+#include "wlan_fwol_ucfg_api.h"
+#include "os_if_fwol.h"
+
+#ifdef WLAN_FEATURE_ELNA
+#define WLAN_WAIT_TIME_GET_ELNA_BYPASS 1500
+
+int os_if_fwol_set_elna_bypass(struct wlan_objmgr_vdev *vdev,
+			       const struct nlattr *attr)
+{
+	struct set_elna_bypass_request req;
+	QDF_STATUS status;
+
+	req.vdev_id = vdev->vdev_objmgr.vdev_id;
+	req.en_dis = nla_get_u8(attr);
+	if (req.en_dis > 1) {
+		osif_err("Invalid elna_bypass value %d", req.en_dis);
+		return -EINVAL;
+	}
+
+	status = ucfg_fwol_set_elna_bypass(vdev, &req);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		osif_err("Failed to set ELNA BYPASS, %d", status);
+
+	return qdf_status_to_os_return(status);
+}
+
+struct osif_get_elna_bypass_priv {
+	uint8_t en_dis;
+};
+
+/**
+ * os_if_fwol_get_elna_bypass_callback() - Get eLNA bypass callback
+ * @context: Call context
+ * @response: Pointer to response structure
+ *
+ * Return: void
+ */
+static void
+os_if_fwol_get_elna_bypass_callback(void *context,
+				    struct get_elna_bypass_response *response)
+{
+	struct osif_request *request;
+	struct osif_get_elna_bypass_priv *priv;
+
+	request = osif_request_get(context);
+	if (!request) {
+		osif_err("Obsolete request");
+		return;
+	}
+
+	priv = osif_request_priv(request);
+	priv->en_dis = response->en_dis;
+
+	osif_request_complete(request);
+	osif_request_put(request);
+}
+
+int os_if_fwol_get_elna_bypass(struct wlan_objmgr_vdev *vdev,
+			       struct sk_buff *skb,
+			       const struct nlattr *attr)
+{
+	struct get_elna_bypass_request req;
+	void *cookie;
+	struct osif_request *request;
+	struct osif_get_elna_bypass_priv *priv;
+	static const struct osif_request_params params = {
+		.priv_size = sizeof(*priv),
+		.timeout_ms = WLAN_WAIT_TIME_GET_ELNA_BYPASS,
+	};
+	QDF_STATUS status;
+	int ret = 0;
+
+	req.vdev_id = vdev->vdev_objmgr.vdev_id;
+
+	request = osif_request_alloc(&params);
+	if (!request) {
+		osif_err("Request allocation failure");
+		return -ENOMEM;
+	}
+	cookie = osif_request_cookie(request);
+
+	status = ucfg_fwol_get_elna_bypass(vdev, &req,
+					   os_if_fwol_get_elna_bypass_callback,
+					   cookie);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		osif_err("Failed to get ELNA BYPASS, %d", status);
+		ret = qdf_status_to_os_return(status);
+		goto end;
+	}
+
+	ret = osif_request_wait_for_response(request);
+	if (ret) {
+		osif_err("Operation timed out");
+		goto end;
+	}
+
+	priv = osif_request_priv(request);
+	if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_CONFIG_ELNA_BYPASS,
+		       priv->en_dis)) {
+		osif_err("put fail");
+		ret = -EINVAL;
+	}
+
+end:
+	osif_request_put(request);
+	return ret;
+}
+#endif /* #ifdef WLAN_FEATURE_ELNA */