Merge changes I87205d59,I91332da9 into wlan-cld3.driver.lnx.2.0-dev

* changes:
  qcacld-3.0: fix a potential spinlock lockup issue
  qcacld-3.0: add device attribute 'tsf'
diff --git a/Kbuild b/Kbuild
index 6f7a83d..d439762 100644
--- a/Kbuild
+++ b/Kbuild
@@ -178,15 +178,11 @@
 	CONFIG_WLAN_FASTPATH := y
 
 	# Flag to enable NAPI
-ifeq (y,$(CONFIG_LITHIUM))
-	CONFIG_WLAN_NAPI := n
-	CONFIG_WLAN_NAPI_DEBUG := n
-else
 	CONFIG_WLAN_NAPI := y
 	CONFIG_WLAN_NAPI_DEBUG := n
-endif
+
 	# Flag to enable FW based TX Flow control
-	ifeq ($(CONFIG_CNSS_EOS),y)
+	ifeq (y,$(findstring y,$(CONFIG_CNSS_EOS) $(CONFIG_LITHIUM)))
 		CONFIG_WLAN_TX_FLOW_CONTROL_V2 := y
 	else
 		CONFIG_WLAN_TX_FLOW_CONTROL_V2 := n
@@ -887,11 +883,11 @@
 	$(UMAC_MGMT_TXRX_DIR)/dispatcher/src/wlan_mgmt_txrx_tgt_api.o
 
 ########## POWER MANAGEMENT OFFLOADS (PMO) ##########
-PMO_DIR := $(WLAN_COMMON_ROOT)/pmo
-PMO_INC :=      -I$(WLAN_COMMON_INC)/pmo/core/inc \
-		-I$(WLAN_COMMON_INC)/pmo/dispatcher/inc \
-		-I$(WLAN_COMMON_INC)/pmo/core/src \
-		-I$(WLAN_COMMON_INC)/pmo/dispatcher/src
+PMO_DIR :=	components/pmo
+PMO_INC :=	-I$(WLAN_ROOT)/$(PMO_DIR)/core/inc \
+			-I$(WLAN_ROOT)/$(PMO_DIR)/core/src \
+			-I$(WLAN_ROOT)/$(PMO_DIR)/dispatcher/inc \
+			-I$(WLAN_ROOT)/$(PMO_DIR)/dispatcher/src \
 
 PMO_OBJS :=     $(PMO_DIR)/core/src/wlan_pmo_main.o \
 		$(PMO_DIR)/core/src/wlan_pmo_arp.o \
@@ -917,6 +913,24 @@
 		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_hw_filter.o \
 		$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_pkt_filter.o
 
+########## CLD TARGET_IF #######
+CLD_TARGET_IF_DIR := components/target_if
+
+CLD_TARGET_IF_INC := -I$(WLAN_ROOT)/$(CLD_TARGET_IF_DIR)/pmo/inc \
+					 -I$(WLAN_ROOT)/$(CLD_TARGET_IF_DIR)/pmo/src \
+
+CLD_TARGET_IF_OBJ := $(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_arp.o \
+		$(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_gtk.o \
+		$(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_hw_filter.o \
+		$(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_lphb.o \
+		$(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_main.o \
+		$(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_mc_addr_filtering.o \
+		$(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_ns.o \
+		$(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_pkt_filter.o \
+		$(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_static_config.o \
+		$(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_suspend_resume.o \
+		$(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_wow.o \
+
 ############## UMAC P2P ###########
 P2P_DIR := umac/p2p
 P2P_CORE_DIR := $(P2P_DIR)/core
@@ -977,25 +991,12 @@
 TARGET_IF_INC := -I$(WLAN_COMMON_INC)/target_if/core/inc \
 		 -I$(WLAN_COMMON_INC)/target_if/core/src \
 		 -I$(WLAN_COMMON_INC)/target_if/init_deinit/inc \
-		 -I$(WLAN_COMMON_INC)/target_if/pmo/inc \
-		 -I$(WLAN_COMMON_INC)/target_if/pmo/src \
 		 -I$(WLAN_COMMON_INC)/target_if/p2p/inc \
 		 -I$(WLAN_COMMON_INC)/target_if/regulatory/inc \
 		 -I$(WLAN_COMMON_INC)/target_if/tdls/inc
 
 TARGET_IF_OBJ := $(TARGET_IF_DIR)/core/src/target_if_main.o \
 		$(TARGET_IF_DIR)/init_deinit/src/service_ready_event_handler.o \
-		$(TARGET_IF_DIR)/pmo/src/target_if_pmo_main.o \
-		$(TARGET_IF_DIR)/pmo/src/target_if_pmo_arp.o \
-		$(TARGET_IF_DIR)/pmo/src/target_if_pmo_ns.o \
-		$(TARGET_IF_DIR)/pmo/src/target_if_pmo_gtk.o \
-		$(TARGET_IF_DIR)/pmo/src/target_if_pmo_wow.o \
-		$(TARGET_IF_DIR)/pmo/src/target_if_pmo_hw_filter.o \
-		$(TARGET_IF_DIR)/pmo/src/target_if_pmo_mc_addr_filtering.o \
-		$(TARGET_IF_DIR)/pmo/src/target_if_pmo_static_config.o \
-		$(TARGET_IF_DIR)/pmo/src/target_if_pmo_lphb.o \
-		$(TARGET_IF_DIR)/pmo/src/target_if_pmo_suspend_resume.o \
-		$(TARGET_IF_DIR)/pmo/src/target_if_pmo_pkt_filter.o \
 		$(TARGET_IF_DIR)/p2p/src/target_if_p2p.o \
 		$(TARGET_IF_DIR)/regulatory/src/target_if_reg.o \
 		$(TARGET_IF_DIR)/tdls/src/target_if_tdls.o
@@ -1079,6 +1080,9 @@
 		$(DP_SRC)/dp_rx_mon_status.o \
 		$(DP_SRC)/dp_rx_defrag.o \
 		$(DP_SRC)/dp_stats.o
+ifeq ($(CONFIG_WLAN_TX_FLOW_CONTROL_V2), y)
+DP_OBJS += $(DP_SRC)/dp_tx_flow_control.o
+endif
 endif
 
 ############ CFG ############
@@ -1256,7 +1260,9 @@
 
 HIF_COMMON_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/ath_procfs.o \
                 $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_main.o \
-                $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/mp_dev.o
+                $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/mp_dev.o \
+                $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_exec.o \
+                $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_irq_affinity.o
 
 HIF_CE_OBJS :=  $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_bmi.o \
                 $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_diag.o \
@@ -1270,6 +1276,7 @@
                 $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_service_srng.o
 endif
 
+
 HIF_USB_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_USB_DIR)/usbdrv.o \
                 $(WLAN_COMMON_ROOT)/$(HIF_USB_DIR)/hif_usb.o \
                 $(WLAN_COMMON_ROOT)/$(HIF_USB_DIR)/if_usb.o \
@@ -1416,6 +1423,7 @@
 		$(CDS_INC) \
 		$(DFS_INC) \
 		$(TARGET_IF_INC) \
+		$(CLD_TARGET_IF_INC) \
 		$(OS_IF_INC) \
 		$(GLOBAL_LMAC_IF_INC)
 
@@ -1508,6 +1516,7 @@
 		$(HTT_OBJS) \
 		$(OS_IF_OBJ) \
 		$(TARGET_IF_OBJ) \
+		$(CLD_TARGET_IF_OBJ) \
 		$(GLOBAL_LMAC_IF_OBJ)
 
 ifeq ($(CONFIG_LITHIUM), y)
@@ -1647,6 +1656,7 @@
 
 ifeq ($(CONFIG_WLAN_NAPI), y)
 CDEFINES += -DFEATURE_NAPI
+CDEFINES += -DHIF_IRQ_AFFINITY
 ifeq ($(CONFIG_WLAN_NAPI_DEBUG), y)
 CDEFINES += -DFEATURE_NAPI_DEBUG
 endif
diff --git a/Kconfig b/Kconfig
index 6536ec7..f8feafc 100644
--- a/Kconfig
+++ b/Kconfig
@@ -105,7 +105,7 @@
 config WLAN_LRO
 	bool "Enable Large Receive Offload"
 	depends on HELIUMPLUS
-	depends on CONFIG_INET_LRO
+	depends on INET_LRO
 	default n
 
 config WLAN_SYNC_TSF
diff --git a/components/pmo/core/inc/wlan_pmo_arp.h b/components/pmo/core/inc/wlan_pmo_arp.h
new file mode 100644
index 0000000..8d97eec
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_arp.h
@@ -0,0 +1,71 @@
+/*
+* Copyright (c) 2017 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: Declare arp offload feature API's
+ */
+
+#ifndef _WLAN_PMO_ARP_H_
+#define _WLAN_PMO_ARP_H_
+
+#include "wlan_pmo_arp_public_struct.h"
+
+/**
+ * pmo_core_cache_arp_offload_req() - API to cache arp req in pmo vdev priv ctx
+ * @arp_req: arp offload request
+ *
+ * API To cache ARP offload in pmo vdev priv ctx
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_cache_arp_offload_req(struct pmo_arp_req *arp_req);
+
+/**
+ * pmo_core_flush_arp_offload_req() - API to flush arp req from pmo vdev ctx
+ * @vdev: objmgr vdev
+ *
+ * API To flush saved ARP request from pmo vdev prov ctx
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_flush_arp_offload_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_enable_arp_offload_in_fwr() - API to enable arp offload in fwr
+ * @vdev: objmgr vdev
+ * @trigger: trigger reason
+ *
+ *  API to enable arp offload in fwr from vdev priv ctx
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_enable_arp_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_core_disable_arp_offload_in_fwr() - API to disable arp offload in fwr
+ * @vdev: objmgr vdev
+ * @trigger: trigger reason
+ *
+ *  API to disable arp offload in fwr
+ *
+ * Return: QQDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_disable_arp_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger);
+
+#endif /* end  of _WLAN_PMO_ARP_H_ */
diff --git a/components/pmo/core/inc/wlan_pmo_gtk.h b/components/pmo/core/inc/wlan_pmo_gtk.h
new file mode 100644
index 0000000..2a9d9f5
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_gtk.h
@@ -0,0 +1,74 @@
+/*
+* Copyright (c) 2017 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: Declare gtk offload feature API's
+ */
+
+#ifndef _WLAN_PMO_GTK_H_
+#define _WLAN_PMO_GTK_H_
+
+#include "wlan_pmo_gtk_public_struct.h"
+
+/**
+ * pmo_core_cache_gtk_offload_req(): API to cache gtk req in pmo vdev priv obj
+ * @vdev: objmgr vdev handle
+ * @gtk_req: pmo gtk req param
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_cache_gtk_offload_req(struct wlan_objmgr_vdev *vdev,
+		struct pmo_gtk_req *gtk_req);
+
+/**
+ * pmo_core_flush_gtk_offload_req(): Flush saved gtk req from pmo vdev priv obj
+ * @vdev: objmgr vdev handle
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_flush_gtk_offload_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_enable_gtk_offload_in_fwr(): enable cached gtk request in fwr
+ * @vdev: objmgr vdev handle
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_enable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_disable_gtk_offload_in_fwr(): disable cached gtk request in fwr
+ * @vdev: objmgr vdev handle
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_disable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_get_gtk_rsp(): API to send gtk response request to fwr
+ * @vdev: objmgr vdev handle
+ * @gtk_rsp: pmo gtk response request
+ *
+ * This api will send gtk response request to fwr
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_get_gtk_rsp(struct wlan_objmgr_vdev *vdev,
+			struct pmo_gtk_rsp_req *gtk_rsp_req);
+
+#endif /* end  of _WLAN_PMO_GTK_H_ */
+
diff --git a/components/pmo/core/inc/wlan_pmo_hw_filter.h b/components/pmo/core/inc/wlan_pmo_hw_filter.h
new file mode 100644
index 0000000..c3cab64
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_hw_filter.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017 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: Declare hardware filter offload feature APIs
+ */
+
+#ifndef _WLAN_PMO_HW_FILTER_H_
+#define _WLAN_PMO_HW_FILTER_H_
+
+#include "qdf_status.h"
+#include "wlan_objmgr_vdev_obj.h"
+#include "wlan_pmo_hw_filter_public_struct.h"
+
+/**
+ * pmo_core_enable_hw_filter_in_fwr() - enable previously configured hw filter
+ * @vdev: objmgr vdev to configure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_core_enable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_disable_hw_filter_in_fwr() - disable previously configured hw filter
+ * @vdev: objmgr vdev to configure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_core_disable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+#endif /* _WLAN_PMO_HW_FILTER_H_*/
diff --git a/components/pmo/core/inc/wlan_pmo_lphb.h b/components/pmo/core/inc/wlan_pmo_lphb.h
new file mode 100644
index 0000000..20b6952
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_lphb.h
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2017 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: Declare low power heart beat offload feature API's
+ */
+
+#ifndef _WLAN_PMO_LPHB_H_
+#define _WLAN_PMO_LPHB_H_
+
+#include "wlan_pmo_lphb_public_struct.h"
+
+/**
+ * pmo_core_lphb_config_req() - API to configure lphb request
+ * @psoc: objmgr psoc handle
+ * @lphb_req: low power heart beat configuration request
+ * @lphb_cb_ctx: low power heart beat context
+ * @callback: osif callback which need to be called when host get lphb event
+ *
+ * API to configure lphb request
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_lphb_config_req(struct wlan_objmgr_psoc *psoc,
+		struct pmo_lphb_req *lphb_req, void *lphb_cb_ctx,
+		pmo_lphb_callback callback);
+
+/**
+ * pmo_core_apply_lphb(): apply cached LPHB settings
+ * @psoc: objmgr psoc handle
+ *
+ * LPHB cache, if any item was enabled, should be
+ * applied.
+ */
+void pmo_core_apply_lphb(struct wlan_objmgr_psoc *psoc);
+
+#endif /* end  of _WLAN_PMO_LPHB_H_ */
diff --git a/components/pmo/core/inc/wlan_pmo_main.h b/components/pmo/core/inc/wlan_pmo_main.h
new file mode 100644
index 0000000..4f09597
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_main.h
@@ -0,0 +1,357 @@
+/*
+* Copyright (c) 2017 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: declare various api which shall be used by
+ * pmo user configuration and target interface
+ */
+
+#ifndef _WLAN_PMO_MAIN_H_
+#define _WLAN_PMO_MAIN_H_
+
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_priv.h"
+#include "wlan_pmo_objmgr.h"
+
+#define pmo_log(level, args...) QDF_TRACE(QDF_MODULE_ID_PMO, level, ## args)
+#define pmo_logfl(level, format, args...) pmo_log(level, FL(format), ## args)
+
+#define pmo_fatal(format, args...) \
+		pmo_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args)
+#define pmo_err(format, args...) \
+		pmo_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args)
+#define pmo_warn(format, args...) \
+		pmo_logfl(QDF_TRACE_LEVEL_WARN, format, ## args)
+#define pmo_info(format, args...) \
+		pmo_logfl(QDF_TRACE_LEVEL_INFO, format, ## args)
+#define pmo_debug(format, args...) \
+		pmo_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args)
+
+#define PMO_ENTER() pmo_debug("enter")
+#define PMO_EXIT() pmo_debug("exit")
+
+#define PMO_VDEV_IN_STA_MODE(mode) \
+	((mode) == QDF_STA_MODE || (mode) == QDF_P2P_CLIENT_MODE ? 1 : 0)
+
+static inline enum tQDF_ADAPTER_MODE pmo_get_vdev_opmode(
+			struct wlan_objmgr_vdev *vdev)
+{
+	enum tQDF_ADAPTER_MODE opmode;
+
+	opmode = wlan_vdev_mlme_get_opmode(vdev);
+
+	return opmode;
+}
+
+/**
+ * pmo_allocate_ctx() - Api to allocate pmo ctx
+ *
+ * Helper function to allocate pmo ctx
+ *
+ * Return: Success or failure.
+ */
+QDF_STATUS pmo_allocate_ctx(void);
+
+/**
+ * pmo_free_ctx() - to free pmo context
+ *
+ * Helper function to free pmo context
+ *
+ * Return: None.
+ */
+void pmo_free_ctx(void);
+
+/**
+ * pmo_get_context() - to get pmo context
+ *
+ * Helper function to get pmo context
+ *
+ * Return: pmo context.
+ */
+struct wlan_pmo_ctx *pmo_get_context(void);
+
+/**
+ * pmo_get_vdev_bss_peer_mac_addr() - API to get bss peer mac address
+ * @vdev: objmgr vdev
+ * @bss_peer_mac_address: bss peer mac address
+ *.
+ * Helper function to  get bss peer mac address
+ *
+ * Return: if success pmo vdev ctx else NULL
+ */
+QDF_STATUS pmo_get_vdev_bss_peer_mac_addr(struct wlan_objmgr_vdev *vdev,
+		struct qdf_mac_addr *bss_peer_mac_address);
+
+/**
+ * pmo_is_vdev_in_beaconning_mode() - check if vdev is in a beaconning mode
+ * @vdev_opmode: vdev opmode
+ *
+ * Helper function to know whether given vdev
+ * is in a beaconning mode or not.
+ *
+ * Return: True if vdev needs to beacon.
+ */
+bool pmo_is_vdev_in_beaconning_mode(enum tQDF_ADAPTER_MODE vdev_opmode);
+
+/**
+ * pmo_core_is_ap_mode_supports_arp_ns() - To check ap mode supports arp/ns
+ * @vdev_opmode: vdev opmode
+ *
+ * API to check if ap mode supports arp/ns offload
+ *
+ * Return: True  if ap mode supports arp/ns offload
+ */
+
+bool pmo_core_is_ap_mode_supports_arp_ns(struct wlan_objmgr_psoc *psoc,
+	enum tQDF_ADAPTER_MODE vdev_opmode);
+
+/**
+ * pmo_core_is_vdev_connected() -  to check whether peer is associated or not
+ * @vdev: objmgr vdev
+ *
+ * Return: true in case success else false
+ */
+bool pmo_core_is_vdev_connected(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_is_vdev_supports_offload() - Check offload is supported on vdev
+ * @vdev: objmgr vdev
+ *
+ * Return: true in case success else false
+ */
+bool pmo_core_is_vdev_supports_offload(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_get_psoc_config(): API to get the psoc user configurations of pmo
+ * @psoc: objmgr psoc handle
+ * @psoc_cfg: fill the current psoc user configurations.
+ *
+ * Return pmo psoc configurations
+ */
+QDF_STATUS pmo_core_get_psoc_config(struct wlan_objmgr_psoc *psoc,
+		struct pmo_psoc_cfg *psoc_cfg);
+
+/**
+ * pmo_core_update_psoc_config(): API to update the psoc user configurations
+ * @psoc: objmgr psoc handle
+ * @psoc_cfg: pmo psoc configurations
+ *
+ * This api shall be used for soc config initialization as well update.
+ * In case of update caller must first call pmo_get_psoc_cfg to get
+ * current config and then apply changes on top of current config.
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_core_update_psoc_config(struct wlan_objmgr_psoc *psoc,
+		struct pmo_psoc_cfg *psoc_cfg);
+
+
+/**
+ * pmo_core_get_vdev_op_mode(): API to get the vdev operation mode
+ * @vdev: objmgr vdev handle
+ *
+ * API to get the vdev operation mode
+ *
+ * Return QDF_MAX_NO_OF_MODE - in case of error else return vdev opmode
+ */
+static inline enum tQDF_ADAPTER_MODE pmo_core_get_vdev_op_mode(
+					struct wlan_objmgr_vdev *vdev)
+{
+	enum tQDF_ADAPTER_MODE op_mode = QDF_MAX_NO_OF_MODE;
+
+	if (!vdev)
+		return op_mode;
+	op_mode = wlan_vdev_mlme_get_opmode(vdev);
+
+	return op_mode;
+}
+
+/**
+ * pmo_core_psoc_update_dp_handle() - update psoc data path handle
+ * @psoc: objmgr psoc handle
+ * @dp_hdl: psoc data path handle
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_psoc_update_dp_handle(struct wlan_objmgr_psoc *psoc,
+	void *dp_hdl)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	psoc_ctx->dp_hdl = dp_hdl;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+/**
+ * pmo_core_psoc_get_dp_handle() - Get psoc data path handle
+ * @psoc: objmgr psoc handle
+ *
+ * Return: psoc data path handle
+ */
+static inline
+void *pmo_core_psoc_get_dp_handle(struct wlan_objmgr_psoc *psoc)
+{
+	void *dp_hdl;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	dp_hdl = psoc_ctx->dp_hdl;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+	return dp_hdl;
+}
+
+/**
+ * pmo_core_vdev_update_dp_handle() - update vdev data path handle
+ * @vdev: objmgr vdev handle
+ * @dp_hdl: Vdev data path handle
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_vdev_update_dp_handle(struct wlan_objmgr_vdev *vdev,
+	void *dp_hdl)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	vdev_ctx->vdev_dp_hdl = dp_hdl;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+
+/**
+ * pmo_core_vdev_get_dp_handle() - Get vdev data path handle
+ * @vdev: objmgr vdev handle
+ *
+ * Return: Vdev data path handle
+ */
+static inline
+void *pmo_core_vdev_get_dp_handle(struct wlan_objmgr_vdev *vdev)
+{
+	void *dp_hdl;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	dp_hdl = vdev_ctx->vdev_dp_hdl;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	return dp_hdl;
+}
+
+/**
+ * pmo_core_psoc_update_htc_handle() - update psoc htc layer handle
+ * @psoc: objmgr psoc handle
+ * @htc_hdl: psoc htc layer handle
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_psoc_update_htc_handle(struct wlan_objmgr_psoc *psoc,
+	void *htc_hdl)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	psoc_ctx->htc_hdl = htc_hdl;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+/**
+ * pmo_core_psoc_get_htc_handle() - Get psoc htc layer handle
+ * @psoc: objmgr psoc handle
+ *
+ * Return: psoc htc layer handle
+ */
+static inline
+void *pmo_core_psoc_get_htc_handle(struct wlan_objmgr_psoc *psoc)
+{
+	void *htc_hdl;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	htc_hdl = psoc_ctx->htc_hdl;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+	return htc_hdl;
+}
+
+/**
+ * pmo_core_psoc_set_hif_handle() - update psoc hif layer handle
+ * @psoc: objmgr psoc handle
+ * @hif_hdl: hif context handle
+ *
+ * Return: None
+ */
+void pmo_core_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc,
+				  void *hif_hdl);
+
+/**
+ * pmo_core_psoc_get_hif_handle() - Get psoc hif layer handle
+ * @psoc: objmgr psoc handle
+ *
+ * Return: psoc hif layer handle
+ */
+void *pmo_core_psoc_get_hif_handle(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_core_psoc_set_txrx_handle() - update psoc pdev txrx layer handle
+ * @psoc: objmgr psoc handle
+ * @txrx_hdl: pdev txrx context handle
+ *
+ * Return: None
+ */
+void pmo_core_psoc_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+				   void *txrx_hdl);
+
+/**
+ * pmo_core_psoc_get_txrx_handle() - Get psoc pdev txrx handle
+ * @psoc: objmgr psoc handle
+ *
+ * Return: pdev txrx handle
+ */
+void *pmo_core_psoc_get_txrx_handle(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_is_vdev_up() - API to check whether vdev is UP
+ * @vdev: objmgr vdev handle
+ *
+ * Return:true if vdev is up else false
+ */
+static inline
+bool pmo_is_vdev_up(struct wlan_objmgr_vdev *vdev)
+{
+	enum wlan_vdev_state state = WLAN_VDEV_S_INIT;
+
+	if (!vdev) {
+		pmo_err("vdev context is invalid!");
+		return false;
+	}
+	state = wlan_vdev_mlme_get_state(vdev);
+
+	return state == WLAN_VDEV_S_RUN;
+}
+
+#endif /* end  of _WLAN_PMO_MAIN_H_ */
diff --git a/components/pmo/core/inc/wlan_pmo_mc_addr_filtering.h b/components/pmo/core/inc/wlan_pmo_mc_addr_filtering.h
new file mode 100644
index 0000000..ddedb64
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_mc_addr_filtering.h
@@ -0,0 +1,129 @@
+/*
+* Copyright (c) 2017 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: Declare mc addr filtering offload feature API's
+ */
+
+#ifndef _WLAN_PMO_MC_ADDR_FILTERING_H_
+#define _WLAN_PMO_MC_ADDR_FILTERING_H_
+
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_mc_addr_filtering_public_struct.h"
+
+/**
+ * pmo_core_set_mc_filter_req() -send mc filter set request
+ * @vdev: objmgr vdev
+ * @mc_list: a list of mc addresses to set in fwr
+ *
+ * Return: QDF_STATUS_SUCCESS in success else error codes
+ */
+QDF_STATUS pmo_core_set_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+	struct pmo_mc_addr_list *mc_list);
+
+/**
+ * pmo_clear_mc_filter_req() -send mc filter clear request
+ * @vdev: objmgr vdev
+ * @mc_list: a list of mc addresses to clear in fwr
+ *
+ * Return: QDF_STATUS_SUCCESS in success else error codes
+ */
+QDF_STATUS pmo_core_clear_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+	struct pmo_mc_addr_list *mc_list);
+
+/**
+ * pmo_core_cache_mc_addr_list(): API to cache mc addr list in pmo vdev priv obj
+ * @psoc: objmgr psoc handle
+ * @vdev_id: vdev id
+ * @gtk_req: pmo gtk req param
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_cache_mc_addr_list(
+		struct pmo_mc_addr_list_params *mc_list_config);
+
+/**
+ * pmo_core_flush_mc_addr_list(): API to flush mc addr list in pmo vdev priv obj
+ * @psoc: objmgr psoc handle
+ * @vdev_id: vdev id
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_flush_mc_addr_list(struct wlan_objmgr_psoc *psoc,
+	uint8_t vdev_id);
+
+/**
+ * pmo_core_enable_mc_addr_filtering_in_fwr(): Enable cached mc add list in fwr
+ * @psoc: objmgr psoc handle
+ * @vdev_id: vdev id
+ * @gtk_req: pmo gtk req param
+ * @action: true for enable els false
+ *
+ * API to enable cached mc add list in fwr
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_enable_mc_addr_filtering_in_fwr(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id,
+		enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_core_disable_mc_addr_filtering_in_fwr(): Disable cached mc addr list
+ * @psoc: objmgr psoc handle
+ * @vdev_id: vdev id
+ * @gtk_req: pmo gtk req param
+ * @action: true for enable els false
+ *
+ * API to disable cached mc add list in fwr
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_disable_mc_addr_filtering_in_fwr(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id,
+		enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_core_get_mc_addr_list_count() -set  mc address count
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id
+ *
+ * Return: set mc address count
+ */
+void pmo_core_set_mc_addr_list_count(struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id, uint8_t count);
+
+/**
+ * pmo_core_get_mc_addr_list_count() -get current mc address count
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id
+ *
+ * Return: current mc address count
+ */
+int pmo_core_get_mc_addr_list_count(struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id);
+
+/**
+ * pmo_core_max_mc_addr_supported() -get max supported mc addresses
+ * @psoc: objmgr psoc
+ *
+ * Return: max supported mc addresses
+ */
+uint8_t pmo_core_max_mc_addr_supported(struct wlan_objmgr_psoc *psoc);
+
+#endif /* end  of _WLAN_PMO_MC_ADDR_FILTERING_H_ */
diff --git a/components/pmo/core/inc/wlan_pmo_ns.h b/components/pmo/core/inc/wlan_pmo_ns.h
new file mode 100644
index 0000000..de30ba9
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_ns.h
@@ -0,0 +1,72 @@
+/*
+* Copyright (c) 2017 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: Declare ns offload feature API's
+ */
+
+#ifndef _WLAN_PMO_NS_H_
+#define _WLAN_PMO_NS_H_
+
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_ns_public_struct.h"
+
+/**
+ * pmo_core_cache_ns_offload_req() - API to cache ns req in pmo vdev priv ctx
+ * @ns_req: ns offload request
+ *
+ * API to cache ns offload in pmo vdev priv ctx
+ *
+ * Return:QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_cache_ns_offload_req(struct pmo_ns_req *ns_req);
+
+/**
+ * pmo_core_flush_ns_offload_req() - API to flush ns req from pmo vdev priv ctx
+ * @vdev: vdev objmgr handle
+ *
+ * API to flush ns offload from pmo vdev priv ctx
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_flush_ns_offload_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_enable_ns_offload_in_fwr() -  API to enable ns offload in fwr
+ * @vdev: objmgr vdev
+ * @trigger: trigger reason enable ns offload
+ *
+ * API to enable ns offload in fwr from vdev priv ctx
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_enable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_core_disable_ns_offload_in_fwr() - API to disable ns offload in fwr
+ * @vdev: objmgr vdev
+ * @trigger: trigger reason disable ns offload
+ *
+ *  API to disable arp offload in fwr
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_disable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger);
+
+#endif /* end  of _WLAN_PMO_NS_H_ */
diff --git a/components/pmo/core/inc/wlan_pmo_objmgr.h b/components/pmo/core/inc/wlan_pmo_objmgr.h
new file mode 100644
index 0000000..10b9889
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_objmgr.h
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2017 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 various object manager related wrappers and helpers
+ */
+
+#ifndef _WLAN_PMO_OBJMGR_H
+#define _WLAN_PMO_OBJMGR_H
+
+#include "wlan_cmn.h"
+#include "wlan_objmgr_cmn.h"
+#include "wlan_objmgr_peer_obj.h"
+#include "wlan_objmgr_vdev_obj.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+/* Get/Put Ref */
+
+#define pmo_peer_get_ref(peer) wlan_objmgr_peer_try_get_ref(peer, WLAN_PMO_ID)
+#define pmo_peer_put_ref(peer) wlan_objmgr_peer_release_ref(peer, WLAN_PMO_ID)
+
+#define pmo_vdev_get_ref(vdev) wlan_objmgr_vdev_try_get_ref(vdev, WLAN_PMO_ID)
+#define pmo_vdev_put_ref(vdev) wlan_objmgr_vdev_release_ref(vdev, WLAN_PMO_ID)
+
+#define pmo_pdev_get_ref(pdev) wlan_objmgr_pdev_try_get_ref(pdev, WLAN_PMO_ID)
+#define pmo_pdev_put_ref(pdev) wlan_objmgr_pdev_release_ref(pdev, WLAN_PMO_ID)
+
+#define pmo_psoc_get_ref(psoc) wlan_objmgr_psoc_try_get_ref(psoc, WLAN_PMO_ID)
+#define pmo_psoc_put_ref(psoc) wlan_objmgr_psoc_release_ref(psoc, WLAN_PMO_ID)
+
+/* Private Data */
+
+#define pmo_vdev_get_priv_nolock(vdev) \
+	wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_PMO)
+#define pmo_psoc_get_priv_nolock(psoc) \
+	wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_PMO)
+
+/* Ids */
+
+static inline uint8_t
+pmo_vdev_get_id(struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t vdev_id;
+
+	vdev_id = wlan_vdev_get_id(vdev);
+
+	QDF_BUG(vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS);
+
+	return vdev_id;
+}
+
+/* Tree Navigation */
+
+/**
+ * !PLEASE READ!
+ *
+ * The following are objmgr naviation helpers for traversing objmgr object
+ * trees.
+ *
+ * Objmgr ensures parents of an objmgr object cannot be freed while a valid
+ * reference to one of its children is held. Based on this fact, all of these
+ * navigation helpers make the following assumptions to ensure safe usage:
+ *
+ * 1) The caller must hold a valid reference to the input objmgr object!
+ *	E.g. Use pmo_[peer|vdev|pdev|psoc]_get_ref() on the input objmgr object
+ *	before using these APIs
+ * 2) Given assumption #1, the caller does not need to hold a reference to the
+ *	parents of the input objmgr object
+ * 3) Given assumption #1, parents of the input objmgr object cannot be null
+ * 4) Given assumption #1, private contexts of any parent of the input objmgr
+ *	object cannot be null
+ *
+ * These characteristics remove the need for most sanity checks when dealing
+ * with objmgr objects. However, please note that if you ever walk the tree
+ * from parent to child, references must be acquired all the way down!
+ *
+ * Example #1:
+ *
+ *	psoc = pmo_vdev_get_psoc(vdev);
+ *	if (!psoc)
+ *		// this is dead code
+ *
+ * Example #2:
+ *
+ *	psoc_priv = pmo_psoc_get_priv(psoc);
+ *	if (!psoci_priv)
+ *		// this is dead code
+ *
+ * Example #3:
+ *
+ *	status = pmo_vdev_get_ref(vdev);
+ *
+ *	...
+ *
+ *	psoc = pmo_vdev_get_psoc(vdev);
+ *
+ *	// the next line is redundant, don't do it!
+ *	status = pmo_psoc_get_ref(psoc);
+ */
+
+/* Tree Navigation: psoc */
+
+static inline struct wlan_objmgr_vdev *
+pmo_psoc_get_vdev(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+
+	if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) {
+		QDF_BUG(0);
+		return NULL;
+	}
+
+	wlan_psoc_obj_lock(psoc);
+	vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id];
+	wlan_psoc_obj_unlock(psoc);
+
+	return vdev;
+}
+
+static inline struct pmo_psoc_priv_obj *
+pmo_psoc_get_priv(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_priv;
+
+	psoc_priv = pmo_psoc_get_priv_nolock(psoc);
+
+	QDF_BUG(psoc_priv);
+
+	return psoc_priv;
+}
+
+/* Tree Navigation: pdev */
+
+static inline struct wlan_objmgr_psoc *
+pmo_pdev_get_psoc(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_objmgr_psoc *psoc;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+
+	QDF_BUG(psoc);
+
+	return psoc;
+}
+
+static inline struct pmo_psoc_priv_obj *
+pmo_pdev_get_psoc_priv(struct wlan_objmgr_pdev *pdev)
+{
+	return pmo_psoc_get_priv(pmo_pdev_get_psoc(pdev));
+}
+
+/* Tree Navigation: vdev */
+
+static inline struct pmo_vdev_priv_obj *
+pmo_vdev_get_priv(struct wlan_objmgr_vdev *vdev)
+{
+	struct pmo_vdev_priv_obj *vdev_priv;
+
+	vdev_priv = pmo_vdev_get_priv_nolock(vdev);
+
+	QDF_BUG(vdev_priv);
+
+	return vdev_priv;
+}
+
+static inline struct wlan_objmgr_pdev *
+pmo_vdev_get_pdev(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_pdev *pdev;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+
+	QDF_BUG(pdev);
+
+	return pdev;
+}
+
+static inline struct wlan_objmgr_psoc *
+pmo_vdev_get_psoc(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_pdev_get_psoc(pmo_vdev_get_pdev(vdev));
+}
+
+static inline struct pmo_psoc_priv_obj *
+pmo_vdev_get_psoc_priv(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_psoc_get_priv(pmo_pdev_get_psoc(pmo_vdev_get_pdev(vdev)));
+}
+
+#endif /* _WLAN_PMO_OBJMGR_H */
diff --git a/components/pmo/core/inc/wlan_pmo_pkt_filter.h b/components/pmo/core/inc/wlan_pmo_pkt_filter.h
new file mode 100644
index 0000000..0a900e5
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_pkt_filter.h
@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2017 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: Declare packet filter feature API's
+ */
+
+#ifndef _WLAN_PMO_PKT_FILTER_H_
+#define _WLAN_PMO_PKT_FILTER_
+
+#include "wlan_pmo_pkt_filter_public_struct.h"
+
+struct wlan_objmgr_psoc;
+
+/**
+ * pmo_set_pkt_fltr_req() - Set packet filter
+ * @vdev: objmgr vdev
+ * @pmo_set_pkt_fltr_req:
+ * @vdev_id:
+ *  API to set packet filter
+ *
+ * Return: QQDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_set_pkt_filter(struct wlan_objmgr_psoc *psoc,
+			struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req,
+			uint8_t vdev_id);
+
+/**
+ * pmo_core_clear_pkt_filter() - Clear packet filter
+ * @vdev: objmgr vdev
+ * @pmo_clr_pkt_fltr_req:
+ * @vdev_id:
+ *
+ *  API to clear packet filter
+ *
+ * Return: QQDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_clear_pkt_filter(struct wlan_objmgr_psoc *psoc,
+		struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_req,
+		uint8_t vdev_id);
+
+#endif /* end  of _WLAN_PMO_PKT_FILTER_H_ */
+
diff --git a/components/pmo/core/inc/wlan_pmo_priv.h b/components/pmo/core/inc/wlan_pmo_priv.h
new file mode 100644
index 0000000..8c7614d
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_priv.h
@@ -0,0 +1,130 @@
+/*
+* Copyright (c) 2017 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: Declare various struct, macros which are used for private to PMO.
+  *
+  * Note: This file shall not contain public API's prototype/declarations.
+  *
+  */
+
+#ifndef _WLAN_PMO_PRIV_STRUCT_H_
+#define _WLAN_PMO_PRIV_STRUCT_H_
+
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_arp_public_struct.h"
+#include "wlan_pmo_ns_public_struct.h"
+#include "wlan_pmo_gtk_public_struct.h"
+#include "wlan_pmo_wow_public_struct.h"
+#include "wlan_pmo_mc_addr_filtering_public_struct.h"
+
+/**
+ * struct pmo_psoc_priv_obj - psoc related data require for pmo
+ * @psoc_cfg: place holder for psoc configuration
+ * @pmo_tx_ops: transmit ops for PMO
+ * @wow: wow configuration
+ * @dp_hdl: psoc data path handle
+ * @htc_hdl: htc layer handle
+ * @hif_hdl: hif layer handle
+ * @txrx_hdl: txrx pdev handle
+ * @pause_bitmap_notifier: registered callback to update pause bitmap value
+ * @pmo_get_pause_bitmap: registered callback to get pause bitmap value
+ * @lock: spin lock for pmo psoc
+ */
+struct pmo_psoc_priv_obj {
+	struct pmo_psoc_cfg psoc_cfg;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+	struct pmo_wow wow;
+	void *dp_hdl;
+	void *htc_hdl;
+	void *hif_hdl;
+	void *txrx_hdl;
+	pmo_notify_pause_bitmap pause_bitmap_notifier;
+	pmo_get_pause_bitmap get_pause_bitmap;
+	pmo_is_device_in_low_pwr_mode is_device_in_low_pwr_mode;
+	qdf_spinlock_t lock;
+};
+
+/**
+ * struct wlan_pmo_ctx -offload mgr context
+ * @psoc_context:     psoc context
+ * @pmo_suspend_handler: suspend handler table for all componenets
+ * @pmo_suspend_handler_arg: suspend handler argument sfor all componenets
+ * @pmo_resume_handler: resume handler table for all componenets
+ * @pmo_resume_handler_arg: resume handler argument for all componenets
+ * @lock: lock for global pmo ctx
+ */
+struct wlan_pmo_ctx {
+	pmo_psoc_suspend_handler
+		pmo_suspend_handler[WLAN_UMAC_MAX_COMPONENTS];
+	void *pmo_suspend_handler_arg[WLAN_UMAC_MAX_COMPONENTS];
+	pmo_psoc_resume_handler
+		pmo_resume_handler[WLAN_UMAC_MAX_COMPONENTS];
+	void *pmo_resume_handler_arg[WLAN_UMAC_MAX_COMPONENTS];
+	qdf_spinlock_t lock;
+};
+
+/**
+ * struct pmo_vdev_priv_obj -vdev specific user configuration required for pmo
+ * @pmo_psoc_ctx: pmo psoc ctx
+ * @vdev_arp_req: place holder for arp request for vdev
+ * @vdev_ns_req: place holder for ns request for vdev
+ * @vdev_mc_list_req: place holder for mc addr list for vdev
+ * @addr_filter_pattern: addr filter pattern for vdev
+ * @vdev_gtk_params: place holder for gtk request for vdev
+ * @gtk_err_enable: gtk error is enabled or not
+ * @vdev_bpf_req: place holder for apf/bpf for vdev
+ * @vdev_pkt_filter: place holder for vdev packet filter
+ * @ptrn_match_enable: true when pattern match is enabled else false
+ * @num_wow_default_patterns: number of wow default patterns for vdev
+ * @num_wow_user_patterns: number of user wow patterns for vdev
+ * @nlo_in_progress: true when pno/nlo in progress else false
+ * @nlo_match_received: true when nlo match recevied from fwr else false
+ * @extscan_in_progress: true when extscan in progress else false
+ * @p2plo_in_progress: true when p2plo_in_progress in progress else false
+ * @dtim_period: dtim period for vdev
+ * @beacon_interval: vdev beacon interval
+ * @alt_modulated_dtim_enabled:dynamic modulated dtim enabled
+ * @dtim_policy: tells vdev beacon dtim policy
+ * @vdev_dp_hdl: vdev data path handle
+ * @pmo_vdev_lock: spin lock for pmo vdev priv ctx
+ */
+struct pmo_vdev_priv_obj {
+	struct pmo_psoc_priv_obj *pmo_psoc_ctx;
+	struct pmo_arp_offload_params vdev_arp_req;
+	struct pmo_ns_offload_params vdev_ns_req;
+	struct pmo_mc_addr_list vdev_mc_list_req;
+	uint8_t addr_filter_pattern;
+	struct pmo_gtk_req vdev_gtk_req;
+	struct pmo_gtk_rsp_req vdev_gtk_rsp_req;
+	qdf_atomic_t gtk_err_enable;
+	bool ptrn_match_enable;
+	uint8_t num_wow_default_patterns;
+	uint8_t num_wow_user_patterns;
+	bool nlo_in_progress;
+	bool nlo_match_received;
+	bool extscan_in_progress;
+	bool p2plo_in_progress;
+	uint8_t dtim_period;
+	uint8_t beacon_interval;
+	bool alt_modulated_dtim_enable;
+	uint32_t dtim_policy;
+	void *vdev_dp_hdl;
+	qdf_spinlock_t pmo_vdev_lock;
+};
+
+#endif /* end  of _WLAN_PMO_PRIV_STRUCT_H_ */
diff --git a/components/pmo/core/inc/wlan_pmo_static_config.h b/components/pmo/core/inc/wlan_pmo_static_config.h
new file mode 100644
index 0000000..fe4544b
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_static_config.h
@@ -0,0 +1,117 @@
+/*
+* Copyright (c) 2017 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: Declare static configuration on vdev attach
+ */
+
+#ifndef _WLAN_PMO_STATIC_CONFIG_H_
+#define _WLAN_PMO_STATIC_CONFIG_H_
+
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_wow.h"
+
+/**
+ * pmo_register_wow_wakeup_events() - register vdev specific wake events with fw
+ * @vdev: objmgr vdev
+ *
+ * WoW wake up event rule is following:
+ * 1) STA mode and P2P CLI mode wake up events are same
+ * 2) SAP mode and P2P GO mode wake up events are same
+ * 3) IBSS mode wake events are same as STA mode plus WOW_BEACON_EVENT
+ *
+ * Return: none
+ */
+void pmo_register_wow_wakeup_events(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_register_wow_default_patterns() - register default wow patterns with fw
+ * @vdev_id: vdev id
+ *
+ * WoW default wake up pattern rule is:
+ *  - For STA & P2P CLI mode register for same STA specific wow patterns
+ *  - For SAP/P2P GO & IBSS mode register for same SAP specific wow patterns
+ *
+ * Return: none
+ */
+void pmo_register_wow_default_patterns(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_register_action_frame_patterns() - register action frame map to fw
+ * @vdev: objmgr vdev
+ *
+ * This is called to push action frames wow patterns from local
+ * cache to firmware.
+ *
+ * Return: None
+ */
+void pmo_register_action_frame_patterns(
+		struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_update_target_service(): API to update wmi target service info to PMO.
+ * @psoc: objmgr psoc
+ * @wmi_service: wmi service number
+ * @value: true when wmi service is enabled in firmware otherwise false.
+ *
+ * Return void
+ */
+void pmo_update_target_service(struct wlan_objmgr_psoc *psoc,
+	WMI_SERVICE service, bool value);
+
+/**
+ * pmo_update_ra_limit() - update ra limit based on bpf filter
+ *  enabled or not
+ * @psoc: objmgr psoc
+ * @bpf_enabled: true when bpf service is enabled else false
+ *
+ * Return: none
+ */
+void pmo_update_ra_limit(struct wlan_objmgr_psoc *psoc,
+	bool bpf_enabled);
+
+/**
+ * pmo_set_wow_event_bitmap() - Assign bitmask with wow event
+ * @event: wow event
+ * @wow_bitmap_size: wow bitmask size
+ * @bitmask: wow bitmask field
+ *
+ * Return: none
+ */
+void pmo_set_wow_event_bitmap(WOW_WAKE_EVENT_TYPE event,
+			      uint32_t wow_bitmap_size,
+			      uint32_t *bitmask);
+
+/**
+ * pmo_set_sta_wow_bitmask() - set predefined STA wow wakeup events
+ * @bitmask: bitmask field
+ * @wow_bitmask_size: bitmask field size
+ *
+ * Return: none
+ */
+void pmo_set_sta_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmask_size);
+
+/**
+ * pmo_set_sap_wow_bitmask() - set predefined SAP wow wakeup events
+ * @bitmask: bitmask field
+ * @wow_bitmask_size: bitmask field size
+ *
+ * Return: none
+ */
+void pmo_set_sap_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmask_size);
+
+#endif /* end  of _WLAN_PMO_STATIC_CONFIG_H_ */
diff --git a/components/pmo/core/inc/wlan_pmo_suspend_resume.h b/components/pmo/core/inc/wlan_pmo_suspend_resume.h
new file mode 100644
index 0000000..516f428
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_suspend_resume.h
@@ -0,0 +1,437 @@
+/*
+* Copyright (c) 2017 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: Declare suspend / resume related API's
+ */
+
+#ifndef _WLAN_PMO_SUSPEND_RESUME_H_
+#define _WLAN_PMO_SUSPEND_RESUME_H_
+
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_wow.h"
+
+/**
+ * pmo_core_configure_dynamic_wake_events(): configure dyanmic wake events
+ * @wma: wma handle
+ *
+ * Some wake events need to be enabled dynamically. Control those here.
+ *
+ * Return: none
+ */
+void pmo_core_configure_dynamic_wake_events(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_core_get_wow_bus_suspend(): API to get wow bus is suspended or not
+ * @psoc: objmgr psoc handle
+ *
+ * Return: True if bus suspende else false
+ */
+static inline
+bool pmo_core_get_wow_bus_suspend(struct wlan_objmgr_psoc *psoc)
+{
+	bool value;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	value = psoc_ctx->wow.is_wow_bus_suspended;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+	return value;
+}
+
+/**
+ * pmo_core_psoc_user_space_suspend_req() -  Core handle user space suspend req
+ * @psoc: objmgr psoc handle
+ * @type: type of suspend
+ *
+ * Pmo core Handles user space suspend request for psoc
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_core_psoc_user_space_suspend_req(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type);
+
+/**
+ * pmo_core_psoc_user_space_resume_req() - Core handle user space resume req
+ * @psoc: objmgr psoc handle
+ * @type: type of suspend from resume required
+ *
+ * Pmo core Handles user space resume request for psoc
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_core_psoc_user_space_resume_req(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type);
+
+/**
+ * pmo_core_psoc_bus_suspend_req(): handles bus suspend for psoc
+ * @psoc: objmgr psoc
+ * @type: is this suspend part of runtime suspend or system suspend?
+ * @wow_params: collection of wow enable override parameters
+ *
+ * Bails if a scan is in progress.
+ * Calls the appropriate handlers based on configuration and event.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_core_psoc_bus_suspend_req(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type,
+		struct pmo_wow_enable_params *wow_params);
+
+#ifdef FEATURE_RUNTIME_PM
+/**
+ * pmo_core_psoc_bus_runtime_suspend(): handles bus runtime suspend
+ * @psoc: objmgr psoc
+ * @pld_cb: callback to do link auto suspend
+ *
+ * Suspend the wlan bus without apps suspend.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_core_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc,
+					     pmo_pld_auto_suspend_cb pld_cb);
+
+/**
+ * pmo_core_psoc_bus_runtime_resume(): handles bus runtime resume
+ * @psoc: objmgr psoc
+ * @pld_cb: callback to do link auto resume
+ *
+ * Resume the wlan bus from runtime suspend.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_core_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc,
+					     pmo_pld_auto_resume_cb pld_cb);
+#endif
+
+/**
+ * pmo_core_psoc_suspend_target() -Send suspend target command
+ * @psoc: objmgr psoc handle
+ * @disable_target_intr: disable target interrupt
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_core_psoc_suspend_target(struct wlan_objmgr_psoc *psoc,
+		int disable_target_intr);
+
+/**
+ * pmo_core_psoc_bus_resume() -handle bus resume request for psoc
+ * @psoc: objmgr psoc handle
+ * @type: is this suspend part of runtime suspend or system suspend?
+ *
+ * Return:QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS pmo_core_psoc_bus_resume_req(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type);
+
+/**
+ * pmo_core_get_vdev_dtim_period() - Get vdev dtim period
+ * @vdev: objmgr vdev handle
+ *
+ * Return: Vdev dtim period
+ */
+static inline
+uint8_t pmo_core_get_vdev_dtim_period(struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t dtim_period = 0;
+
+	if (!vdev) {
+		pmo_err("vdev is null");
+		QDF_ASSERT(0);
+		return 0;
+	}
+	/* TODO */
+	/* dtim_period = wlan_vdev_mlme_get_dtim_period(vdev); */
+
+	return dtim_period;
+}
+
+/**
+ * pmo_core_get_vdev_beacon_interval() - Get vdev beacon interval
+ * @vdev: objmgr vdev handle
+ *
+ * Return: Vdev beacon interval
+ */
+static inline
+uint16_t pmo_core_get_vdev_beacon_interval(struct wlan_objmgr_vdev *vdev)
+{
+	uint16_t beacon_interval = 0;
+
+	if (!vdev) {
+		pmo_err("vdev is null");
+		QDF_ASSERT(0);
+		return 0;
+	}
+	/* TODO */
+	/* beacon_interval = wlan_vdev_mlme_get_beacon_interval(vdev); */
+
+	return beacon_interval;
+}
+
+/**
+ * pmo_core_update_alt_modulated_dtim_enable() - update alt modulatate dtim
+ * @vdev: objmgr vdev handle
+ * @value: true when alt modulated dtim enable else false
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_update_alt_modulated_dtim_enable(struct wlan_objmgr_vdev *vdev,
+	bool value)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	vdev_ctx->alt_modulated_dtim_enable = value;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+
+/**
+ * pmo_core_vdev_set_dtim_policy() - Set vdev beacon dtim policy
+ * @vdev: objmgr vdev handle
+ * @value: carry vdev dtim policy
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_vdev_set_dtim_policy(struct wlan_objmgr_vdev *vdev,
+	uint32_t value)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	vdev_ctx->dtim_policy = value;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+
+/**
+ * pmo_core_vdev_get_dtim_policy() - Get vdev beacon dtim policy
+ * @vdev: objmgr vdev handle
+ *
+ * Return: vdev dtim policy
+ */
+static inline
+uint32_t pmo_core_vdev_get_dtim_policy(struct wlan_objmgr_vdev *vdev)
+{
+	uint32_t value;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	value = vdev_ctx->dtim_policy;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	return value;
+}
+
+/**
+ * pmo_core_update_power_save_mode() - update power save mode
+ * @vdev: objmgr vdev handle
+ * @value:describe vdev power save mode
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_psoc_update_power_save_mode(struct wlan_objmgr_psoc *psoc,
+	uint8_t value)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	psoc_ctx->psoc_cfg.power_save_mode = value;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+/**
+ * pmo_core_psoc_get_power_save_mode() - Get psoc power save mode
+ * @psoc: objmgr psoc handle
+ *
+ * Return: vdev psoc power save mode value
+ */
+static inline
+uint8_t pmo_core_psoc_get_power_save_mode(struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t value;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	value = psoc_ctx->psoc_cfg.power_save_mode;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+	return value;
+}
+
+/**
+ * pmo_core_psoc_get_qpower_config() - get qpower configuration
+ * @psoc: objmgr psoc handle
+ *
+ * Power Save Offload configuration:
+ * 0 -> Power save offload is disabled
+ * 1 -> Legacy Power save enabled + Deep sleep Disabled
+ * 2 -> QPower enabled + Deep sleep Disabled
+ * 3 -> Legacy Power save enabled + Deep sleep Enabled
+ * 4 -> QPower enabled + Deep sleep Enabled
+ * 5 -> Duty cycling QPower enabled
+ *
+ * Return: enum powersave_qpower_mode with below values
+ * QPOWER_DISABLED if QPOWER is disabled
+ * QPOWER_ENABLED if QPOWER is enabled
+ * QPOWER_DUTY_CYCLING if DUTY CYCLING QPOWER is enabled
+ */
+static inline
+enum pmo_power_save_qpower_mode pmo_core_psoc_get_qpower_config(
+		struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t ps_mode = pmo_core_psoc_get_power_save_mode(psoc);
+
+	switch (ps_mode) {
+	case pmo_ps_qpower_no_deep_sleep:
+	case pmo_ps_qpower_deep_sleep:
+		pmo_info("QPOWER is enabled in power save mode %d", ps_mode);
+		return pmo_qpower_enabled;
+	case pmo_ps_duty_cycling_qpower:
+		pmo_info("DUTY cycling QPOWER is enabled in power save mode %d",
+			ps_mode);
+		return pmo_qpower_duty_cycling;
+	default:
+		pmo_info("QPOWER is disabled in power save mode %d",
+			ps_mode);
+		return pmo_qpower_disabled;
+	}
+}
+
+/**
+ * pmo_core_vdev_get_pause_bitmap() - Get vdev pause bitmap
+ * @psoc_ctx: psoc priv ctx
+ * @vdev_id: vdev id
+ *
+ * Return: vdev pause bitmap
+ */
+static inline
+uint16_t pmo_core_vdev_get_pause_bitmap(struct pmo_psoc_priv_obj *psoc_ctx,
+		uint8_t vdev_id)
+{
+	uint16_t value = 0;
+	pmo_get_pause_bitmap handler;
+
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	handler = psoc_ctx->get_pause_bitmap;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+	if (handler)
+		value = handler(vdev_id);
+
+	return value;
+}
+
+/**
+ * wma_is_vdev_in_ap_mode() - check that vdev is in ap mode or not
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ *
+ * Helper function to know whether given vdev id
+ * is in AP mode or not.
+ *
+ * Return: True/False
+ */
+static inline
+bool pmo_is_vdev_in_ap_mode(struct wlan_objmgr_vdev *vdev)
+{
+	enum tQDF_ADAPTER_MODE mode;
+
+	mode = pmo_get_vdev_opmode(vdev);
+
+	return (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE) == 1 ? 1 : 0;
+}
+
+#ifdef QCA_IBSS_SUPPORT
+/**
+ * pmo_is_vdev_in_ibss_mode() - check that vdev is in ibss mode or not
+ * @vdev: objmgr vdev handle
+ * @vdev_id: vdev id
+ *
+ * Helper function to know whether given vdev id
+ * is in IBSS mode or not.
+ *
+ * Return: True/False
+ */
+static inline
+bool pmo_is_vdev_in_ibss_mode(struct wlan_objmgr_vdev *vdev)
+{
+	enum tQDF_ADAPTER_MODE mode;
+
+	mode = pmo_get_vdev_opmode(vdev);
+
+	return (mode == QDF_IBSS_MODE) ? true : false;
+}
+#else
+static inline bool pmo_is_vdev_in_ibss_mode(struct wlan_objmgr_vdev *vdev)
+{
+	return false;
+}
+#endif /* QCA_IBSS_SUPPORT */
+
+/**
+ * pmo_handle_initial_wake_up() - handle initial wake up
+ * @cb_ctx: callback context
+ *
+ * Return: None
+ */
+void pmo_core_psoc_handle_initial_wake_up(void *cb_ctx);
+
+/**
+ * pmo_core_psoc_is_target_wake_up_received() - check for initial wake up
+ *
+ * Check if target initial wake up is received and fail PM suspend gracefully
+ *
+ * Return: -EAGAIN if initial wake up is received else 0
+ */
+int pmo_core_psoc_is_target_wake_up_received(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_core_psoc_clear_target_wake_up() - clear initial wake up
+ *
+ * Clear target initial wake up reason
+ *
+ * Return: 0 for success and negative error code for failure
+ */
+int pmo_core_psoc_clear_target_wake_up(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_core_psoc_target_suspend_acknowledge() - update target susspend status
+ * @context: HTC_INIT_INFO->context
+ * @wow_nack: true when wow is rejected
+ *
+ * Return: none
+ */
+void pmo_core_psoc_target_suspend_acknowledge(void *context, bool wow_nack);
+
+/**
+ * pmo_core_psoc_wakeup_host_event_received() - received host wake up event
+ * @psoc: objmgr psoc handle
+ *
+ * Return: None
+ */
+void pmo_core_psoc_wakeup_host_event_received(struct wlan_objmgr_psoc *psoc);
+
+#endif /* end  of _WLAN_PMO_SUSPEND_RESUME_H_ */
diff --git a/components/pmo/core/inc/wlan_pmo_wow.h b/components/pmo/core/inc/wlan_pmo_wow.h
new file mode 100644
index 0000000..47d2eb5
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_wow.h
@@ -0,0 +1,605 @@
+/*
+ * Copyright (c) 2017 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: Declare API's for wow pattern addition and deletion in fwr
+ */
+
+#ifndef _WLAN_PMO_WOW_H_
+#define _WLAN_PMO_WOW_H_
+
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_wow_public_struct.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+/**
+ * DOC: wlan_pmo_wowl
+ *
+ * This module houses all the logic for WOW(wake on wireless) in
+ * PMO(Power Management and Offload).
+ *
+ * It provides the following APIs
+ *
+ * - Ability to enable/disable following WoWL modes
+ *  1) Magic packet (MP) mode
+ *  2) Pattern Byte Matching (PBM) mode
+ * - Ability to add/remove patterns for PBM
+ *
+ * A Magic Packet is a packet that contains 6 0xFFs followed by 16
+ * contiguous copies of the receiving NIC's Ethernet address. There is
+ * no API to configure Magic Packet Pattern.
+ *
+ * Wakeup pattern (used for PBM) is defined as following:
+ * struct
+ * {
+ *  U8  PatternSize;                  // Non-Zero pattern size
+ *  U8  PatternMaskSize;              // Non-zero pattern mask size
+ *  U8  PatternMask[PatternMaskSize]; // Pattern mask
+ *  U8  Pattern[PatternSize];         // Pattern
+ * } hdd_wowl_ptrn_t;
+ *
+ * PatternSize and PatternMaskSize indicate size of the variable
+ * length Pattern and PatternMask. PatternMask indicates which bytes
+ * of an incoming packet should be compared with corresponding bytes
+ * in the pattern.
+ *
+ * Maximum allowed pattern size is 128 bytes. Maximum allowed
+ * PatternMaskSize is 16 bytes.
+ *
+ * Maximum number of patterns that can be configured is 8
+ *
+ * PMO will add following 2 commonly used patterns for PBM by default:
+ *  1) ARP Broadcast Pattern
+ *  2) Unicast Pattern
+ *
+ * However note that WoWL will not be enabled by default by PMO. WoWL
+ * needs to enabled explcitly by exercising the iwpriv command.
+ *
+ * PMO will expose an API that accepts patterns as Hex string in the
+ * following format:
+ * "PatternSize:PatternMaskSize:PatternMask:Pattern"
+ *
+ * Multiple patterns can be specified by deleimiting each pattern with
+ * the ';' token:
+ * "PatternSize1:PatternMaskSize1:PatternMask1:Pattern1;PatternSize2:..."
+ *
+ * Patterns can be configured dynamically via iwpriv cmd or statically
+ * via qcom_cfg.ini file
+ *
+ * PBM (when enabled) can perform filtering on unicast data or
+ * broadcast data or both. These configurations are part of factory
+ * default (cfg.dat) and the default behavior is to perform filtering
+ * on both unicast and data frames.
+ *
+ * MP filtering (when enabled) is performed ALWAYS on both unicast and
+ * broadcast data frames.
+ *
+ * Management frames are not subjected to WoWL filtering and are
+ * discarded when WoWL is enabled.
+ *
+ * Whenever a patern match succeeds, RX path is restored and packets
+ * (both management and data) will be pushed to the host from that
+ * point onwards.  Therefore, exit from WoWL is implicit and happens
+ * automatically when the first packet match succeeds.
+ *
+ * WoWL works on top of BMPS. So when WoWL is requested, SME will
+ * attempt to put the device in BMPS mode (if not already in BMPS). If
+ * attempt to BMPS fails, request for WoWL will be rejected.
+ */
+
+#define PMO_WOW_MAX_EVENT_BM_LEN 4
+
+/**
+ * pmo_get_and_increment_wow_default_ptrn() -Get and increment wow default ptrn
+ * @vdev_ctx: pmo vdev priv ctx
+ *
+ * API to get and increment wow default ptrn
+ *
+ * Return: current wow default ptrn count
+ */
+static inline uint8_t pmo_get_and_increment_wow_default_ptrn(
+		struct pmo_vdev_priv_obj *vdev_ctx)
+{
+	uint8_t count;
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	count = vdev_ctx->num_wow_default_patterns++;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	return count;
+}
+
+/**
+ * pmo_increment_wow_default_ptrn() -increment wow default ptrn
+ * @vdev_ctx: pmo vdev priv ctx
+ *
+ * API to increment wow default ptrn
+ *
+ * Return: None
+ */
+static inline void pmo_increment_wow_default_ptrn(
+		struct pmo_vdev_priv_obj *vdev_ctx)
+{
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	vdev_ctx->num_wow_default_patterns++;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+
+/**
+ * pmo_decrement_wow_default_ptrn() -decrement wow default ptrn
+ * @vdev_ctx: pmo vdev priv ctx
+ *
+ * API to decrement wow default ptrn
+ *
+ * Return: None
+ */
+static inline void pmo_decrement_wow_default_ptrn(
+		struct pmo_vdev_priv_obj *vdev_ctx)
+{
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	vdev_ctx->num_wow_default_patterns--;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+
+/**
+ * pmo_increment_wow_user_ptrn() -increment wow user ptrn
+ * @vdev_ctx: pmo vdev priv ctx
+ *
+ * API to increment wow user ptrn
+ *
+ * Return: None
+ */
+static inline void pmo_increment_wow_user_ptrn(
+		struct pmo_vdev_priv_obj *vdev_ctx)
+{
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	vdev_ctx->num_wow_user_patterns++;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+
+/**
+ * pmo_decrement_wow_user_ptrn() -decrement wow user ptrn
+ * @vdev_ctx: pmo vdev priv ctx
+ *
+ * API to decrement wow user ptrn
+ *
+ * Return: None
+ */
+static inline void pmo_decrement_wow_user_ptrn(
+		struct pmo_vdev_priv_obj *vdev_ctx)
+{
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	vdev_ctx->num_wow_user_patterns--;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+
+void pmo_dump_wow_ptrn(struct pmo_wow_add_pattern *ptrn);
+
+/**
+ * pmo_core_add_wow_pattern() - Function which will add the WoWL pattern to be
+ *			 used when PBM filtering is enabled
+ * @vdev: pointer to the vdev
+ * @ptrn: pointer to the pattern string to be added
+ *
+ * Return: false if any errors encountered, QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS pmo_core_add_wow_pattern(struct wlan_objmgr_vdev *vdev,
+		const char *ptrn);
+
+/**
+ * pmo_core_del_wow_pattern() - Function which will delete the WoWL pattern
+ * @vdev: pointer to the vdev
+ * @ptrn: pointer to the pattern string to be added
+ *
+ * Return: error if any errors encountered, QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS pmo_core_del_wow_pattern(struct wlan_objmgr_vdev *vdev,
+		const char *ptrn);
+
+/**
+ * pmo_core_wow_enter() - store enable/disable status for pattern
+ * @wma: wma handle
+ * @info: wow parameters
+ *
+ * Records pattern enable/disable status locally. This choice will
+ * take effect when the driver enter into suspend state.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_core_wow_enter(struct wlan_objmgr_vdev *vdev,
+		struct pmo_wow_enter_params *wow_enter_param);
+
+/**
+ * pmo_core_wow_exit() - clear all wma states
+ * @wma: wma handle
+ * @info: wow params
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_core_wow_exit(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_enable_wakeup_event() -  enable wow wakeup events
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id
+ * @bitmap: Event bitmap
+ *
+ * Return: none
+ */
+void pmo_core_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+	uint32_t vdev_id, uint32_t *bitmap);
+
+/**
+ * pmo_core_disable_wakeup_event() -  disable wow wakeup events
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id
+ * @bitmap: Event bitmap
+ *
+ * Return: none
+ */
+void pmo_core_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+	uint32_t vdev_id, uint32_t *bitmap);
+
+/**
+ * pmo_is_wow_applicable(): should enable wow
+ * @psoc: objmgr psoc object
+ *
+ *  Enable WOW if any one of the condition meets,
+ *  1) Is any one of vdev in beaconning mode (in AP mode) ?
+ *  2) Is any one of vdev in connected state (in STA mode) ?
+ *  3) Is PNO in progress in any one of vdev ?
+ *  4) Is Extscan in progress in any one of vdev ?
+ *  5) Is P2P listen offload in any one of vdev?
+ *  6) Is any vdev in NAN data mode? BSS is already started at the
+ *     the time of device creation. It is ready to accept data
+ *     requests.
+ *  7) If LPASS feature is enabled
+ *  8) If NaN feature is enabled
+ *  If none of above conditions is true then return false
+ *
+ * Return: true if wma needs to configure wow false otherwise.
+ */
+bool pmo_core_is_wow_applicable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_core_update_wow_enable() - update wow enable flag
+ * @psoc_ctx: Pointer to objmgr psoc handle
+ * @value: true if wow mode enable else false
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_update_wow_enable(struct pmo_psoc_priv_obj *psoc_ctx,
+	bool value)
+{
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	psoc_ctx->wow.wow_enable = value;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+/**
+ * pmo_core_is_wow_mode_enabled() - check if wow needs to be enabled in fw
+ * @psoc_ctx: Pointer to objmgr psoc handle
+ *
+ * API to check if wow mode is enabled in fwr as part of apps suspend or not
+ *
+ * Return: true is wow mode is enabled else false
+ */
+static inline
+bool pmo_core_is_wow_enabled(struct pmo_psoc_priv_obj *psoc_ctx)
+{
+	bool value;
+
+	if (!psoc_ctx) {
+		pmo_err("psoc_ctx is null");
+		return false;
+	}
+
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	value = psoc_ctx->wow.wow_enable;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+	pmo_debug("WoW enable %d", value);
+
+	return value;
+}
+
+/**
+ * pmo_core_set_wow_nack() - Set wow nack flag
+ * @psoc_ctx: Pointer to objmgr psoc handle
+ * @value: true if received wow nack from else false
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_set_wow_nack(struct pmo_psoc_priv_obj *psoc_ctx, bool value)
+{
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	psoc_ctx->wow.wow_nack = value;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+/**
+ * pmo_core_get_wow_nack() - Get wow nack flag
+ * @psoc_ctx: Pointer to objmgr psoc handle
+ *
+ * Return: wow nack flag
+ */
+static inline
+bool pmo_core_get_wow_nack(struct pmo_psoc_priv_obj *psoc_ctx)
+{
+	bool value;
+
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	value = psoc_ctx->wow.wow_nack;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+	return value;
+}
+/**
+ * pmo_core_update_wow_enable_cmd_sent() - update wow enable cmd sent flag
+ * @psoc_ctx: Pointer to objmgr psoc handle
+ * @value: true if wow enable cmd sent else false
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_update_wow_enable_cmd_sent(struct pmo_psoc_priv_obj *psoc_ctx,
+	bool value)
+{
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	psoc_ctx->wow.wow_enable_cmd_sent = value;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+/**
+ * pmo_core_get_wow_enable_cmd_sent() - Get wow enable cmd sent flag
+ * @psoc_ctx: Pointer to objmgr psoc handle
+ *
+ * Return: return true if wow enable cmd sent else false
+ */
+static inline
+bool pmo_core_get_wow_enable_cmd_sent(struct pmo_psoc_priv_obj *psoc_ctx)
+{
+	bool value;
+
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	value = psoc_ctx->wow.wow_enable_cmd_sent;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+	return value;
+}
+
+/**
+ * pmo_core_update_wow_initial_wake_up() - update wow initial wake up
+ * @psoc_ctx: Pointer to objmgr psoc handle
+ * @value: true if wow initial wake up is received else false
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_update_wow_initial_wake_up(struct pmo_psoc_priv_obj *psoc_ctx,
+	bool value)
+{
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	psoc_ctx->wow.wow_initial_wake_up = value;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+/**
+ * pmo_core_get_wow_initial_wake_up() - Get wow initial wake up
+ * @psoc_ctx: Pointer to objmgr psoc handle
+ *
+ * Return:  true if wow initial wake up is received else false
+ */
+static inline
+bool pmo_core_get_wow_initial_wake_up(struct pmo_psoc_priv_obj *psoc_ctx)
+{
+	bool value;
+
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	value = psoc_ctx->wow.wow_initial_wake_up;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+	return value;
+}
+
+#ifdef FEATURE_WLAN_EXTSCAN
+/**
+ * pmo_core_is_extscan_in_progress(): check if a extscan is in progress
+ * @vdev: objmgr vdev handle
+ *
+ * Return: TRUE/FALSE
+ */
+static inline
+bool pmo_core_is_extscan_in_progress(struct wlan_objmgr_vdev *vdev)
+{
+	bool extscan_in_progress;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	extscan_in_progress = vdev_ctx->extscan_in_progress;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	return extscan_in_progress;
+}
+
+/**
+ * pmo_core_update_extscan_in_progress(): update extscan is in progress flags
+ * @vdev: objmgr vdev handle
+ * @value:true if extscan is in progress else false
+ *
+ * Return: TRUE/FALSE
+ */
+static inline
+void pmo_core_update_extscan_in_progress(struct wlan_objmgr_vdev *vdev,
+	bool value)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	vdev_ctx->extscan_in_progress = value;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+#else
+static inline
+bool pmo_core_is_extscan_in_progress(struct wlan_objmgr_vdev *vdev)
+{
+	return false;
+}
+
+static inline
+void pmo_core_update_extscan_in_progress(struct wlan_objmgr_vdev *vdev,
+	bool value)
+{
+}
+#endif
+
+/**
+ * pmo_core_is_p2plo_in_progress(): check if p2plo is in progress
+ * @vdev: objmgr vdev handle
+ *
+ * Return: TRUE/FALSE
+ */
+static inline
+bool pmo_core_is_p2plo_in_progress(struct wlan_objmgr_vdev *vdev)
+{
+	bool p2plo_in_progress;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	p2plo_in_progress = vdev_ctx->p2plo_in_progress;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	return p2plo_in_progress;
+}
+
+/**
+ * pmo_core_update_p2plo_in_progress(): update p2plo is in progress flags
+ * @vdev: objmgr vdev handle
+ * @value:true if p2plo is in progress else false
+ *
+ * Return: TRUE/FALSE
+ */
+static inline
+void pmo_core_update_p2plo_in_progress(struct wlan_objmgr_vdev *vdev,
+	bool value)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	vdev_ctx->p2plo_in_progress = value;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+
+#ifdef WLAN_FEATURE_LPSS
+/**
+ * pmo_is_lpass_enabled() - check if lpass is enabled
+ * @vdev: objmgr vdev handle
+ *
+ * WoW is needed if LPASS or NaN feature is enabled in INI because
+ * target can't wake up itself if its put in PDEV suspend when LPASS
+ * or NaN features are supported
+ *
+ * Return: true if lpass is enabled else false
+ */
+static inline
+bool pmo_core_is_lpass_enabled(struct wlan_objmgr_vdev *vdev)
+{
+	bool lpass_enable;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	lpass_enable = vdev_ctx->pmo_psoc_ctx->psoc_cfg.lpass_enable;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	return lpass_enable;
+}
+#else
+static inline
+bool pmo_core_is_lpass_enabled(struct wlan_objmgr_vdev *vdev)
+{
+	return false;
+}
+#endif
+
+#ifdef WLAN_FEATURE_NAN
+/**
+ * pmo_is_nan_enabled() - check if NaN is enabled
+ * @vdev: objmgr vdev handle
+ *
+ * WoW is needed if LPASS or NaN feature is enabled in INI because
+ * target can't wake up itself if its put in PDEV suspend when LPASS
+ * or NaN features are supported
+ *
+ * Return: true if NaN is enabled else false
+ */
+static inline
+bool pmo_core_is_nan_enabled(struct wlan_objmgr_vdev *vdev)
+{
+	bool nan_enable;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	nan_enable = vdev_ctx->pmo_psoc_ctx->psoc_cfg.nan_enable;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	return nan_enable;
+}
+#else
+static inline
+bool pmo_core_is_nan_enabled(struct wlan_objmgr_vdev *vdev)
+{
+	return false;
+}
+#endif
+
+/**
+ * pmo_get_event_bitmap_idx() - get indices for extended wow bitmaps
+ * @event: wow event
+ * @wow_bitmap_size: WOW bitmap size
+ * @bit_idx: bit index
+ * @idx: byte index
+ *
+ * Return: none
+ */
+static inline void pmo_get_event_bitmap_idx(WOW_WAKE_EVENT_TYPE event,
+			      uint32_t wow_bitmap_size,
+			      uint32_t *bit_idx,
+			      uint32_t *idx)
+{
+
+	if (!bit_idx || !idx || wow_bitmap_size == 0) {
+		pmo_err("bit_idx:%p idx:%p wow_bitmap_size:%u",
+			 bit_idx, idx, wow_bitmap_size);
+		return;
+	}
+	if (event == 0) {
+		*idx = *bit_idx = 0;
+	} else {
+		*idx = event / (wow_bitmap_size * 8);
+		*bit_idx = event % (wow_bitmap_size * 8);
+	}
+}
+#endif /* end  of _WLAN_PMO_WOW_H_ */
diff --git a/components/pmo/core/src/wlan_pmo_arp.c b/components/pmo/core/src/wlan_pmo_arp.c
new file mode 100644
index 0000000..c419414
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_arp.c
@@ -0,0 +1,368 @@
+/*
+* Copyright (c) 2017 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: Implements arp offload feature API's
+ */
+
+#include "wlan_pmo_arp.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+static QDF_STATUS pmo_core_cache_arp_in_vdev_priv(
+			struct pmo_arp_req *arp_req,
+			struct wlan_objmgr_vdev *vdev)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct pmo_arp_offload_params *request = NULL;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	int index;
+	struct qdf_mac_addr peer_bssid;
+
+	PMO_ENTER();
+	psoc_ctx = pmo_psoc_get_priv(arp_req->psoc);
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	request = qdf_mem_malloc(sizeof(*request));
+	if (!request) {
+		pmo_err("cannot allocate arp request");
+		status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	status = pmo_get_vdev_bss_peer_mac_addr(vdev,
+			&peer_bssid);
+	if (status != QDF_STATUS_SUCCESS)
+		goto out;
+
+	qdf_mem_copy(&request->bssid.bytes, &peer_bssid.bytes,
+			QDF_MAC_ADDR_SIZE);
+	pmo_info("vdev self mac addr: %pM bss peer mac addr: %pM",
+		wlan_vdev_mlme_get_macaddr(vdev),
+		peer_bssid.bytes);
+
+	request->enable = PMO_OFFLOAD_ENABLE;
+	/* converting u32 to IPV4 address */
+	for (index = 0; index < PMO_IPV4_ADDR_LEN; index++)
+		request->host_ipv4_addr[index] =
+		(arp_req->ipv4_addr >> (index * 8)) & 0xFF;
+
+	/* cache arp request */
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	qdf_mem_copy(&vdev_ctx->vdev_arp_req, request,
+		sizeof(vdev_ctx->vdev_arp_req));
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+	pmo_info("arp offload ipv4 addr: %d.%d.%d.%d enable: %d",
+		request->host_ipv4_addr[0],
+		request->host_ipv4_addr[1],
+		request->host_ipv4_addr[2],
+		request->host_ipv4_addr[3],
+		request->enable);
+out:
+	if (request)
+		qdf_mem_free(request);
+	PMO_EXIT();
+
+	return status;
+}
+
+static QDF_STATUS pmo_core_flush_arp_from_vdev_priv(
+			struct wlan_objmgr_vdev *vdev)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	PMO_ENTER();
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	/* clear arp request */
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	qdf_mem_zero(&vdev_ctx->vdev_arp_req, sizeof(vdev_ctx->vdev_arp_req));
+	vdev_ctx->vdev_arp_req.enable = PMO_OFFLOAD_DISABLE;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	PMO_EXIT();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS pmo_core_do_enable_arp_offload(struct wlan_objmgr_vdev *vdev,
+		uint8_t vdev_id, enum pmo_offload_trigger trigger)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	PMO_ENTER();
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	psoc_ctx = vdev_ctx->pmo_psoc_ctx;
+	if (!psoc_ctx) {
+		pmo_err("psoc_ctx is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	switch (trigger) {
+	case pmo_ipv4_change_notify:
+		if (!psoc_ctx->psoc_cfg.active_mode_offload) {
+			pmo_info("active offload is disabled, skip in mode:%d",
+				trigger);
+			status = QDF_STATUS_E_INVAL;
+			goto out;
+		}
+		/* enable arp when active offload is true (ipv4 notifier) */
+		status = pmo_tgt_enable_arp_offload_req(vdev, vdev_id);
+		break;
+	case pmo_apps_suspend:
+		if (psoc_ctx->psoc_cfg.active_mode_offload) {
+			pmo_info("active offload is enabled, skip in mode: %d",
+				trigger);
+			status = QDF_STATUS_E_INVAL;
+			goto out;
+		}
+		/* enable arp when active offload is false (apps suspend) */
+		status = pmo_tgt_enable_arp_offload_req(vdev, vdev_id);
+		break;
+	default:
+		status = QDF_STATUS_E_INVAL;
+		pmo_err("invalid pmo trigger");
+		break;
+	}
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+static QDF_STATUS pmo_core_do_disable_arp_offload(struct wlan_objmgr_vdev *vdev,
+		uint8_t vdev_id, enum pmo_offload_trigger trigger)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	PMO_ENTER();
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	psoc_ctx = vdev_ctx->pmo_psoc_ctx;
+	if (!psoc_ctx) {
+		pmo_err("psoc_ctx is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	switch (trigger) {
+	case pmo_apps_resume:
+		if (psoc_ctx->psoc_cfg.active_mode_offload) {
+			pmo_info("active offload is enabled, skip in mode: %d",
+				trigger);
+			status = QDF_STATUS_E_INVAL;
+			goto out;
+		}
+		/* disable arp on apps resume when active offload is disable */
+		status = pmo_tgt_disable_arp_offload_req(vdev, vdev_id);
+		break;
+	default:
+		status = QDF_STATUS_E_INVAL;
+		pmo_err("invalid pmo trigger");
+		break;
+	}
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+static QDF_STATUS pmo_core_arp_offload_sanity(
+			struct wlan_objmgr_vdev *vdev)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.arp_offload_enable) {
+		pmo_err("user disabled arp offload using ini");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!pmo_core_is_vdev_supports_offload(vdev)) {
+		pmo_info("vdev in invalid opmode for arp offload %d",
+			pmo_get_vdev_opmode(vdev));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!pmo_core_is_vdev_connected(vdev))
+		return QDF_STATUS_E_INVAL;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_core_cache_arp_offload_req(struct pmo_arp_req *arp_req)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
+
+	PMO_ENTER();
+	if (!arp_req) {
+		pmo_err("arp_req is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	if (!arp_req->psoc) {
+		pmo_err("psoc is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	vdev = pmo_psoc_get_vdev(arp_req->psoc, arp_req->vdev_id);
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto out;
+
+	status = pmo_core_arp_offload_sanity(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto dec_ref;
+
+	pmo_info("Cache arp for vdev id: %d psoc: %p vdev: %p",
+			arp_req->vdev_id, arp_req->psoc, vdev);
+
+	status = pmo_core_cache_arp_in_vdev_priv(arp_req, vdev);
+dec_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_flush_arp_offload_req(struct wlan_objmgr_vdev *vdev)
+{
+	QDF_STATUS status;
+	uint8_t vdev_id;
+
+	PMO_ENTER();
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto out;
+
+	status = pmo_core_arp_offload_sanity(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto def_ref;
+
+	vdev_id = pmo_vdev_get_id(vdev);
+	pmo_info("Flush arp for vdev id: %d vdev: %p", vdev_id, vdev);
+
+	status = pmo_core_flush_arp_from_vdev_priv(vdev);
+def_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_enable_arp_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger)
+{
+	QDF_STATUS status;
+	uint8_t vdev_id;
+
+	PMO_ENTER();
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto out;
+
+	status = pmo_core_arp_offload_sanity(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto def_ref;
+
+	vdev_id = pmo_vdev_get_id(vdev);
+	pmo_info("Enable arp offload in fwr vdev id: %d vdev: %p",
+		vdev_id, vdev);
+
+	status = pmo_core_do_enable_arp_offload(vdev, vdev_id, trigger);
+def_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_disable_arp_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger)
+{
+	QDF_STATUS status;
+	uint8_t vdev_id;
+
+	PMO_ENTER();
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto out;
+
+	status = pmo_core_arp_offload_sanity(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto def_ref;
+
+	vdev_id = pmo_vdev_get_id(vdev);
+	pmo_info("Disable arp offload in fwr vdev id: %d vdev: %p",
+		vdev_id, vdev);
+
+	status = pmo_core_do_disable_arp_offload(vdev, vdev_id, trigger);
+def_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
diff --git a/components/pmo/core/src/wlan_pmo_gtk.c b/components/pmo/core/src/wlan_pmo_gtk.c
new file mode 100644
index 0000000..120ff04
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_gtk.c
@@ -0,0 +1,358 @@
+/*
+* Copyright (c) 2017 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: Implements gtk offload feature API's
+ */
+
+#include "wlan_pmo_gtk.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+static QDF_STATUS pmo_core_cache_gtk_req_in_vdev_priv(
+		struct wlan_objmgr_vdev *vdev,
+		struct pmo_gtk_req *gtk_req)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	QDF_STATUS status;
+	struct qdf_mac_addr peer_bssid;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	status = pmo_get_vdev_bss_peer_mac_addr(vdev, &peer_bssid);
+	if (status != QDF_STATUS_SUCCESS)
+		return status;
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	qdf_mem_copy(&vdev_ctx->vdev_gtk_req, gtk_req,
+		sizeof(vdev_ctx->vdev_gtk_req));
+	qdf_mem_copy(&vdev_ctx->vdev_gtk_req.bssid,
+		&peer_bssid, QDF_MAC_ADDR_SIZE);
+	vdev_ctx->vdev_gtk_req.flags = PMO_GTK_OFFLOAD_ENABLE;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS pmo_core_flush_gtk_req_from_vdev_priv(
+		struct wlan_objmgr_vdev *vdev)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	qdf_mem_zero(&vdev_ctx->vdev_gtk_req, sizeof(vdev_ctx->vdev_gtk_req));
+	vdev_ctx->vdev_gtk_req.flags = PMO_GTK_OFFLOAD_DISABLE;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS pmo_core_do_enable_gtk_offload(
+			struct wlan_objmgr_vdev *vdev,
+			struct pmo_vdev_priv_obj *vdev_ctx,
+			struct pmo_gtk_req *op_gtk_req)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t vdev_id;
+
+	if (!pmo_core_is_vdev_supports_offload(vdev)) {
+		pmo_info("vdev in invalid opmode for gtk offload %d",
+			pmo_get_vdev_opmode(vdev));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!pmo_core_is_vdev_connected(vdev))
+		return QDF_STATUS_E_INVAL;
+
+	vdev_id = pmo_vdev_get_id(vdev);
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	qdf_mem_copy(op_gtk_req, &vdev_ctx->vdev_gtk_req,
+		sizeof(*op_gtk_req));
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	if ((op_gtk_req->flags == PMO_GTK_OFFLOAD_ENABLE) &&
+	    (qdf_atomic_read(&vdev_ctx->gtk_err_enable) == 1)) {
+		pmo_info("GTK Offload already enabled, Disabling vdev_id: %d",
+			vdev_id);
+		op_gtk_req->flags = PMO_GTK_OFFLOAD_DISABLE;
+		status = pmo_tgt_send_gtk_offload_req(vdev, op_gtk_req);
+		if (status != QDF_STATUS_SUCCESS) {
+			pmo_err("Failed to disable GTK Offload");
+			goto out;
+		}
+		pmo_debug("Enable GTK Offload again with updated inputs");
+		op_gtk_req->flags = PMO_GTK_OFFLOAD_ENABLE;
+	}
+
+	status = pmo_tgt_send_gtk_offload_req(vdev, op_gtk_req);
+out:
+
+	return status;
+}
+
+static QDF_STATUS pmo_core_is_gtk_enabled_in_fwr(
+			struct wlan_objmgr_vdev *vdev,
+			struct pmo_vdev_priv_obj *vdev_ctx)
+{
+	QDF_STATUS status;
+	struct qdf_mac_addr peer_bssid;
+
+	if (!pmo_core_is_vdev_supports_offload(vdev)) {
+		pmo_info("vdev in invalid opmode for gtk offload enable %d",
+			pmo_get_vdev_opmode(vdev));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!pmo_core_is_vdev_connected(vdev))
+		return QDF_STATUS_E_INVAL;
+
+	status = pmo_get_vdev_bss_peer_mac_addr(vdev,
+			&peer_bssid);
+	if (status != QDF_STATUS_SUCCESS)
+		return QDF_STATUS_E_INVAL;
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	if (qdf_mem_cmp(&vdev_ctx->vdev_gtk_req.bssid,
+		&peer_bssid, QDF_MAC_ADDR_SIZE)) {
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+		pmo_err("cache request mac:%pM, peer mac:%pM are not same",
+			vdev_ctx->vdev_gtk_req.bssid.bytes,
+			peer_bssid.bytes);
+		 return QDF_STATUS_E_INVAL;
+	}
+
+	if (vdev_ctx->vdev_gtk_req.flags != PMO_GTK_OFFLOAD_ENABLE) {
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+		pmo_err("gtk flag is disabled hence no gtk rsp required");
+		return QDF_STATUS_E_INVAL;
+	}
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS pmo_core_do_disable_gtk_offload(
+			struct wlan_objmgr_vdev *vdev,
+			struct pmo_vdev_priv_obj *vdev_ctx,
+			struct pmo_gtk_req *op_gtk_req)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	status = pmo_core_is_gtk_enabled_in_fwr(vdev, vdev_ctx);
+	if (status != QDF_STATUS_SUCCESS)
+		return status;
+
+	op_gtk_req->flags = PMO_GTK_OFFLOAD_DISABLE;
+	status = pmo_tgt_send_gtk_offload_req(vdev, op_gtk_req);
+
+	return status;
+}
+
+QDF_STATUS pmo_core_cache_gtk_offload_req(struct wlan_objmgr_vdev *vdev,
+		struct pmo_gtk_req *gtk_req)
+{
+	QDF_STATUS status;
+	enum tQDF_ADAPTER_MODE opmode;
+	uint8_t vdev_id;
+
+	PMO_ENTER();
+	if (!gtk_req) {
+		pmo_err("gtk_req is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto out;
+
+	opmode = pmo_get_vdev_opmode(vdev);
+	vdev_id = pmo_vdev_get_id(vdev);
+	pmo_info("vdev opmode: %d vdev_id: %d", opmode, vdev_id);
+	if (!pmo_core_is_vdev_supports_offload(vdev)) {
+		pmo_info("vdev in invalid opmode for caching gtk request %d",
+			opmode);
+		status = QDF_STATUS_E_INVAL;
+		goto dec_ref;
+	}
+
+	status = pmo_core_cache_gtk_req_in_vdev_priv(vdev, gtk_req);
+dec_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_flush_gtk_offload_req(struct wlan_objmgr_vdev *vdev)
+{
+	enum tQDF_ADAPTER_MODE opmode;
+	uint8_t vdev_id;
+	QDF_STATUS status;
+
+	PMO_ENTER();
+	if (!vdev) {
+		pmo_err("psoc is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto out;
+
+	opmode = pmo_get_vdev_opmode(vdev);
+	vdev_id = pmo_vdev_get_id(vdev);
+	pmo_info("vdev opmode: %d vdev_id: %d", opmode, vdev_id);
+	if (!pmo_core_is_vdev_supports_offload(vdev)) {
+		pmo_info("vdev in invalid opmode for flushing gtk request %d",
+			opmode);
+		status = QDF_STATUS_E_INVAL;
+		goto dec_ref;
+	}
+
+	status = pmo_core_flush_gtk_req_from_vdev_priv(vdev);
+dec_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_enable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+	QDF_STATUS status;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	struct pmo_gtk_req *op_gtk_req = NULL;
+
+	PMO_ENTER();
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto out;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	op_gtk_req = qdf_mem_malloc(sizeof(*op_gtk_req));
+	if (!op_gtk_req) {
+		pmo_err("op_gtk_req is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto dec_ref;
+	}
+	status = pmo_core_do_enable_gtk_offload(vdev, vdev_ctx, op_gtk_req);
+dec_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	if (op_gtk_req)
+		qdf_mem_free(op_gtk_req);
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_disable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+	QDF_STATUS status;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	struct pmo_gtk_req *op_gtk_req = NULL;
+
+	PMO_ENTER();
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto out;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	op_gtk_req = qdf_mem_malloc(sizeof(*op_gtk_req));
+	if (!op_gtk_req) {
+		pmo_err("op_gtk_req is NULL");
+		status = QDF_STATUS_E_NOMEM;
+		goto dec_ref;
+	}
+
+	status = pmo_core_do_disable_gtk_offload(vdev, vdev_ctx, op_gtk_req);
+dec_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	if (op_gtk_req)
+		qdf_mem_free(op_gtk_req);
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_get_gtk_rsp(struct wlan_objmgr_vdev *vdev,
+			struct pmo_gtk_rsp_req *gtk_rsp_req)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	PMO_ENTER();
+	if (!gtk_rsp_req || !vdev) {
+		pmo_err("%s is null", !vdev ? "vdev":"gtk_rsp_req");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto out;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	status = pmo_core_is_gtk_enabled_in_fwr(vdev, vdev_ctx);
+	if (status != QDF_STATUS_SUCCESS)
+		goto dec_ref;
+
+	/* cache gtk rsp request */
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	qdf_mem_copy(&vdev_ctx->vdev_gtk_rsp_req, gtk_rsp_req,
+		sizeof(vdev_ctx->vdev_gtk_rsp_req));
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+	/* send cmd to fwr */
+	status = pmo_tgt_get_gtk_rsp(vdev);
+dec_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
diff --git a/components/pmo/core/src/wlan_pmo_hw_filter.c b/components/pmo/core/src/wlan_pmo_hw_filter.c
new file mode 100644
index 0000000..ea93d1d
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_hw_filter.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2017 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: Implements arp offload feature API's
+ */
+
+#include "qdf_lock.h"
+#include "wlan_pmo_hw_filter.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+static QDF_STATUS pmo_core_conf_hw_filter(struct wlan_objmgr_vdev *vdev,
+					  enum pmo_hw_filter_mode mode)
+{
+	QDF_STATUS status;
+	struct pmo_hw_filter_params req = { .mode = mode, };
+
+	PMO_ENTER();
+
+	if (!pmo_core_is_vdev_connected(vdev)) {
+		status = QDF_STATUS_E_NOSUPPORT;
+		goto exit_with_status;
+	}
+
+	req.vdev_id = pmo_vdev_get_id(vdev);
+	status = pmo_tgt_conf_hw_filter(pmo_vdev_get_psoc(vdev), &req);
+
+exit_with_status:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_enable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+	QDF_STATUS status;
+	struct pmo_psoc_priv_obj *psoc_priv;
+	enum pmo_hw_filter_mode mode;
+
+	PMO_ENTER();
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto exit_with_status;
+
+	psoc_priv = pmo_vdev_get_psoc_priv(vdev);
+	qdf_spin_lock_bh(&psoc_priv->lock);
+	mode = psoc_priv->psoc_cfg.hw_filter_mode;
+	qdf_spin_unlock_bh(&psoc_priv->lock);
+
+	status = pmo_core_conf_hw_filter(vdev, mode);
+
+	pmo_vdev_put_ref(vdev);
+
+exit_with_status:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_disable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+	QDF_STATUS status;
+
+	PMO_ENTER();
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto exit_with_status;
+
+	status = pmo_core_conf_hw_filter(vdev, PMO_HW_FILTER_DISABLED);
+
+	pmo_vdev_put_ref(vdev);
+
+exit_with_status:
+	PMO_EXIT();
+
+	return status;
+}
diff --git a/components/pmo/core/src/wlan_pmo_lphb.c b/components/pmo/core/src/wlan_pmo_lphb.c
new file mode 100644
index 0000000..31a6372
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_lphb.c
@@ -0,0 +1,243 @@
+/*
+* Copyright (c) 2017 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: Implements low power heart beat offload feature API's
+ */
+
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_lphb.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+#ifdef FEATURE_WLAN_LPHB
+/**
+ * pmo_core_send_lphb_enable() - enable command of LPHB configuration requests
+ * @psoc: objmgr psoc handle
+ * @psoc_ctx: pmo private psoc ctx
+ * @lphb_conf_req: lphb request which need s to configure in fwr
+ * @by_user: whether this call is from user or cached resent
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS pmo_core_send_lphb_enable(struct wlan_objmgr_psoc *psoc,
+			struct pmo_psoc_priv_obj *psoc_ctx,
+			struct pmo_lphb_req *lphb_conf_req, bool by_user)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	struct pmo_lphb_enable_req *ts_lphb_enable;
+	int i;
+
+	if (lphb_conf_req == NULL) {
+		pmo_err("LPHB configuration is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ts_lphb_enable = &(lphb_conf_req->params.lphb_enable_req);
+	qdf_status = pmo_tgt_send_lphb_enable(psoc, ts_lphb_enable);
+	if (qdf_status != QDF_STATUS_SUCCESS)
+		goto out;
+
+	/* No need to cache non user request */
+	if (!by_user) {
+		qdf_status = QDF_STATUS_SUCCESS;
+		goto out;
+	}
+
+	/* target already configured, now cache command status */
+	if (ts_lphb_enable->enable) {
+		i = ts_lphb_enable->item - 1;
+		qdf_spin_lock_bh(&psoc_ctx->lock);
+		psoc_ctx->wow.lphb_cache[i].cmd
+			= pmo_lphb_set_en_param_indid;
+		psoc_ctx->wow.lphb_cache[i].params.lphb_enable_req.enable =
+			ts_lphb_enable->enable;
+		psoc_ctx->wow.lphb_cache[i].params.lphb_enable_req.item =
+			ts_lphb_enable->item;
+		psoc_ctx->wow.lphb_cache[i].params.lphb_enable_req.session =
+			ts_lphb_enable->session;
+		qdf_spin_unlock_bh(&psoc_ctx->lock);
+		pmo_info("cached LPHB status in WMA context for item %d", i);
+	} else {
+		qdf_spin_lock_bh(&psoc_ctx->lock);
+		qdf_mem_zero((void *)&psoc_ctx->wow.lphb_cache,
+				sizeof(psoc_ctx->wow.lphb_cache));
+		qdf_spin_unlock_bh(&psoc_ctx->lock);
+		pmo_info("cleared all cached LPHB status in WMA context");
+	}
+
+out:
+	return qdf_status;
+}
+
+/**
+ * pmo_core_send_lphb_tcp_params() - Send tcp params of LPHB requests
+ * @psoc: objmgr psoc handle
+ * @lphb_conf_req: lphb request which needs to be configured in fwr
+ *
+ * Return: QDF status
+ */
+static
+QDF_STATUS pmo_core_send_lphb_tcp_params(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_req *lphb_conf_req)
+{
+	return pmo_tgt_send_lphb_tcp_params(psoc,
+			&lphb_conf_req->params.lphb_tcp_params);
+
+}
+
+/**
+ * pmo_core_send_lphb_tcp_pkt_filter() - Send tcp packet filter command of LPHB
+ * @psoc: objmgr psoc handle
+ * @lphb_conf_req: lphb request which needs to be configured in fwr
+ *
+ * Return: QDF status
+ */
+static
+QDF_STATUS pmo_core_send_lphb_tcp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_req *lphb_conf_req)
+{
+	return pmo_tgt_send_lphb_tcp_pkt_filter(psoc,
+			&lphb_conf_req->params.lphb_tcp_filter_req);
+}
+
+/**
+ * pmo_core_send_lphb_udp_params() - Send udp param command of LPHB
+ * @psoc: objmgr psoc handle
+ * @lphb_conf_req: lphb request which needs to be configured in fwr
+ *
+ * Return: QDF status
+ */
+static
+QDF_STATUS pmo_core_send_lphb_udp_params(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_req *lphb_conf_req)
+{
+	return pmo_tgt_send_lphb_udp_params(psoc,
+			&lphb_conf_req->params.lphb_udp_params);
+}
+
+/**
+ * pmo_core_send_lphb_udp_pkt_filter() - Send udp pkt filter command of LPHB
+ * @psoc: objmgr psoc handle
+ * @lphb_conf_req: lphb request which need s to configure in fwr
+ *
+ * Return: QDF status
+ */
+static
+QDF_STATUS pmo_core_send_lphb_udp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_req *lphb_conf_req)
+{
+	return pmo_tgt_send_lphb_udp_pkt_filter(psoc,
+			&lphb_conf_req->params.lphb_udp_filter_req);
+}
+
+/**
+ * pmo_process_lphb_conf_req() - handle LPHB configuration requests
+ * @psoc: objmgr psoc handle
+ * @psoc_ctx: pmo private psoc ctx
+ * @lphb_conf_req: lphb request which needs to be configured in fwr
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS pmo_process_lphb_conf_req(struct wlan_objmgr_psoc *psoc,
+		struct pmo_psoc_priv_obj *psoc_ctx,
+		struct pmo_lphb_req *lphb_conf_req)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	pmo_info("LPHB configuration cmd id is %d", lphb_conf_req->cmd);
+	switch (lphb_conf_req->cmd) {
+	case pmo_lphb_set_en_param_indid:
+		status = pmo_core_send_lphb_enable(psoc, psoc_ctx,
+					lphb_conf_req, true);
+		break;
+
+	case pmo_lphb_set_tcp_pararm_indid:
+		status = pmo_core_send_lphb_tcp_params(psoc, lphb_conf_req);
+		break;
+
+	case pmo_lphb_set_tcp_pkt_filter_indid:
+		status = pmo_core_send_lphb_tcp_pkt_filter(psoc, lphb_conf_req);
+		break;
+
+	case pmo_lphb_set_udp_pararm_indid:
+		status = pmo_core_send_lphb_udp_params(psoc, lphb_conf_req);
+		break;
+
+	case pmo_lphb_set_udp_pkt_filter_indid:
+		status = pmo_core_send_lphb_udp_pkt_filter(psoc, lphb_conf_req);
+		break;
+
+	case pmo_lphb_set_network_info_indid:
+	default:
+		break;
+	}
+
+	return status;
+}
+
+void pmo_core_apply_lphb(struct wlan_objmgr_psoc *psoc)
+{
+	int i;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	pmo_debug("checking LPHB cache");
+	for (i = 0; i < 2; i++) {
+		if (psoc_ctx->wow.lphb_cache[i].params.lphb_enable_req.enable) {
+			pmo_debug("LPHB cache for item %d is marked as enable",
+				i + 1);
+			pmo_core_send_lphb_enable(psoc, psoc_ctx,
+				&(psoc_ctx->wow.lphb_cache[i]), false);
+		}
+	}
+}
+
+QDF_STATUS pmo_core_lphb_config_req(struct wlan_objmgr_psoc *psoc,
+		struct pmo_lphb_req *lphb_req, void *lphb_cb_ctx,
+		pmo_lphb_callback callback)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	if (lphb_req == NULL) {
+		pmo_err("LPHB configuration is NULL");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	if (pmo_lphb_set_en_param_indid == lphb_req->cmd) {
+		if (!lphb_cb_ctx) {
+			pmo_err("lphb callback context is null");
+			return QDF_STATUS_E_NULL_VALUE;
+		}
+		if (!callback) {
+			pmo_err("lphb callback function is null");
+			return QDF_STATUS_E_NULL_VALUE;
+		}
+		qdf_spin_lock_bh(&psoc_ctx->lock);
+		psoc_ctx->wow.lphb_cb_ctx = lphb_cb_ctx;
+		psoc_ctx->wow.lphb_cb = callback;
+		qdf_spin_unlock_bh(&psoc_ctx->lock);
+	}
+
+	return pmo_process_lphb_conf_req(psoc, psoc_ctx, lphb_req);
+}
+
+#endif /* FEATURE_WLAN_LPHB */
+
diff --git a/components/pmo/core/src/wlan_pmo_main.c b/components/pmo/core/src/wlan_pmo_main.c
new file mode 100644
index 0000000..58fac41
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_main.c
@@ -0,0 +1,256 @@
+/*
+* Copyright (c) 2017 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: Implement various api / helper function which shall be used
+ * PMO user and target interface.
+ */
+
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+static struct wlan_pmo_ctx *gp_pmo_ctx;
+
+QDF_STATUS pmo_allocate_ctx(void)
+{
+	/* If it is already created, ignore */
+	if (gp_pmo_ctx != NULL) {
+		pmo_debug("already allocated pmo_ctx");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	/* allocate offload mgr ctx */
+	gp_pmo_ctx = (struct wlan_pmo_ctx *)qdf_mem_malloc(
+			sizeof(*gp_pmo_ctx));
+	if (!gp_pmo_ctx) {
+		pmo_err("unable to allocate pmo_ctx");
+		QDF_ASSERT(0);
+		return QDF_STATUS_E_NOMEM;
+	}
+	qdf_spinlock_create(&gp_pmo_ctx->lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void pmo_free_ctx(void)
+{
+	if (!gp_pmo_ctx) {
+		pmo_err("pmo ctx is already freed");
+		QDF_ASSERT(0);
+		return;
+	}
+	qdf_spinlock_destroy(&gp_pmo_ctx->lock);
+	qdf_mem_free(gp_pmo_ctx);
+	gp_pmo_ctx = NULL;
+}
+
+struct wlan_pmo_ctx *pmo_get_context(void)
+{
+	return gp_pmo_ctx;
+}
+
+bool pmo_is_vdev_in_beaconning_mode(enum tQDF_ADAPTER_MODE vdev_opmode)
+{
+	switch (vdev_opmode) {
+	case QDF_SAP_MODE:
+	case QDF_P2P_GO_MODE:
+	case QDF_IBSS_MODE:
+		return true;
+	default:
+		return false;
+	}
+}
+
+QDF_STATUS pmo_get_vdev_bss_peer_mac_addr(struct wlan_objmgr_vdev *vdev,
+		struct qdf_mac_addr *bss_peer_mac_address)
+{
+	struct wlan_objmgr_peer *peer;
+
+	if (!vdev) {
+		pmo_err("vdev is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	peer = wlan_vdev_get_bsspeer(vdev);
+	if (!peer) {
+		pmo_err("peer is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wlan_peer_obj_lock(peer);
+	qdf_mem_copy(bss_peer_mac_address->bytes, wlan_peer_get_macaddr(peer),
+		QDF_MAC_ADDR_SIZE);
+	wlan_peer_obj_unlock(peer);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool pmo_core_is_ap_mode_supports_arp_ns(struct wlan_objmgr_psoc *psoc,
+	enum tQDF_ADAPTER_MODE vdev_opmode)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	if ((vdev_opmode == QDF_SAP_MODE ||
+		vdev_opmode == QDF_P2P_GO_MODE) &&
+		!psoc_ctx->psoc_cfg.ap_arpns_support) {
+		pmo_info("ARP/NS Offload is not supported in SAP/P2PGO mode");
+		return false;
+	}
+
+	return true;
+}
+
+bool pmo_core_is_vdev_connected(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_peer *peer;
+	enum wlan_peer_state peer_state;
+
+	peer = wlan_vdev_get_bsspeer(vdev);
+
+	if (!peer) {
+		pmo_err("peer is null");
+		return false;
+	}
+	peer_state = wlan_peer_mlme_get_state(peer);
+
+	if (peer_state != WLAN_ASSOC_STATE) {
+		pmo_err("peer is not associated.peer state: %d",
+			peer_state);
+		return false;
+	}
+
+	return true;
+}
+
+bool pmo_core_is_vdev_supports_offload(struct wlan_objmgr_vdev *vdev)
+{
+	enum tQDF_ADAPTER_MODE opmode;
+	bool val;
+
+	opmode = pmo_get_vdev_opmode(vdev);
+	pmo_info("vdev opmode: %d", opmode);
+	switch (opmode) {
+	case QDF_STA_MODE:
+	case QDF_P2P_CLIENT_MODE:
+	case QDF_NDI_MODE:
+		val = true;
+		break;
+	default:
+		val = false;
+		break;
+	}
+
+	return val;
+}
+
+QDF_STATUS pmo_core_get_psoc_config(struct wlan_objmgr_psoc *psoc,
+		struct pmo_psoc_cfg *psoc_cfg)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	PMO_ENTER();
+	if (!psoc || !psoc_cfg) {
+		pmo_err("%s is null", !psoc ? "psoc":"psoc_cfg");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	qdf_spin_lock(&psoc_ctx->lock);
+	qdf_mem_copy(psoc_cfg, &psoc_ctx->psoc_cfg, sizeof(*psoc_cfg));
+	qdf_spin_unlock(&psoc_ctx->lock);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_update_psoc_config(struct wlan_objmgr_psoc *psoc,
+		struct pmo_psoc_cfg *psoc_cfg)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	PMO_ENTER();
+	if (!psoc || !psoc_cfg) {
+		pmo_err("%s is null", !psoc ? "psoc":"psoc_cfg");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	qdf_spin_lock(&psoc_ctx->lock);
+	qdf_mem_copy(&psoc_ctx->psoc_cfg, psoc_cfg, sizeof(*psoc_cfg));
+	qdf_spin_unlock(&psoc_ctx->lock);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+void pmo_core_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc,
+				  void *hif_hdl)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	psoc_ctx->hif_hdl = hif_hdl;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+void *pmo_core_psoc_get_hif_handle(struct wlan_objmgr_psoc *psoc)
+{
+	void *hif_hdl;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	hif_hdl = psoc_ctx->hif_hdl;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+	return hif_hdl;
+}
+
+void pmo_core_psoc_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+				   void *txrx_hdl)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	psoc_ctx->txrx_hdl = txrx_hdl;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+void *pmo_core_psoc_get_txrx_handle(struct wlan_objmgr_psoc *psoc)
+{
+	void *txrx_hdl;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	txrx_hdl = psoc_ctx->txrx_hdl;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+	return txrx_hdl;
+}
diff --git a/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c b/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c
new file mode 100644
index 0000000..be4bb2d
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c
@@ -0,0 +1,616 @@
+/*
+* Copyright (c) 2017 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: Implements mc addr filtering offload feature API's
+ */
+
+#include "wlan_pmo_mc_addr_filtering.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+
+#define PMO_INVALID_MC_ADDR_COUNT (-1)
+
+static void pmo_core_fill_mc_list(struct pmo_vdev_priv_obj **vdev_ctx,
+	struct pmo_mc_addr_list_params *ip)
+{
+	struct pmo_mc_addr_list *op_list;
+	int i;
+	static const uint8_t ipv6_rs[] = {
+		0x33, 0x33, 0x00, 0x00, 0x00, 0x02};
+	struct pmo_vdev_priv_obj *temp_ctx;
+	uint8_t addr_fp;
+
+	temp_ctx = *vdev_ctx;
+	addr_fp = temp_ctx->addr_filter_pattern;
+	op_list = &temp_ctx->vdev_mc_list_req;
+
+	qdf_spin_lock_bh(&temp_ctx->pmo_vdev_lock);
+	op_list->mc_cnt = ip->count;
+	qdf_spin_unlock_bh(&temp_ctx->pmo_vdev_lock);
+
+	for (i = 0; i < ip->count; i++) {
+		pmo_debug("%pM", ip->mc_addr[i].bytes);
+		/*
+		 * Skip following addresses:
+		 * 1)IPv6 router solicitation address
+		 * 2)Any other address pattern if its set during
+		 *  RXFILTER REMOVE driver command based on
+		 *  addr_filter_pattern
+		 */
+		if ((!qdf_mem_cmp(ip->mc_addr[i].bytes, ipv6_rs,
+			QDF_MAC_ADDR_SIZE)) ||
+		   (addr_fp &&
+		   (!qdf_mem_cmp(ip->mc_addr[i].bytes, &addr_fp, 1)))) {
+			pmo_debug("MC/BC filtering Skip addr %pM",
+				ip->mc_addr[i].bytes);
+			qdf_spin_lock_bh(&temp_ctx->pmo_vdev_lock);
+			op_list->mc_cnt--;
+			qdf_spin_unlock_bh(&temp_ctx->pmo_vdev_lock);
+			continue;
+		}
+		qdf_spin_lock_bh(&temp_ctx->pmo_vdev_lock);
+		qdf_mem_set(&(op_list->mc_addr[i].bytes), 0,
+			QDF_MAC_ADDR_SIZE);
+		qdf_mem_copy(&(op_list->mc_addr[i].bytes),
+			ip->mc_addr[i].bytes, QDF_MAC_ADDR_SIZE);
+		qdf_spin_unlock_bh(&temp_ctx->pmo_vdev_lock);
+		pmo_debug("mlist[%pM] = ", op_list->mc_addr[i].bytes);
+	}
+}
+
+static QDF_STATUS pmo_core_cache_mc_addr_list_in_vdev_priv(
+		struct pmo_mc_addr_list_params *mc_list_config,
+		struct wlan_objmgr_vdev *vdev)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	pmo_core_fill_mc_list(&vdev_ctx, mc_list_config);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS pmo_core_flush_mc_addr_list_from_vdev_priv(
+			struct wlan_objmgr_vdev *vdev)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	qdf_mem_zero(&vdev_ctx->vdev_mc_list_req,
+		sizeof(vdev_ctx->vdev_mc_list_req));
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_core_set_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+	struct pmo_mc_addr_list *mc_list)
+{
+	uint8_t vdev_id;
+	int i;
+
+	PMO_ENTER();
+
+	vdev_id = pmo_vdev_get_id(vdev);
+	/*
+	 * Configure enhance multicast offload feature for filtering out
+	 * multicast IP data packets transmitted using unicast MAC address
+	 */
+
+	/*
+	* TODO
+	{//(WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
+		//WMI_SERVICE_ENHANCED_MCAST_FILTER)) {
+	*/
+	if (1) {
+		pmo_info("FW supports enhance multicast offload");
+		pmo_tgt_send_enhance_multicast_offload_req(vdev, vdev_id,
+			false);
+	} else {
+		pmo_info("FW does not support enhance multicast offload");
+	}
+
+	/*
+	 * set mc_param->action to clear MCList and reset
+	 * to configure the MCList in FW
+	 */
+	for (i = 0; i < mc_list->mc_cnt; i++) {
+		pmo_tgt_set_mc_filter_req(vdev,
+					mc_list->mc_addr[i]);
+	}
+
+	PMO_EXIT();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_core_clear_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+	struct pmo_mc_addr_list *mc_list)
+{
+	uint8_t vdev_id;
+	int i;
+
+	PMO_ENTER();
+
+	vdev_id = pmo_vdev_get_id(vdev);
+
+	/*
+	 * Configure enhance multicast offload feature for filtering out
+	 * multicast IP data packets transmitted using unicast MAC address
+	 */
+
+	/*
+	* TODO
+	{//(WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
+		//WMI_SERVICE_ENHANCED_MCAST_FILTER)) {
+	*/
+	if (1) {
+		pmo_info("FW supports enhance multicast offload");
+		pmo_tgt_send_enhance_multicast_offload_req(vdev, vdev_id,
+			true);
+	} else {
+		pmo_info("FW does not support enhance multicast offload");
+	}
+
+	/*
+	 * set mcbc_param->action to clear MCList and reset
+	 * to configure the MCList in FW
+	 */
+	for (i = 0; i < mc_list->mc_cnt; i++) {
+		pmo_tgt_clear_mc_filter_req(vdev, mc_list->mc_addr[i]);
+	}
+
+	PMO_EXIT();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS pmo_core_do_enable_mc_addr_list(struct wlan_objmgr_vdev *vdev,
+	struct pmo_vdev_priv_obj *vdev_ctx,
+	struct pmo_mc_addr_list *op_mc_list_req)
+{
+	QDF_STATUS status;
+
+	PMO_ENTER();
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	if (!vdev_ctx->vdev_mc_list_req.mc_cnt) {
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+		pmo_err("mc_cnt is zero so skip to add mc list");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+	qdf_mem_copy(op_mc_list_req, &vdev_ctx->vdev_mc_list_req,
+		sizeof(*op_mc_list_req));
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	status = pmo_core_set_mc_filter_req(vdev, op_mc_list_req);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("cannot apply mc filter request");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	vdev_ctx->vdev_mc_list_req.is_filter_applied = true;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+static QDF_STATUS pmo_core_do_disable_mc_addr_list(
+	struct wlan_objmgr_vdev *vdev,
+	struct pmo_vdev_priv_obj *vdev_ctx,
+	struct pmo_mc_addr_list *op_mc_list_req)
+{
+	QDF_STATUS status;
+
+	PMO_ENTER();
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	/* validate filter is applied before clearing in fwr */
+	if (!vdev_ctx->vdev_mc_list_req.is_filter_applied) {
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+		pmo_err("mc filter is not applied in fwr");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+	qdf_mem_copy(op_mc_list_req, &vdev_ctx->vdev_mc_list_req,
+		sizeof(*op_mc_list_req));
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	status = pmo_core_clear_mc_filter_req(vdev, op_mc_list_req);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("cannot apply mc filter request");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	vdev_ctx->vdev_mc_list_req.is_filter_applied = false;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+uint8_t pmo_core_max_mc_addr_supported(struct wlan_objmgr_psoc *psoc)
+{
+	return PMO_MAX_MC_ADDR_LIST;
+}
+
+int pmo_core_get_mc_addr_list_count(struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	uint8_t mc_cnt;
+
+	vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		return PMO_INVALID_MC_ADDR_COUNT;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pmo_warn("failed to get vdev reference");
+		return PMO_INVALID_MC_ADDR_COUNT;
+	}
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	mc_cnt = vdev_ctx->vdev_mc_list_req.mc_cnt;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	pmo_vdev_put_ref(vdev);
+
+	return mc_cnt;
+}
+
+void pmo_core_set_mc_addr_list_count(struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id, uint8_t count)
+{
+	QDF_STATUS status;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		return;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pmo_warn("failed to get vdev reference");
+		return;
+	}
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	vdev_ctx->vdev_mc_list_req.mc_cnt = count;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	pmo_vdev_put_ref(vdev);
+}
+
+static QDF_STATUS pmo_core_mc_addr_flitering_sanity(
+			struct wlan_objmgr_vdev *vdev)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	/* Check if INI is enabled or not, otherwise just return */
+	if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.enable_mc_list) {
+		pmo_info("user disabled mc_addr_list using INI");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!pmo_core_is_vdev_supports_offload(vdev)) {
+		pmo_info("vdev in invalid opmode for mc addr filtering %d",
+			pmo_get_vdev_opmode(vdev));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!pmo_core_is_vdev_connected(vdev))
+		return QDF_STATUS_E_INVAL;
+
+	return QDF_STATUS_SUCCESS;
+}
+QDF_STATUS pmo_core_cache_mc_addr_list(
+		struct pmo_mc_addr_list_params *mc_list_config)
+{
+	struct wlan_objmgr_vdev *vdev;
+	QDF_STATUS status;
+
+	PMO_ENTER();
+
+	if (!mc_list_config->psoc) {
+		pmo_err("psoc is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	vdev = pmo_psoc_get_vdev(mc_list_config->psoc, mc_list_config->vdev_id);
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pmo_warn("failed to get vdev reference");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = pmo_core_mc_addr_flitering_sanity(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto dec_ref;
+
+	pmo_info("Cache mc addr list for vdev id: %d psoc: %p vdev: %p",
+			mc_list_config->vdev_id, mc_list_config->psoc, vdev);
+
+	status = pmo_core_cache_mc_addr_list_in_vdev_priv(mc_list_config, vdev);
+dec_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_flush_mc_addr_list(struct wlan_objmgr_psoc *psoc,
+	uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	PMO_ENTER();
+	if (!psoc) {
+		pmo_err("psoc is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pmo_warn("failed to get vdev reference");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = pmo_core_mc_addr_flitering_sanity(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto dec_ref;
+
+	pmo_info("Flush mc addr list for vdev id: %d psoc: %p vdev: %p",
+			vdev_id, psoc, vdev);
+
+	status = pmo_core_flush_mc_addr_list_from_vdev_priv(vdev);
+
+dec_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+static QDF_STATUS pmo_core_handle_enable_mc_list_trigger(
+			struct wlan_objmgr_vdev *vdev,
+			enum pmo_offload_trigger trigger)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	QDF_STATUS status;
+	struct pmo_mc_addr_list *op_mc_list_req = NULL;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	op_mc_list_req = qdf_mem_malloc(sizeof(*op_mc_list_req));
+	if (!op_mc_list_req) {
+		pmo_err("op_mc_list_req is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	switch (trigger) {
+	case pmo_mc_list_change_notify:
+		if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.active_mode_offload) {
+			pmo_info("active offload is disabled, skip in mode: %d",
+				trigger);
+			status = QDF_STATUS_E_INVAL;
+			goto out;
+		}
+		status = pmo_core_do_enable_mc_addr_list(vdev, vdev_ctx,
+				op_mc_list_req);
+		break;
+	case pmo_apps_suspend:
+		if (vdev_ctx->pmo_psoc_ctx->psoc_cfg.active_mode_offload) {
+			pmo_info("active offload is enabled, skip in mode: %d",
+				trigger);
+			status = QDF_STATUS_E_INVAL;
+			goto out;
+		}
+		status = pmo_core_do_enable_mc_addr_list(vdev, vdev_ctx,
+				op_mc_list_req);
+		break;
+	default:
+		status = QDF_STATUS_E_INVAL;
+		pmo_err("invalid pmo trigger for enable mc list");
+		break;
+	}
+out:
+	if (op_mc_list_req)
+		qdf_mem_free(op_mc_list_req);
+
+	return status;
+}
+
+QDF_STATUS pmo_core_enable_mc_addr_filtering_in_fwr(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id,
+		enum pmo_offload_trigger trigger)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
+
+	PMO_ENTER();
+	if (!psoc) {
+		pmo_err("psoc is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto out;
+
+	status = pmo_core_mc_addr_flitering_sanity(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto dec_ref;
+
+	pmo_info("enable mclist trigger: %d", trigger);
+	status = pmo_core_handle_enable_mc_list_trigger(vdev, trigger);
+dec_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+static QDF_STATUS pmo_core_handle_disable_mc_list_trigger(
+			struct wlan_objmgr_vdev *vdev,
+			enum pmo_offload_trigger trigger)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	QDF_STATUS status;
+	struct pmo_mc_addr_list *op_mc_list_req = NULL;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	op_mc_list_req = qdf_mem_malloc(sizeof(*op_mc_list_req));
+	if (!op_mc_list_req) {
+		pmo_err("op_mc_list_req is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	switch (trigger) {
+	case pmo_peer_disconnect:
+	case pmo_mc_list_change_notify:
+		if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.active_mode_offload) {
+			pmo_info("active offload is disabled, skip in mode: %d",
+				trigger);
+			status = QDF_STATUS_E_INVAL;
+			goto out;
+		}
+		status = pmo_core_do_disable_mc_addr_list(vdev, vdev_ctx,
+				op_mc_list_req);
+		break;
+	case pmo_apps_resume:
+		if (vdev_ctx->pmo_psoc_ctx->psoc_cfg.active_mode_offload) {
+			pmo_info("active offload is enabled, skip in mode: %d",
+				trigger);
+			status = QDF_STATUS_E_INVAL;
+			goto out;
+		}
+		status = pmo_core_do_disable_mc_addr_list(vdev, vdev_ctx,
+				op_mc_list_req);
+		break;
+	default:
+		status = QDF_STATUS_E_INVAL;
+		pmo_err("invalid pmo trigger for disable mc list");
+		break;
+	}
+out:
+	if (op_mc_list_req)
+		qdf_mem_free(op_mc_list_req);
+
+	return status;
+}
+
+QDF_STATUS pmo_core_disable_mc_addr_filtering_in_fwr(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id,
+		enum pmo_offload_trigger trigger)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
+
+	PMO_ENTER();
+	if (!psoc) {
+		pmo_err("psoc is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto out;
+
+	status = pmo_core_mc_addr_flitering_sanity(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto dec_ref;
+
+	pmo_info("disable mclist trigger: %d", trigger);
+	status = pmo_core_handle_disable_mc_list_trigger(vdev, trigger);
+dec_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
diff --git a/components/pmo/core/src/wlan_pmo_ns.c b/components/pmo/core/src/wlan_pmo_ns.c
new file mode 100644
index 0000000..b34374e
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_ns.c
@@ -0,0 +1,454 @@
+/*
+* Copyright (c) 2017 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: Implements ns offload feature API's
+ */
+
+#include "wlan_pmo_ns.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+static void pmo_core_fill_ns_addr(struct pmo_ns_offload_params *request,
+	struct pmo_ns_req *ns_req)
+{
+	int i;
+
+	for (i = 0; i < ns_req->count; i++) {
+		/*
+		 * Filling up the request structure
+		 * Filling the selfIPv6Addr with solicited address
+		 * A Solicited-Node multicast address is created by
+		 * taking the last 24 bits of a unicast or anycast
+		 * address and appending them to the prefix
+		 *
+		 * FF02:0000:0000:0000:0000:0001:FFXX:XXXX
+		 *
+		 * here XX is the unicast/anycast bits
+		 */
+		request->self_ipv6_addr[i][0] = 0xFF;
+		request->self_ipv6_addr[i][1] = 0x02;
+		request->self_ipv6_addr[i][11] = 0x01;
+		request->self_ipv6_addr[i][12] = 0xFF;
+		request->self_ipv6_addr[i][13] =
+					ns_req->ipv6_addr[i][13];
+		request->self_ipv6_addr[i][14] =
+					ns_req->ipv6_addr[i][14];
+		request->self_ipv6_addr[i][15] =
+					ns_req->ipv6_addr[i][15];
+		request->slot_idx = i;
+		qdf_mem_copy(&request->target_ipv6_addr[i],
+			&ns_req->ipv6_addr[i][0], PMO_MAC_IPV6_ADDR_LEN);
+
+		request->target_ipv6_addr_valid[i] =
+			PMO_IPV6_ADDR_VALID;
+		request->target_ipv6_addr_ac_type[i] =
+			ns_req->ipv6_addr_type[i];
+
+		pmo_info("NSoffload solicitIp: %pI6 targetIp: %pI6 Index: %d",
+			&request->self_ipv6_addr[i],
+			&request->target_ipv6_addr[i], i);
+	}
+}
+
+static QDF_STATUS pmo_core_cache_ns_in_vdev_priv(
+			struct pmo_ns_req *ns_req,
+			struct wlan_objmgr_vdev *vdev)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	struct pmo_ns_offload_params request;
+	struct wlan_objmgr_peer *peer;
+
+	PMO_ENTER();
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	qdf_mem_zero(&request, sizeof(request));
+	pmo_core_fill_ns_addr(&request, ns_req);
+
+	request.enable = PMO_OFFLOAD_ENABLE;
+	qdf_mem_copy(&request.self_macaddr.bytes,
+			  wlan_vdev_mlme_get_macaddr(vdev),
+			  QDF_MAC_ADDR_SIZE);
+
+	/* set number of ns offload address count */
+	request.num_ns_offload_count = ns_req->count;
+
+	peer = wlan_vdev_get_bsspeer(vdev);
+	if (!peer) {
+		pmo_err("peer is null");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+	pmo_info("vdev self mac addr: %pM bss peer mac addr: %pM",
+		wlan_vdev_mlme_get_macaddr(vdev),
+		wlan_peer_get_macaddr(peer));
+	/* get peer and peer mac accdress aka ap mac address */
+	qdf_mem_copy(&request.bssid,
+		wlan_peer_get_macaddr(peer),
+		QDF_MAC_ADDR_SIZE);
+	/* cache ns request */
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	qdf_mem_copy(&vdev_ctx->vdev_ns_req, &request,
+		sizeof(vdev_ctx->vdev_ns_req));
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+static QDF_STATUS pmo_core_flush_ns_from_vdev_priv(
+		struct wlan_objmgr_vdev *vdev)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	PMO_ENTER();
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	/* clear ns request */
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	qdf_mem_zero(&vdev_ctx->vdev_ns_req, sizeof(vdev_ctx->vdev_ns_req));
+	vdev_ctx->vdev_ns_req.enable = PMO_OFFLOAD_DISABLE;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	PMO_EXIT();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS pmo_core_do_enable_ns_offload(struct wlan_objmgr_vdev *vdev,
+		uint8_t vdev_id, enum pmo_offload_trigger trigger)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	PMO_ENTER();
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	psoc_ctx = vdev_ctx->pmo_psoc_ctx;
+	if (!psoc_ctx) {
+		pmo_err("psoc_ctx is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	switch (trigger) {
+	case pmo_ipv6_change_notify:
+	case pmo_ns_offload_dynamic_update:
+		if (!psoc_ctx->psoc_cfg.active_mode_offload) {
+			pmo_info("active offload is disabled, skip in mode:%d",
+				trigger);
+			status = QDF_STATUS_E_INVAL;
+			goto out;
+		}
+		/* enable arp when active offload is true (ipv6 notifier) */
+		status = pmo_tgt_enable_ns_offload_req(vdev, vdev_id);
+		break;
+	case pmo_apps_suspend:
+		if (psoc_ctx->psoc_cfg.active_mode_offload) {
+			pmo_info("active offload is enabled, skip in mode: %d",
+				trigger);
+			status = QDF_STATUS_E_INVAL;
+			goto out;
+		}
+		/* enable arp when active offload is false (apps suspend) */
+		status = pmo_tgt_enable_ns_offload_req(vdev, vdev_id);
+		break;
+	default:
+		status = QDF_STATUS_E_INVAL;
+		pmo_err("invalid pmo trigger");
+		break;
+	}
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+static QDF_STATUS pmo_core_do_disable_ns_offload(struct wlan_objmgr_vdev *vdev,
+		uint8_t vdev_id, enum pmo_offload_trigger trigger)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	PMO_ENTER();
+
+	psoc_ctx = pmo_vdev_get_psoc_priv(vdev);
+
+	switch (trigger) {
+	case pmo_ipv6_change_notify:
+	case pmo_ns_offload_dynamic_update:
+		if (!psoc_ctx->psoc_cfg.active_mode_offload) {
+			pmo_info("active offload is disabled, skip in mode:%d",
+				trigger);
+			status = QDF_STATUS_E_INVAL;
+			goto out;
+		}
+		/* config ns when active offload is enable */
+		status = pmo_tgt_disable_ns_offload_req(vdev, vdev_id);
+		break;
+	case pmo_apps_resume:
+		if (psoc_ctx->psoc_cfg.active_mode_offload) {
+			pmo_info("active offload is enabled, skip in mode: %d",
+				trigger);
+			status = QDF_STATUS_E_INVAL;
+			goto out;
+		}
+		/* config arp/ns when active offload is disable */
+		status = pmo_tgt_disable_ns_offload_req(vdev, vdev_id);
+		break;
+	default:
+		status = QDF_STATUS_E_INVAL;
+		pmo_err("invalid pmo trigger");
+		break;
+	}
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+
+static QDF_STATUS pmo_core_ns_offload_sanity(struct wlan_objmgr_vdev *vdev)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.ns_offload_enable_static) {
+		pmo_info("ns offload statically disable");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.ns_offload_enable_dynamic) {
+		pmo_info("ns offload dynamically disable");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!pmo_core_is_vdev_supports_offload(vdev)) {
+		pmo_info("vdev in invalid opmode for ns offload %d",
+			pmo_get_vdev_opmode(vdev));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (pmo_core_is_vdev_connected(vdev) == false)
+		return QDF_STATUS_E_INVAL;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_core_cache_ns_offload_req(
+		struct pmo_ns_req *ns_req)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
+
+	PMO_ENTER();
+	if (!ns_req) {
+		pmo_err("ns is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	if (!ns_req->psoc) {
+		pmo_err("psoc is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	vdev = pmo_psoc_get_vdev(ns_req->psoc, ns_req->vdev_id);
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto out;
+
+	status = pmo_core_ns_offload_sanity(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto dec_ref;
+
+	if (ns_req->count == 0) {
+		pmo_info("skip ns offload caching as ns count is 0");
+		status = QDF_STATUS_E_INVAL;
+		goto dec_ref;
+	}
+
+	status = pmo_core_cache_ns_in_vdev_priv(ns_req, vdev);
+dec_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_flush_ns_offload_req(struct wlan_objmgr_vdev *vdev)
+{
+	QDF_STATUS status;
+	uint8_t vdev_id;
+
+	PMO_ENTER();
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto out;
+
+	status = pmo_core_ns_offload_sanity(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto dec_ref;
+
+	vdev_id = pmo_vdev_get_id(vdev);
+	pmo_info("Flush ns offload on vdev id: %d vdev: %p", vdev_id, vdev);
+
+	status = pmo_core_flush_ns_from_vdev_priv(vdev);
+dec_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_enable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger)
+{
+	QDF_STATUS status;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	uint8_t vdev_id;
+
+	PMO_ENTER();
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto out;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	status = pmo_core_ns_offload_sanity(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto dec_ref;
+
+	if (trigger == pmo_ns_offload_dynamic_update) {
+		/*
+		 * user disable ns offload using ioctl/vendor cmd dynamically.
+		 */
+		vdev_ctx->pmo_psoc_ctx->psoc_cfg.ns_offload_enable_dynamic =
+			true;
+		goto skip_ns_dynamic_check;
+	}
+
+	if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.ns_offload_enable_dynamic) {
+		pmo_info("ns offload dynamically disable");
+		status = QDF_STATUS_E_INVAL;
+		goto dec_ref;
+	}
+
+skip_ns_dynamic_check:
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	if (vdev_ctx->vdev_ns_req.num_ns_offload_count == 0) {
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+		pmo_info("skip ns offload enable as ns count is 0");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	vdev_id = pmo_vdev_get_id(vdev);
+	pmo_info("Enable ns offload in fwr vdev id: %d vdev: %p trigger: %d",
+		vdev_id, vdev, trigger);
+	status = pmo_core_do_enable_ns_offload(vdev, vdev_id, trigger);
+dec_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_disable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger)
+{
+	QDF_STATUS status;
+	uint8_t vdev_id;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	PMO_ENTER();
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto out;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	status = pmo_core_ns_offload_sanity(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto dec_ref;
+
+	if (trigger == pmo_ns_offload_dynamic_update) {
+		/*
+		 * user disable ns offload using ioctl/vendor cmd dynamically.
+		 */
+		vdev_ctx->pmo_psoc_ctx->psoc_cfg.ns_offload_enable_dynamic =
+			false;
+		goto skip_ns_dynamic_check;
+	}
+
+	if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.ns_offload_enable_dynamic) {
+		pmo_info("ns offload dynamically disable");
+		status = QDF_STATUS_E_INVAL;
+		goto dec_ref;
+	}
+
+skip_ns_dynamic_check:
+	vdev_id = pmo_vdev_get_id(vdev);
+	pmo_info("disable ns offload in fwr vdev id: %d vdev: %p trigger: %d",
+		vdev_id, vdev, trigger);
+
+	status = pmo_core_do_disable_ns_offload(vdev, vdev_id, trigger);
+dec_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
diff --git a/components/pmo/core/src/wlan_pmo_pkt_filter.c b/components/pmo/core/src/wlan_pmo_pkt_filter.c
new file mode 100644
index 0000000..a59e25d
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_pkt_filter.c
@@ -0,0 +1,96 @@
+/*
+* Copyright (c) 2017 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: Implements Packet filter feature API's
+ */
+
+#include "wlan_pmo_pkt_filter.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+QDF_STATUS pmo_core_set_pkt_filter(struct wlan_objmgr_psoc *psoc,
+			struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req,
+			uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	QDF_STATUS status;
+
+	PMO_ENTER();
+
+	if (!psoc) {
+		pmo_err("psoc is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, WLAN_PMO_ID);
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_tgt_set_pkt_filter(vdev, pmo_set_pkt_fltr_req, vdev_id);
+	if (status != QDF_STATUS_SUCCESS)
+		goto dec_ref;
+
+dec_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_PMO_ID);
+out:
+	PMO_EXIT();
+
+	return status;
+
+}
+
+QDF_STATUS pmo_core_clear_pkt_filter(struct wlan_objmgr_psoc *psoc,
+		struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_param,
+		uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	QDF_STATUS status;
+
+	PMO_ENTER();
+
+	if (!psoc) {
+		pmo_err("psoc is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, WLAN_PMO_ID);
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_tgt_clear_pkt_filter(vdev, pmo_clr_pkt_fltr_param,
+								vdev_id);
+	if (status != QDF_STATUS_SUCCESS)
+		goto dec_ref;
+
+dec_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_PMO_ID);
+out:
+	PMO_EXIT();
+
+	return status;
+
+}
diff --git a/components/pmo/core/src/wlan_pmo_static_config.c b/components/pmo/core/src/wlan_pmo_static_config.c
new file mode 100644
index 0000000..b0653f3
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_static_config.c
@@ -0,0 +1,380 @@
+/*
+* Copyright (c) 2017 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: Implements static configuration on vdev attach
+ */
+
+#include "wlan_pmo_static_config.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_wow.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+static const uint8_t arp_ptrn[] = {0x08, 0x06};
+static const uint8_t arp_mask[] = {0xff, 0xff};
+static const uint8_t ns_ptrn[] = {0x86, 0xDD};
+static const uint8_t discvr_ptrn[] = {0xe0, 0x00, 0x00, 0xf8};
+static const uint8_t discvr_mask[] = {0xf0, 0x00, 0x00, 0xf8};
+
+void pmo_register_wow_wakeup_events(struct wlan_objmgr_vdev *vdev)
+{
+	uint32_t event_bitmap[PMO_WOW_MAX_EVENT_BM_LEN] = {0};
+	uint8_t vdev_id;
+	enum tQDF_ADAPTER_MODE  vdev_opmode;
+	const char *iface_type;
+
+	vdev_opmode = pmo_get_vdev_opmode(vdev);
+	vdev_id = pmo_vdev_get_id(vdev);
+	pmo_info("vdev_opmode %d vdev_id %d", vdev_opmode, vdev_id);
+
+	switch (vdev_opmode) {
+	case QDF_P2P_CLIENT_MODE:
+	case QDF_P2P_DEVICE_MODE:
+	case QDF_OCB_MODE:
+	case QDF_STA_MODE:
+	case QDF_MONITOR_MODE:
+		iface_type = "STA";
+		pmo_set_sta_wow_bitmask(event_bitmap, PMO_WOW_MAX_EVENT_BM_LEN);
+		break;
+
+	case QDF_IBSS_MODE:
+		iface_type = "IBSS";
+		pmo_set_sta_wow_bitmask(event_bitmap, PMO_WOW_MAX_EVENT_BM_LEN);
+		pmo_set_wow_event_bitmap(WOW_BEACON_EVENT,
+					 PMO_WOW_MAX_EVENT_BM_LEN,
+					 event_bitmap);
+		break;
+
+	case QDF_P2P_GO_MODE:
+	case QDF_SAP_MODE:
+		iface_type = "SAP";
+		pmo_set_sap_wow_bitmask(event_bitmap, PMO_WOW_MAX_EVENT_BM_LEN);
+		break;
+
+	case QDF_NDI_MODE:
+#ifdef WLAN_FEATURE_NAN_DATAPATH
+		iface_type = "NAN";
+		pmo_set_wow_event_bitmap(WOW_NAN_DATA_EVENT,
+					 PMO_WOW_MAX_EVENT_BM_LEN,
+					 event_bitmap);
+#endif
+		break;
+
+	default:
+		pmo_err("Skipping wake event configuration for vdev_opmode %d",
+			vdev_opmode);
+		return;
+	}
+
+	pmo_info("Selected %s wake event mask 0x%x%x%x%x, vdev %d",
+		 iface_type, event_bitmap[0], event_bitmap[1],
+		 event_bitmap[2], event_bitmap[3], vdev_id);
+
+	pmo_tgt_enable_wow_wakeup_event(vdev, event_bitmap);
+}
+
+/**
+ * pmo_configure_wow_ap() - set WOW patterns in ap mode
+ * @vdev: objmgr vdev handle
+ *
+ * Configures default WOW pattern for the given vdev_id which is in AP mode.
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS pmo_configure_wow_ap(struct wlan_objmgr_vdev *vdev)
+{
+	QDF_STATUS ret;
+	uint8_t arp_offset = 20;
+	uint8_t mac_mask[PMO_80211_ADDR_LEN];
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	/*
+	 * Setup unicast pkt pattern
+	 * WoW pattern id should be unique for each vdev
+	 * WoW pattern id can be same on 2 different VDEVs
+	 */
+	qdf_mem_set(&mac_mask, PMO_80211_ADDR_LEN, 0xFF);
+	ret = pmo_tgt_send_wow_patterns_to_fw(vdev,
+			pmo_get_and_increment_wow_default_ptrn(vdev_ctx),
+			wlan_vdev_mlme_get_macaddr(vdev),
+			PMO_80211_ADDR_LEN, 0, mac_mask,
+			PMO_80211_ADDR_LEN, false);
+	if (ret != QDF_STATUS_SUCCESS) {
+		pmo_err("Failed to add WOW unicast pattern ret %d", ret);
+		return ret;
+	}
+
+	/*
+	 * Setup all ARP pkt pattern. This is dummy pattern hence the length
+	 * is zero. Pattern ID should be unique per vdev.
+	 */
+	ret = pmo_tgt_send_wow_patterns_to_fw(vdev,
+			pmo_get_and_increment_wow_default_ptrn(vdev_ctx),
+			arp_ptrn, 0, arp_offset, arp_mask, 0, false);
+	if (ret != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to add WOW ARP pattern ret %d", ret);
+
+	return ret;
+}
+
+/**
+  * pmo_configure_mc_ssdp() - API to configure SSDP address as MC list
+  *@vdev: objmgr vdev handle.
+  *
+  * SSDP address 239.255.255.250 is converted to Multicast Mac address
+  * and configure it to FW. Firmware will apply this pattern on the incoming
+  * packets to filter them out during chatter/wow mode.
+  *
+  * Return: Success/Failure
+  */
+static QDF_STATUS pmo_configure_mc_ssdp(
+	struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_psoc *psoc;
+	const uint8_t ssdp_addr[QDF_MAC_ADDR_SIZE] = {
+		0x01, 0x00, 0x5e, 0x7f, 0xff, 0xfa };
+	struct qdf_mac_addr multicast_addr;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	qdf_mem_copy(&multicast_addr.bytes, &ssdp_addr, QDF_MAC_ADDR_SIZE);
+	status = pmo_tgt_set_mc_filter_req(vdev,
+					  multicast_addr);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("unable to set ssdp as mc addr list filter");
+
+	return status;
+}
+
+/**
+ * pmo_configure_wow_ssdp() - API to configure WoW SSDP
+ *@vdev: objmgr vdev handle
+ *
+ * API to configure SSDP pattern as WoW pattern
+ *
+ * Return: Success/Failure
+ */
+static QDF_STATUS pmo_configure_wow_ssdp(
+			struct wlan_objmgr_vdev *vdev)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t discvr_offset = 30;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	/*
+	 * WoW pattern ID should be unique for each vdev
+	 * Different WoW patterns can use same pattern ID
+	 */
+	 status = pmo_tgt_send_wow_patterns_to_fw(vdev,
+			pmo_get_and_increment_wow_default_ptrn(vdev_ctx),
+			discvr_ptrn, sizeof(discvr_ptrn), discvr_offset,
+			discvr_mask, sizeof(discvr_ptrn), false);
+
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to add WOW mDNS/SSDP/LLMNR pattern");
+
+	return status;
+}
+
+/**
+ * pmo_configure_ssdp() - API to Configure SSDP pattern to FW
+ *@vdev: objmgr vdev handle
+ *
+ * Setup multicast pattern for mDNS 224.0.0.251, SSDP 239.255.255.250 and LLMNR
+ * 224.0.0.252
+ *
+ * Return: Success/Failure.
+ */
+static QDF_STATUS pmo_configure_ssdp(struct wlan_objmgr_vdev *vdev)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.ssdp) {
+		pmo_err("mDNS, SSDP, LLMNR patterns are disabled from ini");
+		return QDF_STATUS_SUCCESS;
+	}
+
+	pmo_debug("enable_mc_list:%d",
+		vdev_ctx->pmo_psoc_ctx->psoc_cfg.enable_mc_list);
+
+	if (vdev_ctx->pmo_psoc_ctx->psoc_cfg.enable_mc_list)
+		return pmo_configure_mc_ssdp(vdev);
+
+	return pmo_configure_wow_ssdp(vdev);
+}
+
+/**
+ * pmo_configure_wow_sta() - set WOW patterns in sta mode
+ * @vdev: objmgr vdev handle
+ *
+ * Configures default WOW pattern for the given vdev_id which is in sta mode.
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS pmo_configure_wow_sta(struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t arp_offset = 12;
+	uint8_t mac_mask[PMO_80211_ADDR_LEN];
+	QDF_STATUS ret = QDF_STATUS_SUCCESS;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	qdf_mem_set(&mac_mask, PMO_80211_ADDR_LEN, 0xFF);
+	/*
+	 * Set up unicast wow pattern
+	 * WoW pattern ID should be unique for each vdev
+	 * Different WoW patterns can use same pattern ID
+	 */
+	ret = pmo_tgt_send_wow_patterns_to_fw(vdev,
+			pmo_get_and_increment_wow_default_ptrn(vdev_ctx),
+			wlan_vdev_mlme_get_macaddr(vdev),
+			PMO_80211_ADDR_LEN, 0, mac_mask,
+			PMO_80211_ADDR_LEN, false);
+	if (ret != QDF_STATUS_SUCCESS) {
+		pmo_err("Failed to add WOW unicast pattern ret %d", ret);
+		return ret;
+	}
+
+	ret = pmo_configure_ssdp(vdev);
+	if (ret != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to configure SSDP patterns to FW");
+
+	/*
+	 * when arp offload or ns offloaded is disabled
+	 * from ini file, configure broad cast arp pattern
+	 * to fw, so that host can wake up
+	 */
+	if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.arp_offload_enable) {
+		/* Setup all ARP pkt pattern */
+		pmo_info("ARP offload is disabled in INI enable WoW for ARP");
+		ret = pmo_tgt_send_wow_patterns_to_fw(vdev,
+				pmo_get_and_increment_wow_default_ptrn(
+					vdev_ctx),
+				arp_ptrn, sizeof(arp_ptrn), arp_offset,
+				arp_mask, sizeof(arp_mask), false);
+		if (ret != QDF_STATUS_SUCCESS) {
+			pmo_err("Failed to add WOW ARP pattern");
+			return ret;
+		}
+	}
+	/* for NS or NDP offload packets */
+	if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.ns_offload_enable_static) {
+		/* Setup all NS pkt pattern */
+		pmo_info("NS offload is disabled in INI enable WoW for NS");
+		ret = pmo_tgt_send_wow_patterns_to_fw(vdev,
+				pmo_get_and_increment_wow_default_ptrn(
+					vdev_ctx),
+				ns_ptrn, sizeof(arp_ptrn), arp_offset,
+				arp_mask, sizeof(arp_mask), false);
+		if (ret != QDF_STATUS_SUCCESS) {
+			pmo_err("Failed to add WOW NS pattern");
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
+void pmo_register_wow_default_patterns(struct wlan_objmgr_vdev *vdev)
+{
+	enum tQDF_ADAPTER_MODE  vdev_opmode = QDF_MAX_NO_OF_MODE;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	uint8_t vdev_id;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	vdev_id = pmo_vdev_get_id(vdev);
+	if (vdev_id > WLAN_UMAC_PSOC_MAX_VDEVS) {
+		pmo_err("Invalid vdev id %d", vdev_id);
+		return;
+	}
+
+	vdev_opmode = pmo_get_vdev_opmode(vdev);
+	if (vdev_opmode == QDF_MAX_NO_OF_MODE) {
+		pmo_err("Invalid vdev opmode %d", vdev_id);
+		return;
+	}
+
+	if (!vdev_ctx->ptrn_match_enable) {
+		pmo_err("ptrn_match is disable for vdev %d", vdev_id);
+		return;
+	}
+
+	if (pmo_is_vdev_in_beaconning_mode(vdev_opmode)) {
+		/* Configure SAP/GO/IBSS mode default wow patterns */
+		pmo_info("Config SAP default wow patterns vdev_id %d",
+			 vdev_id);
+		pmo_configure_wow_ap(vdev);
+	} else {
+		/* Configure STA/P2P CLI mode default wow patterns */
+		pmo_info("Config STA default wow patterns vdev_id %d",
+			vdev_id);
+		pmo_configure_wow_sta(vdev);
+		psoc_ctx = vdev_ctx->pmo_psoc_ctx;
+		if (psoc_ctx && psoc_ctx->psoc_cfg.ra_ratelimit_enable) {
+			pmo_info("Config STA RA wow pattern vdev_id %d",
+				vdev_id);
+			pmo_tgt_send_ra_filter_req(vdev);
+		}
+	}
+
+}
+
+void pmo_register_action_frame_patterns(struct wlan_objmgr_vdev *vdev)
+{
+
+	struct pmo_action_wakeup_set_params cmd = {0};
+	int i = 0;
+	QDF_STATUS status;
+
+	cmd.vdev_id = pmo_vdev_get_id(vdev);
+	cmd.operation = pmo_action_wakeup_set;
+
+	cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP0;
+	cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP1;
+	cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP2;
+	cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP3;
+	cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP4;
+	cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP5;
+	cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP6;
+	cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP7;
+
+	for (i = 0; i < PMO_SUPPORTED_ACTION_CATE_ELE_LIST; i++) {
+		if (i < ALLOWED_ACTION_FRAME_MAP_WORDS)
+			pmo_debug("%s: %d action Wakeup pattern 0x%x in fw",
+				__func__, i, cmd.action_category_map[i]);
+		else
+			cmd.action_category_map[i] = 0;
+	}
+
+	/*  config action frame patterns */
+	status = pmo_tgt_send_action_frame_pattern_req(vdev, &cmd);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to config wow action frame map, ret %d",
+			status);
+}
+
diff --git a/components/pmo/core/src/wlan_pmo_suspend_resume.c b/components/pmo/core/src/wlan_pmo_suspend_resume.c
new file mode 100644
index 0000000..65e3a20
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_suspend_resume.c
@@ -0,0 +1,1225 @@
+/*
+* Copyright (c) 2017 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: Define API's for suspend / resume handling
+ */
+
+#include "wlan_pmo_wow.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_lphb.h"
+#include "wlan_pmo_suspend_resume.h"
+#include "cdp_txrx_ops.h"
+#include "cdp_txrx_misc.h"
+#include "cdp_txrx_flow_ctrl_legacy.h"
+#include "hif.h"
+#include "htc_api.h"
+#include "wlan_pmo_obj_mgmt_api.h"
+#include <wlan_scan_ucfg_api.h>
+#include "cds_api.h"
+#include "wlan_pmo_static_config.h"
+
+/**
+ * pmo_core_calculate_listen_interval() - Calculate vdev listen interval
+ * @vdev: objmgr vdev handle
+ * @vdev_ctx: pmo vdev priv ctx
+ * @listen_interval: listen interval which is computed for vdev
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS pmo_core_calculate_listen_interval(
+			struct wlan_objmgr_vdev *vdev,
+			struct pmo_vdev_priv_obj *vdev_ctx,
+			uint32_t *listen_interval)
+{
+	uint32_t max_mod_dtim;
+	uint32_t beacon_interval_mod;
+	struct pmo_psoc_cfg *psoc_cfg = &vdev_ctx->pmo_psoc_ctx->psoc_cfg;
+
+	if (psoc_cfg->sta_dynamic_dtim) {
+		*listen_interval = psoc_cfg->sta_dynamic_dtim;
+	} else if ((psoc_cfg->sta_mod_dtim) &&
+		   (psoc_cfg->sta_max_li_mod_dtim)) {
+		/*
+		 * When the system is in suspend
+		 * (maximum beacon will be at 1s == 10)
+		 * If maxModulatedDTIM ((MAX_LI_VAL = 10) / AP_DTIM)
+		 * equal or larger than MDTIM
+		 * (configured in WCNSS_qcom_cfg.ini)
+		 * Set LI to MDTIM * AP_DTIM
+		 * If Dtim = 2 and Mdtim = 2 then LI is 4
+		 * Else
+		 * Set LI to maxModulatedDTIM * AP_DTIM
+		 */
+		beacon_interval_mod =
+			pmo_core_get_vdev_beacon_interval(vdev) / 100;
+		if (beacon_interval_mod == 0)
+			beacon_interval_mod = 1;
+
+		max_mod_dtim = psoc_cfg->sta_max_li_mod_dtim /
+			(pmo_core_get_vdev_dtim_period(vdev)
+			 * beacon_interval_mod);
+
+		if (max_mod_dtim <= 0)
+			max_mod_dtim = 1;
+
+		if (max_mod_dtim >= psoc_cfg->sta_mod_dtim) {
+			*listen_interval =
+				(psoc_cfg->sta_mod_dtim *
+				pmo_core_get_vdev_dtim_period(vdev));
+		} else {
+			*listen_interval =
+				(max_mod_dtim *
+				pmo_core_get_vdev_dtim_period(vdev));
+		}
+	} else {
+		return QDF_STATUS_E_FAULT;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * pmo_core_set_vdev_suspend_dtim() - set suspend dtim parameters in fw
+ * @psoc: objmgr psoc handle
+ * @vdev: objmgr vdev handle
+ * @vdev_ctx: pmo vdev priv ctx
+ *
+ * Return: none
+ */
+static void pmo_core_set_vdev_suspend_dtim(struct wlan_objmgr_psoc *psoc,
+		struct wlan_objmgr_vdev *vdev,
+		struct pmo_vdev_priv_obj *vdev_ctx)
+{
+	uint32_t listen_interval;
+	QDF_STATUS ret;
+	uint8_t vdev_id;
+	enum pmo_power_save_qpower_mode qpower_config;
+	enum tQDF_ADAPTER_MODE opmode = pmo_core_get_vdev_op_mode(vdev);
+
+	qpower_config = pmo_core_psoc_get_qpower_config(psoc);
+	vdev_id = pmo_vdev_get_id(vdev);
+	if (PMO_VDEV_IN_STA_MODE(opmode) &&
+	    pmo_core_get_vdev_dtim_period(vdev) != 0) {
+		/* calculate listen interval */
+		ret = pmo_core_calculate_listen_interval(vdev, vdev_ctx,
+				&listen_interval);
+		if (ret != QDF_STATUS_SUCCESS) {
+			/* even it fails continue fwr will take default LI */
+			pmo_info("Fail to calculate listen interval");
+		}
+
+		ret = pmo_tgt_vdev_update_param_req(vdev,
+				pmo_vdev_param_listen_interval,
+				listen_interval);
+		if (QDF_IS_STATUS_ERROR(ret)) {
+			/* even it fails continue fwr will take default LI */
+			pmo_info("Failed to Set Listen Interval vdevId %d",
+				 vdev_id);
+		}
+		pmo_debug("Set Listen Interval vdevId %d Listen Intv %d",
+			 vdev_id, listen_interval);
+
+		if (qpower_config) {
+			pmo_debug("disable Qpower in suspend mode!");
+			ret = pmo_tgt_send_vdev_sta_ps_param(vdev,
+					pmo_sta_ps_enable_qpower, 0);
+			if (QDF_IS_STATUS_ERROR(ret))
+				pmo_info("Failed to disable Qpower in suspend mode!");
+		}
+
+		ret = pmo_tgt_vdev_update_param_req(vdev,
+				pmo_vdev_param_dtim_policy,
+				pmo_normal_dtim);
+		if (QDF_IS_STATUS_ERROR(ret))
+			pmo_info("Failed to Set to Normal DTIM vdevId %d",
+				vdev_id);
+
+		/* Set it to Normal DTIM */
+		pmo_core_vdev_set_dtim_policy(vdev, pmo_normal_dtim);
+		pmo_debug("Set DTIM Policy to Normal Dtim vdevId %d", vdev_id);
+	}
+}
+
+/**
+ * pmo_core_set_suspend_dtim() - set suspend dtim
+ * @psoc: objmgr psoc handle
+ *
+ * Return: none
+ */
+static void pmo_core_set_suspend_dtim(struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_vdev *vdev;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	bool alt_mdtim_enabled;
+	QDF_STATUS status;
+
+	/* Iterate through VDEV list */
+	for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) {
+		vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+		if (!vdev)
+			continue;
+
+		status = pmo_vdev_get_ref(vdev);
+		if (QDF_IS_STATUS_ERROR(status))
+			continue;
+
+		vdev_ctx = pmo_vdev_get_priv(vdev);
+		qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+		alt_mdtim_enabled = vdev_ctx->alt_modulated_dtim_enable;
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+		if (!alt_mdtim_enabled)
+			pmo_core_set_vdev_suspend_dtim(psoc, vdev, vdev_ctx);
+
+		pmo_vdev_put_ref(vdev);
+	}
+}
+
+/**
+ * pmo_core_update_wow_bus_suspend() - set wow bus suspend flag
+ * @psoc: objmgr psoc handle
+ * @psoc_ctx: pmo psoc priv ctx
+ * @val: true for enable else false
+ * Return: none
+ */
+static inline
+void pmo_core_update_wow_bus_suspend(struct wlan_objmgr_psoc *psoc,
+		struct pmo_psoc_priv_obj *psoc_ctx, int val)
+{
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	psoc_ctx->wow.is_wow_bus_suspended = val;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+	pmo_tgt_psoc_update_wow_bus_suspend_state(psoc, val);
+}
+
+/* Define for conciseness */
+#define BM_LEN PMO_WOW_MAX_EVENT_BM_LEN
+#define EV_NLO WOW_NLO_SCAN_COMPLETE_EVENT
+#define EV_PWR WOW_CHIP_POWER_FAILURE_DETECT_EVENT
+
+void pmo_core_configure_dynamic_wake_events(struct wlan_objmgr_psoc *psoc)
+{
+	int vdev_id;
+	uint32_t adapter_type;
+	uint32_t enable_mask[BM_LEN];
+	uint32_t disable_mask[BM_LEN];
+	struct wlan_objmgr_vdev *vdev;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	bool enable_configured;
+	bool disable_configured;
+
+	/* Iterate through VDEV list */
+	for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) {
+
+		enable_configured = false;
+		disable_configured = false;
+
+		qdf_mem_set(enable_mask,  sizeof(uint32_t) * BM_LEN, 0);
+		qdf_mem_set(disable_mask, sizeof(uint32_t) * BM_LEN, 0);
+
+		vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+		if (!vdev)
+			continue;
+
+		if (ucfg_scan_get_pno_in_progress(vdev)) {
+			if (ucfg_scan_get_pno_match(vdev)) {
+				pmo_set_wow_event_bitmap(EV_NLO,
+							 BM_LEN,
+							 enable_mask);
+				enable_configured = true;
+			} else {
+				pmo_set_wow_event_bitmap(EV_NLO,
+							 BM_LEN,
+							 disable_mask);
+				disable_configured = true;
+		}
+		}
+
+		adapter_type = pmo_get_vdev_opmode(vdev);
+
+		psoc_ctx = pmo_psoc_get_priv(psoc);
+
+		if (psoc_ctx->psoc_cfg.auto_power_save_fail_mode &&
+		    (adapter_type == QDF_STA_MODE ||
+		     adapter_type == QDF_P2P_CLIENT_MODE)
+		   ) {
+			if (psoc_ctx->is_device_in_low_pwr_mode &&
+				psoc_ctx->is_device_in_low_pwr_mode(vdev_id))
+				pmo_set_wow_event_bitmap(EV_PWR,
+						 BM_LEN,
+						 enable_mask);
+			pmo_core_enable_wakeup_event(psoc, vdev_id,
+				enable_mask);
+				enable_configured = true;
+		}
+		if (enable_configured)
+			pmo_core_enable_wakeup_event(psoc, vdev_id,
+				enable_mask);
+
+		if (disable_configured)
+			pmo_core_disable_wakeup_event(psoc, vdev_id,
+					disable_mask);
+	}
+
+}
+
+/**
+ * pmo_core_psoc_configure_suspend(): configure suspend req events
+ * @psoc: objmgr psoc
+ *
+ * Responsibility of the caller to take the psoc reference.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS pmo_core_psoc_configure_suspend(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	PMO_ENTER();
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	if (pmo_core_is_wow_applicable(psoc)) {
+		pmo_info("WOW Suspend");
+		pmo_core_apply_lphb(psoc);
+
+		pmo_core_configure_dynamic_wake_events(psoc);
+		pmo_core_update_wow_enable(psoc_ctx, true);
+		pmo_core_update_wow_enable_cmd_sent(psoc_ctx, false);
+	}
+
+	pmo_core_set_suspend_dtim(psoc);
+
+	/*
+	 * To handle race between hif_pci_suspend and unpause/pause tx handler.
+	 * This happens when host sending WMI_WOW_ENABLE_CMDID to FW and receive
+	 * WMI_TX_PAUSE_EVENT with ACTON_UNPAUSE almost at same time.
+	 */
+	pmo_core_update_wow_bus_suspend(psoc, psoc_ctx, true);
+
+	PMO_EXIT();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_core_psoc_user_space_suspend_req(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type)
+{
+	QDF_STATUS status;
+
+	PMO_ENTER();
+
+	status = pmo_psoc_get_ref(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("pmo cannot get the reference out of psoc");
+		goto out;
+	}
+
+	/* Suspend all components before sending target suspend command */
+	status = pmo_suspend_all_components(psoc, type);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("Failed to suspend all component");
+		goto dec_psoc_ref;
+	}
+
+	status = pmo_core_psoc_configure_suspend(psoc);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to configure suspend");
+
+dec_psoc_ref:
+	pmo_psoc_put_ref(psoc);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+/**
+ * pmo_core_set_vdev_resume_dtim() - set resume dtim parameters in fw
+ * @psoc: objmgr psoc handle
+ * @vdev: objmgr vdev handle
+ * @vdev_ctx: pmo vdev priv ctx
+ *
+ * Return: none
+ */
+static void pmo_core_set_vdev_resume_dtim(struct wlan_objmgr_psoc *psoc,
+		struct wlan_objmgr_vdev *vdev,
+		struct pmo_vdev_priv_obj *vdev_ctx)
+{
+	enum pmo_power_save_qpower_mode qpower_config;
+	QDF_STATUS ret;
+	uint8_t vdev_id;
+	enum tQDF_ADAPTER_MODE opmode = pmo_core_get_vdev_op_mode(vdev);
+	uint32_t cfg_data_val = 0;
+
+	qpower_config = pmo_core_psoc_get_qpower_config(psoc);
+	vdev_id = pmo_vdev_get_id(vdev);
+	if ((PMO_VDEV_IN_STA_MODE(opmode)) &&
+	    (pmo_core_vdev_get_dtim_policy(vdev) == pmo_normal_dtim)) {
+/*
+		if (!mac) {
+			WMA_LOGE(FL("Failed to get mac context"));
+			return;
+		}
+		if ((wlan_cfg_get_int(mac, WNI_CFG_LISTEN_INTERVAL,
+				      &cfg_data_val) != eSIR_SUCCESS)) {
+			pmo_err("Failed to get value for listen interval");
+			cfg_data_val = POWERSAVE_DEFAULT_LISTEN_INTERVAL;
+		}
+*/
+		cfg_data_val = 1;
+		ret = pmo_tgt_vdev_update_param_req(vdev,
+				pmo_vdev_param_listen_interval, cfg_data_val);
+		if (QDF_IS_STATUS_ERROR(ret)) {
+			/* Even it fails continue Fw will take default LI */
+			pmo_err("Failed to Set Listen Interval vdevId %d",
+				 vdev_id);
+		}
+		pmo_debug("Set Listen Interval vdevId %d Listen Intv %d",
+			 vdev_id, cfg_data_val);
+
+		ret = pmo_tgt_vdev_update_param_req(vdev,
+				pmo_vdev_param_dtim_policy,
+				pmo_stick_dtim);
+		if (QDF_IS_STATUS_ERROR(ret)) {
+			/* Set it back to Stick DTIM */
+			pmo_err("Failed to Set to Stick DTIM vdevId %d",
+				 vdev_id);
+		}
+		pmo_core_vdev_set_dtim_policy(vdev, pmo_stick_dtim);
+		pmo_debug("Set DTIM Policy to Stick Dtim vdevId %d", vdev_id);
+
+		if (qpower_config) {
+			pmo_debug("enable Qpower in resume mode!");
+			ret = pmo_tgt_send_vdev_sta_ps_param(vdev,
+				pmo_sta_ps_enable_qpower, qpower_config);
+			if (QDF_IS_STATUS_ERROR(ret))
+				pmo_err("Failed to enable Qpower in resume");
+		}
+	}
+}
+
+/**
+ * pmo_core_set_resume_dtim() - set resume time dtim
+ * @psoc: objmgr psoc handle
+ *
+ * Return: none
+ */
+static void pmo_core_set_resume_dtim(struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_vdev *vdev;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	bool alt_mdtim_enabled;
+	QDF_STATUS status;
+
+	/* Iterate through VDEV list */
+	for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) {
+		vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+		if (!vdev)
+			continue;
+
+		status = pmo_vdev_get_ref(vdev);
+		if (QDF_IS_STATUS_ERROR(status))
+			continue;
+
+		vdev_ctx = pmo_vdev_get_priv(vdev);
+		qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+		alt_mdtim_enabled = vdev_ctx->alt_modulated_dtim_enable;
+		qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+		if (!alt_mdtim_enabled)
+			pmo_core_set_vdev_resume_dtim(psoc, vdev, vdev_ctx);
+
+		pmo_vdev_put_ref(vdev);
+	}
+}
+
+/**
+ * pmo_unpause_vdev - unpause all vdev
+ * @psoc: objmgr psoc handle
+ *
+ * unpause all vdev aftter resume/coming out of wow mode
+ *
+ * Return: none
+ */
+static void pmo_unpause_all_vdev(struct wlan_objmgr_psoc *psoc,
+		struct pmo_psoc_priv_obj *psoc_ctx)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc_objmgr *objmgr;
+	struct wlan_objmgr_vdev *vdev;
+
+	/* Iterate through VDEV list */
+	for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) {
+		wlan_psoc_obj_lock(psoc);
+		objmgr = &psoc->soc_objmgr;
+		if (!objmgr->wlan_vdev_list[vdev_id]) {
+			wlan_psoc_obj_unlock(psoc);
+			continue;
+		}
+		vdev = objmgr->wlan_vdev_list[vdev_id];
+		wlan_psoc_obj_unlock(psoc);
+		if (vdev) {
+#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
+			/*
+			 * When host resume, by default,
+			 * unpause all active vdev
+			 */
+			if (pmo_core_vdev_get_pause_bitmap(psoc_ctx, vdev_id)) {
+				cdp_fc_vdev_unpause(
+					pmo_core_psoc_get_dp_handle(psoc),
+					pmo_core_vdev_get_dp_handle(vdev),
+					0xffffffff);
+				if (psoc_ctx->pause_bitmap_notifier)
+					psoc_ctx->pause_bitmap_notifier(vdev_id,
+							0);
+			}
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+		}
+	}
+}
+
+/**
+ * pmo_core_psoc_configure_resume(): configure events after bus resume
+ * @psoc: objmgr psoc
+ *
+ * Responsibility of the caller to take the psoc reference.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS pmo_core_psoc_configure_resume(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	PMO_ENTER();
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	pmo_core_set_resume_dtim(psoc);
+	pmo_core_update_wow_bus_suspend(psoc, psoc_ctx, false);
+	pmo_unpause_all_vdev(psoc, psoc_ctx);
+
+	PMO_EXIT();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_core_psoc_user_space_resume_req(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	PMO_ENTER();
+
+	status = pmo_psoc_get_ref(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("pmo cannot get the reference out of psoc");
+		goto out;
+	}
+
+	/* Resume all components */
+	status = pmo_resume_all_components(psoc, type);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("Failed to resume all the components");
+		goto dec_psoc_ref;
+	}
+
+	status = pmo_core_psoc_configure_resume(psoc);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to configure resume");
+
+dec_psoc_ref:
+	pmo_psoc_put_ref(psoc);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+/**
+ * pmo_core_enable_wow_in_fw() - enable wow in fw
+ * @psoc: objmgr psoc handle
+ * @psoc_ctx: pmo psoc private ctx
+ * @wow_params: collection of wow enable override parameters
+ *
+ * Return: QDF status
+ */
+static
+QDF_STATUS pmo_core_enable_wow_in_fw(struct wlan_objmgr_psoc *psoc,
+		struct pmo_psoc_priv_obj *psoc_ctx,
+		struct pmo_wow_enable_params *wow_params)
+{
+	int host_credits, wmi_pending_cmds;
+	struct pmo_wow_cmd_params param = {0};
+	QDF_STATUS status;
+
+	PMO_ENTER();
+	qdf_event_reset(&psoc_ctx->wow.target_suspend);
+	pmo_core_set_wow_nack(psoc_ctx, false);
+	host_credits = pmo_tgt_psoc_get_host_credits(psoc);
+	wmi_pending_cmds = pmo_tgt_psoc_get_pending_cmnds(psoc);
+	pmo_debug("Credits:%d; Pending_Cmds: %d",
+		host_credits, wmi_pending_cmds);
+
+	param.enable = true;
+	if (wow_params->is_unit_test)
+		param.flags = WMI_WOW_FLAG_UNIT_TEST_ENABLE;
+
+	switch (wow_params->interface_pause) {
+	default:
+		pmo_err("Invalid interface pause setting: %d",
+			 wow_params->interface_pause);
+		/* intentional fall-through to default */
+	case PMO_WOW_INTERFACE_PAUSE_DEFAULT:
+		param.can_suspend_link =
+			htc_can_suspend_link(
+				pmo_core_psoc_get_htc_handle(psoc));
+		break;
+	case PMO_WOW_INTERFACE_PAUSE_ENABLE:
+		param.can_suspend_link = true;
+		break;
+	case PMO_WOW_INTERFACE_PAUSE_DISABLE:
+		param.can_suspend_link = false;
+		break;
+	}
+
+	switch (wow_params->resume_trigger) {
+	default:
+		pmo_err("Invalid resume trigger setting: %d",
+			 wow_params->resume_trigger);
+		/* intentional fall-through to default */
+	case PMO_WOW_RESUME_TRIGGER_DEFAULT:
+	case PMO_WOW_RESUME_TRIGGER_GPIO:
+		/*
+		 * GPIO is currently implicit. This means you can't actually
+		 * force GPIO if a platform's default wake trigger is HTC wakeup
+		 */
+		break;
+	case PMO_WOW_RESUME_TRIGGER_HTC_WAKEUP:
+		param.flags |= WMI_WOW_FLAG_DO_HTC_WAKEUP;
+		break;
+	}
+
+	status = pmo_tgt_psoc_send_wow_enable_req(psoc, &param);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("Failed to enable wow in fw");
+		goto out;
+	}
+
+	pmo_tgt_update_target_suspend_flag(psoc, true);
+
+	if (qdf_wait_single_event(&psoc_ctx->wow.target_suspend,
+				  PMO_TGT_SUSPEND_COMPLETE_TIMEOUT)
+	    != QDF_STATUS_SUCCESS) {
+		pmo_err("Failed to receive WoW Enable Ack from FW");
+		pmo_err("Credits:%d; Pending_Cmds: %d",
+			pmo_tgt_psoc_get_host_credits(psoc),
+			pmo_tgt_psoc_get_pending_cmnds(psoc));
+		pmo_tgt_update_target_suspend_flag(psoc, false);
+		status = QDF_STATUS_E_FAILURE;
+		QDF_BUG(0);
+		goto out;
+	}
+
+	if (pmo_core_get_wow_nack(psoc_ctx)) {
+		pmo_err("FW not ready to WOW");
+		pmo_tgt_update_target_suspend_flag(psoc, false);
+		status = QDF_STATUS_E_AGAIN;
+		goto out;
+	}
+
+	host_credits = pmo_tgt_psoc_get_host_credits(psoc);
+	wmi_pending_cmds = pmo_tgt_psoc_get_pending_cmnds(psoc);
+
+	if (host_credits < PMO_WOW_REQUIRED_CREDITS) {
+		pmo_err("No Credits after HTC ACK:%d, pending_cmds:%d,"
+			 "cannot resume back", host_credits, wmi_pending_cmds);
+		htc_dump_counter_info(pmo_core_psoc_get_htc_handle(psoc));
+/*
+		if (!cds_is_driver_recovering())
+			QDF_BUG(0);
+		else
+			pmo_err("SSR in progress, ignore no credit issue");
+*/
+	}
+	pmo_debug("WOW enabled successfully in fw: credits:%d pending_cmds: %d",
+		host_credits, wmi_pending_cmds);
+
+	pmo_core_update_wow_enable_cmd_sent(psoc_ctx, true);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_psoc_suspend_target(struct wlan_objmgr_psoc *psoc,
+		int disable_target_intr)
+{
+	QDF_STATUS status;
+	struct pmo_suspend_params param;
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	PMO_ENTER();
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	qdf_event_reset(&psoc_ctx->wow.target_suspend);
+	param.disable_target_intr = disable_target_intr;
+	status = pmo_tgt_psoc_send_supend_req(psoc, &param);
+	if (status != QDF_STATUS_SUCCESS)
+		goto out;
+
+	pmo_tgt_update_target_suspend_flag(psoc, true);
+
+	if (qdf_wait_single_event(&psoc_ctx->wow.target_suspend,
+				  PMO_TGT_SUSPEND_COMPLETE_TIMEOUT)
+	    != QDF_STATUS_SUCCESS) {
+		status = QDF_STATUS_E_TIMEOUT;
+		pmo_err("Failed to get ACK from firmware for pdev suspend");
+		pmo_tgt_update_target_suspend_flag(psoc, false);
+		/* wma_suspend_target_timeout(pmac->sme.enableSelfRecovery); */
+	}
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_psoc_bus_suspend_req(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type,
+		struct pmo_wow_enable_params *wow_params)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	QDF_STATUS status;
+	bool wow_mode_selected = false;
+
+	PMO_ENTER();
+	if (!psoc) {
+		pmo_err("psoc is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	if (!wow_params) {
+		pmo_err("wow_params is NULL");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_psoc_get_ref(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("pmo cannot get the reference out of psoc");
+		goto out;
+	}
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+
+/* TODO - scan manager need to provide the below public api
+	if (wma_check_scan_in_progress(handle)) {
+		pmo_err("Scan in progress. Aborting suspend");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+*/
+
+	wow_mode_selected = pmo_core_is_wow_enabled(psoc_ctx);
+	pmo_info("wow mode selected %d", wow_mode_selected);
+
+	if (wow_mode_selected)
+		status = pmo_core_enable_wow_in_fw(psoc, psoc_ctx, wow_params);
+	else
+		status = pmo_core_psoc_suspend_target(psoc, 0);
+
+	pmo_psoc_put_ref(psoc);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+#ifdef FEATURE_RUNTIME_PM
+QDF_STATUS pmo_core_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc,
+					     pmo_pld_auto_suspend_cb pld_cb)
+{
+	void *hif_ctx;
+	void *dp_soc;
+	void *txrx_pdev;
+	void *htc_ctx;
+	QDF_STATUS status;
+	struct pmo_wow_enable_params wow_params = {0};
+
+	PMO_ENTER();
+
+	if (!psoc) {
+		pmo_err("psoc is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = pmo_psoc_get_ref(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("pmo cannot get the reference out of psoc");
+		goto out;
+	}
+
+	hif_ctx = pmo_core_psoc_get_hif_handle(psoc);
+	dp_soc = pmo_core_psoc_get_dp_handle(psoc);
+	txrx_pdev = pmo_core_psoc_get_txrx_handle(psoc);
+	htc_ctx = pmo_core_psoc_get_htc_handle(psoc);
+	if (!hif_ctx || !dp_soc || !txrx_pdev || !htc_ctx) {
+		pmo_err("Invalid hif: %p, dp: %p, txrx: %p, htc: %p",
+			hif_ctx, dp_soc, txrx_pdev, htc_ctx);
+		status = QDF_STATUS_E_INVAL;
+		goto dec_psoc_ref;
+	}
+
+	wow_params.interface_pause = PMO_WOW_INTERFACE_PAUSE_ENABLE;
+	wow_params.resume_trigger = PMO_WOW_RESUME_TRIGGER_GPIO;
+
+	if (hif_pre_runtime_suspend(hif_ctx))
+		goto runtime_failure;
+
+	status = cdp_runtime_suspend(dp_soc, txrx_pdev);
+	if (status != QDF_STATUS_SUCCESS)
+		goto runtime_failure;
+
+	if (htc_runtime_suspend(htc_ctx))
+		goto cdp_runtime_resume;
+
+	status = pmo_tgt_psoc_set_runtime_pm_inprogress(psoc, true);
+	if (status != QDF_STATUS_SUCCESS)
+		goto resume_htc;
+
+	status = pmo_core_psoc_configure_suspend(psoc);
+	if (status != QDF_STATUS_SUCCESS)
+		goto resume_htc;
+
+	status = pmo_core_psoc_bus_suspend_req(psoc, QDF_RUNTIME_SUSPEND,
+					       &wow_params);
+	if (status != QDF_STATUS_SUCCESS)
+		goto pmo_resume_configure;
+
+	if (hif_runtime_suspend(hif_ctx))
+		goto pmo_bus_resume;
+
+	if (pld_cb && pld_cb())
+		goto resume_hif;
+
+	hif_process_runtime_suspend_success(hif_ctx);
+
+	goto dec_psoc_ref;
+
+resume_hif:
+	QDF_BUG(!hif_runtime_resume(hif_ctx));
+
+pmo_bus_resume:
+	QDF_BUG(QDF_STATUS_SUCCESS ==
+		pmo_core_psoc_bus_resume_req(psoc, QDF_RUNTIME_SUSPEND));
+
+pmo_resume_configure:
+	QDF_BUG(QDF_STATUS_SUCCESS ==
+		pmo_core_psoc_configure_resume(psoc));
+
+resume_htc:
+	QDF_BUG(QDF_STATUS_SUCCESS ==
+		pmo_tgt_psoc_set_runtime_pm_inprogress(psoc, false));
+
+	QDF_BUG(!htc_runtime_resume(htc_ctx));
+
+cdp_runtime_resume:
+	QDF_BUG(QDF_STATUS_SUCCESS ==
+		cdp_runtime_resume(dp_soc, txrx_pdev));
+
+runtime_failure:
+	hif_process_runtime_suspend_failure(hif_ctx);
+
+dec_psoc_ref:
+	pmo_psoc_put_ref(psoc);
+
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc,
+					    pmo_pld_auto_resume_cb pld_cb)
+{
+	void *hif_ctx;
+	void *dp_soc;
+	void *txrx_pdev;
+	void *htc_ctx;
+	QDF_STATUS status;
+
+	PMO_ENTER();
+
+	if (!psoc) {
+		pmo_err("psoc is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = pmo_psoc_get_ref(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("pmo cannot get the reference out of psoc");
+		goto out;
+	}
+
+	hif_ctx = pmo_core_psoc_get_hif_handle(psoc);
+	dp_soc = pmo_core_psoc_get_dp_handle(psoc);
+	txrx_pdev = pmo_core_psoc_get_txrx_handle(psoc);
+	htc_ctx = pmo_core_psoc_get_htc_handle(psoc);
+	if (!hif_ctx || !dp_soc || !txrx_pdev || !htc_ctx) {
+		pmo_err("Invalid hif: %p, dp: %p, txrx: %p, htc: %p",
+			hif_ctx, dp_soc, txrx_pdev, htc_ctx);
+		status = QDF_STATUS_E_INVAL;
+		goto dec_psoc_ref;
+	}
+
+	hif_pre_runtime_resume(hif_ctx);
+
+	if (pld_cb)
+		QDF_BUG(!pld_cb());
+
+	QDF_BUG(!hif_runtime_resume(hif_ctx));
+
+	status = pmo_core_psoc_bus_resume_req(psoc, QDF_RUNTIME_SUSPEND);
+	QDF_BUG(status == QDF_STATUS_SUCCESS);
+
+	status = pmo_core_psoc_configure_resume(psoc);
+	QDF_BUG(status == QDF_STATUS_SUCCESS);
+
+	status = pmo_tgt_psoc_set_runtime_pm_inprogress(psoc, false);
+	QDF_BUG(status == QDF_STATUS_SUCCESS);
+
+	QDF_BUG(!htc_runtime_resume(htc_ctx));
+
+	status = cdp_runtime_resume(dp_soc, txrx_pdev);
+	QDF_BUG(status == QDF_STATUS_SUCCESS);
+
+	hif_process_runtime_resume_success(hif_ctx);
+
+dec_psoc_ref:
+	pmo_psoc_put_ref(psoc);
+
+out:
+	PMO_EXIT();
+
+	return status;
+}
+#endif
+
+/**
+ * pmo_core_psoc_send_host_wakeup_ind_to_fw() - send wakeup ind to fw
+ * @psoc: objmgr psoc handle
+ * @psoc_ctx: pmo psoc private context
+ *
+ * Sends host wakeup indication to FW. On receiving this indication,
+ * FW will come out of WOW.
+ *
+ * Return: QDF status
+ */
+static
+QDF_STATUS pmo_core_psoc_send_host_wakeup_ind_to_fw(
+			struct wlan_objmgr_psoc *psoc,
+			struct pmo_psoc_priv_obj *psoc_ctx)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	PMO_ENTER();
+	qdf_event_reset(&psoc_ctx->wow.target_resume);
+
+	status = pmo_tgt_psoc_send_host_wakeup_ind(psoc);
+	if (status) {
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+	pmo_debug("Host wakeup indication sent to fw");
+
+	status = qdf_wait_single_event(&psoc_ctx->wow.target_resume,
+					PMO_RESUME_TIMEOUT);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("Timeout waiting for resume event from FW");
+		pmo_err("Pending commands %d credits %d",
+			pmo_tgt_psoc_get_pending_cmnds(psoc),
+			pmo_tgt_psoc_get_host_credits(psoc));
+		QDF_BUG(0);
+	} else {
+		pmo_debug("Host wakeup received");
+	}
+
+	if (status == QDF_STATUS_SUCCESS)
+		pmo_tgt_update_target_suspend_flag(psoc, false);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+/**
+ * pmo_core_psoc_disable_wow_in_fw() -  Disable wow in bus resume context.
+ * @psoc: objmgr psoc handle
+ * @psoc_ctx: pmo psoc private context
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static
+QDF_STATUS pmo_core_psoc_disable_wow_in_fw(struct wlan_objmgr_psoc *psoc,
+			struct pmo_psoc_priv_obj *psoc_ctx)
+{
+	QDF_STATUS ret;
+
+	PMO_ENTER();
+	ret = pmo_core_psoc_send_host_wakeup_ind_to_fw(psoc, psoc_ctx);
+	if (ret != QDF_STATUS_SUCCESS)
+		goto out;
+
+	pmo_core_update_wow_enable(psoc_ctx, false);
+	pmo_core_update_wow_enable_cmd_sent(psoc_ctx, false);
+
+	/* To allow the tx pause/unpause events */
+	pmo_core_update_wow_bus_suspend(psoc, psoc_ctx, false);
+	/* Unpause the vdev as we are resuming */
+	pmo_unpause_all_vdev(psoc, psoc_ctx);
+out:
+	PMO_EXIT();
+
+	return ret;
+}
+
+/**
+ * pmo_core_psoc_resume_target() - resume target
+ * @psoc: objmgr psoc handle
+ * @psoc_ctx: pmo psoc private context
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static
+QDF_STATUS pmo_core_psoc_resume_target(struct wlan_objmgr_psoc *psoc,
+		struct pmo_psoc_priv_obj *psoc_ctx)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	PMO_ENTER();
+	qdf_event_reset(&psoc_ctx->wow.target_resume);
+
+	status = pmo_tgt_psoc_send_target_resume_req(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	status = qdf_wait_single_event(&psoc_ctx->wow.target_resume,
+			PMO_RESUME_TIMEOUT);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_fatal("Timeout waiting for resume event from FW");
+		pmo_fatal("Pending commands %d credits %d",
+			pmo_tgt_psoc_get_pending_cmnds(psoc),
+			pmo_tgt_psoc_get_host_credits(psoc));
+		QDF_BUG(0);
+	} else {
+		pmo_debug("Host wakeup received");
+	}
+
+	if (status == QDF_STATUS_SUCCESS)
+		pmo_tgt_update_target_suspend_flag(psoc, false);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_psoc_bus_resume_req(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	bool wow_mode;
+	QDF_STATUS status;
+
+	PMO_ENTER();
+	if (!psoc) {
+		pmo_err("psoc is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_psoc_get_ref(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("pmo cannot get the reference out of psoc");
+		goto out;
+	}
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	wow_mode = pmo_core_is_wow_enabled(psoc_ctx);
+	pmo_info("wow mode %d", wow_mode);
+
+	pmo_core_update_wow_initial_wake_up(psoc_ctx, false);
+
+	if (wow_mode)
+		status = pmo_core_psoc_disable_wow_in_fw(psoc, psoc_ctx);
+	else
+		status = pmo_core_psoc_resume_target(psoc, psoc_ctx);
+
+	pmo_psoc_put_ref(psoc);
+
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+void pmo_core_psoc_target_suspend_acknowledge(void *context, bool wow_nack)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)context;
+	QDF_STATUS status;
+
+	PMO_ENTER();
+	if (!psoc) {
+		pmo_err("psoc is null");
+		goto out;
+	}
+
+	status = pmo_psoc_get_ref(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("Failed to get psoc reference");
+		goto out;
+	}
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	pmo_core_set_wow_nack(psoc_ctx, wow_nack);
+	qdf_event_set(&psoc_ctx->wow.target_suspend);
+	if (wow_nack && !pmo_tgt_psoc_get_runtime_pm_in_progress(psoc)) {
+		qdf_wake_lock_timeout_acquire(&psoc_ctx->wow.wow_wake_lock,
+						PMO_WAKE_LOCK_TIMEOUT);
+	}
+
+	pmo_psoc_put_ref(psoc);
+out:
+	PMO_EXIT();
+}
+
+void pmo_core_psoc_wakeup_host_event_received(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	PMO_ENTER();
+	if (!psoc) {
+		pmo_err("psoc is null");
+		goto out;
+	}
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	qdf_event_set(&psoc_ctx->wow.target_resume);
+out:
+	PMO_EXIT();
+}
+
+int pmo_core_psoc_is_target_wake_up_received(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	int ret = 0;
+	QDF_STATUS status;
+
+	if (!psoc) {
+		pmo_err("psoc is NULL");
+		ret = -EAGAIN;
+		goto out;
+	}
+
+	status = pmo_psoc_get_ref(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("Failed to get psoc reference");
+		ret = -EAGAIN;
+		goto out;
+	}
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	if (pmo_core_get_wow_initial_wake_up(psoc_ctx)) {
+		pmo_err("Target initial wake up received try again");
+		ret = -EAGAIN;
+	}
+
+	pmo_psoc_put_ref(psoc);
+out:
+	PMO_EXIT();
+
+	return ret;
+}
+
+
+int pmo_core_psoc_clear_target_wake_up(struct wlan_objmgr_psoc *psoc)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	int ret = 0;
+	QDF_STATUS status;
+
+	if (!psoc) {
+		pmo_err("psoc is NULL");
+		ret = -EAGAIN;
+		goto out;
+	}
+
+	status = pmo_psoc_get_ref(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("Failed to get psoc reference");
+		ret = -EAGAIN;
+		goto out;
+	}
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	pmo_core_update_wow_initial_wake_up(psoc_ctx, false);
+
+	pmo_psoc_put_ref(psoc);
+out:
+	PMO_EXIT();
+
+	return ret;
+}
+
+void pmo_core_psoc_handle_initial_wake_up(void *cb_ctx)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)cb_ctx;
+	QDF_STATUS status;
+
+	PMO_ENTER();
+	if (!psoc) {
+		pmo_err("cb ctx/psoc is null");
+		goto out;
+	}
+
+	status = pmo_psoc_get_ref(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("Failed to get psoc reference");
+		goto out;
+	}
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	pmo_core_update_wow_initial_wake_up(psoc_ctx, true);
+
+	pmo_psoc_put_ref(psoc);
+
+out:
+	PMO_EXIT();
+}
+
diff --git a/components/pmo/core/src/wlan_pmo_wow.c b/components/pmo/core/src/wlan_pmo_wow.c
new file mode 100644
index 0000000..e32e32f
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_wow.c
@@ -0,0 +1,350 @@
+/*
+* Copyright (c) 2017 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: Define API's for wow pattern addition and deletion in fwr
+ */
+
+#include "wlan_pmo_wow.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include <wlan_scan_ucfg_api.h>
+#include "wlan_pmo_static_config.h"
+#include "wlan_reg_services_api.h"
+
+static inline int pmo_find_wow_ptrn_len(const char *ptrn)
+{
+	int len = 0;
+
+	while (*ptrn != '\0' && *ptrn != PMO_WOW_INTER_PTRN_TOKENIZER) {
+		len++;
+		ptrn++;
+	}
+
+	return len;
+}
+
+QDF_STATUS pmo_core_add_wow_pattern(struct wlan_objmgr_vdev *vdev,
+		const char *ptrn)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_core_del_wow_pattern(struct wlan_objmgr_vdev *vdev,
+		const char *ptrn)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_core_wow_enter(struct wlan_objmgr_vdev *vdev,
+		struct pmo_wow_enter_params *wow_enter_param)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_core_wow_exit(struct wlan_objmgr_vdev *vdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+void pmo_core_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+	uint32_t vdev_id, uint32_t *bitmap)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
+
+	PMO_ENTER();
+	if (!psoc) {
+		pmo_err("psoc is null");
+		goto out;
+	}
+
+	vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto out;
+
+	pmo_info("enable wakeup event vdev_id %d wake up event 0x%x%x%x%x",
+		vdev_id, bitmap[0], bitmap[1], bitmap[2], bitmap[3]);
+	pmo_tgt_enable_wow_wakeup_event(vdev, bitmap);
+
+	pmo_vdev_put_ref(vdev);
+
+out:
+	PMO_EXIT();
+}
+
+void pmo_core_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+	uint32_t vdev_id, uint32_t *bitmap)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
+
+	PMO_ENTER();
+	if (!psoc) {
+		pmo_err("psoc is null");
+		goto out;
+	}
+
+	vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+	if (!vdev) {
+		pmo_err("vdev is NULL");
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto out;
+
+	pmo_info("Disable wakeup event vdev_id %d wake up event 0x%x%x%x%x",
+		vdev_id, bitmap[0], bitmap[1], bitmap[2], bitmap[3]);
+	pmo_tgt_disable_wow_wakeup_event(vdev, bitmap);
+
+	pmo_vdev_put_ref(vdev);
+
+out:
+	PMO_EXIT();
+}
+
+/**
+ * pmo_is_beaconing_vdev_up(): check if a beaconning vdev is up
+ * @psoc: objmgr psoc handle
+ *
+ * Return TRUE if beaconning vdev is up
+ */
+static
+bool pmo_is_beaconing_vdev_up(struct wlan_objmgr_psoc *psoc)
+{
+	int vdev_id;
+	struct wlan_objmgr_vdev *vdev;
+	enum tQDF_ADAPTER_MODE vdev_opmode;
+	bool is_beaconing;
+	QDF_STATUS status;
+
+	/* Iterate through VDEV list */
+	for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) {
+		vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+		if (!vdev)
+			continue;
+
+		status = pmo_vdev_get_ref(vdev);
+		if (QDF_IS_STATUS_ERROR(status))
+			continue;
+
+		vdev_opmode = pmo_get_vdev_opmode(vdev);
+		is_beaconing = pmo_is_vdev_in_beaconning_mode(vdev_opmode) &&
+			pmo_is_vdev_up(vdev);
+
+		pmo_vdev_put_ref(vdev);
+
+		if (is_beaconing)
+			return true;
+	}
+
+	return false;
+}
+
+/**
+ * pmo_support_wow_for_beaconing: wow query for beaconning
+ * @psoc: objmgr psoc handle
+ *
+ * Need to configure wow to enable beaconning offload when
+ * a beaconing vdev is up and beaonning offload is configured.
+ *
+ * Return: true if we need to enable wow for beaconning offload
+ */
+static
+bool pmo_support_wow_for_beaconing(struct wlan_objmgr_psoc *psoc)
+{
+	/*
+	 * if (WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
+	 *			WMI_SERVICE_BEACON_OFFLOAD))
+	 */
+	return pmo_is_beaconing_vdev_up(psoc);
+}
+
+bool pmo_core_is_wow_applicable(struct wlan_objmgr_psoc *psoc)
+{
+	int vdev_id;
+	struct wlan_objmgr_vdev *vdev;
+	bool is_wow_applicable;
+	QDF_STATUS status;
+
+	if (!psoc) {
+		pmo_err("psoc is null");
+		return false;
+	}
+
+	if (pmo_support_wow_for_beaconing(psoc)) {
+		pmo_debug("one of vdev is in beaconning mode, enabling wow");
+		return true;
+	}
+
+	if (wlan_reg_is_11d_scan_inprogress(psoc)) {
+		pmo_debug("11d scan is in progress, enabling wow");
+		return true;
+	}
+
+	/* Iterate through VDEV list */
+	for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) {
+		vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+		if (!vdev)
+			continue;
+
+		status = pmo_vdev_get_ref(vdev);
+		if (QDF_IS_STATUS_ERROR(status))
+			continue;
+
+		if (pmo_core_is_vdev_connected(vdev)) {
+			pmo_debug("STA is connected, enabling wow");
+			is_wow_applicable = true;
+		} else if (ucfg_scan_get_pno_in_progress(vdev)) {
+			pmo_debug("NLO is in progress, enabling wow");
+			is_wow_applicable = true;
+		} else if (pmo_core_is_extscan_in_progress(vdev)) {
+			pmo_debug("EXT is in progress, enabling wow");
+			is_wow_applicable = true;
+		} else if (pmo_core_is_p2plo_in_progress(vdev)) {
+			pmo_debug("P2P LO is in progress, enabling wow");
+			is_wow_applicable = true;
+		} else if (pmo_core_is_lpass_enabled(vdev)) {
+			pmo_debug("LPASS is enabled, enabling WoW");
+			is_wow_applicable = true;
+		} else if (pmo_core_is_nan_enabled(vdev)) {
+			pmo_debug("NAN is enabled, enabling WoW");
+			is_wow_applicable = true;
+		} else if (pmo_core_get_vdev_op_mode(vdev) == QDF_NDI_MODE) {
+			pmo_debug("vdev %d is in NAN data mode, enabling wow",
+				vdev_id);
+			is_wow_applicable = true;
+		}
+
+		pmo_vdev_put_ref(vdev);
+
+		if (is_wow_applicable)
+			return true;
+	}
+
+	pmo_debug("All vdev are in disconnected state\n"
+		"and pno/extscan is not in progress, skipping wow");
+
+	return false;
+}
+
+void pmo_set_wow_event_bitmap(WOW_WAKE_EVENT_TYPE event,
+			      uint32_t wow_bitmap_size,
+			      uint32_t *bitmask)
+{
+	uint32_t bit_idx = 0, idx = 0;
+
+	if (!bitmask || wow_bitmap_size < PMO_WOW_MAX_EVENT_BM_LEN) {
+		pmo_err("wow bitmask length shorter than %d",
+			 PMO_WOW_MAX_EVENT_BM_LEN);
+		return;
+	}
+	pmo_get_event_bitmap_idx(event, wow_bitmap_size, &bit_idx, &idx);
+	bitmask[idx] |= 1 << bit_idx;
+
+	pmo_debug("%s: bitmask updated %x%x%x%x",
+		 __func__, bitmask[0], bitmask[1], bitmask[2], bitmask[3]);
+}
+
+void pmo_set_sta_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmap_size)
+{
+
+	pmo_set_wow_event_bitmap(WOW_CSA_IE_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_CLIENT_KICKOUT_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_PATTERN_MATCH_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_MAGIC_PKT_RECVD_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_DEAUTH_RECVD_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_DISASSOC_RECVD_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_BMISS_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_GTK_ERR_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_BETTER_AP_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_HTT_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_RA_MATCH_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_NLO_DETECTED_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_EXTSCAN_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_OEM_RESPONSE_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_TDLS_CONN_TRACKER_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_11D_SCAN_EVENT,
+				 wow_bitmap_size,
+				 bitmask);
+
+}
+
+void pmo_set_sap_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmap_size)
+{
+
+	pmo_set_wow_event_bitmap(WOW_PROBE_REQ_WPS_IE_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_PATTERN_MATCH_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_AUTH_REQ_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_ASSOC_REQ_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_DEAUTH_RECVD_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_DISASSOC_RECVD_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+	pmo_set_wow_event_bitmap(WOW_HTT_EVENT,
+			     wow_bitmap_size,
+			     bitmask);
+}
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_arp_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_arp_public_struct.h
new file mode 100644
index 0000000..533b809
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_arp_public_struct.h
@@ -0,0 +1,58 @@
+/*
+* Copyright (c) 2017 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: Declare various struct, macros which shall be used in
+  * pmo arp offload feature.
+  *
+  * Note: This file shall not contain public API's prototype/declarations.
+  *
+  */
+
+#ifndef _WLAN_PMO_ARP_PUBLIC_STRUCT_H_
+#define _WLAN_PMO_ARP_PUBLIC_STRUCT_H_
+
+#include "wlan_pmo_common_public_struct.h"
+
+/**
+ * struct pmo_arp_req - pmo arp request
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id on which arp offload needed
+ * @ipv4_addr: ipv4 address for the interface
+ * @trigger: context from where arp offload triggered
+ */
+struct pmo_arp_req {
+	struct wlan_objmgr_psoc *psoc;
+	uint8_t vdev_id;
+	uint32_t ipv4_addr;
+	enum pmo_offload_trigger trigger;
+};
+
+/**
+ * struct pmo_arp_req - pmo arp offload param for target interface
+ * @enable: true when arp offload is enabled else false
+ * @host_ipv4_addr: host interface ipv4 address
+ * @bssid: peer ap address
+ */
+struct pmo_arp_offload_params {
+	uint8_t enable;
+	uint8_t host_ipv4_addr[PMO_IPV4_ADDR_LEN];
+	struct qdf_mac_addr bssid;
+};
+
+#endif /* end  of _WLAN_PMO_ARP_PUBLIC_STRUCT_H_ */
+
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h
new file mode 100644
index 0000000..31b9edb
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h
@@ -0,0 +1,298 @@
+/*
+* Copyright (c) 2017 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: Declare various struct, macros which are common for
+ * various pmo related features.
+  *
+  * Note: This file shall not contain public API's prototype/declartions.
+  *
+  */
+
+#ifndef _WLAN_PMO_COMMONP_PUBLIC_STRUCT_H_
+#define _WLAN_PMO_COMMONP_PUBLIC_STRUCT_H_
+
+#include "wlan_cmn.h"
+#include "wlan_objmgr_cmn.h"
+#include "wlan_objmgr_global_obj.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "wlan_objmgr_vdev_obj.h"
+#include "wlan_objmgr_peer_obj.h"
+#include "wmi_unified.h"
+#include "qdf_status.h"
+#include "qdf_lock.h"
+#include "qdf_event.h"
+#include "wlan_pmo_hw_filter_public_struct.h"
+
+#define PMO_IPV4_ADDR_LEN         4
+
+#define PMO_IPV4_ARP_REPLY_OFFLOAD                  0
+#define PMO_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD         1
+#define PMO_IPV6_NS_OFFLOAD                         2
+#define PMO_OFFLOAD_DISABLE                         0
+#define PMO_OFFLOAD_ENABLE                          1
+
+#define PMO_MAC_NS_OFFLOAD_SIZE               1
+#define PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA 16
+#define PMO_MAC_IPV6_ADDR_LEN                 16
+#define PMO_IPV6_ADDR_VALID                   1
+#define PMO_IPV6_ADDR_UC_TYPE                 0
+#define PMO_IPV6_ADDR_AC_TYPE                 1
+
+#define PMO_80211_ADDR_LEN  6  /* size of 802.11 address */
+
+#define PMO_WOW_REQUIRED_CREDITS 1
+
+/**
+ * enum pmo_offload_type: tell offload type
+ * @pmo_arp_offload: arp offload
+ * @pmo_ns_offload: ns offload
+ * @pmo_gtk_offload: gtk offload
+ */
+enum pmo_offload_type {
+	pmo_arp_offload = 0,
+	pmo_ns_offload,
+	pmo_gtk_offload,
+};
+
+/**
+ * enum pmo_vdev_param_id: tell vdev param id
+ * @pmo_vdev_param_listen_interval: vdev listen interval param id
+ * @pmo_vdev_param_dtim_policy: vdev param dtim policy
+ * @pmo_vdev_max_param: Max vdev param id
+ */
+enum pmo_vdev_param_id {
+	pmo_vdev_param_listen_interval = 0,
+	pmo_vdev_param_dtim_policy,
+	pmo_vdev_max_param
+};
+
+/**
+ * enum pmo_beacon_dtim_policy: tell vdev beacon policy
+ * @pmo_ignore_dtim: fwr need to igonre dtime policy
+ * @pmo_normal_dtim: fwr need to use normal dtime policy
+ * @pmo_stick_dtim: fwr need to use stick dtime policy
+ * @auto_dtim: fwr need to auto dtime policy
+ */
+enum pmo_beacon_dtim_policy {
+	pmo_ignore_dtim = 0x01,
+	pmo_normal_dtim = 0x02,
+	pmo_stick_dtim = 0x03,
+	pmo_auto_dtim = 0x04,
+};
+
+/**
+ * @pmo_sta_ps_param_rx_wake_policy: Controls how frames are retrievd from AP
+ *  while STA is sleeping.
+ * @pmo_sta_ps_param_tx_wake_threshold: STA will go active after this many TX
+ * @pmo_sta_ps_param_pspoll_count:No of PS-Poll to send before STA wakes up
+ * @pmo_sta_ps_param_inactivity_time: TX/RX inactivity time in msec before
+    going to sleep.
+ * @pmo_sta_ps_param_uapsd: Set uapsd configuration.
+ * @pmo_sta_ps_param_qpower_pspoll_count: No of PS-Poll to send before
+    STA wakes up in QPower Mode.
+ * @pmo_sta_ps_enable_qpower:  Enable QPower
+ * @pmo_sta_ps_param_qpower_max_tx_before_wake: Number of TX frames before the
+    entering the Active state
+ */
+enum pmo_sta_powersave_param {
+	pmo_sta_ps_param_rx_wake_policy = 0,
+	pmo_sta_ps_param_tx_wake_threshold = 1,
+	pmo_sta_ps_param_pspoll_count = 2,
+	pmo_sta_ps_param_inactivity_time = 3,
+	pmo_sta_ps_param_uapsd = 4,
+	pmo_sta_ps_param_qpower_pspoll_count = 5,
+	pmo_sta_ps_enable_qpower = 6,
+	pmo_sta_ps_param_qpower_max_tx_before_wake = 7,
+};
+
+/**
+ * enum powersave_qpower_mode: QPOWER modes
+ * @pmo_qpower_disabled: Qpower is disabled
+ * @pmo_qpower_enabled: Qpower is enabled
+ * @pmo_qpower_duty_cycling: Qpower is enabled with duty cycling
+ */
+enum pmo_power_save_qpower_mode {
+	pmo_qpower_disabled = 0,
+	pmo_qpower_enabled = 1,
+	pmo_qpower_duty_cycling = 2
+};
+
+/**
+ * enum powersave_qpower_mode: powersave_mode
+ * @pmo_ps_not_supported: Power save is not supported
+ * @pmo_ps_legacy_no_deep_sleep: Legacy pwr save enabled and deep sleep disabled
+ * @pmo_ps_qpower_no_deep_sleep: QPOWER enabled and deep sleep disabled
+ * @pmo_ps_legacy_deep_sleep: Legacy power save enabled and deep sleep enabled
+ * @pmo_ps_qpower_deep_sleep: QPOWER enabled and deep sleep enabled
+ * @pmo_ps_duty_cycling_qpower: QPOWER enabled in duty cycling mode
+ */
+enum pmo_powersave_mode {
+	pmo_ps_not_supported = 0,
+	pmo_ps_legacy_no_deep_sleep = 1,
+	pmo_ps_qpower_no_deep_sleep = 2,
+	pmo_ps_legacy_deep_sleep = 3,
+	pmo_ps_qpower_deep_sleep = 4,
+	pmo_ps_duty_cycling_qpower = 5
+};
+
+/**
+ * enum wow_resume_trigger - resume trigger override setting values
+ * @PMO_WOW_RESUME_TRIGGER_DEFAULT: fw to use platform default resume trigger
+ * @PMO_WOW_RESUME_TRIGGER_HTC_WAKEUP: force fw to use HTC Wakeup to resume
+ * @PMO_WOW_RESUME_TRIGGER_GPIO: force fw to use GPIO to resume
+ * @PMO_WOW_RESUME_TRIGGER_COUNT: number of resume trigger options
+ */
+enum pmo_wow_resume_trigger {
+	/* always first */
+	PMO_WOW_RESUME_TRIGGER_DEFAULT = 0,
+	PMO_WOW_RESUME_TRIGGER_HTC_WAKEUP,
+	PMO_WOW_RESUME_TRIGGER_GPIO,
+	/* always last */
+	PMO_WOW_RESUME_TRIGGER_COUNT
+};
+
+/**
+ * enum wow_interface_pause - interface pause override setting values
+ * @PMO_WOW_INTERFACE_PAUSE_DEFAULT: use platform default iface pause setting
+ * @PMO_WOW_INTERFACE_PAUSE_ENABLE: force interface pause setting to enabled
+ * @PMO_WOW_INTERFACE_PAUSE_DISABLE: force interface pause setting to disabled
+ * @PMO_WOW_INTERFACE_PAUSE_COUNT: number of interface pause options
+ */
+enum pmo_wow_interface_pause {
+	/* always first */
+	PMO_WOW_INTERFACE_PAUSE_DEFAULT = 0,
+	PMO_WOW_INTERFACE_PAUSE_ENABLE,
+	PMO_WOW_INTERFACE_PAUSE_DISABLE,
+	/* always last */
+	PMO_WOW_INTERFACE_PAUSE_COUNT
+};
+
+#define PMO_TGT_SUSPEND_COMPLETE_TIMEOUT   6000
+#define PMO_WAKE_LOCK_TIMEOUT              1000
+#define PMO_RESUME_TIMEOUT                 25000
+
+/**
+ * struct wow_enable_params - A collection of wow enable override parameters
+ * @is_unit_test: true to notify fw this is a unit-test suspend
+ * @interface_pause: used to override the interface pause indication sent to fw
+ * @resume_trigger: used to force fw to use a particular resume method
+ */
+struct pmo_wow_enable_params {
+	bool is_unit_test;
+	enum pmo_wow_interface_pause interface_pause;
+	enum pmo_wow_resume_trigger resume_trigger;
+};
+
+/**
+ * typedef for psoc suspend handler
+ */
+typedef QDF_STATUS(*pmo_psoc_suspend_handler)
+	(struct wlan_objmgr_psoc *psoc, void *arg);
+/**
+ * typedef for psoc resume handler
+ */
+typedef QDF_STATUS(*pmo_psoc_resume_handler)
+	(struct wlan_objmgr_psoc *psoc, void *arg);
+
+/**
+ * enum pmo_offload_trigger: trigger information
+ * @pmo_apps_suspend: trigger is apps suspend
+ * @pmo_apps_resume: trigger is apps resume
+ * @pmo_runtime_suspend: trigger is runtime suspend
+ * @pmo_runtime_resume: trigger is runtime resume
+ * @pmo_ipv4_change_notify: trigger is ipv4 change handler
+ * @pmo_ipv6_change_notify: trigger is ipv6 change handler
+ * @pmo_ns_offload_dynamic_update: enable/disable ns offload on the fly
+ * @pmo_peer_disconnect: trigger is peer disconnect
+ * @pmo_mcbc_setting_dynamic_update: mcbc value update on the fly
+ *
+ * @pmo_offload_trigger_max: Max trigger value
+ */
+enum pmo_offload_trigger {
+	pmo_apps_suspend = 0,
+	pmo_apps_resume,
+	pmo_runtime_suspend,
+	pmo_runtime_resume,
+	pmo_ipv4_change_notify,
+	pmo_ipv6_change_notify,
+	pmo_mc_list_change_notify,
+	pmo_ns_offload_dynamic_update,
+	pmo_peer_disconnect,
+	pmo_mcbc_setting_dynamic_update,
+
+	pmo_offload_trigger_max,
+};
+
+/**
+ * struct pmo_psoc_cfg - user configuration required for pmo
+ * @ptrn_match_enable_all_vdev: true when pattern match is enable for all vdev
+ * @bpf_enable: true if psoc supports bpf else false
+ * @arp_offload_enable: true if arp offload is supported for psoc else false
+ * @hw_filter_mode: which mode the hardware filter should use during DTIM
+ * @ns_offload_enable_static: true if psoc supports ns offload in ini else false
+ * @ns_offload_enable_dynamic: to enable / disable the ns offload using
+ *    ioctl or vendor command.
+ * @ssdp:  true if psoc supports if ssdp configuration in wow mode
+ * @enable_mc_list: true if psoc supports mc addr list else false
+ * @active_mode_offload: true if psoc supports active mode offload else false
+ * @ap_arpns_support: true if psoc supports arp ns for ap mode
+ * @max_wow_filters: maximum number of wow filter supported
+ * @ra_ratelimit_enable: true when ra filtering ins eanbled else false
+ * @ra_ratelimit_interval: ra packets interval
+ * @magic_ptrn_enable: true when magic pattern is enabled else false
+ * @deauth_enable: true when wake up on deauth is enabled else false
+ * @disassoc_enable:  true when wake up on disassoc is enabled else false
+ * @bmiss_enable: true when wake up on bmiss is enabled else false
+ * @nan_enable:  true when nan is enabled else false
+ * @lpass_enable: true when lpass is enabled else false
+ * @sta_dynamic_dtim: station dynamic DTIM value
+ * @sta_mod_dtim: station modulated DTIM value
+ * @sta_max_li_mod_dtim: station max listen interval DTIM value
+ * @power_save_mode: power save mode for psoc
+ * @auto_power_save_fail_mode: auto detect power save failure
+ */
+struct pmo_psoc_cfg {
+	bool ptrn_match_enable_all_vdev;
+	bool bpf_enable;
+	bool arp_offload_enable;
+	enum pmo_hw_filter_mode hw_filter_mode;
+	bool ns_offload_enable_static;
+	bool ns_offload_enable_dynamic;
+	bool ssdp;
+	bool enable_mc_list;
+	bool active_mode_offload;
+	bool ap_arpns_support;
+	uint8_t max_wow_filters;
+	bool ra_ratelimit_enable;
+	uint16_t ra_ratelimit_interval;
+	bool magic_ptrn_enable;
+	bool deauth_enable;
+	bool disassoc_enable;
+	bool bmiss_enable;
+	bool nan_enable;
+	bool lpass_enable;
+	uint8_t sta_dynamic_dtim;
+	uint8_t sta_mod_dtim;
+	uint8_t sta_max_li_mod_dtim;
+	uint8_t power_save_mode;
+	bool auto_power_save_fail_mode;
+};
+
+#endif /* end  of _WLAN_PMO_COMMONP_STRUCT_H_ */
+
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_gtk_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_gtk_public_struct.h
new file mode 100644
index 0000000..8c27cc0
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_gtk_public_struct.h
@@ -0,0 +1,95 @@
+/*
+* Copyright (c) 2017 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: Declare various struct, macros which shall be used in
+  * pmo gtk related feature.
+  *
+  * Note: This file shall not contain public API's prototype/declarations.
+  *
+  */
+
+#ifndef _WLAN_PMO_GTK_PUBLIC_STRUCT_H
+#define _WLAN_PMO_GTK_PUBLIC_STRUCT_H
+
+#include "wlan_pmo_common_public_struct.h"
+
+#define PMO_GTK_OFFLOAD_ENABLE  0
+#define PMO_GTK_OFFLOAD_DISABLE 1
+#define PMO_KEK_LEN 16
+#define PMO_KCK_LEN 16
+#define PMO_REPLAY_COUNTER_LEN 8
+#define PMO_MAC_MAX_KEY_LENGTH 32
+#define PMO_IGTK_PN_SIZE 6
+
+/**
+ * struct pmo_gtk_req - pmo gtk request
+ * @flags: optional flags
+ * @kck: Key confirmation key
+ * @kek: key encryption key
+ * @replay_counter: replay_counter
+ * @bssid: bssid
+ */
+struct pmo_gtk_req {
+	uint32_t flags;
+	uint8_t kck[PMO_KCK_LEN];
+	uint8_t kek[PMO_KEK_LEN];
+	uint64_t replay_counter;
+	struct qdf_mac_addr bssid;
+};
+
+/**
+ * struct pmo_gtk_rsp_params - pmo gtk response
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id on which arp offload needed
+ * @status_flag: status flags
+ * @refresh_cnt: number of successful GTK refresh exchanges since SET operation
+ * @igtk_key_index: igtk key index
+ * @igtk_key_length: igtk key length
+ * @igtk_key_rsc: igtk key index
+ * @igtk_key: igtk key length
+ */
+struct pmo_gtk_rsp_params {
+	uint8_t  vdev_id;
+	uint32_t status_flag;
+	uint32_t refresh_cnt;
+	uint64_t replay_counter;
+	uint8_t igtk_key_index;
+	uint8_t igtk_key_length;
+	uint8_t igtk_key_rsc[PMO_IGTK_PN_SIZE];
+	uint8_t igtk_key[PMO_MAC_MAX_KEY_LENGTH];
+	struct qdf_mac_addr bssid;
+};
+
+/**
+ * typedef for gtk response callback
+ */
+typedef void (*pmo_gtk_rsp_callback)(void *callback_context,
+		struct pmo_gtk_rsp_params *gtk_rsp);
+
+/**
+ * struct pmo_gtk_rsp_req -gtk respsonse request
+ * @callback: client callback for providing gtk resposne when fwr send event
+ * @callback_context: client callback response
+ */
+struct pmo_gtk_rsp_req {
+	pmo_gtk_rsp_callback callback;
+	void *callback_context;
+};
+
+#endif /* end  of _WLAN_PMO_GTK_PUBLIC_STRUCT_H */
+
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_hw_filter_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_hw_filter_public_struct.h
new file mode 100644
index 0000000..106cef7
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_hw_filter_public_struct.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017 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 shall contain all public parameter (struct/macro/enum)
+ * definitions to support hardware filtering configuration. No APIs, or
+ * implememtations of APIs, shall be contained within.
+ */
+
+#ifndef _WLAN_PMO_HW_FILTER_PUBLIC_STRUCT_H
+#define _WLAN_PMO_HW_FILTER_PUBLIC_STRUCT_H
+
+/**
+ * pmo_hw_filter_mode - bitmap for enabled hardware filters
+ * @HW_FILTER_DISABLED: hardware filter is completely disabled
+ * @HW_FILTER_NON_ARP_BC: drop all broadcast frames, except ARP
+ * @HW_FILTER_NON_ICMPV6_MC: drop all multicast frames, except ICMPv6
+ *
+ * The hardware filter is only effective in DTIM mode. Use this configuration
+ * to blanket drop broadcast/multicast packets at the hardware level, without
+ * waking up the firmware.
+ */
+enum pmo_hw_filter_mode {
+	PMO_HW_FILTER_DISABLED = 0,
+	PMO_HW_FILTER_NON_ARP_BC = 1,
+	PMO_HW_FILTER_NON_ICMPV6_MC = 2,
+};
+
+/**
+ * struct pmo_hw_filter_params - hardware filter configuration parameters
+ * @vdev_id: Id of the virtual device to configure
+ * @mode: the hardware filter mode to configure
+ */
+struct pmo_hw_filter_params {
+	uint8_t vdev_id;
+	enum pmo_hw_filter_mode mode;
+};
+
+#endif /* _WLAN_PMO_HW_FILTER_PUBLIC_STRUCT_H */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_lphb_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_lphb_public_struct.h
new file mode 100644
index 0000000..7778f91
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_lphb_public_struct.h
@@ -0,0 +1,176 @@
+/*
+* Copyright (c) 2017 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: Declare various struct, macros which shall be used in
+  * pmo lphb offload feature.
+  *
+  * Note: This file shall not contain public API's prototype/declarations.
+  *
+  */
+
+#ifndef _WLAN_PMO_LPHB_PUBLIC_STRUCT_H_
+#define _WLAN_PMO_LPHB_PUBLIC_STRUCT_H_
+
+#include "wlan_pmo_common_public_struct.h"
+
+#ifdef FEATURE_WLAN_LPHB
+#define PMO_SIR_LPHB_FILTER_LEN   64
+
+/**
+ * enum lphb_ind_type -Low power heart beat indication type
+ * @pmo_lphb_set_en_param_indid: lphb enable indication
+ * @pmo_lphb_set_tcp_pararm_indid: lphb tcp param indication
+ * @pmo_lphb_set_tcp_pkt_filter_indid: lphb tcp packet filter indication
+ * @pmo_lphb_set_udp_pararm_indid: lphb udp param indication
+ * @pmo_lphb_set_udp_pkt_filter_indid: lphb udp packet filter indication
+ * @pmo_lphb_set_network_info_indid: lphb network information indication
+ */
+enum lphb_ind_type {
+	pmo_lphb_set_en_param_indid,
+	pmo_lphb_set_tcp_pararm_indid,
+	pmo_lphb_set_tcp_pkt_filter_indid,
+	pmo_lphb_set_udp_pararm_indid,
+	pmo_lphb_set_udp_pkt_filter_indid,
+	pmo_lphb_set_network_info_indid,
+};
+
+/**
+ * struct pmo_lphb_enable_req -Low power heart beat enable request
+ * @enable: lphb enable request
+ * @item: request item
+ * @session: lphb session
+ */
+struct pmo_lphb_enable_req {
+	uint8_t enable;
+	uint8_t item;
+	uint8_t session;
+};
+
+/**
+ * struct pmo_lphb_tcp_params - Low power heart beat tcp params
+ * @srv_ip: source ip address
+ * @dev_ip: destination ip address
+ * @src_port: source port
+ * @dst_port: destination port
+ * @timeout: tcp timeout value
+ * @session: session on which lphb needs to be configured
+ * @gateway_mac: gateway mac address
+ * @time_period_sec: time period in seconds
+ * @tcp_sn: tcp sequence number
+ */
+struct pmo_lphb_tcp_params {
+	uint32_t srv_ip;
+	uint32_t dev_ip;
+	uint16_t src_port;
+	uint16_t dst_port;
+	uint16_t timeout;
+	uint8_t session;
+	struct qdf_mac_addr gateway_mac;
+	uint16_t time_period_sec;
+	uint32_t tcp_sn;
+};
+
+/**
+ * struct pmo_lphb_tcp_filter_req - Low power heart beat tcp filter request
+ * @length: length of filter
+ * @offset: offset of filter
+ * @session: session on which lphb needs to be configured
+ * @filter: filter buffer
+ */
+struct pmo_lphb_tcp_filter_req {
+	uint16_t length;
+	uint8_t offset;
+	uint8_t session;
+	uint8_t filter[PMO_SIR_LPHB_FILTER_LEN];
+};
+
+/**
+ * struct pmo_lphb_udp_params - Low power heart beat udp params
+ * @srv_ip: source ip address
+ * @dev_ip: destination ip address
+ * @src_port: source port
+ * @dst_port: destination port
+ * @timeout: tcp timeout value
+ * @session: session on which lphb needs to be configured
+ * @gateway_mac: gateway mac address
+ * @time_period_sec: time period in seconds
+ */
+struct pmo_lphb_udp_params {
+	uint32_t srv_ip;
+	uint32_t dev_ip;
+	uint16_t src_port;
+	uint16_t dst_port;
+	uint16_t interval;
+	uint16_t timeout;
+	uint8_t session;
+	struct qdf_mac_addr gateway_mac;
+};
+
+/**
+ * struct pmo_lphb_udp_filter_req - Low power heart beat udp filter request
+ * @length: length of filter
+ * @offset: offset of filter
+ * @session: session on which lphb needs to be configured
+ * @filter: filter buffer
+ */
+struct pmo_lphb_udp_filter_req {
+	uint16_t length;
+	uint8_t offset;
+	uint8_t session;
+	uint8_t filter[PMO_SIR_LPHB_FILTER_LEN];
+};
+
+/**
+ * struct pmo_lphb_req - Low power heart beat request
+ * @cmd: lphb command type
+ * @dummy: whether dummy or not
+ * @params: based on command lphb request buffer
+ */
+struct pmo_lphb_req {
+	uint16_t cmd;
+	uint16_t dummy;
+	union {
+		struct pmo_lphb_enable_req lphb_enable_req;
+		struct pmo_lphb_tcp_params lphb_tcp_params;
+		struct pmo_lphb_tcp_filter_req lphb_tcp_filter_req;
+		struct pmo_lphb_udp_params lphb_udp_params;
+		struct pmo_lphb_udp_filter_req lphb_udp_filter_req;
+	} params;
+};
+
+/**
+ * struct pmo_lphb_rsp - Low power heart beat response
+ * @session_idx: session id
+ * @protocol_type: tell protocol type
+ * @event_reason: carry reason of lphb event
+ */
+struct pmo_lphb_rsp {
+	uint8_t session_idx;
+	uint8_t protocol_type;   /*TCP or UDP */
+	uint8_t event_reason;
+};
+#endif /* FEATURE_WLAN_LPHB */
+
+/*
+ * Define typedef for lphb callback when fwr send response
+ */
+typedef
+void (*pmo_lphb_callback)(void *cb_ctx, struct pmo_lphb_rsp *ind_param);
+
+#endif /* end  of _WLAN_PMO_LPHB_PUBLIC_STRUCT_H_ */
+
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_mc_addr_filtering_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_mc_addr_filtering_public_struct.h
new file mode 100644
index 0000000..8607c17
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_mc_addr_filtering_public_struct.h
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2017 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: Declare various struct, macros which shall be used in
+  * pmo mc address filterign related features.
+  *
+  * Note: This file shall not contain public API's prototype/declarations.
+  *
+  */
+
+
+#ifndef _WLAN_PMO_MC_ADDR_FILTERING_STRUCT_H_
+#define _WLAN_PMO_MC_ADDR_FILTERING_STRUCT_H_
+
+#include "wlan_pmo_common_public_struct.h"
+
+#define PMO_MAX_MC_ADDR_LIST 32
+
+/**
+ * struct pmo_mc_addr_list_params -pmo mc address list request params
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id on which arp offload needed
+ * @count: multicast address count
+ * @mc_addr: multicast address array
+ */
+struct pmo_mc_addr_list_params {
+	struct wlan_objmgr_psoc *psoc;
+	uint8_t vdev_id;
+	uint8_t count;
+	struct qdf_mac_addr mc_addr[PMO_MAX_MC_ADDR_LIST];
+};
+
+/**
+ * struct pmo_mc_addr_list -pmo mc address list params for vdev
+ * @is_filter_applied: is mc list filter applied on vdev
+ * @mc_cnt: mc address count
+ * @mc_addr:mc address list
+ */
+struct pmo_mc_addr_list {
+	uint8_t is_filter_applied;
+	uint8_t mc_cnt;
+	struct qdf_mac_addr mc_addr[PMO_MAX_MC_ADDR_LIST];
+};
+
+#endif /* end  of _WLAN_PMO_MC_ADDR_FILTERING_STRUCT_H_ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_ns_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_ns_public_struct.h
new file mode 100644
index 0000000..27a0c04
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_ns_public_struct.h
@@ -0,0 +1,79 @@
+/*
+* Copyright (c) 2017 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: Declare various struct, macros which shall be used in
+  * pmo ns offload feature.
+  *
+  * Note: This file shall not contain public API's prototype/declarations.
+  *
+  */
+
+
+#ifndef _WLAN_PMO_NS_PUBLIC_STRUCT_H_
+#define _WLAN_PMO_NS_PUBLIC_STRUCT_H_
+
+#include "wlan_pmo_common_public_struct.h"
+
+/**
+ * struct pmo_ns_offload_params - pmo ns offload parameters
+ * @enable: true when ns offload enable
+ * @num_ns_offload_count: total ns entries
+ * @src_ipv6_addr: in request source ipv 6 address
+ * @self_ipv6_addr: self ipv6 address
+ * @target_ipv6_addr: target ipv6 address
+ * @self_macaddr: self mac address
+ * @src_ipv6_addr_valid: true if source ipv6 address is valid else false
+ * @target_ipv6_addr_valid: target ipv6 address are valid or not
+ * @target_ipv6_addr_ac_type: target ipv6 address type (unicast or anycast)
+ * @slot_idx: slot index
+ */
+struct pmo_ns_offload_params {
+	uint8_t enable;
+	uint32_t num_ns_offload_count;
+	uint8_t src_ipv6_addr[PMO_MAC_IPV6_ADDR_LEN];
+	uint8_t self_ipv6_addr[PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA]
+		[PMO_MAC_IPV6_ADDR_LEN];
+	uint8_t target_ipv6_addr[PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA]
+		[PMO_MAC_IPV6_ADDR_LEN];
+	struct qdf_mac_addr self_macaddr;
+	uint8_t src_ipv6_addr_valid;
+	uint8_t target_ipv6_addr_valid[PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA];
+	uint8_t target_ipv6_addr_ac_type[PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA];
+	uint8_t slot_idx;
+	struct qdf_mac_addr bssid;
+};
+
+/**
+ * struct pmo_ns_req - pmo ns request
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id on which arp offload needed
+ * @trigger: context from where arp offload triggered
+ * @count: ns entries count
+ * @ipv6_addr: ipv6 address array
+ * @ipv6_addr_type: ipv6 address type (unicast/anycast) array
+ */
+struct pmo_ns_req {
+	struct wlan_objmgr_psoc *psoc;
+	uint8_t vdev_id;
+	enum pmo_offload_trigger trigger;
+	uint32_t count;
+	uint8_t ipv6_addr[PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA]
+				[PMO_MAC_IPV6_ADDR_LEN];
+	uint8_t ipv6_addr_type[PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA];
+};
+#endif /* end  of _WLAN_PMO_NS_PUBLIC_STRUCT_H_ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h b/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h
new file mode 100644
index 0000000..42ee0b9
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h
@@ -0,0 +1,241 @@
+/*
+* Copyright (c) 2017 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: declare utility API related to the pmo component
+ * called by other components
+ */
+
+#ifndef _WLAN_PMO_OBJ_MGMT_API_H_
+#define _WLAN_PMO_OBJ_MGMT_API_H_
+
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+/**
+ * pmo_init() - initialize pmo_ctx context.
+ *
+ * This function initializes the power manager offloads (a.k.a pmo) context.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+QDF_STATUS pmo_init(void);
+
+/**
+ * pmo_deinit() - De initialize pmo_ctx context.
+ *
+ * This function De initializes power manager offloads (a.k.a pmo) contex.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+QDF_STATUS pmo_deinit(void);
+
+/**
+ * pmo_psoc_object_created_notification(): pmo psoc create handler
+ * @psoc: psoc which is going to created by objmgr
+ * @arg: argument for vdev create handler
+ *
+ * PMO, register this api with objmgr to detect psoc is created in fwr
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS pmo_psoc_object_created_notification(
+		struct wlan_objmgr_psoc *psoc, void *arg);
+
+/**
+ *  pmo_psoc_object_destroyed_notification(): pmo psoc delete handler
+ * @psco: psoc which is going to delete by objmgr
+ * @arg: argument for vdev delete handler
+ *
+ * PMO, register this api with objmgr to detect psoc is deleted in fwr
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS pmo_psoc_object_destroyed_notification(
+		struct wlan_objmgr_psoc *psoc, void *arg);
+
+/**
+ * pmo_vdev_object_created_notification(): pmo vdev create handler
+ * @vdev: vdev which is going to created by objmgr
+ * @arg: argument for vdev create handler
+ *
+ * PMO, register this api with objmgr to detect vdev is created in fwr
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS pmo_vdev_object_created_notification(
+		struct wlan_objmgr_vdev *vdev, void *arg);
+
+/**
+ * pmo_vdev_ready() - handles vdev ready in firmware event
+ * @vdev: vdev which is ready in firmware
+ *
+ * Objmgr vdev_create event does not guarantee vdev creation in firmware.
+ * Any logic that would normally go in the vdev_create event, but needs to
+ * communicate with firmware, needs to go here instead.
+ *
+ * Return QDF_STATUS
+ */
+QDF_STATUS pmo_vdev_ready(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_vdev_object_destroyed_notification(): pmo vdev delete handler
+ * @vdev: vdev which is going to delete by objmgr
+ * @arg: argument for vdev delete handler
+ *
+ * PMO, register this api with objmgr to detect vdev is deleted in fwr
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS pmo_vdev_object_destroyed_notification(
+		struct wlan_objmgr_vdev *vdev, void *arg);
+
+/**
+ * pmo_register_suspend_handler(): register suspend handler for components
+ * @id: component id
+ * @handler: resume handler for the mention component
+ * @arg: argument to pass while calling resume handler
+ *
+ * Return QDF_STATUS status -in case of success else return error
+ */
+QDF_STATUS pmo_register_suspend_handler(
+		enum wlan_umac_comp_id id,
+		pmo_psoc_suspend_handler handler,
+		void *arg);
+
+/**
+ * pmo_unregister_suspend_handler():unregister suspend handler for components
+ * @id: component id
+ * @handler: resume handler for the mention component
+ *
+ * Return QDF_STATUS status -in case of success else return error
+ */
+QDF_STATUS pmo_unregister_suspend_handler(
+		enum wlan_umac_comp_id id,
+		pmo_psoc_suspend_handler handler);
+
+/**
+ * pmo_register_resume_handler(): API to register resume handler for components
+ * @id: component id
+ * @handler: resume handler for the mention component
+ * @arg: argument to pass while calling resume handler
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_register_resume_handler(
+		enum wlan_umac_comp_id id,
+		pmo_psoc_resume_handler handler,
+		void *arg);
+
+/**
+ * pmo_unregister_resume_handler(): unregister resume handler for components
+ * @id: component id
+ * @handler: resume handler for the mention component
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_unregister_resume_handler(
+		enum wlan_umac_comp_id id,
+		pmo_psoc_resume_handler handler);
+
+/**
+ * pmo_suspend_all_components(): API to suspend all component
+ * @psoc:objmgr psoc
+ * @suspend_type: Tell suspend type (apps suspend / runtime suspend)
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_suspend_all_components(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type suspend_type);
+
+/**
+ * pmo_resume_all_components(): API to resume all component
+ * @psoc:objmgr psoc
+ * @suspend_type: Tell suspend type from which resume is required
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_resume_all_components(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type suspend_type);
+
+/**
+ * pmo_register_pause_bitmap_notifier(): API to register pause bitmap notifier
+ * @psoc: objmgr psoc handle
+ * @handler: pause bitmap updated notifier
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_register_pause_bitmap_notifier(
+		struct wlan_objmgr_psoc *psoc,
+		pmo_notify_pause_bitmap handler);
+
+/**
+ * pmo_unregister_pause_bitmap_notifier(): API to unregister pause bitmap notifier
+ * @psoc: objmgr psoc handle
+ * @handler: pause bitmap updated notifier
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_unregister_pause_bitmap_notifier(
+		struct wlan_objmgr_psoc *psoc,
+		pmo_notify_pause_bitmap handler);
+
+/**
+ * pmo_register_get_pause_bitmap(): API to get register pause bitmap notifier
+ * @psoc: objmgr psoc handle
+ * @handler: pause bitmap updated notifier
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_register_get_pause_bitmap(struct wlan_objmgr_psoc *psoc,
+		pmo_get_pause_bitmap handler);
+
+/**
+ * pmo_unregister_get_pause_bitmap(): API to unregister get pause bitmap callback
+ * @psoc: objmgr psoc handle
+ * @handler: pause bitmap updated notifier
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_unregister_get_pause_bitmap(struct wlan_objmgr_psoc *psoc,
+		pmo_get_pause_bitmap handler);
+
+
+/**
+ * pmo_register_is_device_in_low_pwr_mode(): API to get register device  power
+ * save check notifier.
+ * @psoc: objmgr psoc handle
+ * @handler: device power save check notifier
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_register_is_device_in_low_pwr_mode(struct wlan_objmgr_psoc *psoc,
+		pmo_is_device_in_low_pwr_mode handler);
+
+/**
+ * pmo_unregister_is_device_in_low_pwr_mode(): API to unregister device  power
+ * save check notifier.
+ * @psoc: objmgr psoc handle
+ * @handler: device power save check notifier
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_unregister_is_device_in_low_pwr_mode(
+			struct wlan_objmgr_psoc *psoc,
+			pmo_is_device_in_low_pwr_mode handler);
+
+#endif /* end  of _WLAN_PMO_OBJ_MGMT_API_H_ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h
new file mode 100644
index 0000000..4be33ff
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h
@@ -0,0 +1,189 @@
+/*
+* Copyright (c) 2017 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: Declare various struct, macros which are used for object mgmt in pmo.
+  *
+  * Note: This file shall not contain public API's prototype/declarations.
+  *
+  */
+
+
+#ifndef _WLAN_PMO_OBJ_MGMT_PUBLIC_STRUCT_H_
+#define _WLAN_PMO_OBJ_MGMT_PUBLIC_STRUCT_H_
+
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_arp_public_struct.h"
+#include "wlan_pmo_ns_public_struct.h"
+#include "wlan_pmo_gtk_public_struct.h"
+#include "wlan_pmo_wow_public_struct.h"
+#include "wlan_pmo_mc_addr_filtering_public_struct.h"
+#include "wlan_pmo_hw_filter_public_struct.h"
+#include "wlan_pmo_pkt_filter_public_struct.h"
+#include "wlan_pmo_lphb_public_struct.h"
+
+/**
+ * typedef for vdev notifying the vdev pause bitmap new value to mlme
+ */
+typedef void (*pmo_notify_pause_bitmap)(
+			uint8_t vdev_id, uint16_t value);
+
+/**
+ * typedef for getting vdev pause bitmap
+ */
+typedef  uint16_t(*pmo_get_pause_bitmap)(uint8_t vdev_id);
+
+/**
+ * typedef to know is deviec is in power save mode
+ */
+typedef  bool (*pmo_is_device_in_low_pwr_mode)(uint8_t vdev_id);
+
+/*
+ * typedef for pld auto suspend callback during runtime suspend
+ */
+typedef
+int (*pmo_pld_auto_suspend_cb)(void);
+
+/*
+ * typedef for pld auto resume callback during runtime resume
+ */
+typedef
+int (*pmo_pld_auto_resume_cb)(void);
+
+/**
+ * struct wlan_pmo_tx_ops - structure of tx function
+ *					pointers for pmo component
+ * @send_arp_offload_req: fp to send arp offload request
+ * @send_ns_offload_req: fp to send ns offload request
+ * @send_non_arp_bcast_filter_req: for enable/disable  broadcast filter
+ * @send_set_pkt_filter: send set packet filter
+ * @send_clear_pkt_filter: send clear packet filter
+ * @send_enable_wakeup_event_req: fp to send enable wow wakeup events req
+ * @send_disable_wakeup_event_req: fp to send disable wow wakeup events req
+ * @send_add_wow_pattern: fp to send wow pattern request
+ * @send_enhance_mc_offload_req: fp to send enhanced multicast offload request
+ * @send_set_mc_filter_req: fp to send set mc filter request
+ * @send_clear_mc_filter_req: fp to send clear mc filter request
+ * @send_ra_filter_req: fp to send ra filter request
+ * @send_gtk_offload_req: fp to send gtk offload request command
+ * @send_get_gtk_rsp_cmd: fp to send get gtk response request cmd to firmware
+ * @send_action_frame_pattern_req: fp to send wow action frame patterns request
+ * @send_lphb_enable: fp to send lphb enable request command
+ * @send_lphb_tcp_params: fp to send lphb tcp params request command
+ * @send_lphb_tcp_filter_req: fp to send lphb tcp packet filter request command
+ * @send_lphb_upd_params: fp to send lphb udp params request command
+ * @send_lphb_udp_filter_req: fp to send lphb udp packet filter request command
+ * @send_vdev_param_update_req: fp to send vdev param request
+ * @send_vdev_set_sta_ps_param: fp to send sta vdev ps power set req
+ * @psoc_update_wow_bus_suspend: fp to update bus suspend req flag at wmi
+ * @psoc_get_host_credits: fp to get the host credits
+ * @psoc_get_pending_cmnds: fp to get the host pending wmi commands
+ * @update_target_suspend_flag: fp to update target suspend flag at wmi
+ * @psoc_send_wow_enable_req: fp to send wow enable request
+ * @psoc_send_supend_req: fp to send target suspend request
+ * @psoc_set_runtime_pm_in_progress: fp to set runtime pm is in progress status
+ * @psoc_get_runtime_pm_in_progress: fp to get runtime pm is in progress status
+ * @psoc_send_host_wakeup_ind: fp tp send host wake indication to fwr
+ * @psoc_send_target_resume_req: fp to send target resume request
+ */
+struct wlan_pmo_tx_ops {
+	QDF_STATUS (*send_arp_offload_req)(struct wlan_objmgr_vdev *vdev,
+			struct pmo_arp_offload_params *arp_offload_req,
+			struct pmo_ns_offload_params *ns_offload_req);
+	QDF_STATUS (*send_conf_hw_filter_req)(
+			struct wlan_objmgr_psoc *psoc,
+			struct pmo_hw_filter_params *req);
+	QDF_STATUS (*send_ns_offload_req)(struct wlan_objmgr_vdev *vdev,
+			struct pmo_arp_offload_params *arp_offload_req,
+			struct pmo_ns_offload_params *ns_offload_req);
+	QDF_STATUS(*send_set_pkt_filter)(struct wlan_objmgr_vdev *vdev,
+			struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req);
+	QDF_STATUS(*send_clear_pkt_filter)(struct wlan_objmgr_vdev *vdev,
+			struct pmo_rcv_pkt_fltr_clear_param
+						*pmo_clr_pkt_fltr_param);
+	QDF_STATUS (*send_enable_wow_wakeup_event_req)(
+			struct wlan_objmgr_vdev *vdev,
+			uint32_t *bitmap);
+	QDF_STATUS (*send_disable_wow_wakeup_event_req)(
+			struct wlan_objmgr_vdev *vdev,
+			uint32_t *bitmap);
+	QDF_STATUS (*send_add_wow_pattern)(
+			struct wlan_objmgr_vdev *vdev,
+			uint8_t ptrn_id, const uint8_t *ptrn, uint8_t ptrn_len,
+			uint8_t ptrn_offset, const uint8_t *mask,
+			uint8_t mask_len, bool user);
+	QDF_STATUS (*send_enhance_mc_offload_req)(
+			struct wlan_objmgr_vdev *vdev, bool enable);
+	QDF_STATUS (*send_set_mc_filter_req)(
+			struct wlan_objmgr_vdev *vdev,
+			struct qdf_mac_addr multicast_addr);
+	QDF_STATUS (*send_clear_mc_filter_req)(
+			struct wlan_objmgr_vdev *vdev,
+			struct qdf_mac_addr multicast_addr);
+	QDF_STATUS (*send_ra_filter_req)(
+			struct wlan_objmgr_vdev *vdev,
+			uint8_t default_pattern, uint16_t rate_limit_interval);
+	QDF_STATUS (*send_gtk_offload_req)(
+			struct wlan_objmgr_vdev *vdev,
+			struct pmo_gtk_req *gtk_offload_req);
+	QDF_STATUS (*send_get_gtk_rsp_cmd)(struct wlan_objmgr_vdev *vdev);
+	QDF_STATUS (*send_action_frame_pattern_req)(
+			struct wlan_objmgr_vdev *vdev,
+			struct pmo_action_wakeup_set_params *ip_cmd);
+	QDF_STATUS (*send_lphb_enable)(
+			struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_enable_req *ts_lphb_enable);
+	QDF_STATUS (*send_lphb_tcp_params)(
+			struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_tcp_params *ts_lphb_tcp_param);
+	QDF_STATUS (*send_lphb_tcp_filter_req)(
+			struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_tcp_filter_req *ts_lphb_tcp_filter);
+	QDF_STATUS (*send_lphb_upd_params)(
+			struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_udp_params *ts_lphb_udp_param);
+	QDF_STATUS (*send_lphb_udp_filter_req)(
+			struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_udp_filter_req *ts_lphb_udp_filter);
+	QDF_STATUS (*send_vdev_param_update_req)(
+			struct wlan_objmgr_vdev *vdev,
+			uint32_t param_id, uint32_t param_value);
+	QDF_STATUS (*send_vdev_sta_ps_param_req)(
+			struct wlan_objmgr_vdev *vdev,
+			uint32_t ps_mode, uint32_t value);
+	void (*psoc_update_wow_bus_suspend)(
+			struct wlan_objmgr_psoc *psoc, uint8_t value);
+	int (*psoc_get_host_credits)(
+			struct wlan_objmgr_psoc *psoc);
+	int (*psoc_get_pending_cmnds)(
+			struct wlan_objmgr_psoc *psoc);
+	void (*update_target_suspend_flag)(
+		struct wlan_objmgr_psoc *psoc, uint8_t value);
+	QDF_STATUS (*psoc_send_wow_enable_req)(struct wlan_objmgr_psoc *psoc,
+		struct pmo_wow_cmd_params *param);
+	QDF_STATUS (*psoc_send_supend_req)(struct wlan_objmgr_psoc *psoc,
+		struct pmo_suspend_params *param);
+	void (*psoc_set_runtime_pm_in_progress)(struct wlan_objmgr_psoc *psoc,
+						bool value);
+	bool (*psoc_get_runtime_pm_in_progress)(struct wlan_objmgr_psoc *psoc);
+	QDF_STATUS (*psoc_send_host_wakeup_ind)(struct wlan_objmgr_psoc *psoc);
+	QDF_STATUS (*psoc_send_target_resume_req)(
+			struct wlan_objmgr_psoc *psoc);
+
+};
+
+#endif /* end  of _WLAN_PMO_OBJ_MGMT_PUBLIC_STRUCT_H_ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_pkt_filter_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_pkt_filter_public_struct.h
new file mode 100644
index 0000000..d067fe1
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_pkt_filter_public_struct.h
@@ -0,0 +1,141 @@
+/*
+* Copyright (c) 2017 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: Declare various struct, macros which shall be used in
+  * pmo packet filter feature.
+  *
+  * Note: This file shall not contain public API's prototype/declarations.
+  *
+  */
+
+#ifndef _WLAN_PMO_PKT_FILTER_PUBLIC_STRUCT_H_
+#define _WLAN_PMO_PKT_FILTER_PUBLIC_STRUCT_H_
+
+#include "qdf_types.h"
+
+#define    PMO_MAX_FILTER_TEST_DATA_LEN       8
+#define    PMO_MAX_NUM_TESTS_PER_FILTER      10
+
+/**
+ * enum pmo_rcv_pkt_fltr_type: Receive Filter Parameters
+ * @PMO_RCV_FILTER_TYPE_INVALID: invalied filter type
+ * @PMO_RCV_FILTER_TYPE_FILTER_PKT: packet filter
+ * @PMO_RCV_FILTER_TYPE_BUFFER_PKT: buffer packet
+ * @PMO_RCV_FILTER_TYPE_MAX_ENUM_SIZE: max filter
+ */
+enum pmo_rcv_pkt_fltr_type {
+	PMO_RCV_FILTER_TYPE_INVALID,
+	PMO_RCV_FILTER_TYPE_FILTER_PKT,
+	PMO_RCV_FILTER_TYPE_BUFFER_PKT,
+	PMO_RCV_FILTER_TYPE_MAX_ENUM_SIZE
+};
+
+/**
+ * enum pmo_rcv_pkt_fltr_flag_type: Receive Filter flags
+ * @PMO_FILTER_CMP_TYPE_INVALID: invalied flag
+ * @PMO_FILTER_CMP_TYPE_EQUAL: equal
+ * @PMO_FILTER_CMP_TYPE_MASK_EQUAL: mask
+ * @PMO_FILTER_CMP_TYPE_NOT_EQUAL: not equal
+ * @PMO_FILTER_CMP_TYPE_MASK_NOT_EQUAL: mask not equal
+ * @PMO_FILTER_CMP_TYPE_MAX: max size of flag
+ */
+enum pmo_rcv_pkt_fltr_flag_type {
+	PMO_FILTER_CMP_TYPE_INVALID,
+	PMO_FILTER_CMP_TYPE_EQUAL,
+	PMO_FILTER_CMP_TYPE_MASK_EQUAL,
+	PMO_FILTER_CMP_TYPE_NOT_EQUAL,
+	PMO_FILTER_CMP_TYPE_MASK_NOT_EQUAL,
+	PMO_FILTER_CMP_TYPE_MAX
+};
+
+/**
+ * enum pmo_rcv_pkt_fltr_protocol_params: Receive Filter protocal parameters
+ * @PMO_FILTER_HDR_TYPE_INVALID: invalied type
+ * @PMO_FILTER_HDR_TYPE_MAC: mac protocol
+ * @PMO_FILTER_HDR_TYPE_ARP: arp protocol
+ * @PMO_FILTER_HDR_TYPE_IPV4: ipv4 protocol
+ * @PMO_FILTER_HDR_TYPE_IPV6: ipv6 protocol
+ * @PMO_FILTER_HDR_TYPE_UDP: udp protocol
+ * @PMO_FILTER_HDR_TYPE_MAX: max of type of protocol
+ */
+enum pmo_rcv_pkt_fltr_protocol_params {
+	PMO_FILTER_HDR_TYPE_INVALID,
+	PMO_FILTER_HDR_TYPE_MAC,
+	PMO_FILTER_HDR_TYPE_ARP,
+	PMO_FILTER_HDR_TYPE_IPV4,
+	PMO_FILTER_HDR_TYPE_IPV6,
+	PMO_FILTER_HDR_TYPE_UDP,
+	PMO_FILTER_HDR_TYPE_MAX
+};
+
+/**
+ * struct pmo_rcv_pkt_fltr_field_params  - pmo packet filter field parameters
+ * @protocol_layer: Protocol layer
+ * @compare_flag: Comparison flag
+ * @data_length: Length of the data to compare
+ * @data_offset:  from start of the respective frame header
+ * @reserved: Reserved field
+ * @compare_data: Data to compare
+ * @data_mask: Mask to be applied on the received packet data before compare
+ */
+struct pmo_rcv_pkt_fltr_field_params {
+	enum pmo_rcv_pkt_fltr_protocol_params protocol_layer;
+	enum pmo_rcv_pkt_fltr_flag_type compare_flag;
+	uint16_t data_length;
+	uint8_t data_offset;
+	uint8_t reserved;
+	uint8_t compare_data[PMO_MAX_FILTER_TEST_DATA_LEN];
+	uint8_t data_mask[PMO_MAX_FILTER_TEST_DATA_LEN];
+};
+
+/**
+ * struct pmo_rcv_pkt_fltr_cfg - pmo packet filter config
+ * @filter_id: filter id
+ * @filter_type: filter type
+ * @num_params: number of parameters
+ * @coalesce_time: time
+ * @self_macaddr: mac address
+ * @bssid: Bssid of the connected AP
+ * @params_data: data
+ */
+struct pmo_rcv_pkt_fltr_cfg {
+	uint8_t filter_id;
+	enum pmo_rcv_pkt_fltr_type filter_type;
+	uint32_t num_params;
+	uint32_t coalesce_time;
+	struct qdf_mac_addr self_macaddr;
+	struct qdf_mac_addr bssid;
+	struct pmo_rcv_pkt_fltr_field_params
+		params_data[PMO_MAX_NUM_TESTS_PER_FILTER];
+};
+
+/**
+ * struct pmo_rcv_pkt_fltr_cfg - pmo receive Filter Clear Parameters
+ * @status:  only valid for response message
+ * @filter_id:
+ * @self_macaddr:
+ * @bssid: peer ap address
+ */
+struct pmo_rcv_pkt_fltr_clear_param {
+	uint32_t status;
+	uint8_t filter_id;
+	struct qdf_mac_addr self_macaddr;
+	struct qdf_mac_addr bssid;
+};
+
+#endif /* end of _WLAN_PMO_PKT_FILTER_PUBLIC_STRUCT_H_ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h b/components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h
new file mode 100644
index 0000000..e702da8
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h
@@ -0,0 +1,406 @@
+/*
+* Copyright (c) 2017 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: Declare public API for pmo to interact with target/WMI
+ */
+
+#ifndef _WLAN_PMO_TGT_API_H_
+#define _WLAN_PMO_TGT_API_H_
+
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_arp_public_struct.h"
+#include "wlan_pmo_ns_public_struct.h"
+#include "wlan_pmo_gtk_public_struct.h"
+#include "wlan_pmo_wow_public_struct.h"
+#include "wlan_pmo_mc_addr_filtering_public_struct.h"
+#include "wlan_pmo_hw_filter_public_struct.h"
+#include "wlan_pmo_pkt_filter_public_struct.h"
+
+#define GET_PMO_TX_OPS_FROM_PSOC(psoc) \
+	(pmo_psoc_get_priv(psoc)->pmo_tx_ops)
+
+/**
+ * pmo_tgt_conf_hw_filter() - configure hardware filter mode in firmware
+ * @psoc: the psoc to use to communicate with firmware
+ * @req: the configuration request
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_tgt_conf_hw_filter(struct wlan_objmgr_psoc *psoc,
+				  struct pmo_hw_filter_params *req);
+
+/**
+ * pmo_tgt_set_pkt_filter() - Set packet filter
+ * @vdev: objmgr vdev
+ * @pmo_set_pkt_fltr_req:
+ * @vdev_id: vdev id
+ *
+ * API to set packet filter
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_tgt_set_pkt_filter(struct wlan_objmgr_vdev *vdev,
+		struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req,
+		uint8_t vdev_id);
+
+/**
+ * pmo_tgt_clear_pkt_filter() - Clear packet filter
+ * @vdev: objmgr vdev
+ * @pmo_clr_pkt_fltr_param:
+ * @vdev_id: vdev id
+ *
+ * API to clear packet filter
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_tgt_clear_pkt_filter(struct wlan_objmgr_vdev *vdev,
+		struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_param,
+		uint8_t vdev_id);
+
+/**
+ * pmo_tgt_enable_arp_offload_req() - Enable arp offload req to target
+ * @vdev: objmgr vdev
+ * @vdev_id: vdev id
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_enable_arp_offload_req(struct wlan_objmgr_vdev *vdev,
+		uint8_t vdev_id);
+
+/**
+ * pmo_tgt_disable_arp_offload_req() - Disable arp offload req to target
+ * @vdev: objmgr vdev
+ * @vdev_id: vdev id
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_disable_arp_offload_req(struct wlan_objmgr_vdev *vdev,
+		uint8_t vdev_id);
+
+/**
+ * pmo_tgt_enable_ns_offload_req() -  Send ns offload req to targe
+ * @vdev: objmgr vdev
+ * @vdev_id: vdev id
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_enable_ns_offload_req(struct wlan_objmgr_vdev *vdev,
+		uint8_t vdev_id);
+
+/**
+ * pmo_tgt_disable_ns_offload_req() - Disable arp offload req to target
+ * @vdev: objmgr vdev
+ * @vdev_id: vdev id
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_disable_ns_offload_req(struct wlan_objmgr_vdev *vdev,
+		uint8_t vdev_id);
+
+/**
+ * pmo_tgt_enable_wow_wakeup_event() - Send Enable wow wakeup events req to fwr
+ * @vdev: objmgr vdev handle
+ * @bitmap: Event bitmap
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_enable_wow_wakeup_event(struct wlan_objmgr_vdev *vdev,
+		uint32_t *bitmap);
+
+/**
+ * pmo_tgt_disable_wow_wakeup_event() - Send Disable wow wakeup events to fwr
+ * @vdev: objmgr vdev handle
+ * @bitmap: Event bitmap
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_disable_wow_wakeup_event(struct wlan_objmgr_vdev *vdev,
+		uint32_t *bitmap);
+
+/**
+ * pmo_tgt_send_wow_patterns_to_fw() - Sends WOW patterns to FW.
+ * @vdev: objmgr vdev
+ * @ptrn_id: pattern id
+ * @ptrn: pattern
+ * @ptrn_len: pattern length
+ * @ptrn_offset: pattern offset
+ * @mask: mask
+ * @mask_len: mask length
+ * @user: true for user configured pattern and false for default pattern
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_send_wow_patterns_to_fw(struct wlan_objmgr_vdev *vdev,
+		uint8_t ptrn_id, const uint8_t *ptrn, uint8_t ptrn_len,
+		uint8_t ptrn_offset, const uint8_t *mask,
+		uint8_t mask_len, bool user);
+
+/**
+ * pmo_tgt_set_mc_filter_req() - Set mcast filter command to fw
+ * @vdev: objmgr vdev
+ * @multicastAddr: mcast address
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_tgt_set_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+		struct qdf_mac_addr multicast_addr);
+
+/**
+ * pmo_tgt_clear_mc_filter_req() - Clear mcast filter command to fw
+ * @vdev: objmgr vdev
+ * @multicastAddr: mcast address
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_tgt_clear_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+		struct qdf_mac_addr multicast_addr);
+
+/**
+ * pmo_tgt_send_enhance_multicast_offload_req() - send enhance mc offload req
+ * @wma_handle: wma handle
+ * @vdev_id: vdev id
+ * @action: enable or disable enhance multicast offload
+ *
+ * Return: QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS pmo_tgt_send_enhance_multicast_offload_req(
+		struct wlan_objmgr_vdev *vdev,
+		uint8_t vdev_id,
+		uint8_t action);
+
+/**
+ * pmo_tgt_send_ra_filter_req() - send ra filter request to target
+ * @vdev: objmgr vdev handle
+ *
+ * Return: QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS pmo_tgt_send_ra_filter_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_tgt_send_action_frame_pattern_req - send wow action frame patterns req
+ * @vdev: objmgr vdev handle
+ * @cmd: action frame pattern cmd
+ *
+ * Return: QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS pmo_tgt_send_action_frame_pattern_req(
+		struct wlan_objmgr_vdev *vdev,
+		struct pmo_action_wakeup_set_params *cmd);
+
+/**
+ * pmo_tgt_send_gtk_offload_req() - send GTK offload command to fw
+ * @vdev: objmgr vdev
+ * @gtk_req: pmo gtk req
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_send_gtk_offload_req(struct wlan_objmgr_vdev *vdev,
+		struct pmo_gtk_req *gtk_req);
+
+/**
+ * pmo_tgt_get_gtk_rsp() - send get gtk rsp command to fw
+ * @vdev: objmgr vdev
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_get_gtk_rsp(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_tgt_gtk_rsp_evt() - receive gtk rsp event from fwr
+ * @psoc: objmgr psoc
+ * @gtk_rsp_param: gtk response parameters
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_gtk_rsp_evt(struct wlan_objmgr_psoc *psoc,
+		struct pmo_gtk_rsp_params *rsp_param);
+
+/**
+ * pmo_tgt_send_lphb_enable() - enable command of LPHB configuration requests
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_enable: lphb enable request which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_send_lphb_enable(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_enable_req *ts_lphb_enable);
+
+/**
+ * pmo_tgt_send_lphb_tcp_params() - set tcp params of LPHB configuration req
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_tcp_param: lphb tcp params which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_send_lphb_tcp_params(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_tcp_params *ts_lphb_tcp_param);
+
+/**
+ * pmo_tgt_send_lphb_tcp_pkt_filter() - send tcp packet filter command of LPHB
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_tcp_filter: lphb tcp filter request which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_send_lphb_tcp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_tcp_filter_req *ts_lphb_tcp_filter);
+
+/**
+ * pmo_tgt_send_lphb_udp_params() - Send udp param command of LPHB
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_udp_param: lphb udp params which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_send_lphb_udp_params(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_udp_params *ts_lphb_udp_param);
+
+/**
+ * pmo_tgt_send_lphb_udp_pkt_filter() - Send udp pkt filter command of LPHB
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_udp_filter: lphb udp filter request which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_send_lphb_udp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_udp_filter_req *ts_lphb_udp_filter);
+
+
+/**
+ * pmo_tgt_lphb_rsp_evt() - receive lphb rsp event from fwr
+ * @psoc: objmgr psoc
+ * @rsp_param: lphb response parameters
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_tgt_lphb_rsp_evt(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_rsp *rsp_param);
+
+/**
+ * pmo_tgt_vdev_update_param_req() - Update vdev param value to fwr
+ * @vdev: objmgr vdev
+ * @param_id: tell vdev param id which needs to be updated in fwr
+ * @param_value: vdev parameter value
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_vdev_update_param_req(struct wlan_objmgr_vdev *vdev,
+		enum pmo_vdev_param_id param_id, uint32_t param_value);
+
+/**
+ * pmo_tgt_send_vdev_sta_ps_param() - Send vdev sta power save param to fwr
+ * @vdev: objmgr vdev
+ * @ps_param: sta mode ps power save params type
+ * @param_value: power save parameter value
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_send_vdev_sta_ps_param(struct wlan_objmgr_vdev *vdev,
+		enum pmo_sta_powersave_param ps_param, uint32_t param_value);
+
+/**
+ * pmo_tgt_update_wow_bus_suspend_state() - update wow bus suspend state flag
+ * @psoc: objmgr psoc
+ * @val: true for setting wow suspend flag to set else false
+ *
+ * Return: None
+ */
+void pmo_tgt_psoc_update_wow_bus_suspend_state(struct wlan_objmgr_psoc *psoc,
+		uint8_t val);
+
+/**
+ * pmo_tgt_get_host_credits() - Get host credits
+ * @psoc: objmgr psoc
+ *
+ * Return: Pending WMI commands on success else EAGAIN on error
+ */
+int pmo_tgt_psoc_get_host_credits(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_tgt_get_pending_cmnds() - Get pending commands
+ * @psoc: objmgr psoc
+ *
+ * Return: Pending WMI commands on success else EAGAIN on error
+ */
+int pmo_tgt_psoc_get_pending_cmnds(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_tgt_update_target_suspend_flag() - Set WMI target Suspend flag
+ * @psoc: objmgr psoc
+ * @val: true on suspend false for resume
+ *
+ * Return: Pending WMI commands on success else EAGAIN on error
+ */
+void pmo_tgt_update_target_suspend_flag(struct wlan_objmgr_psoc *psoc,
+		uint8_t val);
+
+/**
+ * pmo_tgt_psoc_send_wow_enable_req() -Send wow enable request
+ * @psoc: objmgr psoc
+ * @param: WOW enable request buffer
+ *
+ * Return: QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS pmo_tgt_psoc_send_wow_enable_req(struct wlan_objmgr_psoc *psoc,
+	struct pmo_wow_cmd_params *param);
+
+/**
+ * pmo_tgt_psoc_send_supend_req() -Send target suspend request to fwr
+ * @psoc: objmgr psoc
+ * @param: suspend request buffer
+ *
+ * Return: QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS pmo_tgt_psoc_send_supend_req(struct wlan_objmgr_psoc *psoc,
+		struct pmo_suspend_params *param);
+
+/**
+ * pmo_tgt_psoc_set_runtime_pm_inprogress() -set runtime status
+ * @psoc: objmgr psoc
+ * @value: set runtime pm in progress true or false
+ *
+ * Return: none
+ */
+QDF_STATUS pmo_tgt_psoc_set_runtime_pm_inprogress(struct wlan_objmgr_psoc *psoc,
+						  bool value);
+
+/**
+ * pmo_tgt_psoc_get_runtime_pm_in_progress() -get runtime status
+ * @psoc: objmgr psoc
+ *
+ * Return: true if runtime pm is in progress else false
+ */
+bool pmo_tgt_psoc_get_runtime_pm_in_progress(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_tgt_psoc_send_host_wakeup_ind() -Send host wake up indication to fwr
+ * @psoc: objmgr psoc
+ *
+ * Return: QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS pmo_tgt_psoc_send_host_wakeup_ind(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_tgt_psoc_send_target_resume_req() -Send target resume request
+ * @psoc: objmgr psoc
+ *
+ * Return: QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS pmo_tgt_psoc_send_target_resume_req(struct wlan_objmgr_psoc *psoc);
+
+#endif /* end  of _WLAN_PMO_TGT_API_H_ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h
new file mode 100644
index 0000000..beb2ade
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h
@@ -0,0 +1,565 @@
+/*
+* Copyright (c) 2017 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: Declare public API related to the pmo called by north bound HDD/OSIF
+ */
+
+#ifndef _WLAN_PMO_UCFG_API_H_
+#define _WLAN_PMO_UCFG_API_H_
+
+#include "wlan_pmo_arp_public_struct.h"
+#include "wlan_pmo_ns_public_struct.h"
+#include "wlan_pmo_gtk_public_struct.h"
+#include "wlan_pmo_mc_addr_filtering_public_struct.h"
+#include "wlan_pmo_wow_public_struct.h"
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_obj_mgmt_api.h"
+#include "wlan_pmo_pkt_filter_public_struct.h"
+#include "wlan_pmo_hw_filter_public_struct.h"
+
+/**
+ * pmo_ucfg_is_ap_mode_supports_arp_ns() - Check ap mode support arp&ns offload
+ * @psoc: objmgr psoc
+ * @vdev_opmode: vdev opmode
+ *
+ * Return: true in case support else false
+ */
+bool pmo_ucfg_is_ap_mode_supports_arp_ns(struct wlan_objmgr_psoc *psoc,
+	enum tQDF_ADAPTER_MODE vdev_opmode);
+
+/**
+ * pmo_ucfg_is_vdev_connected() -  to check whether peer is associated or not
+ * @vdev: objmgr vdev
+ *
+ * Return: true in case success else false
+ */
+bool pmo_ucfg_is_vdev_connected(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_ucfg_is_vdev_supports_offload() - check offload is supported on vdev
+ * @vdev: objmgr vdev
+ *
+ * Return: true in case success else false
+ */
+bool pmo_ucfg_is_vdev_supports_offload(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_ucfg_get_psoc_config(): API to get the psoc user configurations of pmo
+ * @psoc: objmgr psoc handle
+ * @psoc_cfg: fill the current psoc user configurations.
+ *
+ * Return pmo psoc configurations
+ */
+QDF_STATUS pmo_ucfg_get_psoc_config(struct wlan_objmgr_psoc *psoc,
+		struct pmo_psoc_cfg *psoc_cfg);
+
+/**
+ * pmo_ucfg_update_psoc_config(): API to update the psoc user configurations
+ * @psoc: objmgr psoc handle
+ * @psoc_cfg: pmo psoc configurations
+ *
+ * This api shall be used for soc config initialization as well update.
+ * In case of update caller must first call pmo_get_psoc_cfg to get
+ * current config and then apply changes on top of current config.
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_update_psoc_config(struct wlan_objmgr_psoc *psoc,
+		struct pmo_psoc_cfg *psoc_cfg);
+
+/**
+ * pmo_ucfg_enable_wakeup_event() -  enable wow wakeup events
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id
+ * @bitmap: Event bitmap
+ *
+ * Return: none
+ */
+void pmo_ucfg_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+	uint32_t vdev_id, uint32_t *bitmap);
+
+/**
+ * pmo_ucfg_disable_wakeup_event() -  disable wow wakeup events
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id
+ * @bitmap: Event bitmap
+ *
+ * Return: none
+ */
+void pmo_ucfg_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+	uint32_t vdev_id, uint32_t bitmap);
+
+/**
+ * pmo_ucfg_cache_arp_offload_req(): API to cache arp req in pmo vdev priv ctx
+ * @arp_req: pmo arp req param
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_cache_arp_offload_req(struct pmo_arp_req *arp_req);
+
+/**
+ * pmo_ucfg_flush_arp_offload_req(): API to flush arp req from pmo vdev priv ctx
+ * @vdev: objmgr vdev param
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_flush_arp_offload_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_ucfg_enable_arp_offload_in_fwr(): API to enable arp req in fwr
+ * @vdev: objmgr vdev param
+ * @trigger: triger reason for enable arp offload
+ *
+ *  API to enable cache arp req in fwr from pmo vdev priv ctx
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_enable_arp_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_ucfg_disable_arp_offload_in_fwr(): API to disable arp req in fwr
+ * @vdev: objmgr vdev param
+ * @trigger: triger reason  for disable arp offload
+ *  API to disable cache arp req in fwr
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_disable_arp_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_ucfg_cache_ns_offload_req(): API to cache ns req in pmo vdev priv ctx
+ * @ns_req: pmo ns req param
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_cache_ns_offload_req(struct pmo_ns_req *ns_req);
+
+/**
+ * pmo_ucfg_flush_ns_offload_req(): API to flush ns req from pmo vdev priv ctx
+ * @vdev: vdev ojbmgr handle
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_flush_ns_offload_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_ucfg_enable_ns_offload_in_fwr(): API to enable ns req in fwr
+ * @arp_req: pmo arp req param
+ * @trigger: trigger reason to enable ns offload
+ *
+ *  API to enable cache ns req in fwr from pmo vdev priv ctx
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_enable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_ucfg_disable_ns_offload_in_fwr(): API to disable ns req in fwr
+ * @arp_req: pmo arp req param
+ * @trigger: trigger reason to disable ns offload
+ *
+ *  API to disable ns req in fwr
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_disable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_ucfg_enable_hw_filter_in_fwr() - enable previously configured hw filter
+ * @vdev: objmgr vdev to configure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_ucfg_enable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_ucfg_disable_hw_filter_in_fwr() - disable previously configured hw filter
+ * @vdev: objmgr vdev to configure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_ucfg_disable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_ucfg_max_mc_addr_supported() -  to get max support mc address
+ * @psoc: objmgr psoc
+ *
+ * Return: max mc addr supported count for all vdev in corresponding psoc
+ */
+uint8_t pmo_ucfg_max_mc_addr_supported(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_ucfg_cache_mc_addr_list(): API to cache mc addr list in pmo vdev priv obj
+ * @psoc: objmgr psoc handle
+ * @vdev_id: vdev id
+ * @gtk_req: pmo gtk req param
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_cache_mc_addr_list(
+		struct pmo_mc_addr_list_params *mc_list_config);
+
+/**
+ * pmo_ucfg_flush_mc_addr_list(): API to flush mc addr list in pmo vdev priv obj
+ * @psoc: objmgr psoc handle
+ * @vdev_id: vdev id
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_flush_mc_addr_list(struct wlan_objmgr_psoc *psoc,
+	uint8_t vdev_id);
+
+/**
+ * pmo_ucfg_enable_mc_addr_filtering_in_fwr(): Enable cached mc add list in fwr
+ * @psoc: objmgr psoc handle
+ * @vdev_id: vdev id
+ * @gtk_req: pmo gtk req param
+ * @action: true for enable els false
+ *
+ * API to enable cached mc add list in fwr
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_enable_mc_addr_filtering_in_fwr(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id,
+		enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_ucfg_disable_mc_addr_filtering_in_fwr(): Disable cached mc addr list
+ * @psoc: objmgr psoc handle
+ * @vdev_id: vdev id
+ * @gtk_req: pmo gtk req param
+ * @action: true for enable els false
+ *
+ * API to disable cached mc add list in fwr
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_disable_mc_addr_filtering_in_fwr(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id,
+		enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_ucfg_cache_gtk_offload_req(): API to cache gtk req in pmo vdev priv obj
+ * @vdev: objmgr vdev handle
+ * @gtk_req: pmo gtk req param
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_cache_gtk_offload_req(struct wlan_objmgr_vdev *vdev,
+		struct pmo_gtk_req *gtk_req);
+
+/**
+ * pmo_ucfg_flush_gtk_offload_req(): Flush saved gtk req from pmo vdev priv obj
+ * @vdev: objmgr vdev handle
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_flush_gtk_offload_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_ucfg_enable_gtk_offload_in_fwr(): enable cached gtk request in fwr
+ * @vdev: objmgr vdev handle
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_enable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_ucfg_disable_gtk_offload_in_fwr(): disable cached gtk request in fwr
+ * @vdev: objmgr vdev handle
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_disable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_ucfg_set_pkt_filter() - Set packet filter
+ * @psoc: objmgr psoc handle
+ * @pmo_set_pkt_fltr_req:
+ * @vdev_id: vdev id
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_set_pkt_filter(struct wlan_objmgr_psoc *psoc,
+	struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req,
+	uint8_t vdev_id);
+
+/**
+ * pmo_ucfg_clear_pkt_filter() - Clear packet filter
+ * @psoc: objmgr psoc handle
+ * @pmo_clr_pkt_fltr_req:
+ * @vdev_id: vdev id
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_clear_pkt_filter(struct wlan_objmgr_psoc *psoc,
+	struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_param,
+	uint8_t vdev_id);
+
+/**
+ * pmo_ucfg_get_gtk_rsp(): API to send gtk response request to fwr
+ * @vdev: objmgr vdev handle
+ * @gtk_rsp: pmo gtk response request
+ *
+ * This api will send gtk response request to fwr
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_get_gtk_rsp(struct wlan_objmgr_vdev *vdev,
+		struct pmo_gtk_rsp_req *gtk_rsp_req);
+
+/**
+ * pmo_ucfg_update_extscan_in_progress(): update extscan is in progress flags
+ * @vdev: objmgr vdev handle
+ * @value:true if extscan is in progress else false
+ *
+ * Return: TRUE/FALSE
+ */
+void pmo_ucfg_update_extscan_in_progress(struct wlan_objmgr_vdev *vdev,
+	bool value);
+
+/**
+ * pmo_ucfg_update_p2plo_in_progress(): update p2plo is in progress flags
+ * @vdev: objmgr vdev handle
+ * @value:true if p2plo is in progress else false
+ *
+ * Return: TRUE/FALSE
+ */
+void pmo_ucfg_update_p2plo_in_progress(struct wlan_objmgr_vdev *vdev,
+	bool value);
+
+/**
+ * pmo_ucfg_lphb_config_req() -  Handles lphb config request for psoc
+ * @psoc: objmgr psoc handle
+ * @lphb_req: low power heart beat request
+ * @lphb_cb_ctx: Context which needs to pass to soif when lphb callback called
+ * @callback: upon receiving of lphb indication from fwr call lphb callback
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_ucfg_lphb_config_req(struct wlan_objmgr_psoc *psoc,
+		struct pmo_lphb_req *lphb_req, void *lphb_cb_ctx,
+		pmo_lphb_callback callback);
+
+/**
+ * pmo_ucfg_update_alt_modulated_dtim_enable() - update alt modulatate dtim
+ * @vdev: objmgr vdev handle
+ * @value: true for alt_modulated_dtim enable else false
+ *
+ * Return: QDF status
+ */
+void pmo_ucfg_update_alt_modulated_dtim_enable(struct wlan_objmgr_vdev *vdev,
+	bool value);
+
+/**
+ * pmo_ucfg_psoc_update_power_save_mode() - update power save mode
+ * @vdev: objmgr vdev handle
+ * @value:vdev power save mode
+ *
+ * Return: None
+ */
+void pmo_ucfg_psoc_update_power_save_mode(struct wlan_objmgr_psoc *psoc,
+	uint8_t value);
+
+/**
+ * pmo_ucfg_psoc_update_dp_handle() - update psoc data path handle
+ * @psoc: objmgr psoc handle
+ * @dp_hdl: psoc data path handle
+ *
+ * Return: None
+ */
+void pmo_ucfg_psoc_update_dp_handle(struct wlan_objmgr_psoc *psoc,
+	void *dp_hdl);
+
+/**
+ * pmo_ucfg_vdev_update_dp_handle() - update vdev data path handle
+ * @vdev: objmgr vdev handle
+ * @dp_hdl: vdev data path handle
+ *
+ * Return: None
+ */
+void pmo_ucfg_vdev_update_dp_handle(struct wlan_objmgr_vdev *vdev,
+	void *dp_hdl);
+
+/**
+ * pmo_ucfg_psoc_update_htc_handle() - update psoc htc layer handle
+ * @psoc: objmgr psoc handle
+ * @htc_handle: psoc host-to-tagret layer (htc) handle
+ *
+ * Return: None
+ */
+void pmo_ucfg_psoc_update_htc_handle(struct wlan_objmgr_psoc *psoc,
+		void *htc_handle);
+
+/**
+ * pmo_ucfg_psoc_set_hif_handle() - Set psoc hif layer handle
+ * @psoc: objmgr psoc handle
+ * @hif_handle: hif context handle
+ *
+ * Return: None
+ */
+void pmo_ucfg_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc,
+				  void *hif_handle);
+
+/**
+ * pmo_ucfg_psoc_set_txrx_handle() - Set psoc pdev txrx layer handle
+ * @psoc: objmgr psoc handle
+ * @txrx_handle: pdev txrx context handle
+ *
+ * Return: None
+ */
+void pmo_ucfg_psoc_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+				   void *txrx_handle);
+
+/**
+ * pmo_ucfg_psoc_user_space_suspend_req() -  Handles user space suspend req
+ * @psoc: objmgr psoc handle
+ * @type: type of suspend
+ *
+ * Handles user space suspend indication for psoc
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_ucfg_psoc_user_space_suspend_req(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type);
+
+/**
+ * pmo_ucfg_psoc_user_space_resume_req() -  Handles user space resume req
+ * @psoc: objmgr psoc handle
+ * @type: type of suspend from which resume needed
+ *
+ * Handles user space resume indication for psoc
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_ucfg_psoc_user_space_resume_req(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type);
+
+/**
+ * pmo_ucfg_psoc_bus_suspend_req(): handles bus suspend for psoc
+ * @psoc: objmgr psoc
+ * @type: is this suspend part of runtime suspend or system suspend?
+ * @wow_params: collection of wow enable override parameters
+ *
+ * Bails if a scan is in progress.
+ * Calls the appropriate handlers based on configuration and event.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_ucfg_psoc_bus_suspend_req(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type,
+		struct pmo_wow_enable_params *wow_params);
+
+#ifdef FEATURE_RUNTIME_PM
+/**
+ * pmo_ucfg_psoc_bus_runtime_suspend(): handles bus runtime suspend for psoc
+ * @psoc: objmgr psoc
+ * @pld_cb: callback to call link auto suspend
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_ucfg_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc,
+					     pmo_pld_auto_suspend_cb pld_cb);
+
+/**
+ * pmo_ucfg_psoc_bus_runtime_resume(): handles bus runtime resume for psoc
+ * @psoc: objmgr psoc
+ * @pld_cb: callback to call link auto resume
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_ucfg_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc,
+					    pmo_pld_auto_resume_cb pld_cb);
+#endif
+
+/**
+ * pmo_ucfg_psoc_suspend_target() -Send suspend target command
+ * @psoc: objmgr psoc handle
+ * @disable_target_intr: disable target interrupt
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_ucfg_psoc_suspend_target(struct wlan_objmgr_psoc *psoc,
+		int disable_target_intr);
+
+/**
+ * pmo_ucfg_psoc_bus_resume() -handle bus resume request for psoc
+ * @psoc: objmgr psoc handle
+ * @type: is this suspend part of runtime suspend or system suspend?
+ *
+ * Return:QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS pmo_ucfg_psoc_bus_resume_req(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type);
+
+/**
+ * pmo_ucfg_get_wow_bus_suspend(): API to check if wow bus is suspended or not
+ * @psoc: objmgr psoc handle
+ *
+ * Return: True if bus suspende else false
+ */
+bool pmo_ucfg_get_wow_bus_suspend(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_ucfg_psoc_handle_initial_wake_up() - update initial wake up
+ * @cb_ctx: objmgr psoc handle as void * due to htc layer is not aware psoc
+ *
+ * Return: None
+ */
+void pmo_ucfg_psoc_handle_initial_wake_up(void *cb_ctx);
+
+/**
+ * pmo_ucfg_psoc_is_target_wake_up_received() - Get initial wake up status
+ * @psoc: objmgr psoc handle
+ *
+ * Return: 0 on success else error code
+ */
+int pmo_ucfg_psoc_is_target_wake_up_received(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_ucfg_psoc_is_target_wake_up_received() - Clear initial wake up status
+ * @psoc: objmgr psoc handle
+ *
+ * Return: 0 on success else error code
+ */
+int pmo_ucfg_psoc_clear_target_wake_up(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_ucfg_psoc_target_suspend_acknowledge() - Clear initial wake up status
+ * @psoc: objmgr psoc handle
+ *
+ * Return: None
+ */
+void pmo_ucfg_psoc_target_suspend_acknowledge(void *context, bool wow_nack);
+
+/**
+ * pmo_ucfg_psoc_wakeup_host_event_received() - got host wake up evennt from fwr
+ * @psoc: objmgr psoc handle
+ *
+ * Return: None
+ */
+void pmo_ucfg_psoc_wakeup_host_event_received(struct wlan_objmgr_psoc *psoc);
+
+#endif /* end  of _WLAN_PMO_UCFG_API_H_ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h
new file mode 100644
index 0000000..46d7048
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h
@@ -0,0 +1,241 @@
+/*
+* Copyright (c) 2017 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: Declare various struct, macros which shall be used in
+  * pmo wow related features.
+  *
+  * Note: This file shall not contain public API's prototype/declarations.
+  *
+  */
+
+#ifndef _WLAN_PMO_WOW_PUBLIC_STRUCT_H_
+#include "wlan_pmo_lphb_public_struct.h"
+
+#define _WLAN_PMO_WOW_PUBLIC_STRUCT_H_
+
+#define PMO_WOWL_PTRN_MAX_SIZE          146
+#define PMO_WOWL_PTRN_MASK_MAX_SIZE      19
+#define PMO_WOWL_MAX_PTRNS_ALLOWED       CFG_MAX_WOW_FILTERS_MAX
+#define PMO_WOWL_BCAST_PATTERN_MAX_SIZE 146
+
+#define PMO_WOW_INTER_PTRN_TOKENIZER   ';'
+#define PMO_WOW_INTRA_PTRN_TOKENIZER   ':'
+
+
+/* Action frame categories */
+
+#define PMO_MAC_ACTION_SPECTRUM_MGMT   0
+#define PMO_MAC_ACTION_QOS_MGMT        1
+#define PMO_MAC_ACTION_DLP             2
+#define PMO_MAC_ACTION_BLKACK          3
+#define PMO_MAC_ACTION_PUBLIC_USAGE    4
+#define PMO_MAC_ACTION_RRM             5
+#define PMO_MAC_ACTION_FAST_BSS_TRNST  6
+#define PMO_MAC_ACTION_HT              7
+#define PMO_MAC_ACTION_SA_QUERY        8
+#define PMO_MAC_ACTION_PROT_DUAL_PUB   9
+#define PMO_MAC_ACTION_WNM            10
+#define PMO_MAC_ACTION_UNPROT_WNM     11
+#define PMO_MAC_ACTION_TDLS           12
+#define PMO_MAC_ACITON_MESH           13
+#define PMO_MAC_ACTION_MHF            14
+#define PMO_MAC_SELF_PROTECTED        15
+#define PMO_MAC_ACTION_WME            17
+#define PMO_MAC_ACTION_FST            18
+#define PMO_MAC_ACTION_VHT            21
+#define PMO_MAC_ACTION_MAX            256
+
+/*
+ * ALLOWED_ACTION_FRAMES_BITMAP
+ *
+ * Bitmask is based on the below. The frames with 0's
+ * set to their corresponding bit can be dropped in FW.
+ *
+ * -----------------------------+-----+-------+
+ *         Type                 | Bit | Allow |
+ * -----------------------------+-----+-------+
+ * PMO_ACTION_SPECTRUM_MGMT    0      1
+ * PMO_ACTION_QOS_MGMT         1      1
+ * PMO_ACTION_DLP              2      0
+ * PMO_ACTION_BLKACK           3      0
+ * PMO_ACTION_PUBLIC_USAGE     4      1
+ * PMO_ACTION_RRM              5      1
+ * PMO_ACTION_FAST_BSS_TRNST   6      0
+ * PMO_ACTION_HT               7      0
+ * PMO_ACTION_SA_QUERY         8      1
+ * PMO_ACTION_PROT_DUAL_PUB    9      1
+ * PMO_ACTION_WNM             10      1
+ * PMO_ACTION_UNPROT_WNM      11      0
+ * PMO_ACTION_TDLS            12      0
+ * PMO_ACITON_MESH            13      0
+ * PMO_ACTION_MHF             14      0
+ * PMO_SELF_PROTECTED         15      0
+ * PMO_ACTION_WME             17      1
+ * PMO_ACTION_FST             18      1
+ * PMO_ACTION_VHT             21      1
+ * ----------------------------+------+-------+
+ */
+#define ALLOWED_ACTION_FRAMES_BITMAP0 \
+		((1 << PMO_MAC_ACTION_SPECTRUM_MGMT) | \
+		 (1 << PMO_MAC_ACTION_QOS_MGMT) | \
+		 (1 << PMO_MAC_ACTION_PUBLIC_USAGE) | \
+		 (1 << PMO_MAC_ACTION_RRM) | \
+		 (1 << PMO_MAC_ACTION_SA_QUERY) | \
+		 (1 << PMO_MAC_ACTION_PROT_DUAL_PUB) | \
+		 (1 << PMO_MAC_ACTION_WNM) | \
+		 (1 << PMO_MAC_ACTION_WME) | \
+		 (1 << PMO_MAC_ACTION_FST) | \
+		 (1 << PMO_MAC_ACTION_VHT))
+
+#define ALLOWED_ACTION_FRAMES_BITMAP1   0x0
+#define ALLOWED_ACTION_FRAMES_BITMAP2   0x0
+#define ALLOWED_ACTION_FRAMES_BITMAP3   0x0
+#define ALLOWED_ACTION_FRAMES_BITMAP4   0x0
+#define ALLOWED_ACTION_FRAMES_BITMAP5   0x0
+#define ALLOWED_ACTION_FRAMES_BITMAP6   0x0
+#define ALLOWED_ACTION_FRAMES_BITMAP7   0x0
+
+#define ALLOWED_ACTION_FRAME_MAP_WORDS (PMO_MAC_ACTION_MAX / 32)
+
+
+#define PMO_SUPPORTED_ACTION_CATE           256
+#define PMO_SUPPORTED_ACTION_CATE_ELE_LIST (PMO_SUPPORTED_ACTION_CATE/32)
+
+/**
+ * struct pmo_action_wakeup_set_params - action wakeup set params
+ * @vdev_id: virtual device id
+ * @operation: 0 reset to fw default, 1 set the bits,
+ *    2 add the setting bits, 3 delete the setting bits
+ * @action_category_map: bit mapping.
+ */
+struct pmo_action_wakeup_set_params {
+	uint32_t vdev_id;
+	uint32_t operation;
+	uint32_t action_category_map[PMO_SUPPORTED_ACTION_CATE_ELE_LIST];
+};
+
+/**
+ * enum pmo_wow_action_wakeup_opertion: describe action wakeup operation
+ * @pmo_action_wakeup_reset: reset
+ * @pmo_action_wakeup_set: set
+ * @pmo_action_wakeup_add_set: add and set
+ * @pmo_action_wakeup_del_set: delete and set
+ */
+enum pmo_wow_action_wakeup_opertion {
+	pmo_action_wakeup_reset = 0,
+	pmo_action_wakeup_set,
+	pmo_action_wakeup_add_set,
+	pmo_action_wakeup_del_set,
+};
+
+/**
+ * struct pmo_wow - store wow patterns
+ * @wow_enable: wow enable/disable
+ * @wow_enable_cmd_sent: is wow enable command sent to fw
+ * @is_wow_bus_suspended: true if bus is suspended
+ * @target_suspend: target suspend event
+ * @target_resume: target resume event
+ * @wow_nack: wow negative ack flag
+ * @wow_initial_wake_up: target initial wake up is received
+ * @wow_wake_lock: wow wake lock
+ * @lphb_cache: lphb cache
+ * @lphb_cb_ctx: callback context for lphb, kept as void* as
+ *                        osif structures are opaque to pmo.
+ * @pmo_lphb_callback: registered os if calllback function
+ *
+ * This structure stores wow patterns and
+ * wow related parameters in host.
+ */
+struct pmo_wow {
+	bool wow_enable;
+	bool wow_enable_cmd_sent;
+	bool is_wow_bus_suspended;
+	qdf_event_t target_suspend;
+	qdf_event_t target_resume;
+	int wow_nack;
+	bool wow_initial_wake_up;
+	qdf_wake_lock_t wow_wake_lock;
+	/*
+	 * currently supports only vdev 0.
+	 * cache has two entries: one for TCP and one for UDP.
+	 */
+	struct pmo_lphb_req lphb_cache[2];
+	void *lphb_cb_ctx;
+	pmo_lphb_callback lphb_cb;
+};
+
+/* WOW related structures */
+/**
+ * struct pmo_wow_add_pattern - wow pattern add structure
+ * @pattern_id: pattern id
+ * @pattern_byte_offset: pattern byte offset from beginning of the 802.11
+ *			 packet to start of the wake-up pattern
+ * @pattern_size: pattern size
+ * @pattern: pattern byte stream
+ * @pattern_mask_size: pattern mask size
+ * @pattern_mask: pattern mask
+ * @session_id: session id
+ */
+struct pmo_wow_add_pattern {
+	uint8_t pattern_id;
+	uint8_t pattern_byte_offset;
+	uint8_t pattern_size;
+	uint8_t pattern[PMO_WOWL_BCAST_PATTERN_MAX_SIZE];
+	uint8_t pattern_mask_size;
+	uint8_t pattern_mask[PMO_WOWL_BCAST_PATTERN_MAX_SIZE];
+	uint8_t session_id;
+};
+
+/**
+ * struct pmo_wow_add_pattern - wow pattern add structure
+ * @magic_pkt_enable: enables or disables magic packet filtering
+ * @wow_deauth_rcv:  This configuration is valid only when magicPktEnable=1,
+ *    It requests hardware to wake up when it receives the
+ *    Deauthentication Frame.
+ * @pattern_filtering_enable: Enables/disables packet pattern filtering
+ * @wow_bss_conn_loss: wake up host when bss connection lost
+ */
+struct pmo_wow_enter_params {
+	uint8_t magic_pkt_enable;
+	uint8_t wow_deauth_rcv;
+	uint8_t pattern_filtering_enable;
+	uint8_t wow_bss_conn_loss;
+};
+
+/**
+ * struct pmo_wow_cmd_params - wow cmd parameter
+ * @enable: wow enable or disable flag
+ * @can_suspend_link: flag to indicate if link can be suspended
+ * @pause_iface_config: interface config
+ */
+struct pmo_wow_cmd_params {
+	bool enable;
+	bool can_suspend_link;
+	uint8_t pause_iface_config;
+	uint32_t flags;
+};
+
+/**
+ * struct pmo_suspend_params - suspend cmd parameter
+ * @disable_target_intr: disable target interrupt
+ */
+struct pmo_suspend_params {
+	uint8_t disable_target_intr;
+};
+
+#endif /* end  of _WLAN_PMO_WOW_PUBLIC_STRUCT_H_ */
diff --git a/components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c b/components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c
new file mode 100644
index 0000000..0041fa2
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c
@@ -0,0 +1,761 @@
+/*
+* Copyright (c) 2017 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: define utility API related to the pmo component
+ * called by other components
+ */
+
+#include "wlan_pmo_obj_mgmt_api.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_static_config.h"
+#include "wlan_pmo_main.h"
+#include "target_if_pmo.h"
+
+QDF_STATUS pmo_init(void)
+{
+	QDF_STATUS status;
+	struct wlan_pmo_ctx *pmo_ctx;
+
+	PMO_ENTER();
+	if (pmo_allocate_ctx() != QDF_STATUS_SUCCESS) {
+		pmo_err("unable to allocate psoc ctx");
+		status = QDF_STATUS_E_FAULT;
+		goto out;
+	}
+
+	pmo_ctx = pmo_get_context();
+	if (!pmo_ctx) {
+		pmo_err("unable to get pmo ctx");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = wlan_objmgr_register_psoc_create_handler(
+			WLAN_UMAC_COMP_PMO,
+			pmo_psoc_object_created_notification,
+			(void *)pmo_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("unable to register psoc create handle");
+		goto out;
+	}
+
+	status = wlan_objmgr_register_psoc_destroy_handler(
+			WLAN_UMAC_COMP_PMO,
+			 pmo_psoc_object_destroyed_notification,
+			(void *)pmo_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("unable to register psoc create handle");
+		goto out;
+	}
+
+	status = wlan_objmgr_register_vdev_create_handler(
+			WLAN_UMAC_COMP_PMO,
+			pmo_vdev_object_created_notification,
+			(void *)pmo_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("unable to register vdev create handle");
+		goto out;
+	}
+
+	status = wlan_objmgr_register_vdev_destroy_handler(
+			WLAN_UMAC_COMP_PMO,
+			pmo_vdev_object_destroyed_notification,
+			(void *)pmo_ctx);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("unable to register vdev create handle");
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_deinit(void)
+{
+	QDF_STATUS status;
+	struct wlan_pmo_ctx *pmo_ctx;
+
+	PMO_ENTER();
+	pmo_ctx = pmo_get_context();
+	if (!pmo_ctx) {
+		pmo_err("unable to get pmo ctx");
+		status =  QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	status = wlan_objmgr_unregister_psoc_create_handler(
+			WLAN_UMAC_COMP_PMO,
+			pmo_psoc_object_created_notification,
+			(void *)pmo_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("unable to unregister psoc create handle");
+		goto out;
+	}
+
+	status = wlan_objmgr_unregister_psoc_destroy_handler(
+			WLAN_UMAC_COMP_PMO,
+			 pmo_psoc_object_destroyed_notification,
+			(void *)pmo_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("unable to unregister psoc create handle");
+		goto out;
+	}
+
+	status = wlan_objmgr_unregister_vdev_create_handler(
+			WLAN_UMAC_COMP_PMO,
+			pmo_vdev_object_created_notification,
+			(void *)pmo_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("unable to unregister vdev create handle");
+		goto out;
+	}
+
+	status = wlan_objmgr_unregister_vdev_destroy_handler(
+			WLAN_UMAC_COMP_PMO,
+			pmo_vdev_object_destroyed_notification,
+			(void *)pmo_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("unable to unregister vdev create handle");
+		goto out;
+	}
+
+out:
+	pmo_free_ctx();
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_psoc_object_created_notification(
+		struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx = NULL;
+	QDF_STATUS status;
+	struct wlan_pmo_ctx *pmo_ctx;
+
+	PMO_ENTER();
+	pmo_ctx = pmo_get_context();
+	if (!pmo_ctx) {
+		QDF_ASSERT(0);
+		pmo_err("unable to get pmo ctx");
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	psoc_ctx = qdf_mem_malloc(sizeof(*psoc_ctx));
+	if (psoc_ctx == NULL) {
+		pmo_err("Failed to allocate pmo_psoc");
+		status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	status = wlan_objmgr_psoc_component_obj_attach(psoc,
+			WLAN_UMAC_COMP_PMO,
+			psoc_ctx,
+			QDF_STATUS_SUCCESS);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("Failed to attach psoc_ctx with psoc");
+		qdf_mem_free(psoc_ctx);
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+	qdf_spinlock_create(&psoc_ctx->lock);
+	qdf_wake_lock_create(&psoc_ctx->wow.wow_wake_lock, "pmo_wow_wl");
+	status = qdf_event_create(&psoc_ctx->wow.target_suspend);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("target suspend event initialization failed");
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+	status = qdf_event_create(&psoc_ctx->wow.target_resume);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("target resume event initialization failed");
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+	/* Register PMO tx ops*/
+	target_if_pmo_register_tx_ops(&psoc_ctx->pmo_tx_ops);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_psoc_object_destroyed_notification(
+		struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx = NULL;
+	QDF_STATUS status;
+
+	PMO_ENTER();
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	status = wlan_objmgr_psoc_component_obj_detach(psoc,
+			WLAN_UMAC_COMP_PMO,
+			psoc_ctx);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("Failed to detach psoc_ctx from psoc");
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	qdf_spinlock_destroy(&psoc_ctx->lock);
+	qdf_event_destroy(&psoc_ctx->wow.target_suspend);
+	qdf_event_destroy(&psoc_ctx->wow.target_resume);
+	qdf_wake_lock_destroy(&psoc_ctx->wow.wow_wake_lock);
+	qdf_mem_zero(psoc_ctx, sizeof(*psoc_ctx));
+	qdf_mem_free(psoc_ctx);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_vdev_object_created_notification(
+		struct wlan_objmgr_vdev *vdev, void *arg)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx = NULL;
+	struct wlan_objmgr_psoc *psoc;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	QDF_STATUS status;
+
+	PMO_ENTER();
+
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+
+	vdev_ctx = qdf_mem_malloc(sizeof(*vdev_ctx));
+	if (vdev_ctx == NULL) {
+		pmo_err("Failed to allocate vdev_ctx");
+		status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	status = wlan_objmgr_vdev_component_obj_attach(vdev,
+			 WLAN_UMAC_COMP_PMO,
+			(void *)vdev_ctx, QDF_STATUS_SUCCESS);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("Failed to attach vdev_ctx with vdev");
+		qdf_mem_free(vdev_ctx);
+		goto out;
+	}
+
+	qdf_spinlock_create(&vdev_ctx->pmo_vdev_lock);
+	vdev_ctx->ptrn_match_enable =
+		psoc_ctx->psoc_cfg.ptrn_match_enable_all_vdev;
+	vdev_ctx->pmo_psoc_ctx = psoc_ctx;
+	qdf_atomic_init(&vdev_ctx->gtk_err_enable);
+
+out:
+	PMO_EXIT();
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_vdev_ready(struct wlan_objmgr_vdev *vdev)
+{
+	QDF_STATUS status;
+
+	PMO_ENTER();
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	/* Register static configuration with firmware */
+	pmo_register_wow_wakeup_events(vdev);
+	pmo_register_action_frame_patterns(vdev);
+
+	/* Register default wow patterns with firmware */
+	pmo_register_wow_default_patterns(vdev);
+
+	pmo_vdev_put_ref(vdev);
+
+	PMO_EXIT();
+
+	/*
+	 * The above APIs should return a status but don't.
+	 * Just return success for now.
+	 */
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_vdev_object_destroyed_notification(
+		struct wlan_objmgr_vdev *vdev, void *arg)
+{
+	struct pmo_vdev_priv_obj *vdev_ctx = NULL;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	PMO_ENTER();
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	status = wlan_objmgr_vdev_component_obj_detach(vdev,
+			 WLAN_UMAC_COMP_PMO,
+			(void *)vdev_ctx);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to detach vdev_ctx with vdev");
+
+	qdf_spinlock_destroy(&vdev_ctx->pmo_vdev_lock);
+	qdf_mem_free(vdev_ctx);
+
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_register_suspend_handler(
+		enum wlan_umac_comp_id id,
+		pmo_psoc_suspend_handler handler,
+		void *arg)
+{
+	struct wlan_pmo_ctx *pmo_ctx;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	PMO_ENTER();
+	pmo_ctx = pmo_get_context();
+	if (!pmo_ctx) {
+		QDF_ASSERT(0);
+		pmo_err("unable to get pmo ctx");
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	if (id > WLAN_UMAC_MAX_COMPONENTS || id < 0) {
+		pmo_err("component id: %d is %s then valid components id",
+			id, id < 0 ? "Less" : "More");
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	qdf_spin_lock_bh(&pmo_ctx->lock);
+	pmo_ctx->pmo_suspend_handler[id] = handler;
+	pmo_ctx->pmo_suspend_handler_arg[id] = arg;
+	qdf_spin_unlock_bh(&pmo_ctx->lock);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_unregister_suspend_handler(
+		enum wlan_umac_comp_id id,
+		pmo_psoc_suspend_handler handler)
+{
+	struct wlan_pmo_ctx *pmo_ctx;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	PMO_ENTER();
+	pmo_ctx = pmo_get_context();
+	if (!pmo_ctx) {
+		QDF_ASSERT(0);
+		pmo_err("unable to get pmo ctx");
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	if (id > WLAN_UMAC_MAX_COMPONENTS || id < 0) {
+		pmo_err("component id: %d is %s then valid components id",
+			id, id < 0 ? "Less" : "More");
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	qdf_spin_lock_bh(&pmo_ctx->lock);
+	if (pmo_ctx->pmo_suspend_handler[id] == handler) {
+		pmo_ctx->pmo_suspend_handler[id] = NULL;
+		pmo_ctx->pmo_suspend_handler_arg[id] = NULL;
+		qdf_spin_unlock_bh(&pmo_ctx->lock);
+	} else {
+		qdf_spin_unlock_bh(&pmo_ctx->lock);
+		pmo_err("can't find suspend handler for component id: %d ", id);
+		status = QDF_STATUS_E_FAILURE;
+	}
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_register_resume_handler(
+		enum wlan_umac_comp_id id,
+		pmo_psoc_resume_handler handler,
+		void *arg)
+{
+	struct wlan_pmo_ctx *pmo_ctx;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	PMO_ENTER();
+	pmo_ctx = pmo_get_context();
+	if (!pmo_ctx) {
+		pmo_err("unable to get pmo ctx");
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	if (id > WLAN_UMAC_MAX_COMPONENTS || id < 0) {
+		pmo_err("component id: %d is %s then valid components id",
+			id, id < 0 ? "Less" : "More");
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	qdf_spin_lock_bh(&pmo_ctx->lock);
+	pmo_ctx->pmo_resume_handler[id] = handler;
+	pmo_ctx->pmo_resume_handler_arg[id] = arg;
+	qdf_spin_unlock_bh(&pmo_ctx->lock);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_unregister_resume_handler(
+		enum wlan_umac_comp_id id,
+		pmo_psoc_resume_handler handler)
+{
+	struct wlan_pmo_ctx *pmo_ctx;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	PMO_ENTER();
+	pmo_ctx = pmo_get_context();
+	if (!pmo_ctx) {
+		pmo_err("unable to get pmo ctx");
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	if (id > WLAN_UMAC_MAX_COMPONENTS || id < 0) {
+		pmo_err("component id: %d is %s then valid components id",
+			id, id < 0 ? "Less" : "More");
+		status = QDF_STATUS_E_FAILURE;
+		goto out;
+	}
+
+	qdf_spin_lock_bh(&pmo_ctx->lock);
+	if (pmo_ctx->pmo_resume_handler[id] == handler) {
+		pmo_ctx->pmo_resume_handler[id] = NULL;
+		pmo_ctx->pmo_resume_handler_arg[id] = NULL;
+		qdf_spin_unlock_bh(&pmo_ctx->lock);
+	} else {
+		qdf_spin_unlock_bh(&pmo_ctx->lock);
+		pmo_err("can't find resume handler for component id: %d ", id);
+		status = QDF_STATUS_E_FAILURE;
+	}
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_suspend_all_components(struct wlan_objmgr_psoc *psoc,
+				      enum qdf_suspend_type suspend_type)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	QDF_STATUS resume_status;
+	struct wlan_pmo_ctx *pmo_ctx;
+	uint8_t i;
+	pmo_psoc_suspend_handler handler;
+	void *arg;
+
+	PMO_ENTER();
+
+	pmo_ctx = pmo_get_context();
+	if (!pmo_ctx) {
+		pmo_err("unable to get pmo ctx");
+		QDF_ASSERT(0);
+		status = QDF_STATUS_E_FAILURE;
+		goto exit_with_status;
+	}
+
+	/* call each component's suspend handler */
+	for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
+		qdf_spin_lock_bh(&pmo_ctx->lock);
+		handler = pmo_ctx->pmo_suspend_handler[i];
+		arg = pmo_ctx->pmo_suspend_handler_arg[i];
+		qdf_spin_unlock_bh(&pmo_ctx->lock);
+
+		if (!handler)
+			continue;
+
+		status = handler(psoc, arg);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			pmo_err("component %d failed to suspend; status: %d",
+				i, status);
+			QDF_ASSERT(0);
+			goto suspend_recovery;
+		}
+	}
+
+	goto exit_with_status;
+
+suspend_recovery:
+	/* resume, starting with the last successfully suspended component */
+	for (i -= 1; i >= 0; i--) {
+		qdf_spin_lock_bh(&pmo_ctx->lock);
+		handler = pmo_ctx->pmo_resume_handler[i];
+		arg = pmo_ctx->pmo_resume_handler_arg[i];
+		qdf_spin_unlock_bh(&pmo_ctx->lock);
+
+		if (!handler)
+			continue;
+
+		resume_status = handler(psoc, arg);
+		if (QDF_IS_STATUS_ERROR(resume_status)) {
+			pmo_fatal("Non-recoverable failure occurred!");
+			pmo_fatal("component %d failed to resume; status: %d",
+				  i, resume_status);
+			QDF_BUG(0);
+		}
+	}
+
+exit_with_status:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_resume_all_components(struct wlan_objmgr_psoc *psoc,
+				     enum qdf_suspend_type suspend_type)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_pmo_ctx *pmo_ctx;
+	uint8_t i;
+	pmo_psoc_suspend_handler handler;
+	void *arg;
+
+	PMO_ENTER();
+
+	pmo_ctx = pmo_get_context();
+	if (!pmo_ctx) {
+		pmo_err("unable to get pmo ctx");
+		QDF_ASSERT(0);
+		status = QDF_STATUS_E_FAILURE;
+		goto exit_with_status;
+	}
+
+	/* call each component's resume handler */
+	for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
+		qdf_spin_lock_bh(&pmo_ctx->lock);
+		handler = pmo_ctx->pmo_resume_handler[i];
+		arg = pmo_ctx->pmo_resume_handler_arg[i];
+		qdf_spin_unlock_bh(&pmo_ctx->lock);
+
+		if (!handler)
+			continue;
+
+		status = handler(psoc, arg);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			pmo_fatal("Non-recoverable failure occurred!");
+			pmo_fatal("component %d failed to resume; status: %d",
+				  i, status);
+			QDF_BUG(0);
+		}
+	}
+
+exit_with_status:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_register_pause_bitmap_notifier(struct wlan_objmgr_psoc *psoc,
+		pmo_notify_pause_bitmap handler)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	QDF_STATUS status;
+
+	if (!psoc) {
+		pmo_err("psoc is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!handler) {
+		pmo_err("pmo_notify_vdev_pause_bitmap is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	status = pmo_psoc_get_ref(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("pmo cannot get the reference out of psoc");
+		return status;
+	}
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	psoc_ctx->pause_bitmap_notifier = handler;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+	pmo_psoc_put_ref(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_unregister_pause_bitmap_notifier(struct wlan_objmgr_psoc *psoc,
+		pmo_notify_pause_bitmap handler)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	QDF_STATUS status;
+
+	if (!psoc) {
+		pmo_err("psoc is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!handler) {
+		pmo_err("pmo_notify_vdev_pause_bitmap is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	status = pmo_psoc_get_ref(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("pmo cannot get the reference out of psoc");
+		return status;
+	}
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	if (psoc_ctx->pause_bitmap_notifier == handler)
+		psoc_ctx->pause_bitmap_notifier = NULL;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+	pmo_psoc_put_ref(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_register_get_pause_bitmap(struct wlan_objmgr_psoc *psoc,
+		pmo_get_pause_bitmap handler)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	QDF_STATUS status;
+
+	if (!psoc) {
+		pmo_err("psoc is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!handler) {
+		pmo_err("pmo_get_pause_bitmap is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	status = pmo_psoc_get_ref(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("pmo cannot get the reference out of psoc");
+		return status;
+	}
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	psoc_ctx->get_pause_bitmap = handler;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+	pmo_psoc_put_ref(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_unregister_get_pause_bitmap(struct wlan_objmgr_psoc *psoc,
+		pmo_get_pause_bitmap handler)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	QDF_STATUS status;
+
+	if (!psoc) {
+		pmo_err("psoc is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!handler) {
+		pmo_err("pmo_get_pause_bitmap is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	status = pmo_psoc_get_ref(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("pmo cannot get the reference out of psoc");
+		return status;
+	}
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	if (psoc_ctx->get_pause_bitmap == handler)
+		psoc_ctx->get_pause_bitmap = NULL;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+	pmo_psoc_put_ref(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_register_is_device_in_low_pwr_mode(struct wlan_objmgr_psoc *psoc,
+		pmo_is_device_in_low_pwr_mode handler)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	QDF_STATUS status;
+
+	if (!psoc) {
+		pmo_err("psoc is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!handler) {
+		pmo_err("pmo_get_pause_bitmap is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	status = pmo_psoc_get_ref(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("pmo cannot get the reference out of psoc");
+		return status;
+	}
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	psoc_ctx->is_device_in_low_pwr_mode = handler;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+	pmo_psoc_put_ref(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_unregister_is_device_in_low_pwr_mode(
+			struct wlan_objmgr_psoc *psoc,
+			pmo_is_device_in_low_pwr_mode handler)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+	QDF_STATUS status;
+
+	if (!psoc) {
+		pmo_err("psoc is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!handler) {
+		pmo_err("pmo_get_pause_bitmap is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	status = pmo_psoc_get_ref(psoc);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("pmo cannot get the reference out of psoc");
+		return status;
+	}
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	qdf_spin_lock_bh(&psoc_ctx->lock);
+	psoc_ctx->is_device_in_low_pwr_mode = NULL;
+	qdf_spin_unlock_bh(&psoc_ctx->lock);
+	pmo_psoc_put_ref(psoc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_arp.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_arp.c
new file mode 100644
index 0000000..eafcbed
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_arp.c
@@ -0,0 +1,158 @@
+/*
+* Copyright (c) 2017 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: Implements public API for pmo to interact with target/WMI
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_arp_public_struct.h"
+#include "wlan_pmo_ns_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_enable_arp_offload_req(struct wlan_objmgr_vdev *vdev,
+		uint8_t vdev_id)
+{
+	struct pmo_arp_offload_params *arp_offload_req = NULL;
+	struct pmo_ns_offload_params *ns_offload_req = NULL;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	arp_offload_req = qdf_mem_malloc(sizeof(*arp_offload_req));
+	if (!arp_offload_req) {
+		pmo_err("unable to allocate arp_offload_req");
+		status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	ns_offload_req = qdf_mem_malloc(sizeof(*ns_offload_req));
+	if (!ns_offload_req) {
+		pmo_err("unable to allocate ns_offload_req");
+		status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	qdf_mem_copy(arp_offload_req, &vdev_ctx->vdev_arp_req,
+		sizeof(*arp_offload_req));
+	qdf_mem_copy(ns_offload_req, &vdev_ctx->vdev_ns_req,
+		sizeof(*ns_offload_req));
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	pmo_debug("ARP Offload vdev_id: %d enable: %d",
+		vdev_id,
+		arp_offload_req->enable);
+	pmo_debug("NS Offload vdev_id: %d enable: %d ns_count: %u",
+		vdev_id,
+		ns_offload_req->enable,
+		ns_offload_req->num_ns_offload_count);
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_arp_offload_req) {
+		pmo_err("send_arp_offload_req is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+	status = pmo_tx_ops.send_arp_offload_req(
+			vdev, arp_offload_req, ns_offload_req);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to send ARP offload");
+out:
+	if (arp_offload_req)
+		qdf_mem_free(arp_offload_req);
+	if (ns_offload_req)
+		qdf_mem_free(ns_offload_req);
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_tgt_disable_arp_offload_req(struct wlan_objmgr_vdev *vdev,
+		uint8_t vdev_id)
+{
+	struct pmo_arp_offload_params *arp_offload_req = NULL;
+	struct pmo_ns_offload_params *ns_offload_req = NULL;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	arp_offload_req = qdf_mem_malloc(sizeof(*arp_offload_req));
+	if (!arp_offload_req) {
+		pmo_err("unable to allocate arp_offload_req");
+		status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	ns_offload_req = qdf_mem_malloc(sizeof(*ns_offload_req));
+	if (!ns_offload_req) {
+		pmo_err("unable to allocate ns_offload_req");
+		status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	qdf_mem_copy(arp_offload_req, &vdev_ctx->vdev_arp_req,
+		sizeof(*arp_offload_req));
+	qdf_mem_copy(ns_offload_req, &vdev_ctx->vdev_ns_req,
+		sizeof(*ns_offload_req));
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	pmo_debug("ARP Offload vdev_id: %d enable: %d",
+		vdev_id,
+		arp_offload_req->enable);
+	pmo_debug("NS Offload vdev_id: %d enable: %d ns_count: %u",
+		vdev_id,
+		ns_offload_req->enable,
+		ns_offload_req->num_ns_offload_count);
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_arp_offload_req) {
+		pmo_err("send_arp_offload_req is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+	status = pmo_tx_ops.send_arp_offload_req(
+			vdev, arp_offload_req, ns_offload_req);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to send ARP offload");
+
+out:
+	if (arp_offload_req)
+		qdf_mem_free(arp_offload_req);
+	if (ns_offload_req)
+		qdf_mem_free(ns_offload_req);
+	PMO_EXIT();
+
+	return status;
+}
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_gtk.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_gtk.c
new file mode 100644
index 0000000..8f38278
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_gtk.c
@@ -0,0 +1,178 @@
+/*
+* Copyright (c) 2017 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: Implements public API for PMO GTK offload feature to interact
+ * with target/wmi.
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_gtk_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_send_gtk_offload_req(struct wlan_objmgr_vdev *vdev,
+		struct pmo_gtk_req *gtk_req)
+{
+	struct pmo_gtk_req *op_gtk_req = NULL;
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		pmo_err("Failed to find psoc from from vdev:%p",
+			vdev);
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_gtk_offload_req) {
+		pmo_err("send_gtk_offload_req is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	op_gtk_req = qdf_mem_malloc(sizeof(*op_gtk_req));
+	if (!op_gtk_req) {
+		pmo_err("cannot allocate op_gtk_req ");
+		status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	if (gtk_req->flags == PMO_GTK_OFFLOAD_ENABLE) {
+		qdf_atomic_set(&vdev_ctx->gtk_err_enable, true);
+		qdf_mem_copy(op_gtk_req->kck, gtk_req->kck,
+			PMO_KCK_LEN);
+		qdf_mem_copy(op_gtk_req->kek, gtk_req->kek,
+			PMO_KEK_LEN);
+		qdf_mem_copy(&op_gtk_req->replay_counter,
+			&gtk_req->replay_counter, PMO_REPLAY_COUNTER_LEN);
+	} else {
+		qdf_atomic_set(&vdev_ctx->gtk_err_enable, false);
+	}
+
+	pmo_info("replay counter %llu", op_gtk_req->replay_counter);
+	op_gtk_req->flags = gtk_req->flags;
+	status = pmo_tx_ops.send_gtk_offload_req(vdev, op_gtk_req);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to send gtk offload req event");
+out:
+	if (op_gtk_req)
+		qdf_mem_free(op_gtk_req);
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_tgt_get_gtk_rsp(struct wlan_objmgr_vdev *vdev)
+{
+
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		pmo_err("Failed to find psoc from from vdev:%p",
+			vdev);
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_get_gtk_rsp_cmd) {
+		pmo_err("send_get_gtk_rsp_cmd is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+	status = pmo_tx_ops.send_get_gtk_rsp_cmd(vdev);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to send_get_gtk_rsp_cmd  event");
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_tgt_gtk_rsp_evt(struct wlan_objmgr_psoc *psoc,
+			struct pmo_gtk_rsp_params *rsp_param)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_vdev *vdev;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+
+	PMO_ENTER();
+	if (!rsp_param) {
+		pmo_err("gtk rsp param is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	vdev = pmo_psoc_get_vdev(psoc, rsp_param->vdev_id);
+	if (!vdev) {
+		pmo_err("vdev is null vdev_id:%d psoc:%p",
+			rsp_param->vdev_id, psoc);
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto out;
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	status = pmo_get_vdev_bss_peer_mac_addr(vdev, &rsp_param->bssid);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("cannot find peer mac address");
+		goto dec_ref;
+	}
+
+	/* update cached replay counter */
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	vdev_ctx->vdev_gtk_req.replay_counter = rsp_param->replay_counter;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	if (vdev_ctx->vdev_gtk_rsp_req.callback) {
+		pmo_info("callback:%p context:%p psoc:%p vdev_id:%d",
+			vdev_ctx->vdev_gtk_rsp_req.callback,
+			vdev_ctx->vdev_gtk_rsp_req.callback_context,
+			psoc, rsp_param->vdev_id);
+		vdev_ctx->vdev_gtk_rsp_req.callback(
+			vdev_ctx->vdev_gtk_rsp_req.callback_context,
+			rsp_param);
+	} else {
+		pmo_err("gtk rsp callback is null for vdev_id:%d psoc %p",
+			rsp_param->vdev_id,
+			psoc);
+	}
+
+dec_ref:
+	pmo_vdev_put_ref(vdev);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_hw_filter.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_hw_filter.c
new file mode 100644
index 0000000..1d29826
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_hw_filter.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2017 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: Implements public API for pmo to interact with target/WMI
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_hw_filter_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_conf_hw_filter(struct wlan_objmgr_psoc *psoc,
+				  struct pmo_hw_filter_params *req)
+{
+	QDF_STATUS status;
+	struct wlan_pmo_tx_ops ops;
+
+	PMO_ENTER();
+
+	pmo_debug("Configure hw filter; vdev_id:%u, mode:%d",
+		  req->vdev_id, req->mode);
+
+	ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!ops.send_conf_hw_filter_req) {
+		pmo_err("send_conf_hw_filter_req is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto exit_with_status;
+	}
+
+	status = ops.send_conf_hw_filter_req(psoc, req);
+
+exit_with_status:
+	PMO_EXIT();
+
+	return status;
+}
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_lphb.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_lphb.c
new file mode 100644
index 0000000..5dce758
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_lphb.c
@@ -0,0 +1,155 @@
+/*
+* Copyright (c) 2017 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: Implements public API for pmo low power hear beat feature
+ * to interact with target/WMI.
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_lphb_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_send_lphb_enable(struct wlan_objmgr_psoc *psoc,
+		struct pmo_lphb_enable_req *ts_lphb_enable)
+{
+	QDF_STATUS status;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_lphb_enable) {
+		pmo_err("send_lphb_enable is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+	status = pmo_tx_ops.send_lphb_enable(psoc, ts_lphb_enable);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to send lphb enable");
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_tgt_send_lphb_tcp_params(struct wlan_objmgr_psoc *psoc,
+		struct pmo_lphb_tcp_params *ts_lphb_tcp_param)
+{
+	QDF_STATUS status;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_lphb_tcp_params) {
+		pmo_err("send_lphb_tcp_params is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+	status = pmo_tx_ops.send_lphb_tcp_params(psoc, ts_lphb_tcp_param);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to send lphb tcp params");
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_tgt_send_lphb_tcp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+		struct pmo_lphb_tcp_filter_req *ts_lphb_tcp_filter)
+{
+	QDF_STATUS status;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_lphb_tcp_filter_req) {
+		pmo_err("send_lphb_tcp_filter_req is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+	status = pmo_tx_ops.send_lphb_tcp_filter_req(psoc, ts_lphb_tcp_filter);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to send lphb tcp filter req");
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_tgt_send_lphb_udp_params(struct wlan_objmgr_psoc *psoc,
+		struct pmo_lphb_udp_params *ts_lphb_udp_param)
+{
+	QDF_STATUS status;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_lphb_upd_params) {
+		pmo_err("send_lphb_upd_params is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+	status = pmo_tx_ops.send_lphb_upd_params(psoc, ts_lphb_udp_param);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to send lphb udp param");
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_tgt_send_lphb_udp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+		struct pmo_lphb_udp_filter_req *ts_lphb_udp_filter)
+{
+	QDF_STATUS status;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_lphb_udp_filter_req) {
+		pmo_err("send_lphb_udp_filter_req is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+	status = pmo_tx_ops.send_lphb_udp_filter_req(psoc, ts_lphb_udp_filter);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to send lphb udp filter req");
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_tgt_lphb_rsp_evt(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_rsp *rsp_param)
+{
+	struct pmo_psoc_priv_obj *psoc_ctx;
+
+	psoc_ctx = pmo_psoc_get_priv(psoc);
+	if (psoc_ctx->wow.lphb_cb && psoc_ctx->wow.lphb_cb_ctx) {
+		pmo_info("callback:%p context:%p psoc:%p",
+			psoc_ctx->wow.lphb_cb, psoc_ctx->wow.lphb_cb_ctx, psoc);
+		psoc_ctx->wow.lphb_cb(psoc_ctx->wow.lphb_cb_ctx, rsp_param);
+	} else {
+		pmo_err("lphb rsp callback/context is null for psoc %p",
+			psoc);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_mc_addr_filtering.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_mc_addr_filtering.c
new file mode 100644
index 0000000..9cc0563
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_mc_addr_filtering.c
@@ -0,0 +1,83 @@
+/*
+* Copyright (c) 2017 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: Implements public API for pmo to interact with target/WMI
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_mc_addr_filtering_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_set_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+		struct qdf_mac_addr multicast_addr)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_set_mc_filter_req) {
+		pmo_err("send_add_clear_mcbc_filter_request is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_tx_ops.send_set_mc_filter_req(
+			vdev, multicast_addr);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to add/clear mc filter");
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_tgt_clear_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+		struct qdf_mac_addr multicast_addr)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_clear_mc_filter_req) {
+		pmo_err("send_add_clear_mcbc_filter_request is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_tx_ops.send_clear_mc_filter_req(
+			vdev, multicast_addr);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to add/clear mc filter");
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_ns.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_ns.c
new file mode 100644
index 0000000..9757cad
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_ns.c
@@ -0,0 +1,159 @@
+/*
+* Copyright (c) 2017 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: Implements public API for PMO NS offload feature to interact
+ * with target/wmi.
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_arp_public_struct.h"
+#include "wlan_pmo_ns_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_enable_ns_offload_req(struct wlan_objmgr_vdev *vdev,
+		uint8_t vdev_id)
+{
+	struct pmo_arp_offload_params *arp_offload_req = NULL;
+	struct pmo_ns_offload_params *ns_offload_req = NULL;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	arp_offload_req = qdf_mem_malloc(sizeof(*arp_offload_req));
+	if (!arp_offload_req) {
+		pmo_err("unable to allocate arp_offload_req");
+		status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	ns_offload_req = qdf_mem_malloc(sizeof(*ns_offload_req));
+	if (!ns_offload_req) {
+		pmo_err("unable to allocate ns_offload_req");
+		status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	qdf_mem_copy(arp_offload_req, &vdev_ctx->vdev_arp_req,
+		sizeof(*arp_offload_req));
+	qdf_mem_copy(ns_offload_req, &vdev_ctx->vdev_ns_req,
+		sizeof(*ns_offload_req));
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	pmo_debug("ARP Offload vdev_id: %d enable: %d",
+		vdev_id,
+		arp_offload_req->enable);
+	pmo_debug("NS Offload vdev_id: %d enable: %d ns_count: %u",
+		vdev_id,
+		ns_offload_req->enable,
+		ns_offload_req->num_ns_offload_count);
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_ns_offload_req) {
+		pmo_err("send_ns_offload_req is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+	status = pmo_tx_ops.send_ns_offload_req(
+			vdev, arp_offload_req, ns_offload_req);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to send NS offload");
+
+out:
+	if (arp_offload_req)
+		qdf_mem_free(arp_offload_req);
+	if (ns_offload_req)
+		qdf_mem_free(ns_offload_req);
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_tgt_disable_ns_offload_req(struct wlan_objmgr_vdev *vdev,
+		uint8_t vdev_id)
+{
+	struct pmo_arp_offload_params *arp_offload_req = NULL;
+	struct pmo_ns_offload_params *ns_offload_req = NULL;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	arp_offload_req = qdf_mem_malloc(sizeof(*arp_offload_req));
+	if (!arp_offload_req) {
+		pmo_err("unable to allocate arp_offload_req");
+		status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	ns_offload_req = qdf_mem_malloc(sizeof(*ns_offload_req));
+	if (!ns_offload_req) {
+		pmo_err("unable to allocate ns_offload_req");
+		status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	qdf_mem_copy(arp_offload_req, &vdev_ctx->vdev_arp_req,
+		sizeof(*arp_offload_req));
+	qdf_mem_copy(ns_offload_req, &vdev_ctx->vdev_ns_req,
+		sizeof(*ns_offload_req));
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	pmo_debug("ARP Offload vdev_id: %d enable: %d",
+		vdev_id,
+		arp_offload_req->enable);
+	pmo_debug("NS Offload vdev_id: %d enable: %d ns_count: %u",
+		vdev_id,
+		ns_offload_req->enable,
+		ns_offload_req->num_ns_offload_count);
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_ns_offload_req) {
+		pmo_err("send_ns_offload_req is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+	status = pmo_tx_ops.send_ns_offload_req(
+			vdev, arp_offload_req, ns_offload_req);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to send NS offload");
+
+out:
+	if (arp_offload_req)
+		qdf_mem_free(arp_offload_req);
+	if (ns_offload_req)
+		qdf_mem_free(ns_offload_req);
+	PMO_EXIT();
+
+	return status;
+}
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_pkt_filter.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_pkt_filter.c
new file mode 100644
index 0000000..6b46ede
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_pkt_filter.c
@@ -0,0 +1,156 @@
+/*
+* Copyright (c) 2017 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: Implements public API for pmo to interact with target/WMI
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_pkt_filter_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_set_pkt_filter(struct wlan_objmgr_vdev *vdev,
+		struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req,
+		uint8_t vdev_id)
+{
+	QDF_STATUS status;
+	struct pmo_rcv_pkt_fltr_cfg *request_buf = NULL;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+	struct qdf_mac_addr peer_bssid;
+
+	PMO_ENTER();
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		pmo_err("psoc unavailable for vdev %p", vdev);
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	pmo_info("filter_type=%d, filter_id = %d",
+				pmo_set_pkt_fltr_req->filter_type,
+				pmo_set_pkt_fltr_req->filter_id);
+
+	request_buf = qdf_mem_malloc(sizeof(*request_buf));
+
+	if (request_buf == NULL) {
+		pmo_err("Not able to allocate memory for Receive Filter Set Filter request");
+		status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	status = pmo_get_vdev_bss_peer_mac_addr(vdev,
+			&peer_bssid);
+	if (status != QDF_STATUS_SUCCESS) {
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	qdf_mem_copy(request_buf, pmo_set_pkt_fltr_req, sizeof(*request_buf));
+
+	qdf_mem_copy(&request_buf->self_macaddr.bytes,
+			  wlan_vdev_mlme_get_macaddr(vdev),
+			  QDF_MAC_ADDR_SIZE);
+
+	qdf_copy_macaddr(&pmo_set_pkt_fltr_req->bssid,
+				&peer_bssid);
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_set_pkt_filter) {
+		pmo_err("send_set_pkt_filter is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_tx_ops.send_set_pkt_filter(vdev, request_buf);
+	if (status != QDF_STATUS_SUCCESS)
+		goto out;
+
+out:
+	if (request_buf)
+		qdf_mem_free(request_buf);
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_tgt_clear_pkt_filter(struct wlan_objmgr_vdev *vdev,
+		struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_param,
+		uint8_t vdev_id)
+{
+	QDF_STATUS status;
+	struct pmo_rcv_pkt_fltr_clear_param *request_buf = NULL;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+	struct qdf_mac_addr peer_bssid;
+
+	PMO_ENTER();
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		pmo_err("psoc unavailable for vdev %p", vdev);
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	pmo_info("filter_id = %d", pmo_clr_pkt_fltr_param->filter_id);
+
+	request_buf = qdf_mem_malloc(sizeof(*request_buf));
+
+	if (request_buf == NULL) {
+		pmo_err("Not able to allocate memory for Receive Filter Set Filter request");
+		status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	status = pmo_get_vdev_bss_peer_mac_addr(vdev,
+			&peer_bssid);
+	if (status != QDF_STATUS_SUCCESS) {
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	qdf_mem_copy(request_buf, pmo_clr_pkt_fltr_param, sizeof(*request_buf));
+
+	qdf_mem_copy(&request_buf->self_macaddr.bytes,
+			  wlan_vdev_mlme_get_macaddr(vdev),
+			  QDF_MAC_ADDR_SIZE);
+
+	qdf_copy_macaddr(&pmo_clr_pkt_fltr_param->bssid,
+			 &peer_bssid);
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_clear_pkt_filter) {
+		pmo_err("send_clear_pkt_filter is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_tx_ops.send_clear_pkt_filter(vdev, request_buf);
+	if (status != QDF_STATUS_SUCCESS)
+		goto out;
+
+out:
+	if (request_buf)
+		qdf_mem_free(request_buf);
+	PMO_EXIT();
+
+	return status;
+}
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_static_config.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_static_config.c
new file mode 100644
index 0000000..bd322f9
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_static_config.c
@@ -0,0 +1,127 @@
+/*
+* Copyright (c) 2017 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: Implements public API for pmo to interact with target/WMI
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_wow.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_send_enhance_multicast_offload_req(
+		struct wlan_objmgr_vdev *vdev,
+		uint8_t vdev_id,
+		uint8_t action)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_enhance_mc_offload_req) {
+		pmo_err("send_enhance_multicast_offload is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_tx_ops.send_enhance_mc_offload_req(vdev, action);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to config enhance multicast offload");
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_tgt_send_ra_filter_req(struct wlan_objmgr_vdev *vdev)
+{
+
+	QDF_STATUS status;
+	uint8_t default_pattern;
+	uint16_t ra_interval;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	vdev_id = pmo_vdev_get_id(vdev);
+	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+	ra_interval = vdev_ctx->pmo_psoc_ctx->psoc_cfg.ra_ratelimit_interval;
+	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+	pmo_debug("send RA rate limit [%d] to fw vdev = %d",
+		 ra_interval, vdev_id);
+
+	default_pattern = pmo_get_and_increment_wow_default_ptrn(vdev_ctx);
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_ra_filter_req) {
+		pmo_err("send_ra_filter_cmd is null");
+		status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	status = pmo_tx_ops.send_ra_filter_req(
+			vdev, default_pattern, ra_interval);
+	if (status != QDF_STATUS_SUCCESS) {
+		pmo_err("Failed to send RA rate limit to fw");
+		pmo_decrement_wow_default_ptrn(vdev_ctx);
+	}
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_tgt_send_action_frame_pattern_req(
+		struct wlan_objmgr_vdev *vdev,
+		struct pmo_action_wakeup_set_params *cmd)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_action_frame_pattern_req) {
+		pmo_err("send_add_action_frame_pattern_cmd is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_tx_ops.send_action_frame_pattern_req(vdev, cmd);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to add  filter");
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_suspend_resume.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_suspend_resume.c
new file mode 100644
index 0000000..13e89c5
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_suspend_resume.c
@@ -0,0 +1,215 @@
+/*
+* Copyright (c) 2017 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: Implements public API for pmo to interact with target/WMI
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_wow.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_vdev_update_param_req(struct wlan_objmgr_vdev *vdev,
+		enum pmo_vdev_param_id param_id, uint32_t param_value)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_vdev_param_update_req) {
+		pmo_err("send_vdev_param_update_req is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_tx_ops.send_vdev_param_update_req(vdev, param_id,
+			param_value);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_tgt_send_vdev_sta_ps_param(struct wlan_objmgr_vdev *vdev,
+		enum pmo_sta_powersave_param ps_param, uint32_t param_value)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_vdev_sta_ps_param_req) {
+		pmo_err("send_vdev_param_set_req is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	status = pmo_tx_ops.send_vdev_sta_ps_param_req(vdev, ps_param,
+			param_value);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+void pmo_tgt_psoc_update_wow_bus_suspend_state(struct wlan_objmgr_psoc *psoc,
+		uint8_t val)
+{
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.psoc_update_wow_bus_suspend) {
+		pmo_err("psoc_update_wow_bus_suspend is null");
+		return;
+	}
+	pmo_tx_ops.psoc_update_wow_bus_suspend(psoc, val);
+}
+
+int pmo_tgt_psoc_get_host_credits(struct wlan_objmgr_psoc *psoc)
+{
+
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.psoc_get_host_credits) {
+		pmo_err("psoc_get_host_credits is null");
+		return 0;
+	}
+
+	return pmo_tx_ops.psoc_get_host_credits(psoc);
+}
+
+int pmo_tgt_psoc_get_pending_cmnds(struct wlan_objmgr_psoc *psoc)
+{
+
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.psoc_get_pending_cmnds) {
+		pmo_err("psoc_get_pending_cmnds is null");
+		return -EAGAIN;
+	}
+
+	return pmo_tx_ops.psoc_get_pending_cmnds(psoc);
+}
+
+void pmo_tgt_update_target_suspend_flag(struct wlan_objmgr_psoc *psoc,
+		uint8_t val)
+{
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.update_target_suspend_flag) {
+		pmo_err("update_target_suspend_flag is null");
+		return;
+	}
+	pmo_tx_ops.update_target_suspend_flag(psoc, val);
+}
+
+QDF_STATUS pmo_tgt_psoc_send_wow_enable_req(struct wlan_objmgr_psoc *psoc,
+	struct pmo_wow_cmd_params *param)
+{
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.psoc_send_wow_enable_req) {
+		pmo_err("psoc_send_wow_enable_req is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	return pmo_tx_ops.psoc_send_wow_enable_req(psoc, param);
+}
+
+QDF_STATUS pmo_tgt_psoc_send_supend_req(struct wlan_objmgr_psoc *psoc,
+		struct pmo_suspend_params *param)
+{
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.psoc_send_supend_req) {
+		pmo_err("psoc_send_supend_req is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	return pmo_tx_ops.psoc_send_supend_req(psoc, param);
+}
+
+QDF_STATUS pmo_tgt_psoc_set_runtime_pm_inprogress(struct wlan_objmgr_psoc *psoc,
+						  bool value)
+{
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.psoc_set_runtime_pm_in_progress) {
+		pmo_err("pmo ops is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	pmo_tx_ops.psoc_set_runtime_pm_in_progress(psoc, value);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+bool pmo_tgt_psoc_get_runtime_pm_in_progress(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.psoc_get_runtime_pm_in_progress) {
+		pmo_err("psoc_get_runtime_pm_in_progress is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	return pmo_tx_ops.psoc_get_runtime_pm_in_progress(psoc);
+}
+
+QDF_STATUS pmo_tgt_psoc_send_host_wakeup_ind(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.psoc_send_host_wakeup_ind) {
+		pmo_err("psoc_send_host_wakeup_ind is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	return pmo_tx_ops.psoc_send_host_wakeup_ind(psoc);
+}
+
+QDF_STATUS pmo_tgt_psoc_send_target_resume_req(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.psoc_send_target_resume_req) {
+		pmo_err("send_target_resume_req is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	return pmo_tx_ops.psoc_send_target_resume_req(psoc);
+}
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_wow.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_wow.c
new file mode 100644
index 0000000..c3e9826
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_wow.c
@@ -0,0 +1,121 @@
+/*
+* Copyright (c) 2017 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: Implements public API for pmo to interact with target/WMI
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_wow.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_enable_wow_wakeup_event(
+		struct wlan_objmgr_vdev *vdev,
+		uint32_t *bitmap)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_enable_wow_wakeup_event_req) {
+		pmo_err("send_enable_wow_wakeup_event_req is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+	status = pmo_tx_ops.send_enable_wow_wakeup_event_req(vdev, bitmap);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to enable wow wakeup event");
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_tgt_disable_wow_wakeup_event(
+		struct wlan_objmgr_vdev *vdev,
+		uint32_t *bitmap)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_disable_wow_wakeup_event_req) {
+		pmo_err("send_disable_wow_wakeup_event_req is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+	status = pmo_tx_ops.send_disable_wow_wakeup_event_req(vdev, bitmap);
+	if (status != QDF_STATUS_SUCCESS)
+		pmo_err("Failed to disable wow wakeup event");
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_tgt_send_wow_patterns_to_fw(
+		struct wlan_objmgr_vdev *vdev, uint8_t ptrn_id,
+		const uint8_t *ptrn, uint8_t ptrn_len,
+		uint8_t ptrn_offset, const uint8_t *mask,
+		uint8_t mask_len, bool user)
+{
+	QDF_STATUS status;
+	struct pmo_vdev_priv_obj *vdev_ctx;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_pmo_tx_ops pmo_tx_ops;
+
+	PMO_ENTER();
+	psoc = pmo_vdev_get_psoc(vdev);
+
+	vdev_ctx = pmo_vdev_get_priv(vdev);
+
+	pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+	if (!pmo_tx_ops.send_add_wow_pattern) {
+		pmo_err("send_add_wow_pattern is null");
+		status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+	status = pmo_tx_ops.send_add_wow_pattern(
+				vdev, ptrn_id, ptrn,
+				ptrn_len, ptrn_offset, mask,
+				mask_len, user);
+	if (status != QDF_STATUS_SUCCESS) {
+		if (!user)
+			pmo_decrement_wow_default_ptrn(vdev_ctx);
+		pmo_err("Failed to sen wow pattern event");
+		goto out;
+	}
+
+	if (user)
+		pmo_increment_wow_user_ptrn(vdev_ctx);
+out:
+	PMO_EXIT();
+
+	return status;
+}
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c
new file mode 100644
index 0000000..c1a19cb
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c
@@ -0,0 +1,342 @@
+/*
+* Copyright (c) 2017 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: public API related to the pmo called by north bound HDD/OSIF
+ */
+
+#include "wlan_pmo_ucfg_api.h"
+#include "wlan_pmo_arp.h"
+#include "wlan_pmo_ns.h"
+#include "wlan_pmo_gtk.h"
+#include "wlan_pmo_wow.h"
+#include "wlan_pmo_mc_addr_filtering.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_lphb.h"
+#include "wlan_pmo_suspend_resume.h"
+#include "wlan_pmo_pkt_filter.h"
+#include "wlan_pmo_hw_filter.h"
+
+QDF_STATUS pmo_ucfg_get_psoc_config(struct wlan_objmgr_psoc *psoc,
+		struct pmo_psoc_cfg *psoc_cfg)
+{
+	return pmo_core_get_psoc_config(psoc, psoc_cfg);
+}
+
+QDF_STATUS pmo_ucfg_update_psoc_config(struct wlan_objmgr_psoc *psoc,
+		struct pmo_psoc_cfg *psoc_cfg)
+{
+	return pmo_core_update_psoc_config(psoc, psoc_cfg);
+}
+
+bool pmo_ucfg_is_ap_mode_supports_arp_ns(struct wlan_objmgr_psoc *psoc,
+	enum tQDF_ADAPTER_MODE vdev_opmode)
+{
+	return pmo_core_is_ap_mode_supports_arp_ns(psoc, vdev_opmode);
+}
+
+bool pmo_ucfg_is_vdev_connected(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_is_vdev_connected(vdev);
+}
+
+bool pmo_ucfg_is_vdev_supports_offload(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_is_vdev_supports_offload(vdev);
+}
+
+void pmo_ucfg_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+	uint32_t vdev_id, uint32_t *bitmap)
+{
+	pmo_core_enable_wakeup_event(psoc, vdev_id, bitmap);
+}
+
+void pmo_ucfg_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+	uint32_t vdev_id, uint32_t bitmap)
+{
+	pmo_core_disable_wakeup_event(psoc, vdev_id, &bitmap);
+}
+
+QDF_STATUS pmo_ucfg_cache_arp_offload_req(struct pmo_arp_req *arp_req)
+{
+	return pmo_core_cache_arp_offload_req(arp_req);
+}
+
+QDF_STATUS pmo_ucfg_flush_arp_offload_req(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_flush_arp_offload_req(vdev);
+}
+
+QDF_STATUS pmo_ucfg_enable_arp_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger)
+{
+	return pmo_core_enable_arp_offload_in_fwr(vdev, trigger);
+}
+
+QDF_STATUS pmo_ucfg_disable_arp_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger)
+{
+	return pmo_core_disable_arp_offload_in_fwr(vdev, trigger);
+}
+
+QDF_STATUS pmo_ucfg_cache_ns_offload_req(struct pmo_ns_req *ns_req)
+{
+	return pmo_core_cache_ns_offload_req(ns_req);
+}
+
+QDF_STATUS pmo_ucfg_flush_ns_offload_req(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_flush_ns_offload_req(vdev);
+}
+
+QDF_STATUS pmo_ucfg_enable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger)
+{
+	return pmo_core_enable_ns_offload_in_fwr(vdev, trigger);
+}
+
+QDF_STATUS pmo_ucfg_disable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+		enum pmo_offload_trigger trigger)
+{
+	return pmo_core_disable_ns_offload_in_fwr(vdev, trigger);
+}
+
+QDF_STATUS pmo_ucfg_cache_mc_addr_list(
+		struct pmo_mc_addr_list_params *mc_list_config)
+{
+	return pmo_core_cache_mc_addr_list(mc_list_config);
+}
+
+QDF_STATUS pmo_ucfg_flush_mc_addr_list(struct wlan_objmgr_psoc *psoc,
+	uint8_t vdev_id)
+{
+	return pmo_core_flush_mc_addr_list(psoc, vdev_id);
+}
+
+QDF_STATUS pmo_ucfg_enable_mc_addr_filtering_in_fwr(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id,
+		enum pmo_offload_trigger trigger)
+{
+	return pmo_core_enable_mc_addr_filtering_in_fwr(psoc,
+			vdev_id, trigger);
+}
+
+QDF_STATUS pmo_ucfg_disable_mc_addr_filtering_in_fwr(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t vdev_id,
+		enum pmo_offload_trigger trigger)
+{
+	return pmo_core_disable_mc_addr_filtering_in_fwr(psoc,
+			vdev_id, trigger);
+}
+
+uint8_t pmo_ucfg_max_mc_addr_supported(struct wlan_objmgr_psoc *psoc)
+{
+	return pmo_core_max_mc_addr_supported(psoc);
+}
+
+QDF_STATUS pmo_ucfg_cache_gtk_offload_req(struct wlan_objmgr_vdev *vdev,
+		struct pmo_gtk_req *gtk_req)
+{
+	return pmo_core_cache_gtk_offload_req(vdev, gtk_req);
+}
+
+QDF_STATUS pmo_ucfg_flush_gtk_offload_req(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_flush_gtk_offload_req(vdev);
+}
+
+QDF_STATUS pmo_ucfg_enable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_enable_gtk_offload_in_fwr(vdev);
+}
+
+QDF_STATUS pmo_ucfg_disable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_disable_gtk_offload_in_fwr(vdev);
+}
+
+QDF_STATUS pmo_ucfg_set_pkt_filter(struct wlan_objmgr_psoc *psoc,
+		struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req,
+		uint8_t vdev_id)
+{
+	return pmo_core_set_pkt_filter(psoc, pmo_set_pkt_fltr_req, vdev_id);
+}
+
+QDF_STATUS pmo_ucfg_clear_pkt_filter(struct wlan_objmgr_psoc *psoc,
+		struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_param,
+		uint8_t vdev_id)
+{
+	return pmo_core_clear_pkt_filter(psoc,
+				pmo_clr_pkt_fltr_param, vdev_id);
+}
+
+QDF_STATUS pmo_ucfg_get_gtk_rsp(struct wlan_objmgr_vdev *vdev,
+		struct pmo_gtk_rsp_req *gtk_rsp_req)
+{
+	return pmo_core_get_gtk_rsp(vdev, gtk_rsp_req);
+}
+
+void pmo_ucfg_update_extscan_in_progress(struct wlan_objmgr_vdev *vdev,
+	bool value)
+{
+	pmo_core_update_extscan_in_progress(vdev, value);
+}
+
+void pmo_ucfg_update_p2plo_in_progress(struct wlan_objmgr_vdev *vdev,
+	bool value)
+{
+	pmo_core_update_p2plo_in_progress(vdev, value);
+}
+
+QDF_STATUS pmo_ucfg_lphb_config_req(struct wlan_objmgr_psoc *psoc,
+		struct pmo_lphb_req *lphb_req, void *lphb_cb_ctx,
+		pmo_lphb_callback callback)
+{
+	return pmo_core_lphb_config_req(psoc, lphb_req, lphb_cb_ctx, callback);
+}
+
+void pmo_ucfg_update_alt_modulated_dtim_enable(struct wlan_objmgr_vdev *vdev,
+	bool value)
+{
+	pmo_core_update_alt_modulated_dtim_enable(vdev, value);
+}
+
+void pmo_ucfg_psoc_update_power_save_mode(struct wlan_objmgr_psoc *psoc,
+	uint8_t value)
+{
+	pmo_core_psoc_update_power_save_mode(psoc, value);
+}
+
+void pmo_ucfg_psoc_update_dp_handle(struct wlan_objmgr_psoc *psoc,
+		void *dp_handle)
+{
+	pmo_core_psoc_update_dp_handle(psoc, dp_handle);
+}
+
+void pmo_ucfg_vdev_update_dp_handle(struct wlan_objmgr_vdev *vdev,
+		void *dp_handle)
+{
+	pmo_core_vdev_update_dp_handle(vdev, dp_handle);
+}
+
+void pmo_ucfg_psoc_update_htc_handle(struct wlan_objmgr_psoc *psoc,
+		void *htc_handle)
+{
+	pmo_core_psoc_update_htc_handle(psoc, htc_handle);
+}
+
+void pmo_ucfg_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc,
+		void *hif_handle)
+{
+	pmo_core_psoc_set_hif_handle(psoc, hif_handle);
+}
+
+void pmo_ucfg_psoc_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+		void *txrx_handle)
+{
+	pmo_core_psoc_set_txrx_handle(psoc, txrx_handle);
+}
+
+void pmo_ucfg_psoc_handle_initial_wake_up(void *cb_ctx)
+{
+	return pmo_core_psoc_handle_initial_wake_up(cb_ctx);
+}
+
+QDF_STATUS pmo_ucfg_psoc_user_space_suspend_req(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type)
+{
+	return pmo_core_psoc_user_space_suspend_req(psoc, type);
+}
+
+
+QDF_STATUS pmo_ucfg_psoc_user_space_resume_req(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type)
+{
+	return pmo_core_psoc_user_space_resume_req(psoc, type);
+}
+
+QDF_STATUS pmo_ucfg_psoc_bus_suspend_req(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type,
+		struct pmo_wow_enable_params *wow_params)
+{
+	return pmo_core_psoc_bus_suspend_req(psoc, type, wow_params);
+}
+
+#ifdef FEATURE_RUNTIME_PM
+QDF_STATUS pmo_ucfg_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc,
+					     pmo_pld_auto_suspend_cb pld_cb)
+{
+	return pmo_core_psoc_bus_runtime_suspend(psoc, pld_cb);
+}
+
+QDF_STATUS pmo_ucfg_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc,
+					    pmo_pld_auto_suspend_cb pld_cb)
+{
+	return pmo_core_psoc_bus_runtime_resume(psoc, pld_cb);
+}
+#endif
+
+QDF_STATUS pmo_ucfg_psoc_suspend_target(struct wlan_objmgr_psoc *psoc,
+		int disable_target_intr)
+{
+	return pmo_core_psoc_suspend_target(psoc, disable_target_intr);
+}
+
+QDF_STATUS pmo_ucfg_psoc_bus_resume_req(struct wlan_objmgr_psoc *psoc,
+		enum qdf_suspend_type type)
+{
+	return pmo_core_psoc_bus_resume_req(psoc, type);
+}
+
+bool pmo_ucfg_get_wow_bus_suspend(struct wlan_objmgr_psoc *psoc)
+{
+	return pmo_core_get_wow_bus_suspend(psoc);
+}
+
+int pmo_ucfg_psoc_is_target_wake_up_received(struct wlan_objmgr_psoc *psoc)
+{
+	return pmo_core_psoc_is_target_wake_up_received(psoc);
+}
+
+int pmo_ucfg_psoc_clear_target_wake_up(struct wlan_objmgr_psoc *psoc)
+{
+	return pmo_core_psoc_clear_target_wake_up(psoc);
+}
+
+void pmo_ucfg_psoc_target_suspend_acknowledge(void *context, bool wow_nack)
+{
+	pmo_core_psoc_target_suspend_acknowledge(context, wow_nack);
+}
+
+void pmo_ucfg_psoc_wakeup_host_event_received(struct wlan_objmgr_psoc *psoc)
+{
+	pmo_core_psoc_wakeup_host_event_received(psoc);
+}
+
+QDF_STATUS pmo_ucfg_enable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_enable_hw_filter_in_fwr(vdev);
+}
+
+QDF_STATUS pmo_ucfg_disable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_disable_hw_filter_in_fwr(vdev);
+}
+
+
diff --git a/components/target_if/pmo/inc/target_if_pmo.h b/components/target_if/pmo/inc/target_if_pmo.h
new file mode 100644
index 0000000..cb3bea6
--- /dev/null
+++ b/components/target_if/pmo/inc/target_if_pmo.h
@@ -0,0 +1,407 @@
+/*
+* Copyright (c) 2017 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: Declare various api/struct which shall be used
+* by pmo component for wmi cmd (tx path) and
+* event (rx) handling.
+*/
+
+#ifndef _TARGET_IF_PMO_H_
+#define _TARGET_IF_PMO_H_
+
+#include "target_if.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+/**
+ * target_if_pmo_enable_wow_wakeup_event() - Enable wow wakeup events.
+ * @vdev:objmgr vdev handle
+ * @bitmap: Event bitmap
+ * @enable: enable/disable
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_enable_wow_wakeup_event(struct wlan_objmgr_vdev *vdev,
+		uint32_t *bitmap);
+
+/**
+ * target_if_pmo_disable_wow_wakeup_event() -  Disable wow wakeup events.
+ * @vdev:objmgr vdev handle
+ * @bitmap: Event bitmap
+ * @enable: enable/disable
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_disable_wow_wakeup_event(
+		struct wlan_objmgr_vdev *vdev, uint32_t *bitmap);
+
+/**
+ * target_if_pmo_send_wow_patterns_to_fw() - Sends WOW patterns to FW.
+ * @vdev: objmgr vdev handle
+ * @ptrn_id: pattern id
+ * @ptrn: pattern
+ * @ptrn_len: pattern length
+ * @ptrn_offset: pattern offset
+ * @mask: mask
+ * @mask_len: mask length
+ * @user: true for user configured pattern and false for default pattern
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_wow_patterns_to_fw(struct wlan_objmgr_vdev *vdev,
+		uint8_t ptrn_id,
+		const uint8_t *ptrn, uint8_t ptrn_len,
+		uint8_t ptrn_offset, const uint8_t *mask,
+		uint8_t mask_len, bool user);
+
+/**
+ * target_if_pmo_send_enhance_mc_offload_req() - send enhance mc offload req
+ * @vdev: objmgr vdev
+ * @action: enable or disable enhance multicast offload
+ *
+ * Return: QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS target_if_pmo_send_enhance_mc_offload_req(
+		struct wlan_objmgr_vdev *vdev,
+		bool enable);
+
+/**
+ * target_if_pmo_set_mc_filter_req() - set mcast filter command to fw
+ * @vdev: objmgr vdev handle
+ * @multicastAddr: mcast address
+ *
+ * Return: 0 for success or error code
+ */
+QDF_STATUS target_if_pmo_set_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+		struct qdf_mac_addr multicast_addr);
+
+/**
+ * target_if_pmo_clear_mc_filter_req() - clear mcast filter command to fw
+ * @vdev: objmgr vdev handle
+ * @multicastAddr: mcast address
+ *
+ * Return: 0 for success or error code
+ */
+QDF_STATUS target_if_pmo_clear_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+		struct qdf_mac_addr multicast_addr);
+
+/**
+ * target_if_pmo_send_ra_filter_req() - set RA filter pattern in fw
+ * @vdev: objmgr vdev handle
+ * @default_pattern: default pattern id
+ * @rate_limit_interval: ra rate limit interval
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_ra_filter_req(struct wlan_objmgr_vdev *vdev,
+		uint8_t default_pattern, uint16_t rate_limit_interval);
+
+/**
+ * target_if_pmo_send_action_frame_patterns() - register action frame map to fw
+ * @handle: Pointer to wma handle
+ * @vdev_id: VDEV ID
+ *
+ * This is called to push action frames wow patterns from local
+ * cache to firmware.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS target_if_pmo_send_action_frame_patterns(
+		struct wlan_objmgr_vdev *vdev,
+		struct pmo_action_wakeup_set_params *ip_cmd);
+
+/**
+ * target_if_pmo_conf_hw_filter() - configure hardware filter in DTIM mode
+ * @psoc: the psoc containing the vdev to configure
+ * @req: the request parameters
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS target_if_pmo_conf_hw_filter(struct wlan_objmgr_psoc *psoc,
+					struct pmo_hw_filter_params *req);
+
+/**
+ * target_if_pmo_send_pkt_filter_req() - enable packet filter
+ * @vdev: objmgr vdev
+ * @rcv_filter_param: filter params
+ *
+ * This function enable packet filter
+ *
+ *  Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS target_if_pmo_send_pkt_filter_req(struct wlan_objmgr_vdev *vdev,
+			struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param);
+
+/**
+ * target_if_pmo_clear_pkt_filter_req() - disable packet filter
+ * @vdev: objmgr vdev
+ * @rcv_clear_param: filter params
+ *
+ * This function disable packet filter
+ *
+ *  Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS target_if_pmo_clear_pkt_filter_req(struct wlan_objmgr_vdev *vdev,
+			struct pmo_rcv_pkt_fltr_clear_param *rcv_clear_param);
+
+/**
+ * target_if_pmo_send_arp_offload_req() - sends arp request to fwr
+ * @vdev: objmgr vdev
+ * @arp_offload_req: arp offload req
+ * @ns_offload_req: ns offload request
+ *
+ * This functions sends arp request to fwr.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS target_if_pmo_send_arp_offload_req(
+		struct wlan_objmgr_vdev *vdev,
+		struct pmo_arp_offload_params *arp_offload_req,
+		struct pmo_ns_offload_params *ns_offload_req);
+
+/**
+ * target_if_pmo_send_ns_offload_req() - sends ns request to fwr
+ * @vdev: objmgr vdev
+ * @arp_offload_req: arp offload req
+ * @ns_offload_req: ns offload request
+ *
+ * This functions sends ns request to fwr.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS target_if_pmo_send_ns_offload_req(
+		struct wlan_objmgr_vdev *vdev,
+		struct pmo_arp_offload_params *arp_offload_req,
+		struct pmo_ns_offload_params *ns_offload_req);
+
+/**
+ * target_if_pmo_send_gtk_offload_req() - send gtk offload request in fwr
+ * @vdev: objmgr vdev handle
+ * @gtk_offload_req: gtk offload request
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_gtk_offload_req(struct wlan_objmgr_vdev *vdev,
+		struct pmo_gtk_req *gtk_offload_req);
+
+/**
+ * target_if_pmo_send_gtk_response_req() - send gtk response request in fwr
+ * @vdev: objmgr vdev handle
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_gtk_response_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * target_if_pmo_gtk_offload_status_event() - GTK offload status event handler
+ * @scn_handle: scn handle
+ * @event: event buffer
+ * @len: buffer length
+ *
+ * Return: 0 for success or error code
+ */
+int target_if_pmo_gtk_offload_status_event(void *scn_handle,
+	uint8_t *event, uint32_t len);
+
+/**
+ * target_if_pmo_send_lphb_enable() - enable command of LPHB config req
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_enable: lphb enable request which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_lphb_enable(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_enable_req *ts_lphb_enable);
+
+/**
+ * target_if_pmo_send_lphb_tcp_params() - set lphb tcp params config request
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_tcp_param: lphb tcp params which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_lphb_tcp_params(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_tcp_params *ts_lphb_tcp_param);
+
+/**
+ * target_if_pmo_send_lphb_tcp_pkt_filter() - send lphb tcp packet filter req
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_tcp_filter: lphb tcp filter request which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_lphb_tcp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_tcp_filter_req *ts_lphb_tcp_filter);
+
+/**
+ * target_if_pmo_send_lphb_udp_params() - Send udp param command of LPHB
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_udp_param: lphb udp params which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_lphb_udp_params(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_udp_params *ts_lphb_udp_param);
+
+/**
+ * target_if_pmo_send_lphb_udp_pkt_filter() - Send lphb udp pkt filter cmd req
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_udp_filter: lphb udp filter request which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_lphb_udp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_udp_filter_req *ts_lphb_udp_filter);
+
+/**
+ * target_if_pmo_lphb_evt_handler() - send LPHB indication to os if /HDD
+ * @psoc: objmgr psoc handle
+ * @event: lphb event buffer
+ *
+ * Return: QDF_STATUS_SUCCESS for success else error code
+ */
+QDF_STATUS target_if_pmo_lphb_evt_handler(struct wlan_objmgr_psoc *psoc,
+		uint8_t *event);
+
+/**
+ * target_if_pmo_send_vdev_update_param_req() - Send vdev param value to fwr
+ * @vdev: objmgr vdev
+ * @param_id: tell vdev param id which needs to be updated in fwr
+ * @param_value: vdev parameter value
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_vdev_update_param_req(
+		struct wlan_objmgr_vdev *vdev,
+		uint32_t param_id, uint32_t param_value);
+
+/**
+ * target_if_pmo_send_vdev_ps_param_req() - Send vdev ps param value to fwr
+ * @vdev: objmgr vdev
+ * @param_id: tell vdev param id which needs to be updated in fwr
+ * @param_value: vdev parameter value
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_vdev_ps_param_req(
+		struct wlan_objmgr_vdev *vdev,
+		uint32_t param_id,
+		uint32_t param_value);
+
+/**
+ * target_if_pmo_psoc_update_bus_suspend() - update wmi bus suspend flag
+ * @psoc: objmgr psoc
+ * @value: bus suspend value
+ *
+ * Return: None
+ */
+void target_if_pmo_psoc_update_bus_suspend(struct wlan_objmgr_psoc *psoc,
+		uint8_t value);
+
+/**
+ * target_if_pmo_psoc_get_host_credits() - get available host credits
+ * @psoc: objmgr psoc
+ *
+ * Return: return host credits
+ */
+int target_if_pmo_psoc_get_host_credits(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_pmo_psoc_get_pending_cmnds() - get wmi pending commands
+ * @psoc: objmgr psoc
+ *
+ * Return: return wmi pending commands
+ */
+int target_if_pmo_psoc_get_pending_cmnds(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_pmo_update_target_suspend_flag() - set wmi target suspend flag
+ * @psoc: objmgr psoc
+ * @value: value
+ *
+ * Return: return wmi pending commands
+ */
+void target_if_pmo_update_target_suspend_flag(struct wlan_objmgr_psoc *psoc,
+		uint8_t value);
+
+/**
+ * target_if_pmo_psoc_send_wow_enable_req() -send wow enable request
+ * @psoc: objmgr psoc
+ * @param: wow command params
+ *
+ * Return: return QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS target_if_pmo_psoc_send_wow_enable_req(struct wlan_objmgr_psoc *psoc,
+		struct pmo_wow_cmd_params *param);
+
+/**
+ * target_if_pmo_psoc_send_suspend_req() - fp to send suspend request
+ * @psoc: objmgr psoc
+ * @param: target suspend params
+ *
+ * Return: return QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS target_if_pmo_psoc_send_suspend_req(struct wlan_objmgr_psoc *psoc,
+		struct pmo_suspend_params *param);
+
+/**
+ * target_if_pmo_set_runtime_pm_in_progress() - set runtime pm status
+ * @psoc: objmgr psoc
+ * @value: set runtime pm status
+ *
+ * Return: none
+ */
+void target_if_pmo_set_runtime_pm_in_progress(struct wlan_objmgr_psoc *psoc,
+					      bool value);
+
+/**
+ * target_if_pmo_get_runtime_pm_in_progress() - fp to get runtime pm status
+ * @psoc: objmgr psoc
+ *
+ * Return: true if runtime pm in progress else false
+ */
+bool target_if_pmo_get_runtime_pm_in_progress(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_pmo_psoc_send_host_wakeup_ind() - send host wake ind to fwr
+ * @psoc: objmgr psoc
+ *
+ * Return: return QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS target_if_pmo_psoc_send_host_wakeup_ind(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_pmo_psoc_send_target_resume_req() -send target resume request
+ * @psoc: objmgr psoc
+ *
+ * Return: return QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS target_if_pmo_psoc_send_target_resume_req(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_pmo_register_tx_ops() - Register PMO component TX OPS
+ * @tx_ops: PMO if transmit ops
+ *
+ * Return: None
+ */
+void target_if_pmo_register_tx_ops(struct wlan_pmo_tx_ops *tx_ops);
+
+#endif
+
diff --git a/components/target_if/pmo/src/target_if_pmo_arp.c b/components/target_if/pmo/src/target_if_pmo_arp.c
new file mode 100644
index 0000000..b28b08a
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_arp.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017 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_if_pmo_arp.c
+ *
+ * Target interface file for pmo component to
+ * send arp offload related cmd and process event.
+ */
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_api.h"
+
+QDF_STATUS target_if_pmo_send_arp_offload_req(
+		struct wlan_objmgr_vdev *vdev,
+		struct pmo_arp_offload_params *arp_offload_req,
+		struct pmo_ns_offload_params *ns_offload_req)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+
+	if (!vdev) {
+		target_if_err("vdev ptr passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (!psoc) {
+		target_if_err("psoc handle is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_enable_arp_ns_offload_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc),
+			arp_offload_req,
+			ns_offload_req,
+			vdev_id);
+	if (status != QDF_STATUS_SUCCESS)
+		target_if_err("Failed to enable ARP NDP/NSffload");
+
+	return status;
+}
+
+
diff --git a/components/target_if/pmo/src/target_if_pmo_gtk.c b/components/target_if/pmo/src/target_if_pmo_gtk.c
new file mode 100644
index 0000000..5f67b9f
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_gtk.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2017 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_if_pmo_gtk.c
+ *
+ * Target interface file for pmo component to
+ * send gtk offload related cmd and process event.
+ */
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_api.h"
+
+QDF_STATUS target_if_pmo_send_gtk_offload_req(struct wlan_objmgr_vdev *vdev,
+		struct pmo_gtk_req *gtk_req)
+{
+	uint8_t vdev_id;
+	QDF_STATUS status;
+	uint32_t gtk_offload_opcode;
+	struct wlan_objmgr_psoc *psoc;
+
+	if (!vdev) {
+		target_if_err("vdev ptr passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (!psoc) {
+		target_if_err("psoc handle is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (gtk_req->flags == PMO_GTK_OFFLOAD_ENABLE)
+		gtk_offload_opcode = GTK_OFFLOAD_ENABLE_OPCODE;
+	else
+		gtk_offload_opcode = GTK_OFFLOAD_DISABLE_OPCODE;
+
+	status = wmi_unified_send_gtk_offload_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc),
+			vdev_id,
+			gtk_req,
+			gtk_req->flags,
+			gtk_offload_opcode);
+	if (status)
+		target_if_err("Failed to send gtk offload cmd to fw");
+
+	return status;
+}
+
+QDF_STATUS target_if_pmo_send_gtk_response_req(struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint32_t offload_req_opcode;
+
+	if (!vdev) {
+		target_if_err("vdev ptr passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (!psoc) {
+		target_if_err("psoc handle is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* Request for GTK offload status */
+	offload_req_opcode = GTK_OFFLOAD_REQUEST_STATUS_OPCODE;
+
+	/* send the wmi command */
+	status = wmi_unified_process_gtk_offload_getinfo_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc),
+			vdev_id, offload_req_opcode);
+
+	return status;
+}
+
+int target_if_pmo_gtk_offload_status_event(void *scn_handle,
+	uint8_t *event, uint32_t len)
+{
+	struct pmo_gtk_rsp_params *gtk_rsp_param;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS ret;
+
+	TARGET_IF_ENTER();
+	psoc = target_if_get_psoc_from_scn_hdl(scn_handle);
+	if (!psoc) {
+		target_if_err("psoc ptr is NULL");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	gtk_rsp_param = qdf_mem_malloc(sizeof(*gtk_rsp_param));
+	if (!gtk_rsp_param) {
+		target_if_err("memory allocation failed");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (wmi_extract_gtk_rsp_event(GET_WMI_HDL_FROM_PSOC(psoc),
+			event, gtk_rsp_param, len) != QDF_STATUS_SUCCESS) {
+		target_if_err("Extraction of gtk rsp event failed");
+		qdf_mem_free(gtk_rsp_param);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = pmo_tgt_gtk_rsp_evt(psoc, (void *)gtk_rsp_param);
+	if (ret != QDF_STATUS_SUCCESS) {
+		target_if_err("Failed to rx_gtk_rsp_event");
+		ret = -EINVAL;
+	}
+	qdf_mem_free(gtk_rsp_param);
+out:
+	TARGET_IF_EXIT();
+
+	return ret;
+}
+
diff --git a/components/target_if/pmo/src/target_if_pmo_hw_filter.c b/components/target_if/pmo/src/target_if_pmo_hw_filter.c
new file mode 100644
index 0000000..8070a64
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_hw_filter.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017 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_if_pmo_non_arp_bcast_fltr.c
+ *
+ * Target interface file for pmo component to
+ * send non arp hw bcast filtering related cmd and process event.
+ */
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_api.h"
+#include "wlan_pmo_hw_filter_public_struct.h"
+
+QDF_STATUS target_if_pmo_conf_hw_filter(struct wlan_objmgr_psoc *psoc,
+					struct pmo_hw_filter_params *req)
+{
+	QDF_STATUS status;
+
+	if (!psoc) {
+		target_if_err("psoc is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_conf_hw_filter_cmd(
+		GET_WMI_HDL_FROM_PSOC(psoc),
+		req);
+
+	if (QDF_IS_STATUS_ERROR(status))
+		target_if_err("Failed to configure HW Filter");
+
+	return status;
+}
diff --git a/components/target_if/pmo/src/target_if_pmo_lphb.c b/components/target_if/pmo/src/target_if_pmo_lphb.c
new file mode 100644
index 0000000..8c630b8
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_lphb.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2017 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_if_pmo_lphb.c
+ *
+ * Target interface file for pmo component to
+ * send lphb offload related cmd and process event.
+ */
+#ifdef FEATURE_WLAN_LPHB
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_pmo_api.h"
+
+QDF_STATUS target_if_pmo_send_lphb_enable(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_enable_req *ts_lphb_enable)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	int status = 0;
+	wmi_hb_set_enable_cmd_fixed_param hb_enable_fp;
+
+	if (ts_lphb_enable == NULL) {
+		target_if_err("LPHB Enable configuration is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	target_if_info("PMO_HB_SET_ENABLE enable=%d, item=%d, session=%d",
+		ts_lphb_enable->enable,
+		ts_lphb_enable->item, ts_lphb_enable->session);
+
+	if ((ts_lphb_enable->item != 1) && (ts_lphb_enable->item != 2)) {
+		target_if_err("LPHB configuration wrong item %d",
+			ts_lphb_enable->item);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* fill in values */
+	hb_enable_fp.vdev_id = ts_lphb_enable->session;
+	hb_enable_fp.enable = ts_lphb_enable->enable;
+	hb_enable_fp.item = ts_lphb_enable->item;
+	hb_enable_fp.session = ts_lphb_enable->session;
+
+	status = wmi_unified_lphb_config_hbenable_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc),
+			&hb_enable_fp);
+	if (status != EOK) {
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto error;
+	}
+	return QDF_STATUS_SUCCESS;
+error:
+
+	return qdf_status;
+}
+
+QDF_STATUS target_if_pmo_send_lphb_tcp_params(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_tcp_params *ts_lphb_tcp_param)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	int status = 0;
+	wmi_hb_set_tcp_params_cmd_fixed_param hb_tcp_params_fp = {0};
+
+	if (ts_lphb_tcp_param == NULL) {
+		target_if_err("TCP params LPHB configuration is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	target_if_info("PMO --> WMI_HB_SET_TCP_PARAMS srv_ip=%08x, "
+		"dev_ip=%08x, src_port=%d, dst_port=%d, timeout=%d, "
+		"session=%d, gateway_mac= %pM, time_period_sec=%d,"
+		"tcp_sn=%d", ts_lphb_tcp_param->srv_ip,
+		ts_lphb_tcp_param->dev_ip, ts_lphb_tcp_param->src_port,
+		ts_lphb_tcp_param->dst_port, ts_lphb_tcp_param->timeout,
+		ts_lphb_tcp_param->session,
+		ts_lphb_tcp_param->gateway_mac.bytes,
+		ts_lphb_tcp_param->time_period_sec, ts_lphb_tcp_param->tcp_sn);
+
+	/* fill in values */
+	hb_tcp_params_fp.vdev_id = ts_lphb_tcp_param->session;
+	hb_tcp_params_fp.srv_ip = ts_lphb_tcp_param->srv_ip;
+	hb_tcp_params_fp.dev_ip = ts_lphb_tcp_param->dev_ip;
+	hb_tcp_params_fp.seq = ts_lphb_tcp_param->tcp_sn;
+	hb_tcp_params_fp.src_port = ts_lphb_tcp_param->src_port;
+	hb_tcp_params_fp.dst_port = ts_lphb_tcp_param->dst_port;
+	hb_tcp_params_fp.interval = ts_lphb_tcp_param->time_period_sec;
+	hb_tcp_params_fp.timeout = ts_lphb_tcp_param->timeout;
+	hb_tcp_params_fp.session = ts_lphb_tcp_param->session;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(ts_lphb_tcp_param->gateway_mac.bytes,
+				   &hb_tcp_params_fp.gateway_mac);
+
+	status = wmi_unified_lphb_config_tcp_params_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc),
+			&hb_tcp_params_fp);
+	if (status != EOK) {
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto error;
+	}
+
+	return QDF_STATUS_SUCCESS;
+error:
+	return qdf_status;
+}
+
+QDF_STATUS target_if_pmo_send_lphb_tcp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_tcp_filter_req *ts_lphb_tcp_filter)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	int status = 0;
+	wmi_hb_set_tcp_pkt_filter_cmd_fixed_param hb_tcp_filter_fp = {0};
+
+	if (ts_lphb_tcp_filter == NULL) {
+		target_if_err("TCP PKT FILTER LPHB configuration is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	target_if_info("SET_TCP_PKT_FILTER length=%d, offset=%d, session=%d, "
+		"filter=%2x:%2x:%2x:%2x:%2x:%2x ...",
+		ts_lphb_tcp_filter->length, ts_lphb_tcp_filter->offset,
+		ts_lphb_tcp_filter->session, ts_lphb_tcp_filter->filter[0],
+		ts_lphb_tcp_filter->filter[1], ts_lphb_tcp_filter->filter[2],
+		ts_lphb_tcp_filter->filter[3], ts_lphb_tcp_filter->filter[4],
+		ts_lphb_tcp_filter->filter[5]);
+
+	/* fill in values */
+	hb_tcp_filter_fp.vdev_id = ts_lphb_tcp_filter->session;
+	hb_tcp_filter_fp.length = ts_lphb_tcp_filter->length;
+	hb_tcp_filter_fp.offset = ts_lphb_tcp_filter->offset;
+	hb_tcp_filter_fp.session = ts_lphb_tcp_filter->session;
+	memcpy((void *)&hb_tcp_filter_fp.filter,
+	       (void *)&ts_lphb_tcp_filter->filter,
+	       WMI_WLAN_HB_MAX_FILTER_SIZE);
+
+	status = wmi_unified_lphb_config_tcp_pkt_filter_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc),
+			&hb_tcp_filter_fp);
+	if (status != EOK) {
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto error;
+	}
+
+	return QDF_STATUS_SUCCESS;
+error:
+	return qdf_status;
+}
+
+QDF_STATUS target_if_pmo_send_lphb_udp_params(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_udp_params *ts_lphb_udp_param)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	int status = 0;
+	wmi_hb_set_udp_params_cmd_fixed_param hb_udp_params_fp = {0};
+
+	if (ts_lphb_udp_param == NULL) {
+		target_if_err("UDP param for LPHB configuration is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	target_if_info("HB_SET_UDP_PARAMS srv_ip=%d, dev_ip=%d, src_port=%d, "
+		"dst_port=%d, interval=%d, timeout=%d, session=%d, "
+		"gateway_mac= %pM",
+		ts_lphb_udp_param->srv_ip, ts_lphb_udp_param->dev_ip,
+		ts_lphb_udp_param->src_port, ts_lphb_udp_param->dst_port,
+		ts_lphb_udp_param->interval, ts_lphb_udp_param->timeout,
+		ts_lphb_udp_param->session,
+		ts_lphb_udp_param->gateway_mac.bytes);
+
+	/* fill in values */
+	hb_udp_params_fp.vdev_id = ts_lphb_udp_param->session;
+	hb_udp_params_fp.srv_ip = ts_lphb_udp_param->srv_ip;
+	hb_udp_params_fp.dev_ip = ts_lphb_udp_param->dev_ip;
+	hb_udp_params_fp.src_port = ts_lphb_udp_param->src_port;
+	hb_udp_params_fp.dst_port = ts_lphb_udp_param->dst_port;
+	hb_udp_params_fp.interval = ts_lphb_udp_param->interval;
+	hb_udp_params_fp.timeout = ts_lphb_udp_param->timeout;
+	hb_udp_params_fp.session = ts_lphb_udp_param->session;
+	WMI_CHAR_ARRAY_TO_MAC_ADDR(ts_lphb_udp_param->gateway_mac.bytes,
+				   &hb_udp_params_fp.gateway_mac);
+
+	status = wmi_unified_lphb_config_udp_params_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc),
+			&hb_udp_params_fp);
+	if (status != EOK) {
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto error;
+	}
+
+	return QDF_STATUS_SUCCESS;
+error:
+	return qdf_status;
+}
+
+/**
+ * target_if_pmo_lphb_send_udp_pkt_filter() - Send LPHB udp pkt filter req
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_udp_filter: lphb udp filter request which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_lphb_udp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+			struct pmo_lphb_udp_filter_req *ts_lphb_udp_filter)
+{
+	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+	int status = 0;
+	wmi_hb_set_udp_pkt_filter_cmd_fixed_param hb_udp_filter_fp = {0};
+
+	if (ts_lphb_udp_filter == NULL) {
+		target_if_err("LPHB UDP packet filter configuration is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	target_if_info("SET_UDP_PKT_FILTER length=%d, offset=%d, session=%d, "
+		"filter=%2x:%2x:%2x:%2x:%2x:%2x ...",
+		ts_lphb_udp_filter->length, ts_lphb_udp_filter->offset,
+		ts_lphb_udp_filter->session, ts_lphb_udp_filter->filter[0],
+		ts_lphb_udp_filter->filter[1], ts_lphb_udp_filter->filter[2],
+		ts_lphb_udp_filter->filter[3], ts_lphb_udp_filter->filter[4],
+		ts_lphb_udp_filter->filter[5]);
+
+	/* fill in values */
+	hb_udp_filter_fp.vdev_id = ts_lphb_udp_filter->session;
+	hb_udp_filter_fp.length = ts_lphb_udp_filter->length;
+	hb_udp_filter_fp.offset = ts_lphb_udp_filter->offset;
+	hb_udp_filter_fp.session = ts_lphb_udp_filter->session;
+	qdf_mem_copy((void *)&hb_udp_filter_fp.filter,
+	       (void *)&ts_lphb_udp_filter->filter,
+	       WMI_WLAN_HB_MAX_FILTER_SIZE);
+
+	status = wmi_unified_lphb_config_udp_pkt_filter_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc),
+			&hb_udp_filter_fp);
+	if (status != EOK) {
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto error;
+	}
+
+	return QDF_STATUS_SUCCESS;
+error:
+	return qdf_status;
+}
+
+QDF_STATUS target_if_pmo_lphb_evt_handler(struct wlan_objmgr_psoc *psoc,
+		uint8_t *event)
+{
+	wmi_hb_ind_event_fixed_param *hb_fp;
+	struct pmo_lphb_rsp *slphb_indication = NULL;
+	QDF_STATUS qdf_status;
+
+	TARGET_IF_ENTER();
+	if (!psoc) {
+		target_if_err("psoc ptr is NULL");
+		qdf_status = QDF_STATUS_E_NULL_VALUE;
+		goto out;
+	}
+
+	hb_fp = (wmi_hb_ind_event_fixed_param *) event;
+	if (!hb_fp) {
+		target_if_err("Invalid wmi_hb_ind_event_fixed_param buffer");
+		qdf_status = QDF_STATUS_E_INVAL;
+		goto out;
+	}
+
+	target_if_debug("lphb indication received with\n"
+		  "vdev_id=%d, session=%d, reason=%d",
+		hb_fp->vdev_id, hb_fp->session, hb_fp->reason);
+
+	slphb_indication = (struct pmo_lphb_rsp *)qdf_mem_malloc(
+				sizeof(struct pmo_lphb_rsp));
+
+	if (!slphb_indication) {
+		target_if_err("Invalid LPHB indication buffer");
+		qdf_status = QDF_STATUS_E_NOMEM;
+		goto out;
+	}
+
+	slphb_indication->session_idx = hb_fp->session;
+	slphb_indication->protocol_type = hb_fp->reason;
+	slphb_indication->event_reason = hb_fp->reason;
+
+	qdf_status = pmo_tgt_lphb_rsp_evt(psoc, slphb_indication);
+	if (qdf_status != QDF_STATUS_SUCCESS)
+		target_if_err("Failed to lphb_rsp_event");
+out:
+	if (slphb_indication)
+		qdf_mem_free(slphb_indication);
+
+	return qdf_status;
+}
+#endif
+
diff --git a/components/target_if/pmo/src/target_if_pmo_main.c b/components/target_if/pmo/src/target_if_pmo_main.c
new file mode 100644
index 0000000..6e63d04
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_main.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2017 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 file for pmo component to
+ * Implement api's which shall be used by pmo component
+ * in target if internally.
+ */
+
+#include "target_if_pmo.h"
+#include "wlan_pmo_common_public_struct.h"
+
+void target_if_pmo_register_tx_ops(struct wlan_pmo_tx_ops *pmo_tx_ops)
+{
+	if (!pmo_tx_ops) {
+		target_if_err("pmo_tx_ops is null");
+		return;
+	}
+
+	pmo_tx_ops->send_arp_offload_req =
+		target_if_pmo_send_arp_offload_req;
+	pmo_tx_ops->send_conf_hw_filter_req =
+		target_if_pmo_conf_hw_filter;
+	pmo_tx_ops->send_ns_offload_req =
+		target_if_pmo_send_ns_offload_req;
+	pmo_tx_ops->send_enable_wow_wakeup_event_req =
+		target_if_pmo_enable_wow_wakeup_event;
+	pmo_tx_ops->send_disable_wow_wakeup_event_req =
+		target_if_pmo_disable_wow_wakeup_event;
+	pmo_tx_ops->send_add_wow_pattern =
+		target_if_pmo_send_wow_patterns_to_fw;
+	pmo_tx_ops->send_enhance_mc_offload_req =
+		target_if_pmo_send_enhance_mc_offload_req;
+	pmo_tx_ops->send_set_mc_filter_req =
+		target_if_pmo_set_mc_filter_req;
+	pmo_tx_ops->send_clear_mc_filter_req =
+		target_if_pmo_clear_mc_filter_req;
+	pmo_tx_ops->send_ra_filter_req =
+		target_if_pmo_send_ra_filter_req;
+	pmo_tx_ops->send_gtk_offload_req =
+		target_if_pmo_send_gtk_offload_req;
+	pmo_tx_ops->send_get_gtk_rsp_cmd =
+		target_if_pmo_send_gtk_response_req;
+	pmo_tx_ops->send_action_frame_pattern_req =
+		target_if_pmo_send_action_frame_patterns;
+	pmo_tx_ops->send_lphb_enable =
+		target_if_pmo_send_lphb_enable;
+	pmo_tx_ops->send_lphb_tcp_params =
+		target_if_pmo_send_lphb_tcp_params;
+	pmo_tx_ops->send_lphb_tcp_filter_req =
+		target_if_pmo_send_lphb_tcp_pkt_filter;
+	pmo_tx_ops->send_lphb_upd_params =
+		target_if_pmo_send_lphb_udp_params;
+	pmo_tx_ops->send_lphb_udp_filter_req =
+		target_if_pmo_send_lphb_udp_pkt_filter;
+	pmo_tx_ops->send_vdev_param_update_req =
+		target_if_pmo_send_vdev_update_param_req;
+	pmo_tx_ops->send_vdev_sta_ps_param_req =
+		target_if_pmo_send_vdev_ps_param_req;
+	pmo_tx_ops->psoc_update_wow_bus_suspend =
+		target_if_pmo_psoc_update_bus_suspend;
+	pmo_tx_ops->psoc_get_host_credits =
+		target_if_pmo_psoc_get_host_credits;
+	pmo_tx_ops->psoc_get_pending_cmnds =
+		target_if_pmo_psoc_get_pending_cmnds;
+	pmo_tx_ops->update_target_suspend_flag =
+		target_if_pmo_update_target_suspend_flag;
+	pmo_tx_ops->psoc_send_wow_enable_req =
+		target_if_pmo_psoc_send_wow_enable_req;
+	pmo_tx_ops->psoc_send_supend_req =
+		target_if_pmo_psoc_send_suspend_req;
+	pmo_tx_ops->psoc_set_runtime_pm_in_progress =
+		target_if_pmo_set_runtime_pm_in_progress;
+	pmo_tx_ops->psoc_get_runtime_pm_in_progress =
+		target_if_pmo_get_runtime_pm_in_progress;
+	pmo_tx_ops->psoc_send_host_wakeup_ind =
+		target_if_pmo_psoc_send_host_wakeup_ind;
+	pmo_tx_ops->psoc_send_target_resume_req =
+		target_if_pmo_psoc_send_target_resume_req;
+	pmo_tx_ops->send_set_pkt_filter =
+		target_if_pmo_send_pkt_filter_req;
+	pmo_tx_ops->send_clear_pkt_filter =
+		target_if_pmo_clear_pkt_filter_req;
+
+}
+
diff --git a/components/target_if/pmo/src/target_if_pmo_mc_addr_filtering.c b/components/target_if/pmo/src/target_if_pmo_mc_addr_filtering.c
new file mode 100644
index 0000000..bd3b29b
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_mc_addr_filtering.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2017 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_if_pmo_mc_addr_filtering.c
+ *
+ * Target interface file for pmo component to
+ * send mc address filtering offload related cmd and process event.
+ */
+
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_api.h"
+
+QDF_STATUS target_if_pmo_set_mc_filter_req(
+		struct wlan_objmgr_vdev *vdev,
+		struct qdf_mac_addr multicast_addr)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+
+	if (!vdev) {
+		target_if_err("vdev ptr passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (!psoc) {
+		target_if_err("psoc handle is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_add_clear_mcbc_filter_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc),
+			vdev_id,
+			multicast_addr, false);
+	if (status)
+		target_if_err("Failed to send add/clear mcbc filter cmd");
+
+	return status;
+}
+
+QDF_STATUS target_if_pmo_clear_mc_filter_req(
+		struct wlan_objmgr_vdev *vdev,
+		struct qdf_mac_addr multicast_addr)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+
+	if (!vdev) {
+		target_if_err("vdev ptr passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (!psoc) {
+		target_if_err("psoc handle is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_add_clear_mcbc_filter_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc),
+			vdev_id,
+			multicast_addr, true);
+	if (status)
+		target_if_err("Failed to send add/clear mcbc filter cmd");
+
+	return status;
+
+}
+
+
diff --git a/components/target_if/pmo/src/target_if_pmo_ns.c b/components/target_if/pmo/src/target_if_pmo_ns.c
new file mode 100644
index 0000000..6b2946b
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_ns.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017 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_if_pmo_ns.c
+ *
+ * Target interface file for pmo component to
+ * send ns offload related cmd and process event.
+ */
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_api.h"
+
+QDF_STATUS target_if_pmo_send_ns_offload_req(
+		struct wlan_objmgr_vdev *vdev,
+		struct pmo_arp_offload_params *arp_offload_req,
+		struct pmo_ns_offload_params *ns_offload_req)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+
+	if (!vdev) {
+		target_if_err("vdev ptr passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (!psoc) {
+		target_if_err("psoc handle is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_enable_arp_ns_offload_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc),
+			arp_offload_req,
+			ns_offload_req,
+			vdev_id);
+	if (status != QDF_STATUS_SUCCESS)
+		target_if_err("Failed to enable ARP NDP/NSffload");
+
+	return status;
+}
+
diff --git a/components/target_if/pmo/src/target_if_pmo_pkt_filter.c b/components/target_if/pmo/src/target_if_pmo_pkt_filter.c
new file mode 100644
index 0000000..7907c7a
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_pkt_filter.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2017 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_if_pmo_pkt_filter.c
+ *
+ * Target interface file for pmo component to
+ * send packet filter related cmd and process event.
+ */
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_pmo_api.h"
+#include "wlan_pmo_pkt_filter_public_struct.h"
+
+QDF_STATUS target_if_pmo_send_pkt_filter_req(struct wlan_objmgr_vdev *vdev,
+			struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+
+	if (!vdev) {
+		target_if_err("vdev ptr passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (!psoc) {
+		target_if_err("psoc handle is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* send the command along with data */
+	status = wmi_unified_config_packet_filter_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc), vdev_id,
+			rcv_filter_param,
+			rcv_filter_param->filter_id, true);
+	if (status) {
+		target_if_err("Failed to send pkt_filter cmd");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* Enable packet filter */
+	status = wmi_unified_enable_disable_packet_filter_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc),
+			vdev_id, true);
+	if (status)
+		target_if_err("Failed to send packet filter wmi cmd to fw");
+
+	return status;
+}
+
+QDF_STATUS target_if_pmo_clear_pkt_filter_req(struct wlan_objmgr_vdev *vdev,
+			struct pmo_rcv_pkt_fltr_clear_param *rcv_clear_param)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+
+	if (!vdev) {
+		target_if_err("vdev ptr passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (!psoc) {
+		target_if_err("psoc handle is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	/* send the command along with data */
+	status = wmi_unified_config_packet_filter_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc), vdev_id,
+			NULL, rcv_clear_param->filter_id, false);
+
+	if (status)
+		target_if_err("Failed to clear filter cmd");
+
+	return status;
+}
diff --git a/components/target_if/pmo/src/target_if_pmo_static_config.c b/components/target_if/pmo/src/target_if_pmo_static_config.c
new file mode 100644
index 0000000..8207e36
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_static_config.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2017 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_if_pmo_static.c
+ *
+ * Target interface file for pmo component to
+ * send wow related cmd and process event.
+ */
+
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_api.h"
+
+QDF_STATUS target_if_pmo_send_ra_filter_req(struct wlan_objmgr_vdev *vdev,
+		uint8_t default_pattern, uint16_t rate_limit_interval)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+
+	if (!vdev) {
+		target_if_err("vdev ptr passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (!psoc) {
+		target_if_err("psoc handle is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_wow_sta_ra_filter_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc), vdev_id,
+			default_pattern, rate_limit_interval);
+	if (status)
+		target_if_err("Failed to send RA rate limit to fw");
+
+	return status;
+}
+
+QDF_STATUS target_if_pmo_send_action_frame_patterns(
+		struct wlan_objmgr_vdev *vdev,
+		struct pmo_action_wakeup_set_params *ip_cmd)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+
+	if (!vdev) {
+		target_if_err("vdev ptr passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (!psoc) {
+		target_if_err("psoc handle is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_action_frame_patterns_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc), ip_cmd);
+	if (status != QDF_STATUS_SUCCESS)
+		target_if_err("Failed to config wow action frame map, ret %d",
+			status);
+
+	return status;
+}
+
+QDF_STATUS target_if_pmo_send_enhance_mc_offload_req(
+		struct wlan_objmgr_vdev *vdev, bool enable)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+
+	if (!vdev) {
+		target_if_err("vdev ptr passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (!psoc) {
+		target_if_err("psoc handle is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_enable_enhance_multicast_offload_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc), vdev_id, enable);
+	if (status)
+		target_if_err("Failed to config wow wakeup event");
+
+	return status;
+}
+
diff --git a/components/target_if/pmo/src/target_if_pmo_suspend_resume.c b/components/target_if/pmo/src/target_if_pmo_suspend_resume.c
new file mode 100644
index 0000000..fbbd638
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_suspend_resume.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2017 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_if_pmo_static.c
+ *
+ * Target interface file for pmo component to
+ * send suspend / resume related cmd and process event.
+ */
+
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_api.h"
+
+#define TGT_WILDCARD_PDEV_ID 0x0
+
+QDF_STATUS target_if_pmo_send_vdev_update_param_req(
+		struct wlan_objmgr_vdev *vdev,
+		uint32_t param_id, uint32_t param_value)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	struct vdev_set_params param = {0};
+
+	if (!vdev) {
+		target_if_err("vdev ptr passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (!psoc) {
+		target_if_err("psoc handle is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	switch (param_id) {
+	case pmo_vdev_param_listen_interval:
+		param_id = WMI_VDEV_PARAM_LISTEN_INTERVAL;
+		break;
+	case pmo_vdev_param_dtim_policy:
+		param_id = WMI_VDEV_PARAM_DTIM_POLICY;
+		break;
+	default:
+		target_if_err("invalid vdev param id %d", param_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	param.if_id = vdev_id;
+	param.param_id = param_id;
+	param.param_value = param_value;
+	target_if_info("set vdev param vdev_id: %d value: %d for param_id: %d",
+		vdev_id, param_value, param_id);
+	return wmi_unified_vdev_set_param_send(GET_WMI_HDL_FROM_PSOC(psoc),
+			&param);
+}
+
+QDF_STATUS target_if_pmo_send_vdev_ps_param_req(
+		struct wlan_objmgr_vdev *vdev,
+		uint32_t param_id,
+		uint32_t param_value)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+	struct sta_ps_params sta_ps_param = {0};
+
+	if (!vdev) {
+		target_if_err("vdev ptr passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (!psoc) {
+		target_if_err("psoc handle is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	switch (param_id) {
+	case pmo_sta_ps_enable_qpower:
+		param_id = WMI_STA_PS_ENABLE_QPOWER;
+		break;
+	default:
+		target_if_err("invalid vdev param id %d", param_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	sta_ps_param.vdev_id = vdev_id;
+	sta_ps_param.param = param_id;
+	sta_ps_param.value = param_value;
+	target_if_info("set vdev param vdev_id: %d value: %d for param_id: %d",
+		vdev_id, param_value, param_id);
+
+	status = wmi_unified_sta_ps_cmd_send(GET_WMI_HDL_FROM_PSOC(psoc),
+			&sta_ps_param);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	return status;
+
+}
+
+void target_if_pmo_psoc_update_bus_suspend(struct wlan_objmgr_psoc *psoc,
+		uint8_t value)
+{
+	wmi_set_is_wow_bus_suspended(GET_WMI_HDL_FROM_PSOC(psoc), value);
+}
+
+int target_if_pmo_psoc_get_host_credits(struct wlan_objmgr_psoc *psoc)
+{
+	return wmi_get_host_credits(GET_WMI_HDL_FROM_PSOC(psoc));
+}
+
+int target_if_pmo_psoc_get_pending_cmnds(struct wlan_objmgr_psoc *psoc)
+{
+	return wmi_get_pending_cmds(GET_WMI_HDL_FROM_PSOC(psoc));
+}
+
+void target_if_pmo_update_target_suspend_flag(struct wlan_objmgr_psoc *psoc,
+		uint8_t value)
+{
+	wmi_set_target_suspend(GET_WMI_HDL_FROM_PSOC(psoc), value);
+}
+
+QDF_STATUS target_if_pmo_psoc_send_wow_enable_req(
+		struct wlan_objmgr_psoc *psoc,
+		struct pmo_wow_cmd_params *param)
+{
+	return wmi_unified_wow_enable_send(GET_WMI_HDL_FROM_PSOC(psoc),
+			(struct wow_cmd_params *)param,
+			TGT_WILDCARD_PDEV_ID);
+}
+
+QDF_STATUS target_if_pmo_psoc_send_suspend_req(
+		struct wlan_objmgr_psoc *psoc,
+		struct pmo_suspend_params *param)
+{
+	return wmi_unified_suspend_send(GET_WMI_HDL_FROM_PSOC(psoc),
+			(struct suspend_params *) param,
+			TGT_WILDCARD_PDEV_ID);
+}
+
+void target_if_pmo_set_runtime_pm_in_progress(struct wlan_objmgr_psoc *psoc,
+					      bool value)
+{
+	return wmi_set_runtime_pm_inprogress(GET_WMI_HDL_FROM_PSOC(psoc),
+					     value);
+}
+
+bool target_if_pmo_get_runtime_pm_in_progress(
+		struct wlan_objmgr_psoc *psoc)
+{
+	return wmi_get_runtime_pm_inprogress(GET_WMI_HDL_FROM_PSOC(psoc));
+}
+
+QDF_STATUS target_if_pmo_psoc_send_host_wakeup_ind(
+		struct wlan_objmgr_psoc *psoc)
+{
+	return wmi_unified_host_wakeup_ind_to_fw_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc));
+}
+
+QDF_STATUS target_if_pmo_psoc_send_target_resume_req(
+		struct wlan_objmgr_psoc *psoc)
+{
+	return wmi_unified_resume_send(GET_WMI_HDL_FROM_PSOC(psoc),
+					TGT_WILDCARD_PDEV_ID);
+}
+
diff --git a/components/target_if/pmo/src/target_if_pmo_wow.c b/components/target_if/pmo/src/target_if_pmo_wow.c
new file mode 100644
index 0000000..828f0cf
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_wow.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2017 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_if_pmo_wow.c
+ *
+ * Target interface file for pmo component to
+ * send wow related cmd and process event.
+ */
+
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_api.h"
+
+QDF_STATUS target_if_pmo_enable_wow_wakeup_event(struct wlan_objmgr_vdev *vdev,
+		uint32_t *bitmap)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+
+	if (!vdev) {
+		target_if_err("vdev ptr passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (!psoc) {
+		target_if_err("psoc handle is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_add_wow_wakeup_event_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc), vdev_id, bitmap, true);
+	if (status)
+		target_if_err("Failed to config wow wakeup event");
+
+	return status;
+}
+
+QDF_STATUS target_if_pmo_disable_wow_wakeup_event(struct wlan_objmgr_vdev *vdev,
+		uint32_t *bitmap)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+
+	if (!vdev) {
+		target_if_err("vdev ptr passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (!psoc) {
+		target_if_err("psoc handle is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_add_wow_wakeup_event_cmd(
+			GET_WMI_HDL_FROM_PSOC(psoc), vdev_id, bitmap, false);
+	if (status)
+		target_if_err("Failed to config wow wakeup event");
+
+	return status;
+}
+
+QDF_STATUS target_if_pmo_send_wow_patterns_to_fw(struct wlan_objmgr_vdev *vdev,
+		uint8_t ptrn_id,
+		const uint8_t *ptrn, uint8_t ptrn_len,
+		uint8_t ptrn_offset, const uint8_t *mask,
+		uint8_t mask_len, bool user)
+{
+	uint8_t vdev_id;
+	struct wlan_objmgr_psoc *psoc;
+	QDF_STATUS status;
+
+	if (!vdev) {
+		target_if_err("vdev ptr passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	vdev_id = wlan_vdev_get_id(vdev);
+	if (!psoc) {
+		target_if_err("psoc handle is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_unified_wow_patterns_to_fw_cmd(
+				GET_WMI_HDL_FROM_PSOC(psoc),
+				vdev_id, ptrn_id, ptrn,
+				ptrn_len, ptrn_offset, mask,
+				mask_len, user, 0);
+
+	return status;
+}
+
diff --git a/core/cds/inc/cds_config.h b/core/cds/inc/cds_config.h
index 2ced690..e2cd107 100644
--- a/core/cds/inc/cds_config.h
+++ b/core/cds/inc/cds_config.h
@@ -36,11 +36,13 @@
  *
  * @DRIVER_TYPE_PRODUCTION: Driver used in the production
  * @DRIVER_TYPE_MFG: Driver used in the Factory
+ * @DRIVER_TYPE_INVALID: Invalid and unrecognized type
  *
  */
 enum driver_type {
 	DRIVER_TYPE_PRODUCTION = 0,
 	DRIVER_TYPE_MFG = 1,
+	DRIVER_TYPE_INVALID = 0x7FFFFFFF
 };
 
 /**
diff --git a/core/cds/src/cds_reg_service.c b/core/cds/src/cds_reg_service.c
index 3b1dde0..9faf8e9 100644
--- a/core/cds/src/cds_reg_service.c
+++ b/core/cds/src/cds_reg_service.c
@@ -46,13 +46,13 @@
 	uint32_t flags = 0;
 	enum channel_state state;
 	struct ch_params ch_params;
+	int sec_channel;
 
 	state = wlan_reg_get_channel_state(pdev, chan);
 	if (state == CHANNEL_STATE_INVALID)
 		return flags;
 	if (state == CHANNEL_STATE_DFS) {
 		flags |= IEEE80211_CHAN_PASSIVE;
-		flags |= IEEE80211_CHAN_DFS;
 	}
 	if (state == CHANNEL_STATE_DISABLE)
 		flags |= IEEE80211_CHAN_BLOCKED;
@@ -63,7 +63,9 @@
 		    (bandwidth == CH_WIDTH_80MHZ)) {
 			bandwidth = CH_WIDTH_40MHZ;
 		}
-	}
+		flags |= IEEE80211_CHAN_2GHZ;
+	} else
+		flags |= IEEE80211_CHAN_5GHZ;
 
 	switch (bandwidth) {
 	case CH_WIDTH_80P80MHZ:
@@ -95,8 +97,15 @@
 		ch_params.ch_width = bandwidth;
 		wlan_reg_set_channel_params(pdev, chan, 0, &ch_params);
 
+		if (ch_params.sec_ch_offset == LOW_PRIMARY_CH)
+			sec_channel = chan + 4;
+		else if (ch_params.sec_ch_offset == HIGH_PRIMARY_CH)
+			sec_channel = chan - 4;
+		else
+			sec_channel = 0;
+
 		if (wlan_reg_get_bonded_channel_state(pdev, chan, bandwidth,
-					ch_params.sec_ch_offset) !=
+					sec_channel) !=
 				CHANNEL_STATE_INVALID) {
 			if (ch_params.sec_ch_offset == LOW_PRIMARY_CH) {
 				flags |= IEEE80211_CHAN_HT40PLUS;
@@ -124,6 +133,7 @@
 				(sub_20_channel_width ==
 				 WLAN_SUB_20_CH_WIDTH_10))
 			flags |= IEEE80211_CHAN_HALF;
+		bandwidth = CH_WIDTH_5MHZ;
 	/* FALLTHROUGH */
 	case CH_WIDTH_5MHZ:
 		if ((wlan_reg_get_bonded_channel_state(pdev, chan, bandwidth,
diff --git a/core/dp/ol/inc/ol_txrx_ctrl_api.h b/core/dp/ol/inc/ol_txrx_ctrl_api.h
index fd6c498..de4fc9e 100644
--- a/core/dp/ol/inc/ol_txrx_ctrl_api.h
+++ b/core/dp/ol/inc/ol_txrx_ctrl_api.h
@@ -514,7 +514,7 @@
 
 void ol_tx_register_flow_control(struct ol_txrx_pdev_t *pdev);
 void ol_tx_deregister_flow_control(struct ol_txrx_pdev_t *pdev);
-void ol_tx_dump_flow_pool_info(void);
+void ol_tx_dump_flow_pool_info(void *);
 void ol_tx_clear_flow_pool_stats(void);
 void ol_tx_flow_pool_map_handler(uint8_t flow_id, uint8_t flow_type,
 				 uint8_t flow_pool_id, uint16_t flow_pool_size);
@@ -557,7 +557,7 @@
 static inline void ol_tx_deregister_flow_control(struct ol_txrx_pdev_t *pdev)
 {
 }
-static inline void ol_tx_dump_flow_pool_info(void)
+static inline void ol_tx_dump_flow_pool_info(void *ctx)
 {
 }
 static inline void ol_tx_clear_flow_pool_stats(void)
diff --git a/core/dp/txrx/ol_tx.c b/core/dp/txrx/ol_tx.c
index 274af2b..4192c4d 100644
--- a/core/dp/txrx/ol_tx.c
+++ b/core/dp/txrx/ol_tx.c
@@ -1524,7 +1524,7 @@
 					     1 /* error */);
 		if (tx_msdu_info->peer) {
 			/* remove the peer reference added above */
-			ol_txrx_peer_unref_delete(tx_msdu_info->peer);
+			OL_TXRX_PEER_UNREF_DELETE(tx_msdu_info->peer);
 		}
 		return 1; /* can't accept the tx mgmt frame */
 	}
@@ -1549,7 +1549,7 @@
 	ol_tx_enqueue(vdev->pdev, txq, tx_desc, tx_msdu_info);
 	if (tx_msdu_info->peer) {
 		/* remove the peer reference added above */
-		ol_txrx_peer_unref_delete(tx_msdu_info->peer);
+		OL_TXRX_PEER_UNREF_DELETE(tx_msdu_info->peer);
 	}
 	ol_tx_sched(vdev->pdev);
 
@@ -1739,7 +1739,7 @@
 				if (tx_msdu_info.peer) {
 					/* remove the peer reference
 					 * added above */
-					ol_txrx_peer_unref_delete(
+					OL_TXRX_PEER_UNREF_DELETE(
 							tx_msdu_info.peer);
 				}
 				goto MSDU_LOOP_BOTTOM;
@@ -1757,7 +1757,7 @@
 					ol_tx_desc_frame_free_nonstd(pdev,
 								     tx_desc,
 								     1);
-					ol_txrx_peer_unref_delete(
+					OL_TXRX_PEER_UNREF_DELETE(
 							tx_msdu_info.peer);
 					msdu = next;
 					continue;
@@ -1773,7 +1773,7 @@
 						ol_tx_desc_frame_free_nonstd(
 								pdev,
 								tx_desc, 1);
-						ol_txrx_peer_unref_delete(
+						OL_TXRX_PEER_UNREF_DELETE(
 							tx_msdu_info.peer);
 						msdu = next;
 						continue;
@@ -1822,7 +1822,7 @@
 				OL_TX_PEER_STATS_UPDATE(tx_msdu_info.peer,
 							msdu);
 				/* remove the peer reference added above */
-				ol_txrx_peer_unref_delete(tx_msdu_info.peer);
+				OL_TXRX_PEER_UNREF_DELETE(tx_msdu_info.peer);
 			}
 MSDU_LOOP_BOTTOM:
 			msdu = next;
diff --git a/core/dp/txrx/ol_tx_classify.c b/core/dp/txrx/ol_tx_classify.c
index 62c1e80..eb47024 100644
--- a/core/dp/txrx/ol_tx_classify.c
+++ b/core/dp/txrx/ol_tx_classify.c
@@ -357,7 +357,7 @@
 			peer = NULL;
 		} else {
 			if (peer)
-				qdf_atomic_inc(&peer->ref_cnt);
+				OL_TXRX_PEER_INC_REF_CNT(peer);
 		}
 	}
 	if (!peer)
@@ -582,7 +582,7 @@
 					   "%s: remove the peer for invalid peer_id %p\n",
 					   __func__, peer);
 				/* remove the peer reference added above */
-				ol_txrx_peer_unref_delete(peer);
+				OL_TXRX_PEER_UNREF_DELETE(peer);
 				tx_msdu_info->peer = NULL;
 			}
 			return NULL;
@@ -605,7 +605,7 @@
 			   "%s: remove the peer reference %p\n",
 			   __func__, peer);
 		/* remove the peer reference added above */
-		ol_txrx_peer_unref_delete(tx_msdu_info->peer);
+		OL_TXRX_PEER_UNREF_DELETE(tx_msdu_info->peer);
 		/* Making peer NULL in case if multicast non STA mode */
 		tx_msdu_info->peer = NULL;
 	}
@@ -688,11 +688,7 @@
 				if (ol_txrx_peer_find_mac_addr_cmp(
 							mac_addr,
 							&peer->mac_addr) != 0) {
-					rcnt = ol_txrx_peer_unref_delete(peer);
-					QDF_TRACE(QDF_MODULE_ID_TXRX,
-						 QDF_TRACE_LEVEL_INFO_HIGH,
-						 "%s: peer %p peer->ref_cnt %d",
-						 __func__, peer, rcnt);
+					rcnt = OL_TXRX_PEER_UNREF_DELETE(peer);
 					peer = NULL;
 				}
 			}
diff --git a/core/dp/txrx/ol_tx_desc.c b/core/dp/txrx/ol_tx_desc.c
index ed587f0..f5ffd5f 100644
--- a/core/dp/txrx/ol_tx_desc.c
+++ b/core/dp/txrx/ol_tx_desc.c
@@ -767,6 +767,9 @@
 
 	if (tsoseg != NULL) {
 		txdesc = tsoseg->dbg.txdesc;
+		/* Don't validate if TX desc is NULL*/
+		if (!txdesc)
+			return 0;
 		if (txdesc->tso_desc != tsoseg)
 			qdf_tso_seg_dbg_bug("Owner sanity failed");
 		else
@@ -849,6 +852,7 @@
 	}
 	/* sanitize before free */
 	ol_tso_seg_dbg_sanitize(tso_seg);
+	qdf_tso_seg_dbg_setowner(tso_seg, NULL);
 	/*this tso seg is now a part of freelist*/
 	/* retain segment history, if debug is enabled */
 	qdf_tso_seg_dbg_zero(tso_seg);
diff --git a/core/dp/txrx/ol_tx_queue.c b/core/dp/txrx/ol_tx_queue.c
index 0014555..581ed49 100644
--- a/core/dp/txrx/ol_tx_queue.c
+++ b/core/dp/txrx/ol_tx_queue.c
@@ -111,13 +111,7 @@
 			for (i = 0; i < OL_TX_NUM_TIDS; i++) {
 				txq = &peer->txqs[i];
 				if (txq->frms) {
-					qdf_atomic_inc(&peer->ref_cnt);
-					QDF_TRACE(QDF_MODULE_ID_TXRX,
-						 QDF_TRACE_LEVEL_INFO_HIGH,
-						 "%s: peer %p peer->ref_cnt %d",
-						  __func__, peer,
-						  qdf_atomic_read
-							(&peer->ref_cnt));
+					OL_TXRX_PEER_INC_REF_CNT(peer);
 					peers[peer_count++] = peer;
 					break;
 				}
@@ -135,7 +129,7 @@
 			}
 			ol_txrx_info(
 				   "%s: Delete Peer %p\n", __func__, peer);
-			ol_txrx_peer_unref_delete(peers[i]);
+			OL_TXRX_PEER_UNREF_DELETE(peers[i]);
 		}
 	} while (peer_count >= PEER_ARRAY_COUNT);
 }
diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c
index 2e10de5..b984126 100644
--- a/core/dp/txrx/ol_txrx.c
+++ b/core/dp/txrx/ol_txrx.c
@@ -310,10 +310,7 @@
 	if (!peer)
 		return NULL;
 	*peer_id = peer->local_id;
-	qdf_atomic_dec(&peer->ref_cnt);
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
-		 "%s: peer %p peer->ref_cnt %d", __func__, peer,
-		 qdf_atomic_read(&peer->ref_cnt));
+	OL_TXRX_PEER_DEC_REF_CNT(peer);
 	return peer;
 }
 
@@ -369,11 +366,8 @@
 	if (!peer)
 		return NULL;
 	*peer_id = peer->local_id;
-	qdf_atomic_dec(&peer->ref_cnt);
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
-		 "%s: peer %p peer->ref_cnt %d", __func__, peer,
-		 qdf_atomic_read(&peer->ref_cnt));
-	return (void *)peer;
+	OL_TXRX_PEER_DEC_REF_CNT(peer);
+	return peer;
 }
 
 static uint16_t ol_txrx_local_peer_id(void *ppeer)
@@ -1813,7 +1807,7 @@
 	}
 
 	/* to get flow pool status before freeing descs */
-	ol_tx_dump_flow_pool_info();
+	ol_tx_dump_flow_pool_info((void *)pdev);
 
 	for (i = 0; i < pdev->tx_desc.pool_size; i++) {
 		void *htt_tx_desc;
@@ -2505,7 +2499,7 @@
 	qdf_atomic_init(&peer->ref_cnt);
 
 	/* keep one reference for attach */
-	qdf_atomic_inc(&peer->ref_cnt);
+	OL_TXRX_PEER_INC_REF_CNT(peer);
 
 	/*
 	 * Set a flag to indicate peer create is pending in firmware and
@@ -2516,7 +2510,7 @@
 	 */
 	qdf_atomic_init(&peer->fw_create_pending);
 	qdf_atomic_set(&peer->fw_create_pending, 1);
-	qdf_atomic_inc(&peer->ref_cnt);
+	OL_TXRX_PEER_INC_REF_CNT(peer);
 
 	peer->valid = 1;
 	qdf_timer_init(pdev->osdev, &peer->peer_unmap_timer,
@@ -2943,11 +2937,7 @@
 			   "%s: no state change, returns directly\n",
 			   __func__);
 #endif
-		peer_ref_cnt = ol_txrx_peer_unref_delete(peer);
-		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
-			  "%s: peer %p peer->ref_cnt %d",
-			  __func__, peer, peer_ref_cnt);
-
+		peer_ref_cnt = OL_TXRX_PEER_UNREF_DELETE(peer);
 		return QDF_STATUS_SUCCESS;
 	}
 
@@ -2977,15 +2967,12 @@
 				ol_txrx_peer_tid_unpause(peer, tid);
 		}
 	}
-	peer_ref_cnt = ol_txrx_peer_unref_delete(peer);
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
-		 "%s: peer %p peer->ref_cnt %d",
-		 __func__, peer, peer_ref_cnt);
+	peer_ref_cnt = OL_TXRX_PEER_UNREF_DELETE(peer);
 	/*
-	 * after ol_txrx_peer_unref_delete, peer object cannot be accessed
+	 * after OL_TXRX_PEER_UNREF_DELETE, peer object cannot be accessed
 	 * if the return code was 0
 	 */
-	if (peer_ref_cnt)
+	if (peer_ref_cnt > 0)
 		/*
 		 * Set the state after the Pause to avoid the race condiction
 		 * with ADDBA check in tx path
@@ -3090,10 +3077,7 @@
 		break;
 	}
 	} /* switch */
-	peer_ref_cnt = ol_txrx_peer_unref_delete(peer);
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
-		 "%s: peer %p peer->ref_cnt %d",
-		 __func__, peer, peer_ref_cnt);
+	peer_ref_cnt = OL_TXRX_PEER_UNREF_DELETE(peer);
 }
 
 uint8_t
@@ -3119,7 +3103,9 @@
 	return 0;
 }
 
-int ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer)
+int ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer,
+					const char *fname,
+					int line)
 {
 	int    rc;
 	struct ol_txrx_vdev_t *vdev;
@@ -3285,8 +3271,8 @@
 	} else {
 		qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
-			  "%s: peer %p peer->ref_cnt = %d",
-			  __func__, peer, rc);
+			  "ref delete(%s): peer %p peer->ref_cnt = %d",
+			  fname, peer, rc);
 	}
 
 	return rc;
@@ -3347,8 +3333,26 @@
 
 }
 
+void peer_unmap_timer_work_function(void *param)
+{
+	WMA_LOGE("Enter: %s", __func__);
+	/*
+	 * wma_peer_debug_dump() will be replaced with a new routine.
+	 * Add the equivalent of wma_peer_debug_dump() when available.
+	 */
+	if (cds_is_self_recovery_enabled()) {
+		if (!cds_is_driver_recovering())
+			cds_trigger_recovery(false);
+		else
+			WMA_LOGE("%s: Recovery is in progress, ignore!",
+					__func__);
+	} else {
+		QDF_BUG(0);
+	}
+}
+
 /**
- * peer_unmap_timer() - peer unmap timer function
+ * peer_unmap_timer_handler() - peer unmap timer function
  * @data: peer object pointer
  *
  * Return: none
@@ -3356,6 +3360,7 @@
 void peer_unmap_timer_handler(void *data)
 {
 	ol_txrx_peer_handle peer = (ol_txrx_peer_handle)data;
+	ol_txrx_pdev_handle txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
 
 	ol_txrx_err("all unmap events not received for peer %p, ref_cnt %d",
 		    peer, qdf_atomic_read(&peer->ref_cnt));
@@ -3365,10 +3370,10 @@
 		    peer->mac_addr.raw[2], peer->mac_addr.raw[3],
 		    peer->mac_addr.raw[4], peer->mac_addr.raw[5]);
 	if (!cds_is_driver_recovering()) {
-		/*
-		 * Add the equivalent of wma_peer_debug_dump() when available.
-		 */
-		QDF_BUG(0);
+		qdf_create_work(0, &txrx_pdev->peer_unmap_timer_work,
+				peer_unmap_timer_work_function,
+				NULL);
+		qdf_sched_work(0, &txrx_pdev->peer_unmap_timer_work);
 	} else {
 		ol_txrx_err("Recovery is in progress, ignore!");
 	}
@@ -3449,7 +3454,7 @@
 	 * PEER_UNMAP message arrives to remove the other
 	 * reference, added by the PEER_MAP message.
 	 */
-	ol_txrx_peer_unref_delete(peer);
+	OL_TXRX_PEER_UNREF_DELETE(peer);
 }
 
 /**
@@ -3477,7 +3482,7 @@
 	qdf_spin_unlock_bh(&pdev->peer_map_unmap_lock);
 
 	/*
-	 * Set ref_cnt = 1 so that ol_txrx_peer_unref_delete() called by
+	 * Set ref_cnt = 1 so that OL_TXRX_PEER_UNREF_DELETE() called by
 	 * ol_txrx_peer_detach() will actually delete this peer entry properly.
 	 */
 	qdf_spin_lock_bh(&pdev->peer_ref_mutex);
@@ -3497,7 +3502,7 @@
 		ol_txrx_info_high(
 			   "%s: Delete extra reference %p", __func__, peer);
 		/* release the extra reference */
-		ol_txrx_peer_unref_delete(peer);
+		OL_TXRX_PEER_UNREF_DELETE(peer);
 	}
 	return peer;
 }
@@ -4580,7 +4585,7 @@
 		ol_txrx_stats_display_tso(pdev);
 		break;
 	case CDP_DUMP_TX_FLOW_POOL_INFO:
-		ol_tx_dump_flow_pool_info();
+		ol_tx_dump_flow_pool_info((void *)pdev);
 		break;
 	case CDP_TXRX_DESC_STATS:
 		qdf_nbuf_tx_desc_count_display();
@@ -4993,7 +4998,8 @@
  *
  * Return: QDF status
  */
-static QDF_STATUS ol_txrx_register_pause_cb(ol_tx_pause_callback_fp pause_cb)
+static QDF_STATUS ol_txrx_register_pause_cb(struct cdp_soc_t *soc,
+	tx_pause_callback pause_cb)
 {
 	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
 
@@ -5362,7 +5368,7 @@
 #ifdef QCA_LL_TX_FLOW_CONTROL_V2
 	.register_pause_cb = ol_txrx_register_pause_cb,
 	.set_desc_global_pool_size = ol_tx_set_desc_global_pool_size,
-	.dump_flow_pool_info = ol_tx_dump_flow_pool_info
+	.dump_flow_pool_info = ol_tx_dump_flow_pool_info,
 #endif /* QCA_LL_TX_FLOW_CONTROL_V2 */
 };
 
diff --git a/core/dp/txrx/ol_txrx.h b/core/dp/txrx/ol_txrx.h
index de60f40..f4c9927 100644
--- a/core/dp/txrx/ol_txrx.h
+++ b/core/dp/txrx/ol_txrx.h
@@ -39,8 +39,13 @@
  * only for forwarding path.
  */
 #define OL_TX_NON_FWD_RESERVE	100
+#define OL_TXRX_PEER_UNREF_DELETE(peer) \
+	ol_txrx_peer_unref_delete(peer, __func__, __LINE__);
 
-int ol_txrx_peer_unref_delete(struct ol_txrx_peer_t *peer);
+int ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer,
+					      const char *fname,
+					      int line);
+
 
 /**
  * ol_tx_desc_pool_size_hl() - allocate tx descriptor pool size for HL systems
@@ -123,6 +128,7 @@
 				uint8_t *peer_id);
 
 void htt_pkt_log_init(struct cdp_pdev *pdev_handle, void *scn);
+void peer_unmap_timer_work_function(void *);
 void peer_unmap_timer_handler(void *data);
 
 #endif /* _OL_TXRX__H_ */
diff --git a/core/dp/txrx/ol_txrx_flow_control.c b/core/dp/txrx/ol_txrx_flow_control.c
index 0373352..405ed38 100644
--- a/core/dp/txrx/ol_txrx_flow_control.c
+++ b/core/dp/txrx/ol_txrx_flow_control.c
@@ -128,8 +128,10 @@
 			break;
 		qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock);
 		ol_txrx_info("flow pool list is not empty %d!!!\n", i++);
+
 		if (i == 1)
-			ol_tx_dump_flow_pool_info();
+			ol_tx_dump_flow_pool_info((void *)pdev);
+
 		ol_tx_dec_pool_ref(pool, true);
 		qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock);
 	}
@@ -274,13 +276,12 @@
  *
  * Return: none
  */
-void ol_tx_dump_flow_pool_info(void)
+void ol_tx_dump_flow_pool_info(void *ctx)
 {
-	struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	struct ol_txrx_pdev_t *pdev = ctx;
 	struct ol_tx_flow_pool_t *pool = NULL, *pool_prev = NULL;
 	struct ol_tx_flow_pool_t tmp_pool;
 
-
 	ol_txrx_info("Global Pool");
 	if (!pdev) {
 		ol_txrx_err("ERROR: pdev NULL");
diff --git a/core/dp/txrx/ol_txrx_peer_find.c b/core/dp/txrx/ol_txrx_peer_find.c
index ad21218..914bf81 100644
--- a/core/dp/txrx/ol_txrx_peer_find.c
+++ b/core/dp/txrx/ol_txrx_peer_find.c
@@ -69,6 +69,26 @@
 	return log2;
 }
 
+/**
+ * __ol_txrx_peer_change_ref_cnt() - change peer ref count by the input value
+ * @peer: pointer to peer structure
+ * @change: value to add to the peer->ref_cnt, can be negative
+ * @fname: name of the calling function
+ * @line: line number of the calling function
+ *
+ * Return: the QDF_STATUS return from hdd_execute_config_command
+ */
+void __ol_txrx_peer_change_ref_cnt(struct ol_txrx_peer_t *peer,
+						int change,
+						const char *fname,
+						int line)
+{
+	qdf_atomic_add(change, &peer->ref_cnt);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
+		"[%s][%d]: peer %p peer->ref_cnt changed by(%d) to %d",
+		fname, line, peer, change, qdf_atomic_read(&peer->ref_cnt));
+}
+
 /*=== function definitions for peer MAC addr --> peer object hash table =====*/
 
 /*
@@ -178,15 +198,9 @@
 		if (ol_txrx_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) ==
 		    0 && (check_valid == 0 || peer->valid)
 		    && peer->vdev == vdev) {
-			/*
-			 * found it - increment the ref count before releasing
-			 * the lock
-			 */
-			qdf_atomic_inc(&peer->ref_cnt);
-			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
-				 "%s: peer %p peer->ref_cnt %d",
-				 __func__, peer,
-				 qdf_atomic_read(&peer->ref_cnt));
+
+			/* found it */
+			OL_TXRX_PEER_INC_REF_CNT(peer);
 			qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
 			return peer;
 		}
@@ -216,16 +230,9 @@
 	TAILQ_FOREACH(peer, &pdev->peer_hash.bins[index], hash_list_elem) {
 		if (ol_txrx_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) ==
 		    0 && (check_valid == 0 || peer->valid)) {
-			/*
-			 * found it - increment the ref count before
-			 * releasing the lock
-			 */
-			qdf_atomic_inc(&peer->ref_cnt);
+			/* found it */
+			OL_TXRX_PEER_INC_REF_CNT(peer);
 			qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
-			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
-				 "%s: peer %p peer->ref_cnt %d",
-				 __func__, peer,
-				 qdf_atomic_read(&peer->ref_cnt));
 			return peer;
 		}
 	}
@@ -286,16 +293,11 @@
 				/*
 				 * Artificially adjust the peer's ref count to
 				 * 1, so it will get deleted by
-				 * ol_txrx_peer_unref_delete.
+				 * OL_TXRX_PEER_UNREF_DELETE.
 				 */
 				qdf_atomic_init(&peer->ref_cnt); /* set to 0 */
-				qdf_atomic_inc(&peer->ref_cnt); /* incr to 1 */
-				QDF_TRACE(QDF_MODULE_ID_TXRX,
-					 QDF_TRACE_LEVEL_INFO_HIGH,
-					 "%s: Delete Peer %p ref_cnt %d\n",
-					 __func__, peer,
-					 qdf_atomic_read(&peer->ref_cnt));
-				ol_txrx_peer_unref_delete(peer);
+				OL_TXRX_PEER_INC_REF_CNT(peer); /* incr to 1 */
+				OL_TXRX_PEER_UNREF_DELETE(peer);
 			}
 		}
 	}
@@ -345,6 +347,8 @@
 	struct ol_txrx_peer_t *peer;
 	int status;
 	int i;
+	uint32_t peer_id_ref_cnt;
+	uint32_t peer_ref_cnt;
 
 	/* check if there's already a peer object with this MAC address */
 	peer =
@@ -395,18 +399,17 @@
 		 * was sent to firmware.
 		 */
 		qdf_atomic_set(&peer->fw_create_pending, 0);
-		ol_txrx_peer_unref_delete(peer);
+		OL_TXRX_PEER_UNREF_DELETE(peer);
 	}
 
 	qdf_spin_unlock(&pdev->peer_map_unmap_lock);
 
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+	peer_id_ref_cnt = qdf_atomic_read(&pdev->
+				peer_id_to_obj_map[peer_id].peer_id_ref_cnt);
+	peer_ref_cnt = qdf_atomic_read(&peer->ref_cnt);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
 	   "%s: peer %p ID %d peer_id[%d] peer_id_ref_cnt %d peer->ref_cnt %d",
-	   __func__, peer, peer_id, i,
-	   qdf_atomic_read(&pdev->
-				peer_id_to_obj_map[peer_id].
-				peer_id_ref_cnt),
-	   qdf_atomic_read(&peer->ref_cnt));
+	   __func__, peer, peer_id, i, peer_id_ref_cnt, peer_ref_cnt);
 
 	if (status) {
 		/* TBDXXX: assert for now */
@@ -591,7 +594,7 @@
 	 * Remove a reference to the peer.
 	 * If there are no more references, delete the peer object.
 	 */
-	ol_txrx_peer_unref_delete(peer);
+	OL_TXRX_PEER_UNREF_DELETE(peer);
 
 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
 	   "%s: Remove the ID %d reference to peer %p peer_id_ref_cnt %d",
@@ -633,7 +636,7 @@
 			  peer_id, peer_id_ref_cnt, i);
 		/*
 		 * Transfer peer_id_ref_cnt into del_peer_id_ref_cnt so that
-		 * ol_txrx_peer_unref_delete will decrement del_peer_id_ref_cnt
+		 * OL_TXRX_PEER_UNREF_DELETE will decrement del_peer_id_ref_cnt
 		 * and any map events will increment peer_id_ref_cnt. Otherwise
 		 * accounting will be messed up.
 		 *
@@ -660,13 +663,8 @@
 	 */
 	if (vdev->last_real_peer
 	    && vdev->last_real_peer->peer_ids[0] != HTT_INVALID_PEER_ID) {
-		qdf_atomic_inc(&vdev->last_real_peer->ref_cnt);
+		OL_TXRX_PEER_INC_REF_CNT(vdev->last_real_peer);
 		peer = vdev->last_real_peer;
-		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
-			 "%s: peer %p peer->ref_cnt %d",
-			 __func__, peer,
-			 qdf_atomic_read
-				(&peer->ref_cnt));
 	} else {
 		peer = NULL;
 	}
diff --git a/core/dp/txrx/ol_txrx_peer_find.h b/core/dp/txrx/ol_txrx_peer_find.h
index 5e826af..df717a5 100644
--- a/core/dp/txrx/ol_txrx_peer_find.h
+++ b/core/dp/txrx/ol_txrx_peer_find.h
@@ -36,6 +36,17 @@
 #include <cdp_txrx_cmn.h>       /* ol_txrx_pdev_t, etc. */
 #include <ol_txrx_internal.h>   /* TXRX_ASSERT */
 
+
+#define OL_TXRX_PEER_INC_REF_CNT(peer) \
+	__ol_txrx_peer_change_ref_cnt(peer, 1, __func__, __LINE__);
+
+#define OL_TXRX_PEER_DEC_REF_CNT(peer) \
+	__ol_txrx_peer_change_ref_cnt(peer, (-1), __func__, __LINE__);
+
+void __ol_txrx_peer_change_ref_cnt(struct ol_txrx_peer_t *peer,
+						int change,
+						const char *fname,
+						int line);
 int ol_txrx_peer_find_attach(struct ol_txrx_pdev_t *pdev);
 
 void ol_txrx_peer_find_detach(struct ol_txrx_pdev_t *pdev);
@@ -107,10 +118,8 @@
 void ol_txrx_peer_find_hash_erase(struct ol_txrx_pdev_t *pdev);
 
 struct ol_txrx_peer_t *ol_txrx_assoc_peer_find(struct ol_txrx_vdev_t *vdev);
-
 void ol_txrx_peer_remove_obj_map_entries(ol_txrx_pdev_handle pdev,
 					struct ol_txrx_peer_t *peer);
-
 #if defined(TXRX_DEBUG_LEVEL) && TXRX_DEBUG_LEVEL > 5
 void ol_txrx_peer_find_display(ol_txrx_pdev_handle pdev, int indent);
 #else
diff --git a/core/dp/txrx/ol_txrx_types.h b/core/dp/txrx/ol_txrx_types.h
index 969c01d..b9e48c6 100644
--- a/core/dp/txrx/ol_txrx_types.h
+++ b/core/dp/txrx/ol_txrx_types.h
@@ -48,7 +48,7 @@
 #include "ol_htt_tx_api.h"
 #include "ol_htt_rx_api.h"
 #include "ol_txrx_ctrl_api.h" /* WLAN_MAX_STA_COUNT */
-#include "ol_txrx_osif_api.h" /* ol_rx_callback_fp */
+#include "ol_txrx_osif_api.h" /* ol_rx_callback */
 #include "cdp_txrx_flow_ctrl_v2.h"
 #include "cdp_txrx_peer_ops.h"
 
@@ -971,13 +971,14 @@
 	int tid_to_ac[OL_TX_NUM_TIDS + OL_TX_VDEV_NUM_QUEUES];
 	uint8_t ocb_peer_valid;
 	struct ol_txrx_peer_t *ocb_peer;
-	ol_tx_pause_callback_fp pause_cb;
+	tx_pause_callback pause_cb;
 
 	struct {
 		void (*lro_flush_cb)(void *);
 		qdf_atomic_t lro_dev_cnt;
 	} lro_info;
 	struct ol_txrx_peer_t *self_peer;
+	qdf_work_t peer_unmap_timer_work;
 };
 
 struct ol_txrx_vdev_t {
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index 5375635..7c512b9 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -5798,6 +5798,29 @@
 #define CFG_RATE_FOR_TX_MGMT_5G_MAX        (WNI_CFG_RATE_FOR_TX_MGMT_5G_STAMAX)
 #define CFG_RATE_FOR_TX_MGMT_5G_DEFAULT    (WNI_CFG_RATE_FOR_TX_MGMT_5G_STADEF)
 
+/*
+ * <ini>
+ * gPreventLinkDown - Enable to prevent bus link from going down
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * Enable to prevent bus link from going down. Useful for platforms that do not
+ * (yet) support link down suspend cases.
+ *
+ * Related: N/A
+ *
+ * Supported Feature: Suspend/Resume
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_PREVENT_LINK_DOWN_NAME		"gPreventLinkDown"
+#define CFG_PREVENT_LINK_DOWN_MIN		(0)
+#define CFG_PREVENT_LINK_DOWN_MAX		(1)
+#define CFG_PREVENT_LINK_DOWN_DEFAULT		(0)
+
 #ifdef FEATURE_WLAN_TDLS
 /*
  * <ini>
@@ -10457,6 +10480,70 @@
 #define CFG_ITO_REPEAT_COUNT_MAX        (5)
 #define CFG_ITO_REPEAT_COUNT_DEFAULT    (0)
 /*
+ * <ini>
+ * 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
+ *
+ * </ini>
+ */
+#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)
+
+/*
+ * <ini>
+ * 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
+ *
+ * </ini>
+ */
+#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)
+
+/*
+ * <ini>
+ * 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
+ *
+ * </ini>
+ */
+#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
  */
 
@@ -10784,6 +10871,7 @@
 	uint8_t enable_tx_ldpc;
 	uint8_t enable_rx_ldpc;
 	bool enable5gEBT;
+	bool prevent_link_down;
 #ifdef FEATURE_WLAN_TDLS
 	bool fEnableTDLSSupport;
 	bool fEnableTDLSImplicitTrigger;
@@ -11200,6 +11288,11 @@
 	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/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index 822e49e..4a1cb2b 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -92,6 +92,14 @@
 #define NUM_TX_QUEUES 4
 #endif
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
+#define HDD_NL80211_BAND_2GHZ   NL80211_BAND_2GHZ
+#define HDD_NL80211_BAND_5GHZ   NL80211_BAND_5GHZ
+#else
+#define HDD_NL80211_BAND_2GHZ   IEEE80211_BAND_2GHZ
+#define HDD_NL80211_BAND_5GHZ   IEEE80211_BAND_5GHZ
+#endif
+
 /** Length of the TX queue for the netdev */
 #define HDD_NETDEV_TX_QUEUE_LEN (3000)
 
@@ -288,6 +296,7 @@
 #define HDD_SESSION_ID_INVALID    0xFF
 
 #define SCAN_REJECT_THRESHOLD_TIME 300000 /* Time is in msec, equal to 5 mins */
+#define SCAN_REJECT_THRESHOLD 15
 
 /* Default Psoc id */
 #define DEFAULT_PSOC_ID 1
@@ -1619,6 +1628,7 @@
 	uint8_t last_scan_reject_session_id;
 	enum scan_reject_states last_scan_reject_reason;
 	unsigned long last_scan_reject_timestamp;
+	uint8_t scan_reject_cnt;
 	bool dfs_cac_offload;
 	bool reg_offload;
 #ifdef FEATURE_WLAN_CH_AVOID
@@ -1635,6 +1645,8 @@
 	/* the context that is capturing tsf */
 	hdd_adapter_t *cap_tsf_context;
 #endif
+	uint8_t bt_a2dp_active:1;
+	uint8_t bt_vo_active:1;
 };
 
 /**
diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c
index c76fd7f..3a24594 100644
--- a/core/hdd/src/wlan_hdd_assoc.c
+++ b/core/hdd/src/wlan_hdd_assoc.c
@@ -165,31 +165,30 @@
 
 /**
  * hdd_conn_set_connection_state() - set connection state
- * @pAdapter: pointer to the adapter
- * @connState: connection state
+ * @adapter: pointer to the adapter
+ * @conn_state: connection state
  *
  * This function updates the global HDD station context connection state.
  *
  * Return: none
  */
-void hdd_conn_set_connection_state(hdd_adapter_t *pAdapter,
-				   eConnectionState connState)
+void hdd_conn_set_connection_state(hdd_adapter_t *adapter,
+				   eConnectionState conn_state)
 {
-	hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
-	hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+	hdd_station_ctx_t *hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 
 	/* save the new connection state */
-	hdd_debug("%pS Changed connectionState Changed from oldState:%d to State:%d",
-		(void *)_RET_IP_, pHddStaCtx->conn_info.connState,
-		connState);
+	hdd_debug("%pS Changed conn state from old:%d to new:%d for dev %s",
+		(void *)_RET_IP_, hdd_sta_ctx->conn_info.connState,
+		conn_state, adapter->dev->name);
 
-	hdd_tsf_notify_wlan_state_change(pAdapter,
-					 pHddStaCtx->conn_info.connState,
-					 connState);
-	pHddStaCtx->conn_info.connState = connState;
+	hdd_tsf_notify_wlan_state_change(adapter,
+					 hdd_sta_ctx->conn_info.connState,
+					 conn_state);
+	hdd_sta_ctx->conn_info.connState = conn_state;
 
-	/* Check is pending ROC request or not when connection state changed */
-	schedule_delayed_work(&pHddCtx->roc_req_work, 0);
+	schedule_delayed_work(&hdd_ctx->roc_req_work, 0);
 }
 
 /**
@@ -2113,8 +2112,11 @@
 	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
 			   buf_ssid_ie, ssid_ie_len);
 	final_req_ie = qdf_mem_malloc(IW_GENERIC_IE_MAX);
-	if (final_req_ie == NULL)
+	if (final_req_ie == NULL) {
+		if (bss)
+			cfg80211_put_bss(pAdapter->wdev.wiphy, bss);
 		goto done;
+	}
 	buf_ptr = final_req_ie;
 	qdf_mem_copy(buf_ptr, buf_ssid_ie, ssid_ie_len);
 	buf_ptr += ssid_ie_len;
@@ -2471,7 +2473,9 @@
 	    pHddStaCtx->conn_info.connState)) &&
 	    ((eCSR_ROAM_RESULT_ASSOCIATED == roamResult) ||
 	    (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus))) {
-		hdd_info("Disconnect from HDD in progress");
+		hdd_info("hddDisconInProgress state=%d, result=%d, status=%d",
+				pHddStaCtx->conn_info.connState,
+				roamResult, roamStatus);
 		hddDisconInProgress = true;
 	}
 
@@ -3204,10 +3208,10 @@
 
 			if (chan_no <= 14)
 				freq = ieee80211_channel_to_frequency(chan_no,
-					  NL80211_BAND_2GHZ);
+					  HDD_NL80211_BAND_2GHZ);
 			else
 				freq = ieee80211_channel_to_frequency(chan_no,
-					  NL80211_BAND_5GHZ);
+					  HDD_NL80211_BAND_5GHZ);
 
 			chan = ieee80211_get_channel(pAdapter->wdev.wiphy, freq);
 
@@ -3347,8 +3351,8 @@
 
 	if (MAX_PEERS == empty_slots) {
 		/* Last peer departed, set the IBSS state appropriately */
-		pHddStaCtx->conn_info.connState =
-			eConnectionState_IbssDisconnected;
+		hdd_conn_set_connection_state(pAdapter,
+				eConnectionState_IbssDisconnected);
 		hdd_debug("Last IBSS Peer Departed!!!");
 	}
 	/* Find next active staId, to have a valid sta trigger for TL. */
@@ -3445,7 +3449,7 @@
 		hdd_debug("MIC MAC " MAC_ADDRESS_STR,
 			 MAC_ADDR_ARRAY(msg.src_addr.sa_data));
 
-		if (pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE)
+		if (pRoamInfo->u.pMICFailureInfo->multicast == true)
 			msg.flags = IW_MICFAILURE_GROUP;
 		else
 			msg.flags = IW_MICFAILURE_PAIRWISE;
@@ -3459,7 +3463,7 @@
 					     taMacAddr,
 					     ((pRoamInfo->u.pMICFailureInfo->
 					       multicast ==
-					       eSIR_TRUE) ?
+					       true) ?
 					      NL80211_KEYTYPE_GROUP :
 					      NL80211_KEYTYPE_PAIRWISE),
 					     pRoamInfo->u.pMICFailureInfo->
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index 07c7036..0a29fc0 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -2197,6 +2197,13 @@
 		     CFG_PPS_ENABLE_5G_EBT_FEATURE_MIN,
 		     CFG_PPS_ENABLE_5G_EBT_FEATURE_MAX),
 
+	REG_VARIABLE(CFG_PREVENT_LINK_DOWN_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, prevent_link_down,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_PREVENT_LINK_DOWN_DEFAULT,
+		     CFG_PREVENT_LINK_DOWN_MIN,
+		     CFG_PREVENT_LINK_DOWN_MAX),
+
 #ifdef FEATURE_WLAN_TDLS
 	REG_VARIABLE(CFG_TDLS_SUPPORT_ENABLE, WLAN_PARAM_Integer,
 		     struct hdd_config, fEnableTDLSSupport,
@@ -4463,6 +4470,27 @@
 		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 +6032,15 @@
 	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);
 }
 
 
@@ -7238,6 +7275,27 @@
 	return status;
 }
 /**
+ * hdd_to_csr_wmm_mode() - Utility function to convert HDD to CSR WMM mode
+ *
+ * @enum hdd_wmm_user_mode - hdd WMM user mode
+ *
+ * Return: CSR WMM mode
+ */
+static eCsrRoamWmmUserModeType
+hdd_to_csr_wmm_mode(enum hdd_wmm_user_mode mode)
+{
+	switch (mode) {
+	case HDD_WMM_USER_MODE_QBSS_ONLY:
+		return eCsrRoamWmmQbssOnly;
+	case HDD_WMM_USER_MODE_NO_QOS:
+		return eCsrRoamWmmNoQos;
+	case HDD_WMM_USER_MODE_AUTO:
+	default:
+		return eCsrRoamWmmAuto;
+	}
+}
+
+/**
  * hdd_set_sme_config() -initializes the sme configuration parameters
  *
  * @pHddCtx: the pointer to hdd context
@@ -7321,7 +7379,8 @@
 
 #endif
 	smeConfig->csrConfig.Is11eSupportEnabled = pConfig->b80211eIsEnabled;
-	smeConfig->csrConfig.WMMSupportMode = pConfig->WmmMode;
+	smeConfig->csrConfig.WMMSupportMode =
+		hdd_to_csr_wmm_mode(pConfig->WmmMode);
 
 	smeConfig->rrmConfig.rrm_enabled = pConfig->fRrmEnable;
 	smeConfig->rrmConfig.max_randn_interval = pConfig->nRrmRandnIntvl;
@@ -7604,6 +7663,13 @@
 
 	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/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index cd80c13..2276153 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -112,6 +112,44 @@
 #include "wlan_utility.h"
 #include "wlan_reg_ucfg_api.h"
 
+/* define short names for get station info attributes */
+#ifndef LINK_INFO_STANDARD_NL80211_ATTR
+#define LINK_INFO_STANDARD_NL80211_ATTR \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_LINK_STANDARD_NL80211_ATTR
+#endif
+#ifndef AP_INFO_STANDARD_NL80211_ATTR
+#define AP_INFO_STANDARD_NL80211_ATTR \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_STANDARD_NL80211_ATTR
+#endif
+#ifndef INFO_ROAM_COUNT
+#define INFO_ROAM_COUNT \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ROAM_COUNT
+#endif
+#ifndef INFO_AKM
+#define INFO_AKM \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AKM
+#endif
+#ifndef WLAN802_11_MODE
+#define WLAN802_11_MODE \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_802_11_MODE
+#endif
+#ifndef AP_INFO_HS20_INDICATION
+#define AP_INFO_HS20_INDICATION \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_HS20_INDICATION
+#endif
+#ifndef HT_OPERATION
+#define HT_OPERATION \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HT_OPERATION
+#endif
+#ifndef VHT_OPERATION
+#define VHT_OPERATION \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_VHT_OPERATION
+#endif
+#ifndef INFO_ASSOC_FAIL_REASON
+#define INFO_ASSOC_FAIL_REASON \
+	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_FAIL_REASON
+#endif
+
 #define g_mode_rates_size (12)
 #define a_mode_rates_size (8)
 #define GET_IE_LEN_IN_BSS_DESC(lenInBss) (lenInBss + sizeof(lenInBss) - \
@@ -130,7 +168,7 @@
 #define IBSS_CFG_PROTECTION_ENABLE_MASK 0x8282
 
 #define HDD2GHZCHAN(freq, chan, flag)   {     \
-		.band =  NL80211_BAND_2GHZ, \
+		.band = HDD_NL80211_BAND_2GHZ, \
 		.center_freq = (freq), \
 		.hw_value = (chan), \
 		.flags = (flag), \
@@ -139,7 +177,7 @@
 }
 
 #define HDD5GHZCHAN(freq, chan, flag)   {     \
-		.band =  NL80211_BAND_5GHZ, \
+		.band =  HDD_NL80211_BAND_5GHZ, \
 		.center_freq = (freq), \
 		.hw_value = (chan), \
 		.flags = (flag), \
@@ -277,7 +315,7 @@
 static struct ieee80211_supported_band wlan_hdd_band_2_4_ghz = {
 	.channels = NULL,
 	.n_channels = ARRAY_SIZE(hdd_channels_2_4_ghz),
-	.band = NL80211_BAND_2GHZ,
+	.band = HDD_NL80211_BAND_2GHZ,
 	.bitrates = g_mode_rates,
 	.n_bitrates = g_mode_rates_size,
 	.ht_cap.ht_supported = 1,
@@ -296,7 +334,7 @@
 static struct ieee80211_supported_band wlan_hdd_band_5_ghz = {
 	.channels = NULL,
 	.n_channels = ARRAY_SIZE(hdd_channels_5_ghz),
-	.band = NL80211_BAND_5GHZ,
+	.band = HDD_NL80211_BAND_5GHZ,
 	.bitrates = a_mode_rates,
 	.n_bitrates = a_mode_rates_size,
 	.ht_cap.ht_supported = 1,
@@ -1706,6 +1744,8 @@
 				sap_config->acs_cfg.is_ht_enabled,
 				sap_config->acs_cfg.is_vht_enabled,
 				hdd_ctx->config->enable_sub_20_channel_width);
+		if (icv->flags & IEEE80211_CHAN_PASSIVE)
+			icv->flagext |= IEEE80211_CHAN_DFS;
 
 		hdd_info("freq %d flags %d flagext %d ieee %d maxreg %d maxpw %d minpw %d regClass %d antenna %d seg0 %d seg1 %d",
 			icv->freq, icv->flags,
@@ -1863,12 +1903,12 @@
 	int i, temp_count = 0;
 	int acs_list_count = sap_config->acs_cfg.ch_list_count;
 	/* Get scan band */
-	if ((sap_config->acs_cfg.hw_mode == QCA_ACS_MODE_IEEE80211B) ||
-	   (sap_config->acs_cfg.hw_mode == QCA_ACS_MODE_IEEE80211G)) {
+	if ((sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211B) ||
+	   (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211G)) {
 		*band = eCSR_BAND_24;
-	} else if (sap_config->acs_cfg.hw_mode == QCA_ACS_MODE_IEEE80211A) {
+	} else if (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211A) {
 		*band = eCSR_BAND_5G;
-	} else if (sap_config->acs_cfg.hw_mode == QCA_ACS_MODE_IEEE80211ANY) {
+	} else if (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211ANY) {
 		*band = eCSR_BAND_ALL;
 	}
 	/* Auto is not supported currently */
@@ -1956,7 +1996,7 @@
 	hdd_update_reg_chan_info(adapter, channel_count, channel_list);
 	hdd_get_freq_list(channel_list, freq_list, channel_count);
 	/* Get phymode */
-	phy_mode = sme_get_phy_mode(WLAN_HDD_GET_HAL_CTX(adapter));
+	phy_mode = adapter->sessionCtx.ap.sapConfig.acs_cfg.hw_mode;
 
 	skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
 			&(adapter->wdev),
@@ -2161,6 +2201,7 @@
 		goto out;
 	}
 	hw_mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);
+	/* This value will be overwritten in wlan_hdd_set_acs_ch_range */
 	sap_config->acs_cfg.hw_mode = hw_mode;
 
 	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED])
@@ -2175,6 +2216,7 @@
 	else
 		ht40_enabled = 0;
 
+	hdd_debug("ht40_enabled %d", ht40_enabled);
 	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED])
 		vht_enabled =
 			nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED]);
@@ -2203,6 +2245,7 @@
 			ch_width = 20;
 	}
 
+	hdd_debug("channel width =%d", ch_width);
 	if (ch_width == 80)
 		sap_config->acs_cfg.ch_width = CH_WIDTH_80MHZ;
 	else if (ch_width == 40)
@@ -2277,28 +2320,34 @@
 				  pcl_channels_weight_list[i]);
 		}
 
+	wlan_hdd_set_acs_ch_range(sap_config, ht_enabled, vht_enabled);
 	/* ACS override for android */
+
+	sap_config->acs_cfg.band = hw_mode;
 	if (hdd_ctx->config->sap_p2p_11ac_override && ht_enabled &&
 	    !hdd_ctx->config->sap_force_11n_for_11ac) {
-		hdd_debug("ACS Config override for 11AC");
+		hdd_debug("ACS Config override for 11AC vhtChannelWidth %d",
+			hdd_ctx->config->vhtChannelWidth);
 		vht_enabled = 1;
 		sap_config->acs_cfg.hw_mode = eCSR_DOT11_MODE_11ac;
 		sap_config->acs_cfg.ch_width =
 					hdd_ctx->config->vhtChannelWidth;
+		ch_width = 80;
 		/* No VHT80 in 2.4G so perform ACS accordingly */
 		if (sap_config->acs_cfg.end_ch <= 14 &&
 		    sap_config->acs_cfg.ch_width == eHT_CHANNEL_WIDTH_80MHZ) {
 			sap_config->acs_cfg.ch_width = eHT_CHANNEL_WIDTH_40MHZ;
 			ch_width = 40;
+			hdd_debug("resetting to 40Mhz in 2.4Ghz");
 		}
 	}
 
-	wlan_hdd_set_acs_ch_range(sap_config, ht_enabled, vht_enabled);
 
-	hdd_debug("ACS Config for wlan%d: HW_MODE: %d ACS_BW: %d HT: %d VHT: %d START_CH: %d END_CH: %d",
-		adapter->dev->ifindex, sap_config->acs_cfg.hw_mode,
+	hdd_debug("ACS Config for %s: HW_MODE: %d ACS_BW: %d HT: %d VHT: %d START_CH: %d END_CH: %d band %d",
+		adapter->dev->name, sap_config->acs_cfg.hw_mode,
 		ch_width, ht_enabled, vht_enabled,
-		sap_config->acs_cfg.start_ch, sap_config->acs_cfg.end_ch);
+		sap_config->acs_cfg.start_ch, sap_config->acs_cfg.end_ch,
+		sap_config->acs_cfg.band);
 
 	sap_config->acs_cfg.is_ht_enabled = ht_enabled;
 	sap_config->acs_cfg.is_vht_enabled = vht_enabled;
@@ -2325,7 +2374,6 @@
 	} else {
 		/* Check if vendor specific acs is enabled */
 		if (hdd_ctx->config->vendor_acs_support) {
-			sap_config->acs_cfg.hw_mode = hw_mode;
 			hdd_create_acs_timer(adapter);
 			hdd_update_acs_timer_reason(adapter,
 				QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT);
@@ -2636,6 +2684,7 @@
 #endif
 	fset |= WIFI_FEATURE_RSSI_MONITOR;
 	fset |= WIFI_FEATURE_TX_TRANSMIT_POWER;
+	fset |= WIFI_FEATURE_SET_TX_POWER_LIMIT;
 
 	if (hdd_link_layer_stats_supported())
 		fset |= WIFI_FEATURE_LINK_LAYER_STATS;
@@ -2793,6 +2842,15 @@
 	return ret;
 }
 
+#define MAX_CONCURRENT_MATRIX \
+	QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
+#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
+	QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
+static const struct nla_policy
+wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
+	[MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
+};
+
 /**
  * __wlan_hdd_cfg80211_get_concurrency_matrix() - to retrieve concurrency matrix
  * @wiphy: pointer phy adapter
@@ -2811,7 +2869,7 @@
 {
 	uint32_t feature_set_matrix[CDS_MAX_FEATURE_SET] = {0};
 	uint8_t i, feature_sets, max_feature_sets;
-	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
+	struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
 	struct sk_buff *reply_skb;
 	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
 	int ret;
@@ -2827,19 +2885,18 @@
 	if (ret)
 		return ret;
 
-	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
-			data, data_len, NULL)) {
+	if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
+		      wlan_hdd_get_concurrency_matrix_policy)) {
 		hdd_err("Invalid ATTR");
 		return -EINVAL;
 	}
 
 	/* Parse and fetch max feature set */
-	if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
+	if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
 		hdd_err("Attr max feature set size failed");
 		return -EINVAL;
 	}
-	max_feature_sets = nla_get_u32(tb[
-		QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
+	max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
 	hdd_debug("Max feature set size: %d", max_feature_sets);
 
 	/* Fill feature combination matrix */
@@ -2877,6 +2934,9 @@
 	return cfg80211_vendor_cmd_reply(reply_skb);
 }
 
+#undef MAX_CONCURRENT_MATRIX
+#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
+
 /**
  * wlan_hdd_cfg80211_get_concurrency_matrix() - get concurrency matrix
  * @wiphy:   pointer to wireless wiphy structure.
@@ -3011,6 +3071,12 @@
 	hdd_debug("dbs_capability is %d", dbs_capability);
 
 	if (nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_CONCURRENCY_CAPA,
+			dbs_capability))
+		goto nla_put_failure;
+
+
+	if (nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_2_4_BAND,
 			MAX_CONCURRENT_CHAN_ON_24G))
 		goto nla_put_failure;
@@ -6628,11 +6694,11 @@
 		if (pcl[i] <= ARRAY_SIZE(hdd_channels_2_4_ghz))
 			freq_list[i] =
 				ieee80211_channel_to_frequency(pcl[i],
-							NL80211_BAND_2GHZ);
+							HDD_NL80211_BAND_2GHZ);
 		else
 			freq_list[i] =
 				ieee80211_channel_to_frequency(pcl[i],
-							NL80211_BAND_5GHZ);
+							HDD_NL80211_BAND_5GHZ);
 	}
 
 	/* send the freq_list back to supplicant */
@@ -8183,6 +8249,7 @@
 		hdd_err("Failed to get channel list");
 		return -EINVAL;
 	}
+
 	for (i = 0; i < chan_count; i++) {
 		if (*channel_count < QDF_MAX_NUM_CHAN) {
 			if ((eCSR_BAND_24 == band) &&
@@ -8492,7 +8559,7 @@
 
 	status = wlan_hdd_cfg80211_start_bss(pre_cac_adapter, NULL,
 			PRE_CAC_SSID, qdf_str_len(PRE_CAC_SSID),
-			eHIDDEN_SSID_NOT_IN_USE, false, false);
+			NL80211_HIDDEN_SSID_NOT_IN_USE, false, false);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		hdd_err("start bss failed");
 		goto stop_close_pre_cac_adapter;
@@ -8540,6 +8607,8 @@
 static const struct nla_policy
 wlan_hdd_sap_config_policy[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_MAX + 1] = {
 	[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL] = {.type = NLA_U8 },
+	[QCA_WLAN_VENDOR_ATTR_SAP_MANDATORY_FREQUENCY_LIST] = {
+							.type = NLA_NESTED },
 };
 
 static const struct nla_policy
@@ -9847,10 +9916,10 @@
 	int ret = 0;
 
 	switch (nl80211_value) {
-	case NL80211_BAND_2GHZ:
+	case HDD_NL80211_BAND_2GHZ:
 		*wmi_value = WMI_SAR_2G_ID;
 		break;
-	case NL80211_BAND_5GHZ:
+	case HDD_NL80211_BAND_5GHZ:
 		*wmi_value = WMI_SAR_5G_ID;
 		break;
 	default:
@@ -10356,6 +10425,47 @@
 	return ret;
 }
 
+
+void hdd_bt_activity_cb(void *context, uint32_t bt_activity)
+{
+	hdd_context_t *hdd_ctx = (hdd_context_t *)context;
+	int status;
+
+	status = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != status)
+		return;
+
+	if (bt_activity == WLAN_COEX_EVENT_BT_A2DP_PROFILE_ADD)
+		hdd_ctx->bt_a2dp_active = 1;
+	else if (bt_activity == WLAN_COEX_EVENT_BT_A2DP_PROFILE_REMOVE)
+		hdd_ctx->bt_a2dp_active = 0;
+	else if (bt_activity == WLAN_COEX_EVENT_BT_VOICE_PROFILE_ADD)
+		hdd_ctx->bt_vo_active = 1;
+	else if (bt_activity == WLAN_COEX_EVENT_BT_VOICE_PROFILE_REMOVE)
+		hdd_ctx->bt_vo_active = 0;
+	else
+		return;
+
+	hdd_info("a2dp_active:%d vo_active:%d", hdd_ctx->bt_a2dp_active,
+		 hdd_ctx->bt_vo_active);
+}
+
+
+/**
+ * wlan_hdd_is_bt_in_progress() - check if bt activity is in progress
+ * @hdd_ctx : HDD context
+ *
+ * Return: true if BT activity is in progress else false
+ */
+static inline bool wlan_hdd_is_bt_in_progress(hdd_context_t *hdd_ctx)
+{
+	if (hdd_ctx->bt_a2dp_active || hdd_ctx->bt_vo_active)
+		return true;
+
+	return false;
+}
+
+
 const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
 	{
 		.info.vendor_id = QCA_NL80211_VENDOR_ID,
@@ -11107,7 +11217,8 @@
 					hdd_ctx->hdd_pdev,
 					band->channels[j].hw_value);
 
-			if (NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) {
+			if (HDD_NL80211_BAND_2GHZ == i &&
+				eCSR_BAND_5G == eBand) {
 				/* 5G only */
 #ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY
 				/* Enable Social channels for P2P */
@@ -11122,7 +11233,7 @@
 				band->channels[j].flags |=
 					IEEE80211_CHAN_DISABLED;
 				continue;
-			} else if (NL80211_BAND_5GHZ == i &&
+			} else if (HDD_NL80211_BAND_5GHZ == i &&
 					eCSR_BAND_24 == eBand) {
 				/* 2G only */
 				band->channels[j].flags |=
@@ -11265,14 +11376,14 @@
 	 * wiphy flags don't get reset because of static memory.
 	 * It's better not to store channel in static memory.
 	 */
-	wiphy->bands[NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_ghz;
-	wiphy->bands[NL80211_BAND_2GHZ]->channels =
+	wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_ghz;
+	wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
 		qdf_mem_malloc(sizeof(hdd_channels_2_4_ghz));
-	if (wiphy->bands[NL80211_BAND_2GHZ]->channels == NULL) {
+	if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL) {
 		hdd_err("Not enough memory to allocate channels");
 		return -ENOMEM;
 	}
-	qdf_mem_copy(wiphy->bands[NL80211_BAND_2GHZ]->channels,
+	qdf_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
 			&hdd_channels_2_4_ghz[0],
 			sizeof(hdd_channels_2_4_ghz));
 	if ((hdd_is_5g_supported(pHddCtx)) &&
@@ -11280,17 +11391,17 @@
 		 (eHDD_DOT11_MODE_11g != pCfg->dot11Mode) &&
 		 (eHDD_DOT11_MODE_11b_ONLY != pCfg->dot11Mode) &&
 		 (eHDD_DOT11_MODE_11g_ONLY != pCfg->dot11Mode))) {
-		wiphy->bands[NL80211_BAND_5GHZ] = &wlan_hdd_band_5_ghz;
-		wiphy->bands[NL80211_BAND_5GHZ]->channels =
+		wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_ghz;
+		wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
 			qdf_mem_malloc(sizeof(hdd_channels_5_ghz));
-		if (wiphy->bands[NL80211_BAND_5GHZ]->channels == NULL) {
+		if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL) {
 			hdd_err("Not enough memory to allocate channels");
 			qdf_mem_free(wiphy->
-				bands[NL80211_BAND_2GHZ]->channels);
-			wiphy->bands[NL80211_BAND_2GHZ]->channels = NULL;
+				bands[HDD_NL80211_BAND_2GHZ]->channels);
+			wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
 			return -ENOMEM;
 		}
-		qdf_mem_copy(wiphy->bands[NL80211_BAND_5GHZ]->channels,
+		qdf_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
 			&hdd_channels_5_ghz[0],
 			sizeof(hdd_channels_5_ghz));
 	}
@@ -11303,7 +11414,7 @@
 		for (j = 0; j < wiphy->bands[i]->n_channels; j++) {
 			struct ieee80211_supported_band *band = wiphy->bands[i];
 
-			if (NL80211_BAND_2GHZ == i &&
+			if (HDD_NL80211_BAND_2GHZ == i &&
 				eCSR_BAND_5G == pCfg->nBandCapability) {
 				/* 5G only */
 #ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY
@@ -11317,7 +11428,7 @@
 				band->channels[j].flags |=
 					IEEE80211_CHAN_DISABLED;
 				continue;
-			} else if (NL80211_BAND_5GHZ == i &&
+			} else if (HDD_NL80211_BAND_5GHZ == i &&
 					eCSR_BAND_24 == pCfg->nBandCapability) {
 				/* 2G only */
 				band->channels[j].flags |=
@@ -11418,21 +11529,21 @@
 	ht_cap_info = (tSirMacHTCapabilityInfo *)&val16;
 
 	if (ht_cap_info->txSTBC == true) {
-		if (NULL != hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ])
-			hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap |=
+		if (NULL != hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ])
+			hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ]->ht_cap.cap |=
 						IEEE80211_HT_CAP_TX_STBC;
-		if (NULL != hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ])
-			hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ]->ht_cap.cap |=
+		if (NULL != hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ])
+			hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]->ht_cap.cap |=
 						IEEE80211_HT_CAP_TX_STBC;
 	}
 
 	if (!sme_is_feature_supported_by_fw(DOT11AC)) {
-		hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ]->
+		hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ]->
 						vht_cap.vht_supported = 0;
-		hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ]->vht_cap.cap = 0;
-		hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ]->
+		hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ]->vht_cap.cap = 0;
+		hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]->
 						vht_cap.vht_supported = 0;
-		hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.cap = 0;
+		hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]->vht_cap.cap = 0;
 	}
 }
 
@@ -13354,15 +13465,15 @@
 	}
 
 	if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_ghz) &&
-	    (wiphy->bands[NL80211_BAND_2GHZ] != NULL)) {
+	    (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL)) {
 		freq =
 			ieee80211_channel_to_frequency(chan_no,
-						       NL80211_BAND_2GHZ);
+						       HDD_NL80211_BAND_2GHZ);
 	} else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_ghz))
-		   && (wiphy->bands[NL80211_BAND_5GHZ] != NULL)) {
+		   && (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL)) {
 		freq =
 			ieee80211_channel_to_frequency(chan_no,
-						       NL80211_BAND_5GHZ);
+						       HDD_NL80211_BAND_5GHZ);
 	} else {
 		hdd_err("Invalid channel: %d", chan_no);
 		qdf_mem_free(mgmt);
@@ -15381,7 +15492,8 @@
 	wlan_hdd_netif_queue_control(pAdapter,
 		WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, WLAN_CONTROL_PATH);
 	hdd_debug("Set HDD connState to eConnectionState_Disconnecting");
-	pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
+	hdd_conn_set_connection_state(pAdapter, eConnectionState_Disconnecting);
+
 	INIT_COMPLETION(pAdapter->disconnect_comp_var);
 
 	/* issue disconnect */
diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h
index ff9893d..3bc3667 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.h
+++ b/core/hdd/src/wlan_hdd_cfg80211.h
@@ -167,6 +167,9 @@
 #define WIFI_FEATURE_CONFIG_NDO         0x200000  /* ND offload configure */
 #define WIFI_FEATURE_TX_TRANSMIT_POWER  0x400000  /* Tx transmit power levels */
 
+/* Support Tx Power Limit setting */
+#define WIFI_FEATURE_SET_TX_POWER_LIMIT 0x4000000
+
 /* Add more features here */
 #define WIFI_TDLS_SUPPORT			BIT(0)
 #define WIFI_TDLS_EXTERNAL_CONTROL_SUPPORT	BIT(1)
@@ -563,4 +566,13 @@
  */
 int wlan_hdd_merge_avoid_freqs(tHddAvoidFreqList *destFreqList,
 		tHddAvoidFreqList *srcFreqList);
+
+/**
+ * hdd_bt_activity_cb() - callback function to receive bt activity
+ * @context: HDD context
+ * @bt_activity: specifies the kind of bt activity
+ *
+ * Return: none
+ */
+void hdd_bt_activity_cb(void *context, uint32_t bt_activity);
 #endif
diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c
index d18c628..06b6ede 100644
--- a/core/hdd/src/wlan_hdd_driver_ops.c
+++ b/core/hdd/src/wlan_hdd_driver_ops.c
@@ -230,6 +230,9 @@
 		goto err_hif_close;
 	}
 
+	if (hdd_ctx->config->prevent_link_down)
+		hif_vote_link_up(hif_ctx);
+
 	status = hif_enable(hif_ctx, dev, bdev, bid, bus_type,
 			    (reinit == true) ?  HIF_ENABLE_TYPE_REINIT :
 			    HIF_ENABLE_TYPE_PROBE);
@@ -486,6 +489,13 @@
 		return;
 	}
 
+	if (!hif_ctx) {
+		hdd_err("Failed to get HIF context, ignore SSR shutdown");
+		return;
+	}
+	/* mask the host controller interrupts */
+	hif_mask_interrupt_call(hif_ctx);
+
 	if (cds_is_load_or_unload_in_progress()) {
 		hdd_err("Load/unload in progress, ignore SSR shutdown");
 		return;
@@ -498,10 +508,7 @@
 		hdd_err("Host is not ready for SSR, attempting anyway");
 
 	if (!QDF_IS_EPPING_ENABLED(cds_get_conparam())) {
-		if (!hif_ctx)
-			hdd_err("Invalid hif ctx!");
-		else
-			hif_disable_isr(hif_ctx);
+		hif_disable_isr(hif_ctx);
 		hdd_wlan_shutdown();
 	}
 }
diff --git a/core/hdd/src/wlan_hdd_ftm.c b/core/hdd/src/wlan_hdd_ftm.c
index 4546e60..67c9b30 100644
--- a/core/hdd/src/wlan_hdd_ftm.c
+++ b/core/hdd/src/wlan_hdd_ftm.c
@@ -186,7 +186,8 @@
 	switch (pqcmbr_data->cmd) {
 	case ATH_XIOCTL_UNIFIED_UTF_CMD: {
 		pqcmbr_data->copy_to_user = 0;
-		if (pqcmbr_data->length) {
+		if (pqcmbr_data->length &&
+			pqcmbr_data->length <= sizeof(pqcmbr_data->buf)) {
 			if (wlan_hdd_ftm_testmode_cmd(pqcmbr_data->buf,
 						      pqcmbr_data->
 						      length)
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index 950bd02..f3e2cfc 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -1420,12 +1420,23 @@
 		}
 		break;
 	case eSAP_DFS_RADAR_DETECT:
+	{
+		int i;
+		tsap_Config_t *sap_config =
+				&pHostapdAdapter->sessionCtx.ap.sapConfig;
+
 		hdd_dfs_indicate_radar(pHddCtx);
 		wlan_hdd_send_svc_nlink_msg(pHddCtx->radio_index,
 					WLAN_SVC_DFS_RADAR_DETECT_IND,
 					    &dfs_info,
 					    sizeof(struct wlan_dfs_info));
 		pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
+		for (i = 0; i < sap_config->channel_info_count; i++) {
+			if (sap_config->channel_info[i].ieee_chan_number
+							== dfs_info.channel)
+				sap_config->channel_info[i].flags |=
+					IEEE80211_CHAN_RADAR_DFS;
+		}
 		if (QDF_STATUS_SUCCESS !=
 			hdd_send_radar_event(pHddCtx, eSAP_DFS_RADAR_DETECT,
 				dfs_info, &pHostapdAdapter->wdev)) {
@@ -1434,6 +1445,7 @@
 			hdd_debug("Sent radar detected to user space");
 		}
 		break;
+	}
 	case eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC:
 		hdd_debug("notification for radar detect during pre cac:%d",
 			pHostapdAdapter->sessionId);
@@ -1484,7 +1496,7 @@
 		hdd_debug("MIC MAC " MAC_ADDRESS_STR,
 		       MAC_ADDR_ARRAY(msg.src_addr.sa_data));
 		if (pSapEvent->sapevt.sapStationMICFailureEvent.
-		    multicast == eSAP_TRUE)
+		    multicast == true)
 			msg.flags = IW_MICFAILURE_GROUP;
 		else
 			msg.flags = IW_MICFAILURE_PAIRWISE;
@@ -1501,7 +1513,7 @@
 					     ((pSapEvent->sapevt.
 					       sapStationMICFailureEvent.
 					       multicast ==
-					       eSAP_TRUE) ?
+					       true) ?
 					      NL80211_KEYTYPE_GROUP :
 					      NL80211_KEYTYPE_PAIRWISE),
 					     pSapEvent->sapevt.
@@ -2604,6 +2616,10 @@
 	case QCSAP_IOCTL_SET_FW_CRASH_INJECT:
 		hdd_err("WE_SET_FW_CRASH_INJECT: %d %d",
 		       value[1], value[2]);
+		if (value[1] == 3) {
+			cds_trigger_recovery(false);
+			return 0;
+		}
 		ret = wma_cli_set2_command(adapter->sessionId,
 					   GEN_PARAM_CRASH_INJECT,
 					   value[1], value[2],
@@ -8066,7 +8082,7 @@
 	return ret;
 }
 
-static int hdd_destroy_acs_timer(hdd_adapter_t *adapter)
+int hdd_destroy_acs_timer(hdd_adapter_t *adapter)
 {
 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
 
diff --git a/core/hdd/src/wlan_hdd_hostapd.h b/core/hdd/src/wlan_hdd_hostapd.h
index 557c620..c5c6a01 100644
--- a/core/hdd/src/wlan_hdd_hostapd.h
+++ b/core/hdd/src/wlan_hdd_hostapd.h
@@ -152,6 +152,8 @@
 				    struct net_device *dev,
 				    struct cfg80211_beacon_data *params);
 
+int hdd_destroy_acs_timer(hdd_adapter_t *adapter);
+
 QDF_STATUS wlan_hdd_config_acs(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter);
 void hdd_sap_indicate_disconnect_for_sta(hdd_adapter_t *adapter);
 void hdd_sap_destroy_events(hdd_adapter_t *adapter);
diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c
index 78d7aa8..e513a06 100644
--- a/core/hdd/src/wlan_hdd_ipa.c
+++ b/core/hdd/src/wlan_hdd_ipa.c
@@ -91,6 +91,8 @@
 
 #define HDD_IPA_MAX_PENDING_EVENT_COUNT    20
 
+#define IPA_WLAN_RX_SOFTIRQ_THRESH 16
+
 enum hdd_ipa_uc_op_code {
 	HDD_IPA_UC_OPCODE_TX_SUSPEND = 0,
 	HDD_IPA_UC_OPCODE_TX_RESUME = 1,
@@ -4076,6 +4078,40 @@
 			    "RM CONS resource delete failed %d", ret);
 }
 
+#ifdef QCA_CONFIG_SMP
+static int hdd_ipa_aggregated_rx_ind(qdf_nbuf_t skb)
+{
+	return netif_rx_ni(skb);
+}
+#else
+static int hdd_ipa_aggregated_rx_ind(qdf_nbuf_t skb)
+{
+	struct iphdr *ip_h;
+	static atomic_t softirq_mitigation_cntr =
+		ATOMIC_INIT(IPA_WLAN_RX_SOFTIRQ_THRESH);
+	int result;
+
+	ip_h = (struct iphdr *)(skb->data);
+	if ((skb->protocol == htons(ETH_P_IP)) &&
+		(ip_h->protocol == IPPROTO_ICMP)) {
+		result = netif_rx_ni(skb);
+	} else {
+		/* Call netif_rx_ni for every IPA_WLAN_RX_SOFTIRQ_THRESH packets
+		 * to avoid excessive softirq's.
+		 */
+		if (atomic_dec_and_test(&softirq_mitigation_cntr)) {
+			result = netif_rx_ni(skb);
+			atomic_set(&softirq_mitigation_cntr,
+					IPA_WLAN_RX_SOFTIRQ_THRESH);
+		} else {
+			result = netif_rx(skb);
+		}
+	}
+
+	return result;
+}
+#endif
+
 /**
  * hdd_ipa_send_skb_to_network() - Send skb to kernel
  * @skb: network buffer
@@ -4089,6 +4125,7 @@
 static void hdd_ipa_send_skb_to_network(qdf_nbuf_t skb,
 	hdd_adapter_t *adapter)
 {
+	int result;
 	struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
 	unsigned int cpu_index;
 
@@ -4114,7 +4151,8 @@
 	cpu_index = wlan_hdd_get_cpu();
 
 	++adapter->hdd_stats.hddTxRxStats.rxPackets[cpu_index];
-	if (netif_rx_ni(skb) == NET_RX_SUCCESS)
+	result = hdd_ipa_aggregated_rx_ind(skb);
+	if (result == NET_RX_SUCCESS)
 		++adapter->hdd_stats.hddTxRxStats.rxDelivered[cpu_index];
 	else
 		++adapter->hdd_stats.hddTxRxStats.rxRefused[cpu_index];
diff --git a/core/hdd/src/wlan_hdd_lro.c b/core/hdd/src/wlan_hdd_lro.c
index a2635db..c043b2b 100644
--- a/core/hdd/src/wlan_hdd_lro.c
+++ b/core/hdd/src/wlan_hdd_lro.c
@@ -154,10 +154,6 @@
 		}
 
 		ctx = wlan_hdd_get_lro_ctx(skb);
-
-		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
-			 "%s %d: ctx %p\n", __func__, __LINE__, ctx);
-
 		if (ctx == NULL) {
 			hdd_err("LRO mgr is NULL, vdev could be going down");
 			return status;
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index 620fb41..267a229 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -120,6 +120,7 @@
 #include "os_if_nan.h"
 #include "nan_public_structs.h"
 #include "wlan_reg_ucfg_api.h"
+#include "wlan_hdd_rx_monitor.h"
 
 #ifdef CNSS_GENL
 #include <net/cnss_nl.h>
@@ -488,6 +489,8 @@
 /* variable to hold the insmod parameters */
 static int con_mode;
 
+static int con_mode_ftm;
+
 /* Variable to hold connection mode including module parameter con_mode */
 static int curr_con_mode;
 
@@ -1058,7 +1061,7 @@
 	struct hdd_config *pconfig = hdd_ctx->config;
 	struct wiphy *wiphy = hdd_ctx->wiphy;
 	struct ieee80211_supported_band *band_5g =
-		wiphy->bands[NL80211_BAND_5GHZ];
+		wiphy->bands[HDD_NL80211_BAND_5GHZ];
 	uint32_t temp = 0;
 	uint32_t ch_width = eHT_CHANNEL_WIDTH_80MHZ;
 
@@ -1701,6 +1704,10 @@
 	ENTER_DEV(dev);
 	hdd_mon_mode_ether_setup(dev);
 	ret = hdd_set_mon_rx_cb(dev);
+
+	if (!ret)
+		ret = hdd_enable_monitor_mode(dev);
+
 	return ret;
 }
 
@@ -3134,7 +3141,8 @@
 	if (!rc) {
 		hdd_err("timed out waiting for open sme session: %ld", rc);
 		errno = -ETIMEDOUT;
-		goto objmgr_vdev_destroy;
+		set_bit(SME_SESSION_OPENED, &adapter->event_flags);
+		goto hdd_vdev_destroy;
 	}
 
 	/* firmware ready for component communication, raise vdev_ready event */
@@ -3188,10 +3196,7 @@
 		hdd_err("failed to register wireless extensions: %d", status);
 		goto error_register_wext;
 	}
-
-	/* Set the Connection State to Not Connected */
-	hdd_debug("Set HDD connState to eConnectionState_NotConnected");
-	pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
+	hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
 
 	qdf_mem_set(pHddStaCtx->conn_info.staId,
 		sizeof(pHddStaCtx->conn_info.staId), HDD_WLAN_INVALID_STA_ID);
@@ -4122,6 +4127,7 @@
 
 		hdd_deregister_tx_flow_control(adapter);
 
+		hdd_destroy_acs_timer(adapter);
 		mutex_lock(&hdd_ctx->sap_lock);
 		if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
 			QDF_STATUS status;
@@ -4307,14 +4313,18 @@
 			clear_bit(WMM_INIT_DONE, &adapter->event_flags);
 		}
 
-		/*
-		 * If adapter is SAP, set session ID to invalid since SAP
-		 * session will be cleanup during SSR.
-		 */
-		if (adapter->device_mode == QDF_SAP_MODE)
+		if (adapter->device_mode == QDF_SAP_MODE) {
+			/*
+			 * If adapter is SAP, set session ID to invalid
+			 * since SAP session will be cleanup during SSR.
+			 */
 			wlansap_set_invalid_session(
 				WLAN_HDD_GET_SAP_CTX_PTR(adapter));
 
+			wlansap_cleanup_cac_timer(
+				WLAN_HDD_GET_SAP_CTX_PTR(adapter));
+		}
+
 		/* Delete peers if any for STA and P2P client modes */
 		if (adapter->device_mode == QDF_STA_MODE ||
 		    adapter->device_mode == QDF_P2P_CLIENT_MODE) {
@@ -4579,10 +4589,10 @@
 
 		if (chan_no <= 14)
 			freq = ieee80211_channel_to_frequency(chan_no,
-			NL80211_BAND_2GHZ);
+				HDD_NL80211_BAND_2GHZ);
 		else
 			freq = ieee80211_channel_to_frequency(chan_no,
-			NL80211_BAND_5GHZ);
+				HDD_NL80211_BAND_5GHZ);
 
 		chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
 		bss = hdd_cfg80211_get_bss(padapter->wdev.wiphy, chan, bssid,
@@ -4636,6 +4646,8 @@
 
 		hdd_wmm_init(adapter);
 
+		adapter->scan_info.mScanPending = false;
+
 		switch (adapter->device_mode) {
 		case QDF_STA_MODE:
 		case QDF_P2P_CLIENT_MODE:
@@ -4647,7 +4659,6 @@
 			hdd_init_station_mode(adapter);
 			/* Open the gates for HDD to receive Wext commands */
 			adapter->isLinkUpSvcNeeded = false;
-			adapter->scan_info.mScanPending = false;
 
 			/* Indicate disconnect event to supplicant
 			 * if associated previously
@@ -9053,6 +9064,9 @@
 	if (ret)
 		goto cds_disable;
 
+	if (hdd_enable_egap(hdd_ctx))
+		hdd_debug("enhance green ap is not enabled");
+
 	return 0;
 
 cds_disable:
@@ -9495,9 +9509,6 @@
 	memdump_init();
 	hdd_driver_memdump_init();
 
-	if (hdd_enable_egap(hdd_ctx))
-		hdd_debug("enhance green ap is not enabled");
-
 	if (hdd_ctx->config->fIsImpsEnabled)
 		hdd_set_idle_ps_config(hdd_ctx, true);
 
@@ -9545,7 +9556,8 @@
 	sme_cli_set_command(0, (int)WMI_PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM,
 			    num_abg_tx_chains, PDEV_CMD);
 
-	qdf_mc_timer_start(&hdd_ctx->iface_change_timer,
+	if (QDF_GLOBAL_FTM_MODE != hdd_get_conparam())
+		qdf_mc_timer_start(&hdd_ctx->iface_change_timer,
 			   hdd_ctx->config->iface_change_wait_time);
 
 	hdd_start_complete(0);
@@ -9689,6 +9701,11 @@
 	if (!QDF_IS_STATUS_SUCCESS(status))
 		hdd_err("set congestion callback failed");
 
+	status = sme_set_bt_activity_info_cb(hdd_ctx->hHal,
+					     hdd_bt_activity_cb);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		hdd_err("set bt activity info callback failed");
+
 	EXIT();
 
 	return ret;
@@ -10709,6 +10726,26 @@
 }
 
 /**
+ * component_init - API to init cld component's
+ *
+ * Return: None
+ */
+static void component_init(void)
+{
+	pmo_init();
+}
+
+/**
+ * component_deinit - API to deinit cld component's
+ *
+ * Return: None
+ */
+static void component_deinit(void)
+{
+	pmo_deinit();
+}
+
+/**
  * __hdd_module_init - Module init helper
  *
  * Module init helper function used by both module and static driver.
@@ -10741,6 +10778,9 @@
 
 	dispatcher_init();
 
+	/* Ensure to call post objmgr init */
+	component_init();
+
 	qdf_wake_lock_create(&wlan_wake_lock, "wlan");
 
 	hdd_set_conparam((uint32_t) con_mode);
@@ -10809,6 +10849,9 @@
 
 	qdf_wake_lock_destroy(&wlan_wake_lock);
 
+	/* Ensure to call prior to objmgr deinit */
+	component_deinit();
+
 	dispatcher_deinit();
 	hdd_deinit();
 	pld_deinit();
@@ -11247,6 +11290,24 @@
 	return ret;
 }
 
+static int con_mode_handler_ftm(const char *kmessage,
+				struct kernel_param *kp)
+{
+	int ret;
+
+	ret = param_set_int(kmessage, kp);
+
+	if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) {
+		pr_err("Only FTM mode supported!");
+		return -ENOTSUPP;
+	}
+
+	hdd_set_conparam(con_mode_ftm);
+	con_mode = con_mode_ftm;
+
+	return ret;
+}
+
 /**
  * hdd_get_conparam() - driver exit point
  *
@@ -12089,6 +12150,9 @@
 module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
 		  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
 
+module_param_call(con_mode_ftm, con_mode_handler_ftm, param_get_int,
+		  &con_mode_ftm, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
 module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
 		  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
 
diff --git a/core/hdd/src/wlan_hdd_nan_datapath.c b/core/hdd/src/wlan_hdd_nan_datapath.c
index 3b3c1ea..23eae3c 100644
--- a/core/hdd/src/wlan_hdd_nan_datapath.c
+++ b/core/hdd/src/wlan_hdd_nan_datapath.c
@@ -292,20 +292,21 @@
 {
 	hdd_adapter_t *adapter;
 	uint8_t i, attempts, max_attempt = 16;
-	struct qdf_mac_addr bcast_mac_addr = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
 
 	for (attempts = 0; attempts < max_attempt; attempts++) {
 		cds_rand_get_bytes(0, (uint8_t *)mac_addr, sizeof(*mac_addr));
-		WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(mac_addr->bytes);
+
+		/*
+		 * Reset multicast bit (bit-0) and set locally-administered bit
+		 */
+		mac_addr->bytes[0] = 0x2;
+
 		/*
 		 * to avoid potential conflict with FW's generated NMI mac addr,
 		 * host sets LSB if 6th byte to 0
 		 */
 		mac_addr->bytes[5] &= 0xFE;
 
-		if (!qdf_mem_cmp(mac_addr, &bcast_mac_addr, sizeof(*mac_addr)))
-			continue;
-
 		for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
 			if (!qdf_mem_cmp(hdd_ctx->config->intfMacAddr[i].bytes,
 					 mac_addr, sizeof(*mac_addr)))
@@ -1250,8 +1251,8 @@
 	hdd_ctx->sta_to_adapter[new_peer_ind->sta_id] = adapter;
 	/* perform following steps for first new peer ind */
 	if (ndp_ctx->active_ndp_peers == 1) {
-		hdd_info("Set ctx connection state to connected");
-		sta_ctx->conn_info.connState = eConnectionState_NdiConnected;
+		hdd_conn_set_connection_state(adapter,
+				eConnectionState_NdiConnected);
 		hdd_wmm_connect(adapter, &roam_info, eCSR_BSS_TYPE_NDI);
 		wlan_hdd_netif_queue_control(adapter,
 				WLAN_WAKE_ALL_NETIF_QUEUE, WLAN_CONTROL_PATH);
@@ -1280,7 +1281,6 @@
 
 	if (--ndp_ctx->active_ndp_peers == 0) {
 		hdd_info("No more ndp peers.");
-		sta_ctx->conn_info.connState = eConnectionState_NdiDisconnected;
 		hdd_conn_set_connection_state(adapter,
 			eConnectionState_NdiDisconnected);
 		hdd_info("Stop netif tx queues.");
diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c
index caa94c5..176b573 100644
--- a/core/hdd/src/wlan_hdd_power.c
+++ b/core/hdd/src/wlan_hdd_power.c
@@ -1406,6 +1406,7 @@
 	pHddCtx->last_scan_reject_session_id = 0xFF;
 	pHddCtx->last_scan_reject_reason = 0;
 	pHddCtx->last_scan_reject_timestamp = 0;
+	pHddCtx->scan_reject_cnt = 0;
 
 	hdd_set_roaming_in_progress(false);
 	complete(&pAdapter->roaming_comp_var);
diff --git a/core/hdd/src/wlan_hdd_regulatory.c b/core/hdd/src/wlan_hdd_regulatory.c
index 6749e1d..e647029 100644
--- a/core/hdd/src/wlan_hdd_regulatory.c
+++ b/core/hdd/src/wlan_hdd_regulatory.c
@@ -259,9 +259,9 @@
 	 * disable 2.4 Ghz channels that dont have 20 mhz bw
 	 */
 	for (chan_num = 0;
-	     chan_num < wiphy->bands[NL80211_BAND_2GHZ]->n_channels;
+	     chan_num < wiphy->bands[HDD_NL80211_BAND_2GHZ]->n_channels;
 	     chan_num++) {
-		chan = &(wiphy->bands[NL80211_BAND_2GHZ]->channels[chan_num]);
+		chan = &(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels[chan_num]);
 		if (chan->flags & IEEE80211_CHAN_NO_20MHZ)
 			chan->flags |= IEEE80211_CHAN_DISABLED;
 	}
@@ -489,11 +489,11 @@
 static void hdd_set_dfs_region(hdd_context_t *hdd_ctx,
 			       enum dfs_reg dfs_reg)
 {
-	wlan_reg_set_dfs_region(hdd_ctx->hdd_psoc, dfs_reg);
+	wlan_reg_set_dfs_region(hdd_ctx->hdd_pdev, dfs_reg);
 }
 #else
 static void hdd_set_dfs_region(hdd_context_t *hdd_ctx,
-				     enum dfs_region dfs_reg)
+			       enum dfs_region dfs_reg)
 {
 
 	/* remap the ctl code to dfs region code */
@@ -550,7 +550,7 @@
 	cds_fill_and_send_ctl_to_fw(reg_info);
 
 	hdd_set_dfs_region(hdd_ctx, DFS_FCC_REG);
-	wlan_reg_get_dfs_region(hdd_ctx->hdd_psoc, &dfs_reg);
+	wlan_reg_get_dfs_region(hdd_ctx->hdd_pdev, &dfs_reg);
 
 	reg_program_config_vars(hdd_ctx, &config_vars);
 	ucfg_reg_set_config_vars(hdd_ctx->hdd_psoc, config_vars);
@@ -715,11 +715,11 @@
 
 	if (('K' == request->alpha2[0]) &&
 	    ('R' == request->alpha2[1]))
-		request->dfs_region = DFS_KR_REG;
+		request->dfs_region = (enum nl80211_dfs_regions) DFS_KR_REG;
 
 	if (('C' == request->alpha2[0]) &&
 	    ('N' == request->alpha2[1]))
-		request->dfs_region = DFS_CN_REG;
+		request->dfs_region = (enum nl80211_dfs_regions) DFS_CN_REG;
 
 	/* first check if this callback is in response to the driver callback */
 
@@ -774,7 +774,7 @@
 		cds_fill_and_send_ctl_to_fw(&hdd_ctx->reg);
 
 		hdd_set_dfs_region(hdd_ctx, request->dfs_region);
-		wlan_reg_get_dfs_region(hdd_ctx->hdd_psoc, &dfs_reg);
+		wlan_reg_get_dfs_region(hdd_ctx->hdd_pdev, &dfs_reg);
 
 		reg_program_config_vars(hdd_ctx, &config_vars);
 		ucfg_reg_set_config_vars(hdd_ctx->hdd_psoc, config_vars);
diff --git a/core/hdd/src/wlan_hdd_rx_monitor.c b/core/hdd/src/wlan_hdd_rx_monitor.c
index 8fcbe6f..7ba0396 100644
--- a/core/hdd/src/wlan_hdd_rx_monitor.c
+++ b/core/hdd/src/wlan_hdd_rx_monitor.c
@@ -118,3 +118,26 @@
 {
 	txrx->rx.mon = rx_monitor_cb;
 }
+
+/**
+ * hdd_enable_monitor_mode() - Enable monitor mode
+ * @dev: Pointer to the net_device structure
+ *
+ * This function invokes cdp interface API to enable
+ * monitor mode configuration on the hardware. In this
+ * case sends HTT messages to FW to setup hardware rings
+ *
+ * Return: 0 for success; non-zero for failure
+ */
+int hdd_enable_monitor_mode(struct net_device *dev)
+{
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+	void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+
+	ENTER_DEV(dev);
+
+	return cdp_set_monitor_mode(soc,
+			(struct cdp_vdev *)cdp_get_vdev_from_vdev_id(soc,
+			(struct cdp_pdev *)pdev, adapter->sessionId), false);
+}
diff --git a/core/hdd/src/wlan_hdd_rx_monitor.h b/core/hdd/src/wlan_hdd_rx_monitor.h
index 161b8a1..415b523 100644
--- a/core/hdd/src/wlan_hdd_rx_monitor.h
+++ b/core/hdd/src/wlan_hdd_rx_monitor.h
@@ -37,12 +37,18 @@
 void hdd_rx_monitor_callback(ol_osif_vdev_handle vdev,
 				qdf_nbuf_t mpdu,
 				void *rx_status);
+
+int hdd_enable_monitor_mode(struct net_device *dev);
 #else
-static void hdd_monitor_set_rx_monitor_cb(struct ol_txrx_ops *txrx,
+static inline void hdd_monitor_set_rx_monitor_cb(struct ol_txrx_ops *txrx,
 					ol_txrx_rx_mon_fp rx_monitor_cb){ }
-static void hdd_rx_monitor_callback(ol_osif_vdev_handle vdev,
+static inline void hdd_rx_monitor_callback(ol_osif_vdev_handle vdev,
 				qdf_nbuf_t mpdu,
 				void *rx_status){ }
+static inline int hdd_enable_monitor_mode(struct net_device *dev)
+{
+	return -ENOSYS;
+}
 #endif /* CONFIG_LITHIUM */
 
 #endif /* __WLAN_HDD_RX_MONITOR_H */
diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c
index aaeccef..fbb1e01 100644
--- a/core/hdd/src/wlan_hdd_scan.c
+++ b/core/hdd/src/wlan_hdd_scan.c
@@ -505,19 +505,16 @@
 	uint32_t size = 0;
 
 	ret = wlan_hdd_validate_context(hddctx);
-	if (0 != ret)
+	if (ret) {
+		hdd_err("Invalid hdd_ctx; Drop results for scanId %d", scanId);
 		return QDF_STATUS_E_INVAL;
+	}
 
 	hdd_debug("called with hal = %p, pContext = %p, ID = %d, status = %d",
 		   halHandle, pContext, (int)scanId, (int)status);
 
 	pScanInfo->mScanPendingCounter = 0;
 
-	if (pScanInfo->mScanPending != true) {
-		QDF_ASSERT(pScanInfo->mScanPending);
-		goto allow_suspend;
-	}
-
 	if (QDF_STATUS_SUCCESS !=
 		wlan_hdd_scan_request_dequeue(hddctx, scanId, &req, &source,
 			&scan_time)) {
@@ -926,16 +923,21 @@
 			pHddCtx->last_scan_reject_session_id = curr_session_id;
 			pHddCtx->last_scan_reject_reason = curr_reason;
 			pHddCtx->last_scan_reject_timestamp =
-				jiffies_to_msecs(jiffies);
+				jiffies_to_msecs(jiffies) +
+				SCAN_REJECT_THRESHOLD_TIME;
+			pHddCtx->scan_reject_cnt = 0;
 		} else {
-			hdd_debug("curr_session id %d curr_reason %d time delta %lu",
-				curr_session_id, curr_reason,
-				(jiffies_to_msecs(jiffies) -
-				 pHddCtx->last_scan_reject_timestamp));
-			if ((jiffies_to_msecs(jiffies) -
-			    pHddCtx->last_scan_reject_timestamp) >=
-			    SCAN_REJECT_THRESHOLD_TIME) {
+			pHddCtx->scan_reject_cnt++;
+			hdd_debug("curr_session id %d curr_reason %d count %d threshold time has elapsed? %d",
+				curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
+				qdf_system_time_after(jiffies_to_msecs(jiffies),
+				pHddCtx->last_scan_reject_timestamp));
+			if ((pHddCtx->scan_reject_cnt >=
+			   SCAN_REJECT_THRESHOLD) &&
+			   qdf_system_time_after(jiffies_to_msecs(jiffies),
+			   pHddCtx->last_scan_reject_timestamp)) {
 				pHddCtx->last_scan_reject_timestamp = 0;
+				pHddCtx->scan_reject_cnt = 0;
 				if (pHddCtx->config->enable_fatal_event) {
 					cds_flush_logs(WLAN_LOG_TYPE_FATAL,
 					   WLAN_LOG_INDICATOR_HOST_DRIVER,
@@ -957,6 +959,7 @@
 	pHddCtx->last_scan_reject_timestamp = 0;
 	pHddCtx->last_scan_reject_session_id = 0xFF;
 	pHddCtx->last_scan_reject_reason = 0;
+	pHddCtx->scan_reject_cnt = 0;
 
 	/* Check whether SAP scan can be skipped or not */
 	if (pAdapter->device_mode == QDF_SAP_MODE &&
diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c
index b29e56b..f96a2e0 100644
--- a/core/hdd/src/wlan_hdd_stats.c
+++ b/core/hdd/src/wlan_hdd_stats.c
@@ -1855,16 +1855,18 @@
 hdd_populate_wifi_signal_info(struct sir_wifi_peer_signal_stats *peer_signal,
 			      struct sk_buff *skb)
 {
-	uint32_t i;
+	uint32_t i, chain_count;
 	struct nlattr *chains, *att;
 
 	/* There might be no signal info for a peer */
 	if (!peer_signal)
 		return 0;
 
+	chain_count = peer_signal->num_chain < WIFI_MAX_CHAINS ?
+		      peer_signal->num_chain : WIFI_MAX_CHAINS;
 	if (nla_put_u32(skb,
 			QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_ANT_NUM,
-			WIFI_MAX_CHAINS)) {
+			chain_count)) {
 		hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
 		return -EINVAL;
 	}
@@ -1876,7 +1878,7 @@
 		return -EINVAL;
 	}
 
-	for (i = 0; i < WIFI_MAX_CHAINS; i++) {
+	for (i = 0; i < chain_count; i++) {
 		chains = nla_nest_start(skb, i);
 
 		if (!chains) {
@@ -1884,12 +1886,23 @@
 			return -EINVAL;
 		}
 
+		hdd_debug("SNR=%d, NF=%d, Rx=%d, Tx=%d",
+			  peer_signal->per_ant_snr[i],
+			  peer_signal->nf[i],
+			  peer_signal->per_ant_rx_mpdus[i],
+			  peer_signal->per_ant_tx_mpdus[i]);
 		if (nla_put_u32(skb,
 				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_SNR,
 				peer_signal->per_ant_snr[i]) ||
 		    nla_put_u32(skb,
 				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_NF,
-				peer_signal->nf[i])) {
+				peer_signal->nf[i]) ||
+		    nla_put_u32(skb,
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU,
+				peer_signal->per_ant_rx_mpdus[i]) ||
+		    nla_put_u32(skb,
+				QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MPDU,
+				peer_signal->per_ant_tx_mpdus[i])) {
 			hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
 			return -EINVAL;
 		}
diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c
index beaee5f..eb6e24a 100644
--- a/core/hdd/src/wlan_hdd_wext.c
+++ b/core/hdd/src/wlan_hdd_wext.c
@@ -5006,8 +5006,7 @@
 					   SME_SUMMARY_STATS |
 					   SME_GLOBAL_CLASSA_STATS |
 					   SME_GLOBAL_CLASSD_STATS,
-					   hdd_statistics_cb, 0,
-					   false,
+					   hdd_statistics_cb,
 					   pHddStaCtx->conn_info.staId[0],
 					   pAdapter, pAdapter->sessionId);
 
@@ -6165,8 +6164,6 @@
 	hstatus = sme_get_statistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
 				     eCSR_HDD, SME_GLOBAL_CLASSA_STATS,
 				     hdd_get_class_a_statistics_cb,
-				     0, /* not periodic */
-				     false, /* non-cached results */
 				     pHddStaCtx->conn_info.staId[0],
 				     cookie, pAdapter->sessionId);
 	if (QDF_STATUS_SUCCESS != hstatus) {
@@ -6283,8 +6280,6 @@
 					    SME_GLOBAL_CLASSA_STATS |
 					    SME_PER_CHAIN_RSSI_STATS,
 				    hdd_get_station_statistics_cb,
-				    0, /* not periodic */
-				    false, /* non-cached results */
 				    pHddStaCtx->conn_info.staId[0],
 				    cookie,
 				    pAdapter->sessionId);
@@ -7574,10 +7569,10 @@
 			return -EIO;
 		}
 		if (phddctx->config->nChannelBondingMode5GHz)
-			phddctx->wiphy->bands[NL80211_BAND_5GHZ]->ht_cap.cap
+			phddctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]->ht_cap.cap
 				|= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
 		else
-			phddctx->wiphy->bands[NL80211_BAND_5GHZ]->ht_cap.cap
+			phddctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]->ht_cap.cap
 				&= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
 
 		hdd_debug("New_Phymode= %d ch_bonding=%d band=%d VHT_ch_width=%u",
@@ -11670,7 +11665,7 @@
 		pmo_set_pkt_fltr_req =
 			qdf_mem_malloc(sizeof(*pmo_set_pkt_fltr_req));
 		if (!pmo_set_pkt_fltr_req) {
-			pmo_err("unable to allocate pmo_set_pkt_fltr_req");
+			hdd_err("unable to allocate pmo_set_pkt_fltr_req");
 			return QDF_STATUS_E_NOMEM;
 		}
 
@@ -11683,7 +11678,7 @@
 		}
 		pmo_set_pkt_fltr_req->num_params = request->num_params;
 		pmo_set_pkt_fltr_req->coalesce_time = 0;
-		pmo_set_pkt_fltr_req->filter_type = HDD_RCV_FILTER_SET;
+		pmo_set_pkt_fltr_req->filter_type = PMO_RCV_FILTER_TYPE_FILTER_PKT;
 		for (i = 0; i < request->num_params; i++) {
 			pmo_set_pkt_fltr_req->params_data[i].protocol_layer =
 				request->params_data[i].protocol_layer;
@@ -11930,7 +11925,7 @@
 					    SME_SUMMARY_STATS |
 					    SME_GLOBAL_CLASSA_STATS |
 					    SME_GLOBAL_CLASSD_STATS,
-					    hdd_statistics_cb, 0, false,
+					    hdd_statistics_cb,
 					    (WLAN_HDD_GET_STATION_CTX_PTR
 						(pAdapter))->conn_info.staId[0],
 					    pAdapter, pAdapter->sessionId);
@@ -11954,7 +11949,7 @@
 						    SME_SUMMARY_STATS |
 						    SME_GLOBAL_CLASSA_STATS |
 						    SME_GLOBAL_CLASSD_STATS,
-						    NULL, 0, false,
+						    NULL,
 						    (WLAN_HDD_GET_STATION_CTX_PTR
 							 (pAdapter))->conn_info.
 						    staId[0], pAdapter,
@@ -12702,6 +12697,10 @@
 		       value[1], value[2]);
 		pr_err("SSR is triggered by iwpriv CRASH_INJECT: %d %d\n",
 			   value[1], value[2]);
+		if (value[1] == 3) {
+			cds_trigger_recovery(false);
+			return 0;
+		}
 		ret = wma_cli_set2_command(pAdapter->sessionId,
 					   GEN_PARAM_CRASH_INJECT,
 					   value[1], value[2], GEN_CMD);
diff --git a/core/mac/inc/ani_system_defs.h b/core/mac/inc/ani_system_defs.h
index 4d5796e..2e228a5 100644
--- a/core/mac/inc/ani_system_defs.h
+++ b/core/mac/inc/ani_system_defs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -63,12 +63,6 @@
 #define true    1
 #endif
 
-typedef enum eAniBool {
-	eSIR_FALSE,
-	eSIR_TRUE,
-	eSIR_DONOT_USE_BOOL = SIR_MAX_ENUM_SIZE
-} tAniBool;
-
 /* / Authentication type enum used with peer */
 typedef enum eAniAuthType {
 	eSIR_OPEN_SYSTEM,
@@ -180,7 +174,7 @@
 	tSirMacAddr srcMacAddr; /* address used to compute MIC */
 	tSirMacAddr taMacAddr;  /* transmitter address */
 	tSirMacAddr dstMacAddr;
-	tAniBool multicast;
+	bool multicast;
 	uint8_t IV1;            /* first byte of IV */
 	uint8_t keyId;          /* second byte of IV */
 	uint8_t TSC[SIR_CIPHER_SEQ_CTR_SIZE];   /* sequence number */
diff --git a/core/mac/inc/mac_init_api.h b/core/mac/inc/mac_init_api.h
index a439d19..6004c1e 100644
--- a/core/mac/inc/mac_init_api.h
+++ b/core/mac/inc/mac_init_api.h
@@ -42,9 +42,9 @@
 #include "sir_types.h"
 
 tSirRetStatus mac_start(tHalHandle hHal, void *pHalMacStartParams);
-tSirRetStatus mac_stop(tHalHandle hHal, tHalStopType stopType);
+QDF_STATUS mac_stop(tHalHandle hHal, tHalStopType stopType);
 tSirRetStatus mac_open(struct wlan_objmgr_psoc *psoc, tHalHandle *pHalHandle,
 			tHddHandle hHdd, struct cds_config_info *cds_cfg);
-tSirRetStatus mac_close(tHalHandle hHal);
+QDF_STATUS mac_close(tHalHandle hHal);
 
 #endif /* __MAC_INIT_API_H */
diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h
index 50d421a..93f29c1 100644
--- a/core/mac/inc/qwlan_version.h
+++ b/core/mac/inc/qwlan_version.h
@@ -41,9 +41,9 @@
 #define QWLAN_VERSION_MAJOR            5
 #define QWLAN_VERSION_MINOR            2
 #define QWLAN_VERSION_PATCH            0
-#define QWLAN_VERSION_EXTRA            "Z"
-#define QWLAN_VERSION_BUILD            33
+#define QWLAN_VERSION_EXTRA            "I"
+#define QWLAN_VERSION_BUILD            35
 
-#define QWLAN_VERSIONSTR               "5.2.0.33Z"
+#define QWLAN_VERSIONSTR               "5.2.0.35I"
 
 #endif /* QWLAN_VERSION_H */
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 55a6a4b..e30acfd 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -1166,15 +1166,15 @@
 	tAniEdType MgmtEncryptionType;
 #endif
 
-	tAniBool is11Rconnection;
+	bool is11Rconnection;
 #ifdef FEATURE_WLAN_ESE
-	tAniBool isESEFeatureIniEnabled;
-	tAniBool isESEconnection;
+	bool isESEFeatureIniEnabled;
+	bool isESEconnection;
 	tESETspecInfo eseTspecInfo;
 #endif
 
-	tAniBool isFastTransitionEnabled;
-	tAniBool isFastRoamIniFeatureEnabled;
+	bool isFastTransitionEnabled;
+	bool isFastRoamIniFeatureEnabled;
 
 	uint8_t txLdpcIniFeatureEnabled;
 	tSirHTConfig htConfig;
@@ -1190,11 +1190,11 @@
 	bool send_smps_action;
 
 	uint8_t max_amsdu_num;
-	tAniBool isWMEenabled;
-	tAniBool isQosEnabled;
-	tAniBool isOSENConnection;
+	bool isWMEenabled;
+	bool isQosEnabled;
+	bool isOSENConnection;
 	struct rrm_config_param rrm_config;
-	tAniBool spectrumMgtIndicator;
+	bool spectrumMgtIndicator;
 	tSirMacPowerCapInfo powerCap;
 	tSirSupChnl supportedChannels;
 	bool enable_bcast_probe_rsp;
@@ -1287,6 +1287,12 @@
 	enum phy_ch_width ch_width;
 } tSirSmeChanInfo, *tpSirSmeChanInfo;
 
+enum sir_sme_phy_mode {
+	SIR_SME_PHY_MODE_LEGACY = 0,
+	SIR_SME_PHY_MODE_HT = 1,
+	SIR_SME_PHY_MODE_VHT = 2
+};
+
 /* / Definition for Association indication from peer */
 /* / MAC ---> */
 typedef struct sSirSmeAssocInd {
@@ -1310,11 +1316,11 @@
 
 	/* powerCap & supportedChannels are present only when */
 	/* spectrumMgtIndicator flag is set */
-	tAniBool spectrumMgtIndicator;
+	bool spectrumMgtIndicator;
 	tSirMacPowerCapInfo powerCap;
 	tSirSupChnl supportedChannels;
-	tAniBool wmmEnabledSta; /* if present - STA is WMM enabled */
-	tAniBool reassocReq;
+	bool wmmEnabledSta; /* if present - STA is WMM enabled */
+	bool reassocReq;
 	/* Required for indicating the frames to upper layer */
 	uint32_t beaconLength;
 	uint8_t *beaconPtr;
@@ -1324,6 +1330,17 @@
 	/* Timing measurement capability */
 	uint8_t timingMeasCap;
 	tSirSmeChanInfo chan_info;
+	bool ampdu;
+	bool sgi_enable;
+	bool tx_stbc;
+	bool rx_stbc;
+	tSirMacHTChannelWidth ch_width;
+	enum sir_sme_phy_mode mode;
+	uint8_t max_supp_idx;
+	uint8_t max_ext_idx;
+	uint8_t max_mcs_idx;
+	uint8_t rx_mcs_map;
+	uint8_t tx_mcs_map;
 } tSirSmeAssocInd, *tpSirSmeAssocInd;
 
 /* / Definition for Association confirm */
@@ -1563,7 +1580,7 @@
 	struct qdf_mac_addr peer_macaddr;
 	tAniStaStatStruct perStaStats;  /* STA stats */
 	uint16_t staId;
-} qdf_packed tSirSmeDisassocRsp, *tpSirSmeDisassocRsp;
+} tSirSmeDisassocRsp, *tpSirSmeDisassocRsp;
 
 /* / Definition for Disassociation indication from peer */
 typedef struct sSirSmeDisassocInd {
@@ -1897,8 +1914,8 @@
 	uint16_t msgType;       /* message type is same as the request type */
 	uint16_t msgLen;        /* length of the entire request */
 	uint8_t countryCode[WNI_CFG_COUNTRY_CODE_LEN]; /* 3 char country code */
-	tAniBool countryFromUserSpace;
-	tAniBool sendRegHint;   /* true if we want to send hint to NL80211 */
+	bool countryFromUserSpace;
+	bool sendRegHint;   /* true if we want to send hint to NL80211 */
 	void *changeCCCallback;
 	void *pDevContext;      /* device context */
 	void *p_cds_context;    /* cds context */
@@ -2983,6 +3000,20 @@
 	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 +3071,7 @@
 	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 {
@@ -5225,6 +5257,9 @@
  * @peer_id: peer ID
  * @per_ant_snr: per antenna SNR
  * @nf: peer background noise
+ * @per_ant_rx_mpdus: MPDUs received per antenna
+ * @per_ant_tx_mpdus: MPDUs transferred per antenna
+ * @num_chain: valid chain count
  */
 struct sir_wifi_peer_signal_stats {
 	uint32_t vdev_id;
@@ -5235,6 +5270,10 @@
 
 	/* Background noise */
 	int32_t nf[WIFI_MAX_CHAINS];
+
+	int32_t per_ant_rx_mpdus[WIFI_MAX_CHAINS];
+	int32_t per_ant_tx_mpdus[WIFI_MAX_CHAINS];
+	int32_t num_chain;
 };
 
 #define WIFI_VDEV_NUM           4
diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h
index 508f0d6..60b8417 100644
--- a/core/mac/inc/sir_mac_prot_def.h
+++ b/core/mac/inc/sir_mac_prot_def.h
@@ -560,7 +560,7 @@
 #define SIR_MAC_MAX_NUMBER_OF_RATES          12
 #define SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS      4
 #define SIR_MAC_KEY_LENGTH                   13 /* WEP Maximum key length size */
-#define SIR_MAC_AUTH_CHALLENGE_LENGTH        128
+#define SIR_MAC_AUTH_CHALLENGE_LENGTH        253
 #define SIR_MAC_WEP_IV_LENGTH                4
 #define SIR_MAC_WEP_ICV_LENGTH               4
 
diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h
index 7c95510..8f9d7cb 100644
--- a/core/mac/inc/wni_api.h
+++ b/core/mac/inc/wni_api.h
@@ -261,6 +261,7 @@
 	eWMI_SME_LL_STATS_IND,
 	eWNI_SME_DFS_CAC_COMPLETE,
 	eWNI_SME_UPDATE_CONFIG,
+	eWNI_SME_BT_ACTIVITY_INFO_IND,
 	eWNI_SME_MSG_TYPES_END
 };
 
diff --git a/core/mac/src/cfg/cfgUtil/dot11f.frms b/core/mac/src/cfg/cfgUtil/dot11f.frms
index e4b4773..6923da0 100644
--- a/core/mac/src/cfg/cfgUtil/dot11f.frms
+++ b/core/mac/src/cfg/cfgUtil/dot11f.frms
@@ -3634,6 +3634,7 @@
     OPTIE  vendor_he_op;
     OPTIE  bss_color_change;
     OPTIE  mu_edca_param_set;
+    OPTIE  MBO_IE;
 } // End frame AssocResponse.
 
 FRAME ReAssocRequest                      // 7.2.3.6
@@ -3712,6 +3713,7 @@
     OPTIE  vendor_he_op;
     OPTIE  bss_color_change;
     OPTIE  mu_edca_param_set;
+    OPTIE  MBO_IE;
 } // End frame ReAssocResponse.
 
 FRAME ProbeRequest                        // 7.2.3.8
diff --git a/core/mac/src/dph/dph_hash_table.c b/core/mac/src/dph/dph_hash_table.c
index 3ebcb6a..3fd4940 100644
--- a/core/mac/src/dph/dph_hash_table.c
+++ b/core/mac/src/dph/dph_hash_table.c
@@ -240,7 +240,7 @@
 {
 	uint32_t val;
 
-	tpDphHashNode pStaDs;
+	tpDphHashNode pStaDs, pnext;
 	uint16_t staIdx = STA_INVALID_IDX;
 
 	if (assocId >= pDphHashTable->size) {
@@ -250,10 +250,11 @@
 
 	pStaDs = get_node(pMac, (uint8_t) assocId, pDphHashTable);
 	staIdx = pStaDs->staIndex;
+	pnext = pStaDs->next;
 
-	/* Clear the STA node except for the next pointer (last 4 bytes) */
-	qdf_mem_set((uint8_t *) pStaDs,
-		    sizeof(tDphHashNode) - sizeof(tpDphHashNode), 0);
+	/* Clear the STA node except for the next pointer */
+	qdf_mem_set((uint8_t *)pStaDs, sizeof(tDphHashNode), 0);
+	pStaDs->next = pnext;
 
 	/* Initialize the assocId */
 	pStaDs->assocId = assocId;
diff --git a/core/mac/src/include/dot11f.h b/core/mac/src/include/dot11f.h
index 3885b4b..8ee738c 100644
--- a/core/mac/src/include/dot11f.h
+++ b/core/mac/src/include/dot11f.h
@@ -35,7 +35,7 @@
  *
  *
  * This file was automatically generated by 'framesc'
- * Thu Jul  6 16:41:06 2017 from the following file(s):
+ * Fri Jul 14 12:29:59 2017 from the following file(s):
  *
  * dot11f.frms
  *
@@ -9291,6 +9291,7 @@
 	tDot11fIEvendor_he_op                 vendor_he_op;
 	tDot11fIEbss_color_change             bss_color_change;
 	tDot11fIEmu_edca_param_set            mu_edca_param_set;
+	tDot11fIEMBO_IE                       MBO_IE;
 } tDot11fAssocResponse;
 
 #define DOT11F_ASSOCRESPONSE (4)
@@ -10218,6 +10219,7 @@
 	tDot11fIEvendor_he_op              vendor_he_op;
 	tDot11fIEbss_color_change          bss_color_change;
 	tDot11fIEmu_edca_param_set         mu_edca_param_set;
+	tDot11fIEMBO_IE                    MBO_IE;
 } tDot11fReAssocResponse;
 
 #define DOT11F_REASSOCRESPONSE (27)
diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h
index c8fe42c..ee757fe 100644
--- a/core/mac/src/pe/include/lim_session.h
+++ b/core/mac/src/pe/include/lim_session.h
@@ -55,7 +55,7 @@
 	tpAniSirGlobal pMac;
 	uint8_t sessionID;
 	tLimMlmStates limPrevMlmState;  /* Previous MLM State */
-	tLimSmeStates limMlmState;      /* MLM State */
+	tLimMlmStates limMlmState;      /* MLM State */
 } tComebackTimerInfo;
 #endif /* WLAN_FEATURE_11W */
 /*--------------------------------------------------------------------------
@@ -292,14 +292,14 @@
 	int8_t maxTxPower;   /* MIN (Regulatory and local power constraint) */
 	enum tQDF_ADAPTER_MODE pePersona;
 	int8_t txMgmtPower;
-	tAniBool is11Rconnection;
+	bool is11Rconnection;
 
 #ifdef FEATURE_WLAN_ESE
-	tAniBool isESEconnection;
+	bool isESEconnection;
 	tEsePEContext eseContext;
 #endif
-	tAniBool isFastTransitionEnabled;
-	tAniBool isFastRoamIniFeatureEnabled;
+	bool isFastTransitionEnabled;
+	bool isFastRoamIniFeatureEnabled;
 	tSirNoAParam p2pNoA;
 	tSirP2PNoaAttr p2pGoPsUpdate;
 	uint32_t defaultAuthFailureTimeout;
diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c
index b8041c9..9356f4f 100644
--- a/core/mac/src/pe/lim/lim_api.c
+++ b/core/mac/src/pe/lim/lim_api.c
@@ -479,7 +479,7 @@
  */
 tSirRetStatus lim_start(tpAniSirGlobal pMac)
 {
-	tSirResultCodes retCode = eSIR_SUCCESS;
+	tSirRetStatus retCode = eSIR_SUCCESS;
 
 	pe_debug("enter");
 
@@ -1354,34 +1354,34 @@
  * @param  pBeacon  - Parsed Beacon Frame structure
  * @param  pSession - Pointer to the PE session
  *
- * @return eSIR_TRUE if encryption type is matched; eSIR_FALSE otherwise
+ * @return true if encryption type is matched; false otherwise
  */
-static tAniBool lim_ibss_enc_type_matched(tpSchBeaconStruct pBeacon,
+static bool lim_ibss_enc_type_matched(tpSchBeaconStruct pBeacon,
 					  tpPESession pSession)
 {
 	if (!pBeacon || !pSession)
-		return eSIR_FALSE;
+		return false;
 
 	/* Open case */
 	if (pBeacon->capabilityInfo.privacy == 0
 	    && pSession->encryptType == eSIR_ED_NONE)
-		return eSIR_TRUE;
+		return true;
 
 	/* WEP case */
 	if (pBeacon->capabilityInfo.privacy == 1 && pBeacon->wpaPresent == 0
 	    && pBeacon->rsnPresent == 0
 	    && (pSession->encryptType == eSIR_ED_WEP40
 		|| pSession->encryptType == eSIR_ED_WEP104))
-		return eSIR_TRUE;
+		return true;
 
 	/* WPA-None case */
 	if (pBeacon->capabilityInfo.privacy == 1 && pBeacon->wpaPresent == 1
 	    && pBeacon->rsnPresent == 0
 	    && ((pSession->encryptType == eSIR_ED_CCMP) ||
 		(pSession->encryptType == eSIR_ED_TKIP)))
-		return eSIR_TRUE;
+		return true;
 
-	return eSIR_FALSE;
+	return false;
 }
 
 /**
@@ -1424,7 +1424,7 @@
 	    lim_cmp_ssid(&pBeacon->ssId, psessionEntry) ||
 	    (psessionEntry->currentOperChannel != pBeacon->channelNumber))
 		retCode = eSIR_LIM_IGNORE_BEACON;
-	else if (lim_ibss_enc_type_matched(pBeacon, psessionEntry) != eSIR_TRUE) {
+	else if (lim_ibss_enc_type_matched(pBeacon, psessionEntry) != true) {
 		pe_debug("peer privacy: %d peer wpa: %d peer rsn: %d self encType: %d",
 			       pBeacon->capabilityInfo.privacy,
 			       pBeacon->wpaPresent, pBeacon->rsnPresent,
@@ -1985,6 +1985,15 @@
 	bss_desc_ptr->timeStamp[1]   = parsed_frm_ptr->timeStamp[1];
 	qdf_mem_copy(&bss_desc_ptr->capabilityInfo,
 	&bcn_proberesp_ptr[SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_CAPAB_OFFSET], 2);
+
+	if (qdf_is_macaddr_zero((struct qdf_mac_addr *)mac_hdr->bssId)) {
+		pe_debug("bssid is 0 in beacon/probe update it with bssId %pM in sync ind",
+			roam_offload_synch_ind_ptr->bssid.bytes);
+		qdf_mem_copy(mac_hdr->bssId,
+			roam_offload_synch_ind_ptr->bssid.bytes,
+			sizeof(tSirMacAddr));
+	}
+
 	qdf_mem_copy((uint8_t *) &bss_desc_ptr->bssId,
 			(uint8_t *) mac_hdr->bssId,
 			sizeof(tSirMacAddr));
diff --git a/core/mac/src/pe/lim/lim_link_monitoring_algo.c b/core/mac/src/pe/lim/lim_link_monitoring_algo.c
index 95d4390..1734eee 100644
--- a/core/mac/src/pe/lim/lim_link_monitoring_algo.c
+++ b/core/mac/src/pe/lim/lim_link_monitoring_algo.c
@@ -231,7 +231,7 @@
 				pe_err("Do not process in limMlmState %s(%x) limSmeState %s(%x)",
 				  lim_mlm_state_str(session_entry->limMlmState),
 				  session_entry->limMlmState,
-				  lim_mlm_state_str(session_entry->limSmeState),
+				  lim_sme_state_str(session_entry->limSmeState),
 				  session_entry->limSmeState);
 				qdf_mem_free(msg);
 				return;
diff --git a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c
index 970533b..9c39b71 100644
--- a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c
+++ b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c
@@ -2110,6 +2110,50 @@
 	return;
 }
 
+static uint8_t lim_get_max_rate_idx(tSirMacRateSet *rateset)
+{
+	uint8_t maxidx;
+	int i;
+
+	maxidx = rateset->rate[0] & 0x7f;
+	for (i = 1; i < rateset->numRates; i++) {
+		if ((rateset->rate[i] & 0x7f) > maxidx)
+			maxidx = rateset->rate[i] & 0x7f;
+	}
+
+	return maxidx;
+}
+
+static void fill_mlm_assoc_ind_vht(tpSirAssocReq assocreq,
+		tpDphHashNode stads,
+		tpLimMlmAssocInd assocind)
+{
+	if (stads->mlmStaContext.vhtCapability) {
+		/* ampdu */
+		assocind->ampdu = true;
+
+		/* sgi */
+		if (assocreq->VHTCaps.shortGI80MHz ||
+		    assocreq->VHTCaps.shortGI160and80plus80MHz)
+			assocind->sgi_enable = true;
+
+		/* stbc */
+		assocind->tx_stbc = assocreq->VHTCaps.txSTBC;
+		assocind->rx_stbc = assocreq->VHTCaps.rxSTBC;
+
+		/* ch width */
+		assocind->ch_width = stads->vhtSupportedChannelWidthSet ?
+			eHT_CHANNEL_WIDTH_80MHZ :
+			stads->htSupportedChannelWidthSet ?
+			eHT_CHANNEL_WIDTH_40MHZ : eHT_CHANNEL_WIDTH_20MHZ;
+
+		/* mode */
+		assocind->mode = SIR_SME_PHY_MODE_VHT;
+		assocind->rx_mcs_map = assocreq->VHTCaps.rxMCSMap & 0xff;
+		assocind->tx_mcs_map = assocreq->VHTCaps.txMCSMap & 0xff;
+	}
+}
+
 /**
  * lim_send_mlm_assoc_ind() - Sends assoc indication to SME
  * @mac_ctx: Global Mac context
@@ -2130,6 +2174,7 @@
 	uint32_t phy_mode;
 	uint8_t sub_type;
 	uint8_t *wpsie = NULL;
+	uint8_t maxidx, i;
 	uint32_t tmp;
 
 	/* Get a copy of the already parsed Assoc Request */
@@ -2192,7 +2237,7 @@
 		/* Fill in 802.11h related info */
 		if (assoc_req->powerCapabilityPresent
 			&& assoc_req->supportedChannelsPresent) {
-			assoc_ind->spectrumMgtIndicator = eSIR_TRUE;
+			assoc_ind->spectrumMgtIndicator = true;
 			assoc_ind->powerCap.minTxPower =
 				assoc_req->powerCapability.minTxPower;
 			assoc_ind->powerCap.maxTxPower =
@@ -2200,7 +2245,7 @@
 			lim_convert_supported_channels(mac_ctx, assoc_ind,
 				 assoc_req);
 		} else {
-			assoc_ind->spectrumMgtIndicator = eSIR_FALSE;
+			assoc_ind->spectrumMgtIndicator = false;
 		}
 
 		/* This check is to avoid extra Sec IEs present incase of WPS */
@@ -2295,6 +2340,57 @@
 		assoc_ind->chan_info.nss = sta_ds->nss;
 		assoc_ind->chan_info.rate_flags =
 			lim_get_max_rate_flags(mac_ctx, sta_ds);
+		assoc_ind->ampdu = false;
+		assoc_ind->sgi_enable = false;
+		assoc_ind->tx_stbc = false;
+		assoc_ind->rx_stbc = false;
+		assoc_ind->ch_width = eHT_CHANNEL_WIDTH_20MHZ;
+		assoc_ind->mode = SIR_SME_PHY_MODE_LEGACY;
+		assoc_ind->max_supp_idx = 0xff;
+		assoc_ind->max_ext_idx = 0xff;
+		assoc_ind->max_mcs_idx = 0xff;
+		assoc_ind->rx_mcs_map = 0xff;
+		assoc_ind->tx_mcs_map = 0xff;
+
+		if (assoc_req->supportedRates.numRates)
+			assoc_ind->max_supp_idx =
+				lim_get_max_rate_idx(
+					&assoc_req->supportedRates);
+		if (assoc_req->extendedRates.numRates)
+			assoc_ind->max_ext_idx =
+				lim_get_max_rate_idx(
+					&assoc_req->extendedRates);
+
+		if (sta_ds->mlmStaContext.htCapability) {
+			/* ampdu */
+			assoc_ind->ampdu = true;
+
+			/* sgi */
+			if (sta_ds->htShortGI20Mhz || sta_ds->htShortGI40Mhz)
+				assoc_ind->sgi_enable = true;
+
+			/* stbc */
+			assoc_ind->tx_stbc = assoc_req->HTCaps.txSTBC;
+			assoc_ind->rx_stbc = assoc_req->HTCaps.rxSTBC;
+
+			/* ch width */
+			assoc_ind->ch_width =
+				sta_ds->htSupportedChannelWidthSet ?
+				eHT_CHANNEL_WIDTH_40MHZ :
+				eHT_CHANNEL_WIDTH_20MHZ;
+
+			/* mode */
+			assoc_ind->mode = SIR_SME_PHY_MODE_HT;
+			maxidx = 0;
+			for (i = 0; i < 8; i++) {
+				if (assoc_req->HTCaps.supportedMCSSet[0] &
+					(1 << i))
+					maxidx = i;
+			}
+			assoc_ind->max_mcs_idx = maxidx;
+		}
+		fill_mlm_assoc_ind_vht(assoc_req, sta_ds, assoc_ind);
+
 		/* updates VHT information in assoc indication */
 		lim_fill_assoc_ind_vht_info(mac_ctx, session_entry, assoc_req,
 			assoc_ind);
diff --git a/core/mac/src/pe/lim/lim_process_auth_frame.c b/core/mac/src/pe/lim/lim_process_auth_frame.c
index 71bd8a0..090f982 100644
--- a/core/mac/src/pe/lim/lim_process_auth_frame.c
+++ b/core/mac/src/pe/lim/lim_process_auth_frame.c
@@ -281,7 +281,7 @@
 	if (sta_ds_ptr) {
 		tLimMlmDisassocReq *pMlmDisassocReq = NULL;
 		tLimMlmDeauthReq *pMlmDeauthReq = NULL;
-		tAniBool isConnected = eSIR_TRUE;
+		bool isConnected = true;
 
 		pMlmDisassocReq =
 			mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
@@ -294,7 +294,7 @@
 				MAC_ADDR_ARRAY(
 					pMlmDisassocReq->peer_macaddr.bytes));
 			lim_process_disassoc_ack_timeout(mac_ctx);
-			isConnected = eSIR_FALSE;
+			isConnected = false;
 		}
 		pMlmDeauthReq =
 			mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
@@ -307,7 +307,7 @@
 				MAC_ADDR_ARRAY(
 					pMlmDeauthReq->peer_macaddr.bytes));
 			lim_process_deauth_ack_timeout(mac_ctx);
-			isConnected = eSIR_FALSE;
+			isConnected = false;
 		}
 
 		/*
diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c
index 2dcbe8b..f63f074 100644
--- a/core/mac/src/pe/lim/lim_process_message_queue.c
+++ b/core/mac/src/pe/lim/lim_process_message_queue.c
@@ -878,7 +878,7 @@
 	tpSirMacMgmtHdr pHdr = NULL;
 	tpPESession psessionEntry = NULL;
 	uint8_t sessionId;
-	tAniBool isFrmFt = false;
+	bool isFrmFt = false;
 
 	*pDeferMsg = false;
 	lim_get_b_dfrom_rx_packet(pMac, limMsg->bodyptr,
diff --git a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c
index 030e1fd..7b0d693 100644
--- a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c
+++ b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c
@@ -489,7 +489,7 @@
 	if (NULL == addbss_param) {
 		pe_err("Unable to allocate memory during ADD_BSS");
 		/* Respond to SME with LIM_MLM_START_CNF */
-		return eSIR_MEM_ALLOC_FAILED;
+		return eSIR_SME_RESOURCES_UNAVAILABLE;
 	}
 
 	/* Fill in tAddBssParams members */
diff --git a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
index b0cf987..209e209 100644
--- a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
+++ b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
@@ -756,7 +756,7 @@
 
 	/* Copy the new TITAN capabilities */
 	sme_assoc_ind->spectrumMgtIndicator = assoc_ind->spectrumMgtIndicator;
-	if (assoc_ind->spectrumMgtIndicator == eSIR_TRUE) {
+	if (assoc_ind->spectrumMgtIndicator == true) {
 		sme_assoc_ind->powerCap.minTxPower =
 			assoc_ind->powerCap.minTxPower;
 		sme_assoc_ind->powerCap.maxTxPower =
@@ -772,6 +772,17 @@
 		sizeof(tSirSmeChanInfo));
 	/* Fill in WmmInfo */
 	sme_assoc_ind->wmmEnabledSta = assoc_ind->WmmStaInfoPresent;
+	sme_assoc_ind->ampdu = assoc_ind->ampdu;
+	sme_assoc_ind->sgi_enable = assoc_ind->sgi_enable;
+	sme_assoc_ind->tx_stbc = assoc_ind->tx_stbc;
+	sme_assoc_ind->rx_stbc = assoc_ind->rx_stbc;
+	sme_assoc_ind->ch_width = assoc_ind->ch_width;
+	sme_assoc_ind->mode = assoc_ind->mode;
+	sme_assoc_ind->max_supp_idx = assoc_ind->max_supp_idx;
+	sme_assoc_ind->max_ext_idx = assoc_ind->max_ext_idx;
+	sme_assoc_ind->max_mcs_idx = assoc_ind->max_mcs_idx;
+	sme_assoc_ind->rx_mcs_map = assoc_ind->rx_mcs_map;
+	sme_assoc_ind->tx_mcs_map = assoc_ind->tx_mcs_map;
 }
 
 /**
@@ -3205,7 +3216,7 @@
 	case SIR_SCAN_EVENT_START_FAILED:
 		if (ROC_SCAN_REQUESTOR_ID == pScanEvent->requestor) {
 			lim_send_sme_roc_rsp(pMac, eWNI_SME_REMAIN_ON_CHN_RSP,
-					 QDF_STATUS_SUCCESS,
+					 eSIR_SME_SUCCESS,
 					 pScanEvent->sessionId,
 					 pScanEvent->scanId);
 			qdf_mem_free(pMac->lim.gpLimRemainOnChanReq);
@@ -3233,7 +3244,7 @@
 			if (pMac->lim.gpLimRemainOnChanReq) {
 				lim_send_sme_roc_rsp(pMac,
 						 eWNI_SME_REMAIN_ON_CHN_RDY_IND,
-						 QDF_STATUS_SUCCESS,
+						 eSIR_SME_SUCCESS,
 						 pScanEvent->sessionId,
 						 pScanEvent->scanId);
 			} else {
diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
index 2ae9522..b425330 100644
--- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c
+++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
@@ -3505,7 +3505,7 @@
 				       sta_ds->mlmStaContext.subType,
 				       true, sta_ds->mlmStaContext.authType,
 				       sta_ds->assocId, true,
-				       eSIR_MAC_UNSPEC_FAILURE_STATUS,
+				       eSIR_SME_UNEXPECTED_REQ_RESULT_CODE,
 				       session_entry);
 	}
 end:
@@ -3569,10 +3569,7 @@
 
 	if (!LIM_IS_STA_ROLE(psessionEntry)) {
 		pe_err("AddTs received on AP - ignoring");
-		lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
-				       psessionEntry, pSirAddts->req.tspec,
-				       smesessionId, smetransactionId);
-		return;
+		goto send_failure_addts_rsp;
 	}
 
 	pStaDs =
@@ -3581,19 +3578,13 @@
 
 	if (pStaDs == NULL) {
 		pe_err("Cannot find AP context for addts req");
-		lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
-				       psessionEntry, pSirAddts->req.tspec,
-				       smesessionId, smetransactionId);
-		return;
+		goto send_failure_addts_rsp;
 	}
 
 	if ((!pStaDs->valid) || (pStaDs->mlmStaContext.mlmState !=
 	    eLIM_MLM_LINK_ESTABLISHED_STATE)) {
 		pe_err("AddTs received in invalid MLM state");
-		lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
-				       psessionEntry, pSirAddts->req.tspec,
-				       smesessionId, smetransactionId);
-		return;
+		goto send_failure_addts_rsp;
 	}
 
 	pSirAddts->req.wsmTspecPresent = 0;
@@ -3610,20 +3601,14 @@
 		pSirAddts->req.lleTspecPresent = 1;
 	else {
 		pe_warn("ADDTS_REQ ignore - qos is disabled");
-		lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
-				       psessionEntry, pSirAddts->req.tspec,
-				       smesessionId, smetransactionId);
-		return;
+		goto send_failure_addts_rsp;
 	}
 
 	if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
 	    (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
 		pe_err("AddTs received in invalid LIMsme state (%d)",
 			psessionEntry->limSmeState);
-		lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
-				       psessionEntry, pSirAddts->req.tspec,
-				       smesessionId, smetransactionId);
-		return;
+		goto send_failure_addts_rsp;
 	}
 
 	if (pMac->lim.gLimAddtsSent) {
@@ -3632,10 +3617,7 @@
 			pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.tsid,
 			pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.
 			userPrio);
-		lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
-				       psessionEntry, pSirAddts->req.tspec,
-				       smesessionId, smetransactionId);
-		return;
+		goto send_failure_addts_rsp;
 	}
 
 	sir_copy_mac_addr(peerMac, psessionEntry->bssId);
@@ -3656,21 +3638,21 @@
 		 eSIR_SUCCESS) {
 		pe_err("Unable to get Cfg param %d (Addts Rsp Timeout)",
 			WNI_CFG_ADDTS_RSP_TIMEOUT);
-		return;
+		goto send_failure_addts_rsp;
 	}
 
 	timeout = SYS_MS_TO_TICKS(timeout);
 	if (tx_timer_change(&pMac->lim.limTimers.gLimAddtsRspTimer, timeout, 0)
 	    != TX_SUCCESS) {
 		pe_err("AddtsRsp timer change failed!");
-		return;
+		goto send_failure_addts_rsp;
 	}
 	pMac->lim.gLimAddtsRspTimerCount++;
 	if (tx_timer_change_context(&pMac->lim.limTimers.gLimAddtsRspTimer,
 				    pMac->lim.gLimAddtsRspTimerCount) !=
 	    TX_SUCCESS) {
 		pe_err("AddtsRsp timer change failed!");
-		return;
+		goto send_failure_addts_rsp;
 	}
 	MTRACE(mac_trace
 		       (pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId,
@@ -3681,9 +3663,14 @@
 	if (tx_timer_activate(&pMac->lim.limTimers.gLimAddtsRspTimer) !=
 	    TX_SUCCESS) {
 		pe_err("AddtsRsp timer activation failed!");
-		return;
+		goto send_failure_addts_rsp;
 	}
 	return;
+
+send_failure_addts_rsp:
+	lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
+			       psessionEntry, pSirAddts->req.tspec,
+			       smesessionId, smetransactionId);
 }
 
 static void __lim_process_sme_delts_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
@@ -5823,7 +5810,7 @@
 		switch_mode = 1;
 
 	if (LIM_IS_AP_ROLE(session_entry)) {
-		for (i = 0; i < mac_ctx->lim.maxStation; i++) {
+		for (i = 0; i <= mac_ctx->lim.maxStation; i++) {
 			psta =
 			  session_entry->dph.dphHashTable.pDphNodeArray + i;
 			if (psta && psta->added)
diff --git a/core/mac/src/pe/lim/lim_process_tdls.c b/core/mac/src/pe/lim/lim_process_tdls.c
index f1103f7..85d5e9b 100644
--- a/core/mac/src/pe/lim/lim_process_tdls.c
+++ b/core/mac/src/pe/lim/lim_process_tdls.c
@@ -2416,8 +2416,6 @@
 	tDot11fIEVHTCaps *pVhtCaps_txbf = NULL;
 	tDot11fIEVHTCaps vhtCap;
 	uint8_t cbMode;
-	tpDphHashNode pSessStaDs = NULL;
-	uint16_t aid;
 
 	if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_ADD) {
 		populate_dot11f_ht_caps(pMac, psessionEntry, &htCap);
@@ -2516,8 +2514,6 @@
 		else
 			pStaDs->htSecondaryChannelOffset = cbMode;
 	}
-	pSessStaDs = dph_lookup_hash_entry(pMac, psessionEntry->bssId, &aid,
-					   &psessionEntry->dph.dphHashTable);
 	/* Lets enable QOS parameter */
 	pStaDs->qosMode = (pTdlsAddStaReq->capability & CAPABILITIES_QOS_OFFSET)
 				|| pTdlsAddStaReq->htcap_present;
diff --git a/core/mac/src/pe/lim/lim_security_utils.c b/core/mac/src/pe/lim/lim_security_utils.c
index 68416e9..28f31a6 100644
--- a/core/mac/src/pe/lim/lim_security_utils.c
+++ b/core/mac/src/pe/lim/lim_security_utils.c
@@ -562,7 +562,7 @@
  * @return None
  */
 
-void lim_compute_crc32(uint8_t *pDest, uint8_t *pSrc, uint8_t len)
+void lim_compute_crc32(uint8_t *pDest, uint8_t *pSrc, uint16_t len)
 {
 	uint32_t crc;
 	int i;
diff --git a/core/mac/src/pe/lim/lim_security_utils.h b/core/mac/src/pe/lim/lim_security_utils.h
index 47175b8..3dc6a93 100644
--- a/core/mac/src/pe/lim/lim_security_utils.h
+++ b/core/mac/src/pe/lim/lim_security_utils.h
@@ -60,7 +60,7 @@
 uint8_t lim_delete_open_auth_pre_auth_node(tpAniSirGlobal mac_ctx);
 
 /* Encryption/Decryption related functions */
-void lim_compute_crc32(uint8_t *, uint8_t *, uint8_t);
+void lim_compute_crc32(uint8_t *, uint8_t *, uint16_t);
 void lim_rc4(uint8_t *, uint8_t *, uint8_t *, uint32_t, uint16_t);
 void lim_encrypt_auth_frame(tpAniSirGlobal, uint8_t, uint8_t *, uint8_t *,
 			    uint8_t *, uint32_t);
diff --git a/core/mac/src/pe/lim/lim_send_frames_host_roam.c b/core/mac/src/pe/lim/lim_send_frames_host_roam.c
index b3d109d..655c533 100644
--- a/core/mac/src/pe/lim/lim_send_frames_host_roam.c
+++ b/core/mac/src/pe/lim/lim_send_frames_host_roam.c
@@ -142,7 +142,7 @@
 		      LIM_BSS_CAPS_GET(WSM, pe_session->limReassocBssQosCaps);
 
 	if (pe_session->lim11hEnable &&
-	    pe_session->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE) {
+	    pe_session->pLimReAssocReq->spectrumMgtIndicator == true) {
 		power_caps_populated = true;
 
 		populate_dot11f_power_caps(mac_ctx, &frm.PowerCaps,
@@ -604,7 +604,7 @@
 		     LIM_BSS_CAPS_GET(WSM, psessionEntry->limReassocBssQosCaps);
 
 	if (psessionEntry->lim11hEnable &&
-	    psessionEntry->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE) {
+	    psessionEntry->pLimReAssocReq->spectrumMgtIndicator == true) {
 		PowerCapsPopulated = true;
 		populate_dot11f_power_caps(pMac, &frm.PowerCaps, LIM_REASSOC,
 					   psessionEntry);
diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c
index 9117329..7944fbc 100644
--- a/core/mac/src/pe/lim/lim_send_management_frames.c
+++ b/core/mac/src/pe/lim/lim_send_management_frames.c
@@ -1636,6 +1636,7 @@
 
 	if (NULL == pe_session) {
 		pe_err("pe_session is NULL");
+		qdf_mem_free(mlm_assoc_req);
 		return;
 	}
 
@@ -1644,6 +1645,7 @@
 	/* check this early to avoid unncessary operation */
 	if (NULL == pe_session->pLimJoinReq) {
 		pe_err("pe_session->pLimJoinReq is NULL");
+		qdf_mem_free(mlm_assoc_req);
 		return;
 	}
 	add_ie_len = pe_session->pLimJoinReq->addIEAssoc.length;
@@ -1652,6 +1654,7 @@
 	frm = qdf_mem_malloc(sizeof(tDot11fAssocRequest));
 	if (NULL == frm) {
 		pe_err("Unable to allocate memory");
+		qdf_mem_free(mlm_assoc_req);
 		return;
 	}
 	qdf_mem_set((uint8_t *) frm, sizeof(tDot11fAssocRequest), 0);
@@ -1713,7 +1716,7 @@
 		      LIM_BSS_CAPS_GET(WSM, pe_session->limCurrentBssQosCaps);
 
 	if (pe_session->lim11hEnable &&
-	    pe_session->pLimJoinReq->spectrumMgtIndicator == eSIR_TRUE) {
+	    pe_session->pLimJoinReq->spectrumMgtIndicator == true) {
 		power_caps = true;
 
 		populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
@@ -1947,8 +1950,7 @@
 		lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
 			(uint32_t *) &assoc_cnf);
 
-		qdf_mem_free(frm);
-		return;
+		goto end;
 	}
 	/* Paranoia: */
 	qdf_mem_set(frame, bytes, 0);
@@ -1963,8 +1965,7 @@
 	if (DOT11F_FAILED(status)) {
 		pe_err("Assoc request pack failure (0x%08x)", status);
 		cds_packet_free((void *)packet);
-		qdf_mem_free(frm);
-		return;
+		goto end;
 	} else if (DOT11F_WARNED(status)) {
 		pe_warn("Assoc request pack warning (0x%08x)", status);
 	}
@@ -2024,9 +2025,8 @@
 		pe_err("Failed to send Association Request (%X)!",
 			qdf_status);
 		/* Pkt will be freed up by the callback */
-		qdf_mem_free(frm);
-		return;
 	}
+end:
 	/* Free up buffer allocated for mlm_assoc_req */
 	qdf_mem_free(mlm_assoc_req);
 	mlm_assoc_req = NULL;
diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
index 338ecb6..330974a 100644
--- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
+++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
@@ -2314,6 +2314,12 @@
 	}
 	pe_debug("new ch width: %d space: %d",
 			session_entry->gLimChannelSwitch.ch_width, chan_space);
+	if ((session_entry->currentOperChannel == csa_params->channel) &&
+		(session_entry->ch_width ==
+		 session_entry->gLimChannelSwitch.ch_width)) {
+		pe_debug("Ignore CSA, no change in ch and bw");
+		goto err;
+	}
 
 	lim_prepare_for11h_channel_switch(mac_ctx, session_entry);
 	csa_offload_ind = qdf_mem_malloc(sizeof(tSmeCsaOffloadInd));
diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h
index 9c50a84..4cfa3d7 100644
--- a/core/mac/src/pe/lim/lim_types.h
+++ b/core/mac/src/pe/lim/lim_types.h
@@ -253,12 +253,12 @@
 	tSirWAPIie wapiIE;
 	tSirAddie addIE;        /* additional IE received from the peer, which possibly includes WSC IE and/or P2P IE. */
 	tSirMacCapabilityInfo capabilityInfo;
-	tAniBool spectrumMgtIndicator;
+	bool spectrumMgtIndicator;
 	tSirMacPowerCapInfo powerCap;
 	tSirSupChnl supportedChannels;
 	uint8_t sessionId;
 
-	tAniBool WmmStaInfoPresent;
+	bool WmmStaInfoPresent;
 
 	/* Required for indicating the frames to upper layer */
 	uint32_t beaconLength;
@@ -266,6 +266,17 @@
 	uint32_t assocReqLength;
 	uint8_t *assocReqPtr;
 	tSirSmeChanInfo chan_info;
+	bool ampdu;
+	bool sgi_enable;
+	bool tx_stbc;
+	bool rx_stbc;
+	tSirMacHTChannelWidth ch_width;
+	enum sir_sme_phy_mode mode;
+	uint8_t max_supp_idx;
+	uint8_t max_ext_idx;
+	uint8_t max_mcs_idx;
+	uint8_t rx_mcs_map;
+	uint8_t tx_mcs_map;
 } tLimMlmAssocInd, *tpLimMlmAssocInd;
 
 typedef struct sLimMlmReassocReq {
@@ -292,11 +303,11 @@
 	tSirWAPIie wapiIE;
 	tSirAddie addIE;        /* additional IE received from the peer, which can be WSC IE and/or P2P IE. */
 	tSirMacCapabilityInfo capabilityInfo;
-	tAniBool spectrumMgtIndicator;
+	bool spectrumMgtIndicator;
 	tSirMacPowerCapInfo powerCap;
 	tSirSupChnl supportedChannels;
 
-	tAniBool WmmStaInfoPresent;
+	bool WmmStaInfoPresent;
 
 	/* Required for indicating the frames to upper layer */
 	uint32_t beaconLength;
diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c
index 2c9a435..e94c931 100644
--- a/core/mac/src/pe/lim/lim_utils.c
+++ b/core/mac/src/pe/lim/lim_utils.c
@@ -4930,7 +4930,7 @@
  * @param  channel - New channel to which we are expected to move
  * @return None
  */
-tAniBool lim_is_channel_valid_for_channel_switch(tpAniSirGlobal pMac, uint8_t channel)
+bool lim_is_channel_valid_for_channel_switch(tpAniSirGlobal pMac, uint8_t channel)
 {
 	uint8_t index;
 	uint32_t validChannelListLen = WNI_CFG_VALID_CHANNEL_LIST_LEN;
@@ -4941,16 +4941,16 @@
 			     (uint32_t *) &validChannelListLen) !=
 			eSIR_SUCCESS) {
 		pe_err("could not retrieve valid channel list");
-		return eSIR_FALSE;
+		return false;
 	}
 
 	for (index = 0; index < validChannelListLen; index++) {
 		if (validChannelList[index] == channel)
-			return eSIR_TRUE;
+			return true;
 	}
 
 	/* channel does not belong to list of valid channels */
-	return eSIR_FALSE;
+	return false;
 }
 
 /**------------------------------------------------------
diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h
index 645059d..17c9187 100644
--- a/core/mac/src/pe/lim/lim_utils.h
+++ b/core/mac/src/pe/lim/lim_utils.h
@@ -247,7 +247,7 @@
 void lim_cancel_dot11h_channel_switch(tpAniSirGlobal pMac,
 		tpPESession psessionEntry);
 void lim_cancel_dot11h_quiet(tpAniSirGlobal pMac, tpPESession psessionEntry);
-tAniBool lim_is_channel_valid_for_channel_switch(tpAniSirGlobal pMac,
+bool lim_is_channel_valid_for_channel_switch(tpAniSirGlobal pMac,
 		uint8_t channel);
 void lim_frame_transmission_control(tpAniSirGlobal pMac, tLimQuietTxMode type,
 		tLimControlTx mode);
diff --git a/core/mac/src/sys/legacy/src/system/src/mac_init_api.c b/core/mac/src/sys/legacy/src/system/src/mac_init_api.c
index 3d4a6ee..e6b7458 100644
--- a/core/mac/src/sys/legacy/src/system/src/mac_init_api.c
+++ b/core/mac/src/sys/legacy/src/system/src/mac_init_api.c
@@ -83,13 +83,13 @@
    \return tSirRetStatus
    -------------------------------------------------------------*/
 
-tSirRetStatus mac_stop(tHalHandle hHal, tHalStopType stopType)
+QDF_STATUS mac_stop(tHalHandle hHal, tHalStopType stopType)
 {
 	tpAniSirGlobal pMac = (tpAniSirGlobal) hHal;
 	pe_stop(pMac);
 	cfg_cleanup(pMac);
 
-	return eSIR_SUCCESS;
+	return QDF_STATUS_SUCCESS;
 }
 
 /** -------------------------------------------------------------
@@ -157,13 +157,13 @@
    \return none
    -------------------------------------------------------------*/
 
-tSirRetStatus mac_close(tHalHandle hHal)
+QDF_STATUS mac_close(tHalHandle hHal)
 {
 
 	tpAniSirGlobal pMac = (tpAniSirGlobal) hHal;
 
 	if (!pMac)
-		return eSIR_FAILURE;
+		return QDF_STATUS_E_FAILURE;
 
 	pe_close(pMac);
 
@@ -177,5 +177,5 @@
 	wlan_objmgr_psoc_release_ref(pMac->psoc, WLAN_LEGACY_MAC_ID);
 	pMac->psoc = NULL;
 
-	return eSIR_SUCCESS;
+	return QDF_STATUS_SUCCESS;
 }
diff --git a/core/mac/src/sys/legacy/src/utils/src/dot11f.c b/core/mac/src/sys/legacy/src/utils/src/dot11f.c
index 4b6623e..a6051e5 100644
--- a/core/mac/src/sys/legacy/src/utils/src/dot11f.c
+++ b/core/mac/src/sys/legacy/src/utils/src/dot11f.c
@@ -33,7 +33,7 @@
  *
  *
  * This file was automatically generated by 'framesc'
- * Thu Jul  6 16:41:06 2017 from the following file(s):
+ * Fri Jul 14 12:29:59 2017 from the following file(s):
  *
  * dot11f.frms
  *
@@ -7370,6 +7370,9 @@
 	offsetof(tDot11fIEmu_edca_param_set, present), 0, "mu_edca_param_set",
 	0, 19, 19, SigIemu_edca_param_set, {0, 19, 116, 4, 0},
 	4, DOT11F_EID_MU_EDCA_PARAM_SET, 0, 0, },
+	{ offsetof(tDot11fAssocResponse, MBO_IE), offsetof(tDot11fIEMBO_IE,
+	present), 0, "MBO_IE", 0, 6, 295, SigIeMBO_IE, {80, 111, 154, 22, 0},
+	4, DOT11F_EID_MBO_IE, 0, 0, },
 	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
 
 uint32_t dot11f_unpack_assoc_response(tpAniSirGlobal pCtx,
@@ -9150,6 +9153,9 @@
 	offsetof(tDot11fIEmu_edca_param_set, present), 0, "mu_edca_param_set",
 	0, 19, 19, SigIemu_edca_param_set, {0, 19, 116, 4, 0},
 	4, DOT11F_EID_MU_EDCA_PARAM_SET, 0, 0, },
+	{ offsetof(tDot11fReAssocResponse, MBO_IE), offsetof(tDot11fIEMBO_IE,
+	present), 0, "MBO_IE", 0, 6, 295, SigIeMBO_IE, {80, 111, 154, 22, 0},
+	4, DOT11F_EID_MBO_IE, 0, 0, },
 	{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
 
 uint32_t dot11f_unpack_re_assoc_response(tpAniSirGlobal pCtx,
diff --git a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
index 5744ae9..79cd5ef 100644
--- a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
+++ b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
@@ -414,6 +414,8 @@
 		CASE_RETURN_STRING(eWNI_SME_DEFAULT_SCAN_IE);
 		CASE_RETURN_STRING(eWNI_SME_ROAM_SCAN_OFFLOAD_REQ);
 		CASE_RETURN_STRING(eWNI_SME_LOST_LINK_INFO_IND);
+		CASE_RETURN_STRING(eWNI_SME_GET_PEER_INFO_IND);
+		CASE_RETURN_STRING(eWNI_SME_GET_PEER_INFO_EXT_IND);
 		CASE_RETURN_STRING(eWNI_SME_RSO_CMD_STATUS_IND);
 		CASE_RETURN_STRING(eWNI_SME_MSG_TYPES_END);
 	default:
diff --git a/core/pld/inc/pld_common.h b/core/pld/inc/pld_common.h
index 30abc28..ad20d09 100644
--- a/core/pld/inc/pld_common.h
+++ b/core/pld/inc/pld_common.h
@@ -33,6 +33,10 @@
 #include <linux/pm.h>
 #include <osapi_linux.h>
 
+#ifdef CONFIG_CNSS_UTILS
+#include <net/cnss_utils.h>
+#endif
+
 #define PLD_IMAGE_FILE               "athwlan.bin"
 #define PLD_UTF_FIRMWARE_FILE        "utf.bin"
 #define PLD_BOARD_DATA_FILE          "fakeboar.bin"
@@ -366,14 +370,150 @@
 				u32 target_type, u32 target_version);
 void pld_is_pci_link_down(struct device *dev);
 int pld_shadow_control(struct device *dev, bool enable);
-int pld_set_wlan_unsafe_channel(struct device *dev, u16 *unsafe_ch_list,
-				u16 ch_count);
-int pld_get_wlan_unsafe_channel(struct device *dev, u16 *unsafe_ch_list,
-				u16 *ch_count, u16 buf_len);
-int pld_wlan_set_dfs_nol(struct device *dev, void *info, u16 info_len);
-int pld_wlan_get_dfs_nol(struct device *dev, void *info, u16 info_len);
 void pld_schedule_recovery_work(struct device *dev,
 				enum pld_recovery_reason reason);
+#ifdef CONFIG_CNSS_UTILS
+/**
+ * pld_set_wlan_unsafe_channel() - Set unsafe channel
+ * @dev: device
+ * @unsafe_ch_list: unsafe channel list
+ * @ch_count: number of channel
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+static inline int pld_set_wlan_unsafe_channel(struct device *dev,
+					      u16 *unsafe_ch_list,
+					      u16 ch_count)
+{
+	return cnss_utils_set_wlan_unsafe_channel(dev, unsafe_ch_list,
+						  ch_count);
+}
+/**
+ * pld_get_wlan_unsafe_channel() - Get unsafe channel
+ * @dev: device
+ * @unsafe_ch_list: buffer to unsafe channel list
+ * @ch_count: number of channel
+ * @buf_len: buffer length
+ *
+ * Return WLAN unsafe channel to the buffer.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+static inline int pld_get_wlan_unsafe_channel(struct device *dev,
+					      u16 *unsafe_ch_list,
+					      u16 *ch_count, u16 buf_len)
+{
+	return cnss_utils_get_wlan_unsafe_channel(dev, unsafe_ch_list,
+						  ch_count, buf_len);
+}
+/**
+ * pld_wlan_set_dfs_nol() - Set DFS info
+ * @dev: device
+ * @info: DFS info
+ * @info_len: info length
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+static inline int pld_wlan_set_dfs_nol(struct device *dev, void *info,
+				       u16 info_len)
+{
+	return cnss_utils_wlan_set_dfs_nol(dev, info, info_len);
+}
+/**
+ * pld_wlan_get_dfs_nol() - Get DFS info
+ * @dev: device
+ * @info: buffer to DFS info
+ * @info_len: info length
+ *
+ * Return DFS info to the buffer.
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+static inline int pld_wlan_get_dfs_nol(struct device *dev,
+				       void *info, u16 info_len)
+{
+	return cnss_utils_wlan_get_dfs_nol(dev, info, info_len);
+}
+/**
+ * pld_get_wlan_mac_address() - API to query MAC address from Platform
+ * Driver
+ * @dev: Device Structure
+ * @num: Pointer to number of MAC address supported
+ *
+ * Platform Driver can have MAC address stored. This API needs to be used
+ * to get those MAC address
+ *
+ * Return: Pointer to the list of MAC address
+ */
+static inline uint8_t *pld_get_wlan_mac_address(struct device *dev,
+						uint32_t *num)
+{
+	return cnss_utils_get_wlan_mac_address(dev, num);
+}
+/**
+ * pld_increment_driver_load_cnt() - Maintain driver load count
+ * @dev: device
+ *
+ * This function maintain a count which get increase whenever wiphy
+ * is registered
+ *
+ * Return: void
+ */
+static inline void pld_increment_driver_load_cnt(struct device *dev)
+{
+	cnss_utils_increment_driver_load_cnt(dev);
+}
+/**
+ * pld_get_driver_load_cnt() - get driver load count
+ * @dev: device
+ *
+ * This function provide total wiphy registration count from starting
+ *
+ * Return: driver load count
+ */
+static inline int pld_get_driver_load_cnt(struct device *dev)
+{
+	return cnss_utils_get_driver_load_cnt(dev);
+}
+#else
+static inline int pld_set_wlan_unsafe_channel(struct device *dev,
+					      u16 *unsafe_ch_list,
+					      u16 ch_count)
+{
+	return -EINVAL;
+}
+static inline int pld_get_wlan_unsafe_channel(struct device *dev,
+					      u16 *unsafe_ch_list,
+					      u16 *ch_count, u16 buf_len)
+{
+	return -EINVAL;
+}
+static inline int pld_wlan_set_dfs_nol(struct device *dev,
+				       void *info, u16 info_len)
+{
+	return -EINVAL;
+}
+static inline int pld_wlan_get_dfs_nol(struct device *dev,
+				       void *info, u16 info_len)
+{
+	return -EINVAL;
+}
+static inline uint8_t *pld_get_wlan_mac_address(struct device *dev,
+						uint32_t *num)
+{
+	*num = 0;
+	return NULL;
+}
+static inline void pld_increment_driver_load_cnt(struct device *dev) {}
+static inline int pld_get_driver_load_cnt(struct device *dev)
+{
+	return -EINVAL;
+}
+#endif
 int pld_wlan_pm_control(struct device *dev, bool vote);
 void *pld_get_virt_ramdump_mem(struct device *dev, unsigned long *size);
 void pld_device_crashed(struct device *dev);
@@ -418,7 +558,6 @@
 void pld_get_msi_address(struct device *dev, uint32_t *msi_addr_low,
 			 uint32_t *msi_addr_high);
 unsigned int pld_socinfo_get_serial_number(struct device *dev);
-uint8_t *pld_get_wlan_mac_address(struct device *dev, uint32_t *num);
 int pld_is_qmi_disable(struct device *dev);
 int pld_force_assert_target(struct device *dev);
 
diff --git a/core/pld/src/pld_common.c b/core/pld/src/pld_common.c
index 382a59c..eaa37b6 100644
--- a/core/pld/src/pld_common.c
+++ b/core/pld/src/pld_common.c
@@ -543,140 +543,6 @@
 }
 
 /**
- * pld_set_wlan_unsafe_channel() - Set unsafe channel
- * @dev: device
- * @unsafe_ch_list: unsafe channel list
- * @ch_count: number of channel
- *
- * Return: 0 for success
- *         Non zero failure code for errors
- */
-int pld_set_wlan_unsafe_channel(struct device *dev,
-				u16 *unsafe_ch_list, u16 ch_count)
-{
-	int ret = 0;
-
-	switch (pld_get_bus_type(dev)) {
-	case PLD_BUS_TYPE_PCIE:
-		ret = pld_pcie_set_wlan_unsafe_channel(unsafe_ch_list,
-						       ch_count);
-		break;
-	case PLD_BUS_TYPE_SNOC:
-		ret = pld_snoc_set_wlan_unsafe_channel(unsafe_ch_list,
-						       ch_count);
-		break;
-	case PLD_BUS_TYPE_SDIO:
-		/* To do get unsafe channel via cnss sdio API */
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
-/**
- * pld_get_wlan_unsafe_channel() - Get unsafe channel
- * @dev: device
- * @unsafe_ch_list: buffer to unsafe channel list
- * @ch_count: number of channel
- * @buf_len: buffer length
- *
- * Return WLAN unsafe channel to the buffer.
- *
- * Return: 0 for success
- *         Non zero failure code for errors
- */
-int pld_get_wlan_unsafe_channel(struct device *dev, u16 *unsafe_ch_list,
-				u16 *ch_count, u16 buf_len)
-{
-	int ret = 0;
-
-	switch (pld_get_bus_type(dev)) {
-	case PLD_BUS_TYPE_PCIE:
-		ret = pld_pcie_get_wlan_unsafe_channel(unsafe_ch_list,
-						       ch_count, buf_len);
-		break;
-	case PLD_BUS_TYPE_SNOC:
-		ret = pld_snoc_get_wlan_unsafe_channel(unsafe_ch_list,
-						       ch_count, buf_len);
-		break;
-	case PLD_BUS_TYPE_SDIO:
-		/* To do get unsafe channel via cnss sdio API */
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
-/**
- * pld_wlan_set_dfs_nol() - Set DFS info
- * @dev: device
- * @info: DFS info
- * @info_len: info length
- *
- * Return: 0 for success
- *         Non zero failure code for errors
- */
-int pld_wlan_set_dfs_nol(struct device *dev, void *info, u16 info_len)
-{
-	int ret = 0;
-
-	switch (pld_get_bus_type(dev)) {
-	case PLD_BUS_TYPE_PCIE:
-		ret = pld_pcie_wlan_set_dfs_nol(info, info_len);
-		break;
-	case PLD_BUS_TYPE_SNOC:
-		ret = pld_snoc_wlan_set_dfs_nol(info, info_len);
-		break;
-	case PLD_BUS_TYPE_SDIO:
-		/* To do get nol via cnss sdio API */
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
-/**
- * pld_wlan_get_dfs_nol() - Get DFS info
- * @dev: device
- * @info: buffer to DFS info
- * @info_len: info length
- *
- * Return DFS info to the buffer.
- *
- * Return: 0 for success
- *         Non zero failure code for errors
- */
-int pld_wlan_get_dfs_nol(struct device *dev, void *info, u16 info_len)
-{
-	int ret = 0;
-
-	switch (pld_get_bus_type(dev)) {
-	case PLD_BUS_TYPE_PCIE:
-		ret = pld_pcie_wlan_get_dfs_nol(info, info_len);
-		break;
-	case PLD_BUS_TYPE_SNOC:
-		ret = pld_snoc_wlan_get_dfs_nol(info, info_len);
-		break;
-	case PLD_BUS_TYPE_SDIO:
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
-/**
  * pld_schedule_recovery_work() - Schedule recovery work
  * @dev: device
  * @reason: recovery reason
@@ -1630,40 +1496,6 @@
 	return ret;
 }
 
-/*
- * pld_get_wlan_mac_address() - API to query MAC address from Platform
- * Driver
- * @dev: Device Structure
- * @num: Pointer to number of MAC address supported
- *
- * Platform Driver can have MAC address stored. This API needs to be used
- * to get those MAC address
- *
- * Return: Pointer to the list of MAC address
- */
-uint8_t *pld_get_wlan_mac_address(struct device *dev, uint32_t *num)
-{
-	enum pld_bus_type type = pld_get_bus_type(dev);
-
-	switch (type) {
-	case PLD_BUS_TYPE_PCIE:
-		return pld_pcie_get_wlan_mac_address(dev, num);
-	case PLD_BUS_TYPE_SDIO:
-		return pld_sdio_get_wlan_mac_address(dev, num);
-	case PLD_BUS_TYPE_SNOC:
-		return pld_snoc_get_wlan_mac_address(dev, num);
-	case PLD_BUS_TYPE_USB:
-		pr_err("Not supported on type %d\n", type);
-		break;
-	default:
-		pr_err("Invalid device type\n");
-		break;
-	}
-
-	*num = 0;
-	return NULL;
-}
-
 /**
  * pld_is_qmi_disable() - Check QMI support is present or not
  * @dev: device
@@ -1713,8 +1545,9 @@
 	case PLD_BUS_TYPE_SNOC:
 		ret = pld_snoc_force_assert_target(dev);
 		break;
-
 	case PLD_BUS_TYPE_PCIE:
+		ret = pld_pcie_force_assert_target(dev);
+		break;
 	case PLD_BUS_TYPE_SDIO:
 		ret = -EINVAL;
 		break;
diff --git a/core/pld/src/pld_pcie.h b/core/pld/src/pld_pcie.h
index 95481e9..186dfb4 100644
--- a/core/pld/src/pld_pcie.h
+++ b/core/pld/src/pld_pcie.h
@@ -238,7 +238,10 @@
 {
 	return 0;
 }
-
+static inline int pld_pcie_force_assert_target(struct device *dev)
+{
+	return -EINVAL;
+}
 static inline uint8_t *pld_pcie_get_wlan_mac_address(struct device *dev,
 						     uint32_t *num)
 {
@@ -356,7 +359,10 @@
 {
 	return cnss_power_down(dev);
 }
-
+static inline int pld_pcie_force_assert_target(struct device *dev)
+{
+	return cnss_force_fw_assert(dev);
+}
 static inline uint8_t *pld_pcie_get_wlan_mac_address(struct device *dev,
 						     uint32_t *num)
 {
diff --git a/core/sap/dfs/inc/dfs.h b/core/sap/dfs/inc/dfs.h
index a074f70..b0a034c 100644
--- a/core/sap/dfs/inc/dfs.h
+++ b/core/sap/dfs/inc/dfs.h
@@ -342,7 +342,7 @@
 	uint8_t dfs_phyerr_eventq_serial_num;
 	uint8_t peak_mag;
 	STAILQ_ENTRY(dfs_event) re_list;
-} qdf_packed;
+};
 #ifdef WIN32
 #pragma pack(pop, dfs_event)
 #endif
@@ -496,7 +496,7 @@
 	uint32_t nol_timeout_ms;        /* NOL timeout value in msec */
 	os_timer_t nol_timer;   /* per element NOL timer */
 	struct dfs_nolelem *nol_next;   /* next element pointer */
-} qdf_packed;
+};
 #ifdef WIN32
 #pragma pack(pop, dfs_nolelem)
 #endif
diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h
index 987bdd6..1412220 100644
--- a/core/sap/inc/sap_api.h
+++ b/core/sap/inc/sap_api.h
@@ -201,12 +201,6 @@
 	eSAP_USR_INITATED_DISASSOC
 } eSapDisassocReason;
 
-/*Handle bool over here*/
-typedef enum {
-	eSAP_FALSE,
-	eSAP_TRUE,
-} eSapBool;
-
 typedef enum {
 	eSAP_DFS_NOL_CLEAR,
 	eSAP_DFS_NOL_RANDOMIZE,
@@ -293,6 +287,17 @@
 	uint8_t *assocRespPtr;
 	uint8_t timingMeasCap;
 	tSirSmeChanInfo chan_info;
+	bool ampdu;
+	bool sgi_enable;
+	bool tx_stbc;
+	bool rx_stbc;
+	tSirMacHTChannelWidth ch_width;
+	enum sir_sme_phy_mode mode;
+	uint8_t max_supp_idx;
+	uint8_t max_ext_idx;
+	uint8_t max_mcs_idx;
+	uint8_t rx_mcs_map;
+	uint8_t tx_mcs_map;
 } tSap_StationAssocReassocCompleteEvent;
 
 typedef struct sap_StationDisassocCompleteEvent_s {
@@ -313,7 +318,7 @@
 	struct qdf_mac_addr srcMacAddr;    /* address used to compute MIC */
 	struct qdf_mac_addr staMac;        /* taMacAddr transmitter address */
 	struct qdf_mac_addr dstMacAddr;
-	eSapBool multicast;
+	bool multicast;
 	uint8_t IV1;            /* first byte of IV */
 	uint8_t keyId;          /* second byte of IV */
 	uint8_t TSC[SIR_CIPHER_SEQ_CTR_SIZE];           /* sequence number */
@@ -517,6 +522,7 @@
 	uint8_t    ht_sec_ch;
 	uint8_t    vht_seg0_center_ch;
 	uint8_t    vht_seg1_center_ch;
+	uint32_t   band;
 };
 
 /*
@@ -1060,6 +1066,18 @@
  * Return: None
  */
 void sap_dfs_set_current_channel(void *sap_ctx);
+
+/**
+ * wlansap_cleanup_cac_timer() - Force cleanup DFS CAC timer
+ * @sap_ctx: sap context
+ *
+ * Force cleanup DFS CAC timer when reset all adapters. It will not
+ * check concurrency SAP since just called when reset all adapters.
+ *
+ * Return: None
+ */
+void wlansap_cleanup_cac_timer(void *sap_ctx);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/core/sap/src/sap_api_link_cntl.c b/core/sap/src/sap_api_link_cntl.c
index cb0c236..9ca306c 100644
--- a/core/sap/src/sap_api_link_cntl.c
+++ b/core/sap/src/sap_api_link_cntl.c
@@ -568,7 +568,7 @@
 		 * beacon template will be cleared by now. A new beacon template
 		 * with no CSA IE will be sent to firmware.
 		 */
-		dfs_beacon_start_req = eSAP_TRUE;
+		dfs_beacon_start_req = true;
 		sap_ctx->pre_cac_complete = false;
 		*ret_status = sme_roam_start_beacon_req(hHal, sap_ctx->bssid,
 							dfs_beacon_start_req);
diff --git a/core/sap/src/sap_ch_select.c b/core/sap/src/sap_ch_select.c
index eb8022f..0535060 100644
--- a/core/sap/src/sap_ch_select.c
+++ b/core/sap/src/sap_ch_select.c
@@ -587,7 +587,7 @@
 	if (pSpectCh == NULL) {
 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
 			  "In %s, QDF_MALLOC_ERR", __func__);
-		return eSAP_FALSE;
+		return false;
 	}
 
 	/* Initialize the pointers in the DfsParams to the allocated memory */
@@ -658,12 +658,12 @@
 
 		if (true == chSafe) {
 			pSpectCh->chNum = *pChans;
-			pSpectCh->valid = eSAP_TRUE;
+			pSpectCh->valid = true;
 			pSpectCh->rssiAgr = SOFTAP_MIN_RSSI;    /* Initialise for all channels */
 			pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH;      /* Initialise 20MHz for all the Channels */
 		}
 	}
-	return eSAP_TRUE;
+	return true;
 }
 
 /*==========================================================================
@@ -2084,12 +2084,12 @@
 static bool sap_filter_over_lap_ch(ptSapContext pSapCtx, uint16_t chNum)
 {
 	if (pSapCtx->enableOverLapCh)
-		return eSAP_TRUE;
+		return true;
 	else if ((chNum == CHANNEL_1) ||
 		 (chNum == CHANNEL_6) || (chNum == CHANNEL_11))
-		return eSAP_TRUE;
+		return true;
 
-	return eSAP_FALSE;
+	return false;
 }
 
 #ifdef FEATURE_WLAN_CH_AVOID
@@ -2238,7 +2238,7 @@
 	}
 
 	/* Initialize the structure pointed by spect_info */
-	if (sap_chan_sel_init(hal, spect_info, sap_ctx) != eSAP_TRUE) {
+	if (sap_chan_sel_init(hal, spect_info, sap_ctx) != true) {
 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
 			  FL("Ch Select initialization failed"));
 		return SAP_CHANNEL_NOT_SELECTED;
diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c
index 760d1a3..5cfd69c 100644
--- a/core/sap/src/sap_fsm.c
+++ b/core/sap/src/sap_fsm.c
@@ -1257,7 +1257,7 @@
 	}
 
 	mac = PMAC_STRUCT(hal);
-	wlan_reg_get_dfs_region(mac->psoc, dfs_region);
+	wlan_reg_get_dfs_region(mac->pdev, dfs_region);
 	if (mac->sap.SapDfsInfo.ignore_cac) {
 		*cac_duration_ms = 0;
 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
@@ -1266,17 +1266,6 @@
 	}
 	*cac_duration_ms = DEFAULT_CAC_TIMEOUT;
 
-	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
-		  FL("sapdfs: dfs_region=%d, chwidth=%d, seg0=%d, seg1=%d"),
-		  *dfs_region, ch_params->ch_width,
-		  ch_params->center_freq_seg0, ch_params->center_freq_seg1);
-
-	if (*dfs_region != DFS_ETSI_REG) {
-		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
-			  FL("sapdfs: defult cac duration"));
-		return;
-	}
-
 	if (sap_is_channel_bonding_etsi_weather_channel(sap_ctx)) {
 		*cac_duration_ms = ETSI_WEATHER_CH_CAC_TIMEOUT;
 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
@@ -2462,6 +2451,17 @@
 		reassoc_complete->wmmEnabled = csr_roaminfo->wmmEnabledSta;
 		reassoc_complete->status = (eSapStatus) context;
 		reassoc_complete->timingMeasCap = csr_roaminfo->timingMeasCap;
+		reassoc_complete->ampdu = csr_roaminfo->ampdu;
+		reassoc_complete->sgi_enable = csr_roaminfo->sgi_enable;
+		reassoc_complete->tx_stbc = csr_roaminfo->tx_stbc;
+		reassoc_complete->rx_stbc = csr_roaminfo->rx_stbc;
+		reassoc_complete->ch_width = csr_roaminfo->ch_width;
+		reassoc_complete->mode = csr_roaminfo->mode;
+		reassoc_complete->max_supp_idx = csr_roaminfo->max_supp_idx;
+		reassoc_complete->max_ext_idx = csr_roaminfo->max_ext_idx;
+		reassoc_complete->max_mcs_idx = csr_roaminfo->max_mcs_idx;
+		reassoc_complete->rx_mcs_map = csr_roaminfo->rx_mcs_map;
+		reassoc_complete->tx_mcs_map = csr_roaminfo->tx_mcs_map;
 		break;
 
 	case eSAP_STA_DISASSOC_EVENT:
@@ -3708,8 +3708,6 @@
 			     pconfig_params->RSNWPAReqIELength);
 		profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength;
 	}
-	/* Turn off CB mode */
-	profile->CBMode = eCSR_CB_OFF;
 
 	/* set the phyMode to accept anything */
 	/* Best means everything because it covers all the things we support */
@@ -3837,7 +3835,7 @@
 	}
 }
 
-eSapBool
+bool
 sap_search_mac_list(struct qdf_mac_addr *macList,
 		    uint8_t num_mac, uint8_t *peerMac,
 		    uint8_t *index)
@@ -3849,7 +3847,7 @@
 	if ((NULL == macList) || (num_mac > MAX_ACL_MAC_ADDRESS)) {
 		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
 		    FL("either buffer is NULL or size = %d is more."), num_mac);
-		return eSAP_FALSE;
+		return false;
 	}
 
 	while (nStart <= nEnd) {
@@ -3869,7 +3867,7 @@
 					  QDF_TRACE_LEVEL_INFO_HIGH, "index %d",
 					  *index);
 			}
-			return eSAP_TRUE;
+			return true;
 		}
 		if (nRes < 0)
 			nStart = nMiddle + 1;
@@ -3879,7 +3877,7 @@
 
 	QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
 		  "search not succ");
-	return eSAP_FALSE;
+	return false;
 }
 
 void sap_add_mac_to_acl(struct qdf_mac_addr *macList,
@@ -4101,9 +4099,9 @@
 		 * - DFS scan enabled and chan not in CHANNEL_STATE_DISABLE
 		 * - DFS scan disable but chan in CHANNEL_STATE_ENABLE
 		 */
-		if (!(((eSAP_TRUE == mac_ctx->scan.fEnableDFSChnlScan) &&
+		if (!(((true == mac_ctx->scan.fEnableDFSChnlScan) &&
 		      wlan_reg_get_channel_state(mac_ctx->pdev, loop_count)) ||
-		    ((eSAP_FALSE == mac_ctx->scan.fEnableDFSChnlScan) &&
+		    ((false == mac_ctx->scan.fEnableDFSChnlScan) &&
 		     (CHANNEL_STATE_ENABLE ==
 		      wlan_reg_get_channel_state(mac_ctx->pdev, loop_count)))))
 			continue;
@@ -4212,7 +4210,7 @@
 	 * if the radar is found in the STARTED state
 	 */
 	if (eSAP_STARTED == sap_ctx->sapsMachine)
-		mac->sap.SapDfsInfo.csaIERequired = eSAP_TRUE;
+		mac->sap.SapDfsInfo.csaIERequired = true;
 
 	if (sap_ctx->csr_roamProfile.disableDFSChSwitch)
 		return sap_ctx->channel;
diff --git a/core/sap/src/sap_internal.h b/core/sap/src/sap_internal.h
index 02b4b79..0116e47 100644
--- a/core/sap/src/sap_internal.h
+++ b/core/sap/src/sap_internal.h
@@ -368,7 +368,7 @@
 void
 sap_print_acl(struct qdf_mac_addr *macList, uint8_t size);
 
-eSapBool
+bool
 sap_search_mac_list(struct qdf_mac_addr *macList, uint8_t num_mac,
 		 uint8_t *peerMac, uint8_t *index);
 
diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c
index c8d92bc..2c810ea 100644
--- a/core/sap/src/sap_module.c
+++ b/core/sap/src/sap_module.c
@@ -1300,7 +1300,7 @@
 wlansap_modify_acl
 	(void *ctx,
 	uint8_t *peer_sta_mac, eSapACLType list_type, eSapACLCmdType cmd) {
-	eSapBool sta_white_list = eSAP_FALSE, sta_black_list = eSAP_FALSE;
+	bool sta_white_list = false, sta_black_list = false;
 	uint8_t staWLIndex, staBLIndex;
 	ptSapContext sap_ctx = CDS_GET_SAP_CB(ctx);
 
@@ -2976,7 +2976,7 @@
 		return QDF_STATUS_E_FAULT;
 	}
 
-	wlan_reg_get_dfs_region(pMac->psoc, &dfs_region);
+	wlan_reg_get_dfs_region(pMac->pdev, &dfs_region);
 
 	/*
 	 * Set the JAPAN W53 restriction only if the current
@@ -3072,7 +3072,7 @@
 		return QDF_STATUS_E_FAULT;
 	}
 
-	wlan_reg_get_dfs_region(pMac->psoc, &dfs_region);
+	wlan_reg_get_dfs_region(pMac->pdev, &dfs_region);
 
 	/*
 	 * The Indoor/Outdoor only random channel selection
@@ -3745,3 +3745,26 @@
 
 	return QDF_STATUS_SUCCESS;
 }
+
+void wlansap_cleanup_cac_timer(void *sap_ctx)
+{
+	tHalHandle hal;
+	ptSapContext psap_ctx;
+	tpAniSirGlobal pmac;
+
+	if (!sap_ctx)
+		return;
+
+	psap_ctx = CDS_GET_SAP_CB(sap_ctx);
+	hal = CDS_GET_HAL_CB(psap_ctx->p_cds_gctx);
+	pmac = PMAC_STRUCT(hal);
+	if (pmac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
+		qdf_mc_timer_stop(&pmac->sap.SapDfsInfo.
+				  sap_dfs_cac_timer);
+		pmac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
+		qdf_mc_timer_destroy(
+			&pmac->sap.SapDfsInfo.sap_dfs_cac_timer);
+		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+			FL("sapdfs, force cleanup running dfs cac timer"));
+	}
+}
diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h
index 81a9f1b..cec91f0 100644
--- a/core/sme/inc/csr_api.h
+++ b/core/sme/inc/csr_api.h
@@ -527,6 +527,7 @@
 /* comment inside indicates what roaming callback gets */
 typedef enum {
 	eCSR_ROAM_RESULT_NONE,
+	eCSR_ROAM_RESULT_SUCCESS = eCSR_ROAM_RESULT_NONE,
 	/*
 	 * If roamStatus is eCSR_ROAM_ASSOCIATION_COMPLETION,
 	 * tCsrRoamInfo's pBssDesc may pass back
@@ -922,7 +923,6 @@
 	uint8_t MFPCapable;
 #endif
 	tCsrKeys Keys;
-	eCsrCBChoice CBMode;
 	tCsrChannelInfo ChannelInfo;
 	uint8_t operationChannel;
 	struct ch_params ch_params;
@@ -1012,7 +1012,6 @@
 	tCsrEncryptionList EncryptionInfo;
 	eCsrEncryptionType mcEncryptionType;
 	tCsrEncryptionList mcEncryptionInfo;
-	eCsrCBChoice CBMode;
 	uint8_t operationChannel;
 	uint32_t vht_channel_width;
 	uint16_t beaconInterval;
@@ -1320,6 +1319,9 @@
 	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 */
@@ -1448,6 +1450,17 @@
 	tDot11fIEVHTOperation vht_operation;
 	tDot11fIEHTInfo ht_operation;
 	bool reassoc;
+	bool ampdu;
+	bool sgi_enable;
+	bool tx_stbc;
+	bool rx_stbc;
+	tSirMacHTChannelWidth ch_width;
+	enum sir_sme_phy_mode mode;
+	uint8_t max_supp_idx;
+	uint8_t max_ext_idx;
+	uint8_t max_mcs_idx;
+	uint8_t rx_mcs_map;
+	uint8_t tx_mcs_map;
 } tCsrRoamInfo;
 
 typedef struct tagCsrFreqScanInfo {
@@ -1475,6 +1488,17 @@
 	uint8_t timingMeasCap;
 	tSirSmeChanInfo chan_info;
 	uint8_t target_channel;
+	bool ampdu;
+	bool sgi_enable;
+	bool tx_stbc;
+	tSirMacHTChannelWidth ch_width;
+	enum sir_sme_phy_mode mode;
+	bool rx_stbc;
+	uint8_t max_supp_idx;
+	uint8_t max_ext_idx;
+	uint8_t max_mcs_idx;
+	uint8_t rx_mcs_map;
+	uint8_t tx_mcs_map;
 } tSirSmeAssocIndToUpperLayerCnf, *tpSirSmeAssocIndToUpperLayerCnf;
 
 typedef struct tagCsrSummaryStatsInfo {
diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h
index 095f90d..f0edfd7 100644
--- a/core/sme/inc/csr_internal.h
+++ b/core/sme/inc/csr_internal.h
@@ -624,6 +624,9 @@
 	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 {
@@ -768,24 +771,17 @@
 typedef struct tagCsrPeStatsReqInfo {
 	tListElem link;         /* list links */
 	uint32_t statsMask;
-	uint32_t periodicity;
 	bool rspPending;
-	qdf_mc_timer_t hPeStatsTimer;
-	bool timerRunning;
 	uint8_t staId;
 	uint8_t numClient;
 	tpAniSirGlobal pMac;
-	/* To remember if the peStats timer is stopped successfully or not */
-	bool timerStopFailed;
 	uint8_t sessionId;
-
 } tCsrPeStatsReqInfo;
 
 typedef struct tagCsrStatsClientReqInfo {
 	tListElem link;         /* list links */
 	eCsrStatsRequesterType requesterId;
 	tCsrStatsCallback callback;
-	uint32_t periodicity;
 	void *pContext;
 	uint32_t statsMask;
 	tCsrPeStatsReqInfo *pPeStaEntry;
@@ -797,9 +793,6 @@
 } tCsrStatsClientReqInfo;
 
 typedef struct tagCsrTlStatsReqInfo {
-	uint32_t periodicity;
-	bool timerRunning;
-	qdf_mc_timer_t hTlStatsTimer;
 	uint8_t numClient;
 } tCsrTlStatsReqInfo;
 
@@ -1209,8 +1202,7 @@
 QDF_STATUS csr_get_statistics(tpAniSirGlobal pMac,
 		eCsrStatsRequesterType requesterId,
 		uint32_t statsMask, tCsrStatsCallback callback,
-		uint32_t periodicity, bool cache, uint8_t staId,
-		void *pContext, uint8_t sessionId);
+		uint8_t staId, void *pContext, uint8_t sessionId);
 QDF_STATUS csr_get_rssi(tpAniSirGlobal pMac, tCsrRssiCallback callback,
 		uint8_t staId, struct qdf_mac_addr bssId, int8_t lastRSSI,
 		void *pContext, void *p_cds_context);
diff --git a/core/sme/inc/csr_neighbor_roam.h b/core/sme/inc/csr_neighbor_roam.h
index cf9b257..dff1bd9 100644
--- a/core/sme/inc/csr_neighbor_roam.h
+++ b/core/sme/inc/csr_neighbor_roam.h
@@ -170,6 +170,7 @@
 	uint8_t currentRoamBmissFinalBcnt;
 	uint8_t currentRoamBeaconRssiWeight;
 	uint8_t last_sent_cmd;
+	bool b_roam_scan_offload_started;
 } tCsrNeighborRoamControlInfo, *tpCsrNeighborRoamControlInfo;
 
 /* All the necessary Function declarations are here */
diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h
index b395657..fece2e1 100644
--- a/core/sme/inc/sme_api.h
+++ b/core/sme/inc/sme_api.h
@@ -348,8 +348,7 @@
 QDF_STATUS sme_get_statistics(tHalHandle hHal,
 		eCsrStatsRequesterType requesterId,
 		uint32_t statsMask, tCsrStatsCallback callback,
-		uint32_t periodicity, bool cache, uint8_t staId,
-		void *pContext, uint8_t sessionId);
+		uint8_t staId, void *pContext, uint8_t sessionId);
 QDF_STATUS sme_get_rssi(tHalHandle hHal,
 		tCsrRssiCallback callback,
 		uint8_t staId, struct qdf_mac_addr bssId, int8_t lastRSSI,
@@ -444,8 +443,8 @@
 		uint8_t *pCountry,
 		void *pContext,
 		void *p_cds_context,
-		tAniBool countryFromUserSpace,
-		tAniBool sendRegHint);
+		bool countryFromUserSpace,
+		bool sendRegHint);
 QDF_STATUS sme_generic_change_country_code(tHalHandle hHal,
 					   uint8_t *pCountry);
 QDF_STATUS sme_tx_fail_monitor_start_stop_ind(tHalHandle hHal,
@@ -1618,4 +1617,47 @@
  */
 int sme_cli_set_command(int vdev_id, int param_id, int sval, int vpdev);
 
+/**
+ * sme_set_bt_activity_info_cb - set the callback handler for bt events
+ * @hal: handle returned by mac_open
+ * @cb: callback handler
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_bt_activity_info_cb(tHalHandle hal,
+				void (*cb)(void *, uint32_t profile_info));
+
+/**
+ * sme_get_peer_info() - sme api to get peer info
+ * @hal: hal handle for getting global mac struct
+ * @req: peer info request struct send to wma
+ * @context: context of callback function
+ * @callbackfn: hdd callback function when receive response
+ *
+ * This function will send WMA_GET_PEER_INFO to WMA
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure
+ */
+QDF_STATUS sme_get_peer_info(tHalHandle hal,
+		struct sir_peer_info_req req,
+		void *context,
+		void (*callbackfn)(struct sir_peer_info_resp *param,
+			void *pcontext));
+
+/**
+ * sme_get_peer_info_ext() - sme api to get peer ext info
+ * @hal: hal handle for getting global mac struct
+ * @req: peer ext info request struct send to wma
+ * @context: context of callback function
+ * @callbackfn: hdd callback function when receive response
+ *
+ * This function will send WMA_GET_PEER_INFO_EXT to WMA
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure
+ */
+QDF_STATUS sme_get_peer_info_ext(tHalHandle hal,
+		struct sir_peer_info_ext_req *req,
+		void *context,
+		void (*callbackfn)(struct sir_peer_info_ext_resp *param,
+			void *pcontext));
 #endif /* #if !defined( __SME_API_H ) */
diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h
index 7a13c60..585cced 100644
--- a/core/sme/inc/sme_internal.h
+++ b/core/sme/inc/sme_internal.h
@@ -197,6 +197,14 @@
 	void (*pLinkSpeedIndCb)(tSirLinkSpeedInfo *indParam,
 			void *pDevContext);
 	void *pLinkSpeedCbContext;
+	/* get peer info callback */
+	void (*pget_peer_info_ind_cb)(struct sir_peer_info_resp *param,
+		void *pcontext);
+	void *pget_peer_info_cb_context;
+	/* get extended peer info callback */
+	void (*pget_peer_info_ext_ind_cb)(struct sir_peer_info_ext_resp *param,
+		void *pcontext);
+	void *pget_peer_info_ext_cb_context;
 #ifdef FEATURE_WLAN_EXTSCAN
 	void (*pExtScanIndCb)(void *, const uint16_t, void *);
 #endif /* FEATURE_WLAN_EXTSCAN */
@@ -252,6 +260,7 @@
 	void (*stats_ext2_cb)(void *, struct sir_sme_rx_aggr_hole_ind *);
 	void (*chip_power_save_fail_cb)(void *,
 			struct chip_pwr_save_fail_detected_params *);
+	void (*bt_activity_info_cb)(void *context, uint32_t bt_activity);
 } tSmeStruct, *tpSmeStruct;
 
 #endif /* #if !defined( __SMEINTERNAL_H ) */
diff --git a/core/sme/inc/sme_qos_internal.h b/core/sme/inc/sme_qos_internal.h
index 109fd50..9c66feb 100644
--- a/core/sme/inc/sme_qos_internal.h
+++ b/core/sme/inc/sme_qos_internal.h
@@ -123,17 +123,6 @@
   ------------------------------------------------------------------------*/
 QDF_STATUS sme_qos_validate_params(tpAniSirGlobal pMac,
 		tSirBssDescription *pBssDesc);
-/**
- * sme_qos_remove_addts_delts_cmd - Remove addts/delts command
- * @mac_ctx: Pointer to the global MAC structure.
- * @session_id: Session id
- *
- * This function is used to remove addts/delts command
- * during csr roam sync callback.
- *
- * Return: void
- */
-void sme_qos_remove_addts_delts_cmd(tpAniSirGlobal mac_ctx, uint8_t session_id);
 QDF_STATUS sme_qos_csr_event_ind(tpAniSirGlobal pMac,
 		uint8_t sessionId,
 		sme_qos_csr_event_indType ind, void *pEvent_info);
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index 6925da8..617e8a6 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -1823,7 +1823,7 @@
 QDF_STATUS sme_set_ese_beacon_request(tHalHandle hHal, const uint8_t sessionId,
 				      const tCsrEseBeaconReq *pEseBcnReq)
 {
-	QDF_STATUS status = eSIR_SUCCESS;
+	QDF_STATUS status;
 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
 	tpSirBeaconReportReqInd pSmeBcnReportReq = NULL;
 	tCsrEseBeaconReqParams *pBeaconReq = NULL;
@@ -2413,6 +2413,18 @@
 		}
 		break;
 #endif
+	case eWNI_SME_GET_PEER_INFO_IND:
+		if (pMac->sme.pget_peer_info_ind_cb)
+			pMac->sme.pget_peer_info_ind_cb(pMsg->bodyptr,
+				pMac->sme.pget_peer_info_cb_context);
+		qdf_mem_free(pMsg->bodyptr);
+		break;
+	case eWNI_SME_GET_PEER_INFO_EXT_IND:
+		if (pMac->sme.pget_peer_info_ext_ind_cb)
+			pMac->sme.pget_peer_info_ext_ind_cb(pMsg->bodyptr,
+				pMac->sme.pget_peer_info_ext_cb_context);
+		qdf_mem_free(pMsg->bodyptr);
+		break;
 	case eWNI_SME_CSA_OFFLOAD_EVENT:
 		if (pMsg->bodyptr) {
 			csr_scan_flush_bss_entry(pMac, pMsg->bodyptr);
@@ -2638,7 +2650,11 @@
 							  pMsg->bodyptr);
 		qdf_mem_free(pMsg->bodyptr);
 		break;
-
+	case eWNI_SME_BT_ACTIVITY_INFO_IND:
+		if (pMac->sme.bt_activity_info_cb)
+			pMac->sme.bt_activity_info_cb(pMac->hHdd,
+						      pMsg->bodyval);
+		break;
 	default:
 
 		if ((pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN)
@@ -4226,6 +4242,7 @@
 		qdf_mem_copy(&pParam->rrmConfig,
 				&pMac->rrm.rrmSmeContext.rrmConfig,
 				sizeof(pMac->rrm.rrmSmeContext.rrmConfig));
+		pParam->snr_monitor_enabled = pMac->snr_monitor_enabled;
 		sme_release_global_lock(&pMac->sme);
 	}
 
@@ -4583,8 +4600,9 @@
 	if (eSIR_SUCCESS != ret_code) {
 		sme_err("Posting WMA_WOWL_ADD_BCAST_PTRN failed, reason: %X",
 			ret_code);
+		return QDF_STATUS_E_FAILURE;
 	}
-	return ret_code;
+	return QDF_STATUS_SUCCESS;
 }
 
 /**
@@ -4622,8 +4640,10 @@
 	if (eSIR_SUCCESS != ret_code) {
 		sme_err("Posting WMA_WOWL_DEL_BCAST_PTRN failed, reason: %X",
 			ret_code);
+		return QDF_STATUS_E_FAILURE;
 	}
-	return ret_code;
+
+	return QDF_STATUS_SUCCESS;
 }
 
 /**
@@ -4904,9 +4924,6 @@
     \param statsMask - The different category/categories of stats requester
 	is looking for
     \param callback - SME sends back the requested stats using the callback
-    \param periodicity - If requester needs periodic update in millisec, 0 means
-			 it's an one time request
-    \param cache - If requester is happy with cached stats
     \param staId - The station ID for which the stats is requested for
     \param pContext - user context to be passed back along with the callback
     \param sessionId - sme session interface
@@ -4915,20 +4932,16 @@
 QDF_STATUS sme_get_statistics(tHalHandle hHal,
 			      eCsrStatsRequesterType requesterId,
 			      uint32_t statsMask, tCsrStatsCallback callback,
-			      uint32_t periodicity, bool cache, uint8_t staId,
-			      void *pContext, uint8_t sessionId)
+			      uint8_t staId, void *pContext, uint8_t sessionId)
 {
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
 
-	MTRACE(qdf_trace(QDF_MODULE_ID_SME,
-			 TRACE_CODE_SME_RX_HDD_GET_STATS, NO_SESSION,
-			 periodicity));
 	status = sme_acquire_global_lock(&pMac->sme);
 	if (QDF_IS_STATUS_SUCCESS(status)) {
 		status =
-			csr_get_statistics(pMac, requesterId, statsMask, callback,
-					   periodicity, cache, staId, pContext,
+			csr_get_statistics(pMac, requesterId, statsMask,
+					   callback, staId, pContext,
 					   sessionId);
 		sme_release_global_lock(&pMac->sme);
 	}
@@ -5062,8 +5075,8 @@
 				   uint8_t *pCountry,
 				   void *pContext,
 				   void *p_cds_context,
-				   tAniBool countryFromUserSpace,
-				   tAniBool sendRegHint)
+				   bool countryFromUserSpace,
+				   bool sendRegHint)
 {
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
 	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
@@ -7975,27 +7988,29 @@
 
 }
 
-/*--------------------------------------------------------------------------
-   \brief sme_stop_roaming() - Stop roaming for a given sessionId
-   This is a synchronous call
-   \param hHal      - The handle returned by mac_open
-   \param  sessionId - Session Identifier
-   \return QDF_STATUS_SUCCESS on success
-	   Other status on failure
-   \sa
-   --------------------------------------------------------------------------*/
-QDF_STATUS sme_stop_roaming(tHalHandle hHal, uint8_t sessionId, uint8_t reason)
+/**
+ * sme_stop_roaming() - Stop roaming for a given sessionId
+ *  This is a synchronous call
+ *
+ * @hHal      - The handle returned by mac_open
+ * @sessionId - Session Identifier
+ *
+ * Return QDF_STATUS_SUCCESS on success
+ *	   Other status on failure
+ */
+QDF_STATUS sme_stop_roaming(tHalHandle hal, uint8_t session_id, uint8_t reason)
 {
 	struct scheduler_msg wma_msg = {0};
 	tSirRetStatus status;
 	tSirRoamOffloadScanReq *req;
-	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hHal);
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	tpCsrNeighborRoamControlInfo roam_info;
 
-	if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) {
+	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
 		sme_err("incorrect session/vdev ID");
 		return QDF_STATUS_E_INVAL;
 	}
-
+	roam_info = &mac_ctx->roam.neighborRoamInfo[session_id];
 	req = qdf_mem_malloc(sizeof(*req));
 	if (!req) {
 		sme_err("failed to allocated memory");
@@ -8007,8 +8022,8 @@
 		req->reason = REASON_ROAM_STOP_ALL;
 	else
 		req->reason = REASON_ROAM_SYNCH_FAILED;
-	req->sessionId = sessionId;
-	if (csr_neighbor_middle_of_roaming(mac_ctx, sessionId))
+	req->sessionId = session_id;
+	if (csr_neighbor_middle_of_roaming(mac_ctx, session_id))
 		req->middle_of_roaming = 1;
 	else
 		csr_roam_reset_roam_params(mac_ctx);
@@ -8019,10 +8034,12 @@
 	status = wma_post_ctrl_msg(mac_ctx, &wma_msg);
 	if (eSIR_SUCCESS != status) {
 		sme_err("WMA_ROAM_SCAN_OFFLOAD_REQ failed, session_id: %d",
-			sessionId);
+			session_id);
 		qdf_mem_free(req);
 		return QDF_STATUS_E_FAULT;
 	}
+	roam_info->b_roam_scan_offload_started = false;
+	roam_info->last_sent_cmd = ROAM_SCAN_OFFLOAD_STOP;
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -9681,6 +9698,100 @@
 	return status;
 }
 
+QDF_STATUS sme_get_peer_info(tHalHandle hal, struct sir_peer_info_req req,
+			void *context,
+			void (*callbackfn)(struct sir_peer_info_resp *param,
+						void *pcontext))
+{
+
+	QDF_STATUS status;
+	QDF_STATUS qdf_status;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+	struct scheduler_msg message;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		if (NULL == callbackfn) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: Indication Call back is NULL",
+				__func__);
+			sme_release_global_lock(&mac->sme);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		mac->sme.pget_peer_info_ind_cb = callbackfn;
+		mac->sme.pget_peer_info_cb_context = context;
+
+		/* serialize the req through MC thread */
+		message.bodyptr = qdf_mem_malloc(sizeof(req));
+		if (NULL == message.bodyptr) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: Memory allocation failed.", __func__);
+			sme_release_global_lock(&mac->sme);
+			return QDF_STATUS_E_NOMEM;
+		}
+		qdf_mem_copy(message.bodyptr, &req, sizeof(req));
+		message.type = WMA_GET_PEER_INFO;
+		qdf_status = scheduler_post_msg(QDF_MODULE_ID_WMA, &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: Post get peer info msg fail", __func__);
+			qdf_mem_free(message.bodyptr);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&mac->sme);
+	}
+	return status;
+}
+
+QDF_STATUS sme_get_peer_info_ext(tHalHandle hal,
+		struct sir_peer_info_ext_req *req,
+		void *context,
+		void (*callbackfn)(struct sir_peer_info_ext_resp *param,
+			void *pcontext))
+{
+	QDF_STATUS status;
+	QDF_STATUS qdf_status;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+	struct scheduler_msg message;
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_STATUS_SUCCESS == status) {
+		if (NULL == callbackfn) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: Indication Call back is NULL",
+				__func__);
+			sme_release_global_lock(&mac->sme);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		mac->sme.pget_peer_info_ext_ind_cb = callbackfn;
+		mac->sme.pget_peer_info_ext_cb_context = context;
+
+		/* serialize the req through MC thread */
+		message.bodyptr =
+			qdf_mem_malloc(sizeof(struct sir_peer_info_ext_req));
+		if (NULL == message.bodyptr) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: Memory allocation failed.", __func__);
+			sme_release_global_lock(&mac->sme);
+			return QDF_STATUS_E_NOMEM;
+		}
+		qdf_mem_copy(message.bodyptr,
+				req,
+				sizeof(struct sir_peer_info_ext_req));
+		message.type = WMA_GET_PEER_INFO_EXT;
+		qdf_status = scheduler_post_msg(QDF_MODULE_ID_WMA, &message);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+				"%s: Post get rssi msg fail", __func__);
+			qdf_mem_free(message.bodyptr);
+			status = QDF_STATUS_E_FAILURE;
+		}
+		sme_release_global_lock(&mac->sme);
+	}
+	return status;
+}
 
 /*
  * SME API to enable/disable WLAN driver initiated SSR
@@ -13451,7 +13562,7 @@
 			    (scheduler_post_msg(QDF_MODULE_ID_WMA,
 						 &message))) {
 			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
-				  "%s: Not able to post WMA_SET_DHCP_SERVER_OFFLOAD_CMD to WMA!",
+				  "%s:WMA_SET_DHCP_SERVER_OFFLOAD_CMD failed",
 				  __func__);
 			qdf_mem_free(pSmeDhcpSrvInfo);
 			status = QDF_STATUS_E_FAILURE;
@@ -16349,3 +16460,21 @@
 {
 	return wma_cli_set_command(vdev_id, param_id, sval, vpdev);
 }
+
+QDF_STATUS sme_set_bt_activity_info_cb(tHalHandle hal,
+			void (*cb)(void *, uint32_t bt_activity))
+{
+	QDF_STATUS status;
+	tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+	status = sme_acquire_global_lock(&mac->sme);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		mac->sme.bt_activity_info_cb = cb;
+		sme_release_global_lock(&mac->sme);
+		sme_debug("bt activity info callback set");
+	} else {
+		sme_debug("sme_acquire_global_lock failed %d", status);
+	}
+
+	return status;
+}
diff --git a/core/sme/src/common/sme_power_save.c b/core/sme/src/common/sme_power_save.c
index ed87cd8..0d4b961 100644
--- a/core/sme/src/common/sme_power_save.c
+++ b/core/sme/src/common/sme_power_save.c
@@ -440,7 +440,7 @@
 
 	if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
 		sme_err("Invalid Session_id: %d", session_id);
-		return eSIR_FAILURE;
+		return QDF_STATUS_E_INVAL;
 	}
 	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
 			FL("Power Save command %d"), command);
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index 53efb0b..8820dc6 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -98,8 +98,6 @@
 #define ROAMING_OFFLOAD_TIMER_STOP	2
 #define CSR_ROAMING_OFFLOAD_TIMEOUT_PERIOD    (5 * QDF_MC_TIMER_TO_SEC_UNIT)
 
-static bool b_roam_scan_offload_started;
-
 /* Static Type declarations */
 static tCsrRoamSession csr_roam_roam_session[CSR_ROAM_SESSION_MAX];
 
@@ -246,18 +244,9 @@
 							tDblLinkList *pStaList,
 							tCsrStatsClientReqInfo *
 							pStaEntry);
-static void csr_roam_stats_client_timer_handler(void *pv);
-tCsrPeStatsReqInfo *csr_roam_check_pe_stats_req_list(tpAniSirGlobal pMac,
-						     uint32_t statsMask,
-						     uint32_t periodicity,
-						     bool *pFound,
-						uint8_t staId,
-						     uint8_t sessionId);
 static void csr_roam_report_statistics(tpAniSirGlobal pMac, uint32_t statsMask,
 				tCsrStatsCallback callback, uint8_t staId,
 				void *pContext);
-static void csr_roam_tl_stats_timer_handler(void *pv);
-static void csr_roam_pe_stats_timer_handler(void *pv);
 tListElem *csr_roam_check_client_req_list(tpAniSirGlobal pMac,
 					uint32_t statsMask);
 static void csr_roam_remove_entry_from_pe_stats_req_list(tpAniSirGlobal pMac,
@@ -897,8 +886,6 @@
 		for (i = 0; i < CSR_ROAM_SESSION_MAX; i++)
 			status = csr_neighbor_roam_init(pMac, i);
 		pMac->roam.tlStatsReqInfo.numClient = 0;
-		pMac->roam.tlStatsReqInfo.periodicity = 0;
-		pMac->roam.tlStatsReqInfo.timerRunning = false;
 		/* init the link quality indication also */
 		pMac->roam.vccLinkQuality = eCSR_ROAM_LINK_QUAL_MIN_IND;
 		if (!QDF_IS_STATUS_SUCCESS(status)) {
@@ -938,14 +925,6 @@
 		pMac->roam.curSubState[sessionId] = eCSR_ROAM_SUBSTATE_NONE;
 	}
 
-	/* When HAL resets all the context information
-	 * in HAL is lost, so we might need to send the
-	 * scan offload request again when it comes
-	 * out of reset for scan offload to be functional
-	 */
-	if (HAL_STOP_TYPE_SYS_RESET == stopType)
-		b_roam_scan_offload_started = false;
-
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -1083,13 +1062,6 @@
 			sme_err("cannot allocate memory for packetdump timer");
 			break;
 		}
-		status = qdf_mc_timer_init(&pMac->roam.tlStatsReqInfo.
-					hTlStatsTimer, QDF_TIMER_TYPE_SW,
-					csr_roam_tl_stats_timer_handler, pMac);
-		if (!QDF_IS_STATUS_SUCCESS(status)) {
-			sme_err("cannot allocate memory for summary Statistics timer");
-			return QDF_STATUS_E_FAILURE;
-		}
 	} while (0);
 	return status;
 }
@@ -1103,8 +1075,6 @@
 
 	qdf_mc_timer_stop(&pMac->roam.hTimerWaitForKey);
 	qdf_mc_timer_destroy(&pMac->roam.hTimerWaitForKey);
-	qdf_mc_timer_stop(&pMac->roam.tlStatsReqInfo.hTlStatsTimer);
-	qdf_mc_timer_destroy(&pMac->roam.tlStatsReqInfo.hTlStatsTimer);
 	qdf_mc_timer_stop(&pMac->roam.packetdump_timer);
 	qdf_mc_timer_destroy(&pMac->roam.packetdump_timer);
 	return QDF_STATUS_SUCCESS;
@@ -1176,7 +1146,6 @@
 		pProfile->mcEncryptionType = connected_prof->mcEncryptionType;
 		pProfile->BSSType = connected_prof->BSSType;
 		pProfile->operationChannel = connected_prof->operationChannel;
-		pProfile->CBMode = connected_prof->CBMode;
 		qdf_mem_copy(&pProfile->bssid, &connected_prof->bssid,
 			sizeof(struct qdf_mac_addr));
 		qdf_mem_copy(&pProfile->SSID, &connected_prof->SSID,
@@ -2806,6 +2775,8 @@
 			pParam->sta_roam_policy_params.dfs_mode;
 		pMac->roam.configParam.sta_roam_policy.skip_unsafe_channels =
 			pParam->sta_roam_policy_params.skip_unsafe_channels;
+		pMac->roam.configParam.sta_roam_policy.sap_operating_band =
+			pParam->sta_roam_policy_params.sap_operating_band;
 
 		pMac->roam.configParam.tx_aggregation_size =
 			pParam->tx_aggregation_size;
@@ -2817,6 +2788,12 @@
 			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);
 	}
@@ -3056,6 +3033,12 @@
 		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);
 
@@ -5876,8 +5859,13 @@
 			if (!QDF_IS_STATUS_SUCCESS(status)) {
 				sme_err("failed status %d", status);
 				csr_release_command(mac_ctx, cmd);
+			} else {
+				csr_neighbor_roam_state_transition(mac_ctx,
+					eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING,
+					session_id);
 			}
 
+
 			qdf_mem_free(pIes);
 			pIes = NULL;
 		}
@@ -7577,7 +7565,6 @@
 		if (pDstProfile->phyMode & eCSR_DOT11_MODE_11n)
 			pDstProfile->phyMode &= ~eCSR_DOT11_MODE_11n;
 #endif /* FEATURE_WLAN_WAPI */
-	pDstProfile->CBMode = pSrcProfile->CBMode;
 	pDstProfile->ch_params.ch_width = pSrcProfile->ch_params.ch_width;
 	pDstProfile->ch_params.center_freq_seg0 =
 		pSrcProfile->ch_params.center_freq_seg0;
@@ -7714,7 +7701,6 @@
 	pDstProfile->negotiatedMCEncryptionType =
 		pSrcProfile->mcEncryptionType;
 	pDstProfile->BSSType = pSrcProfile->BSSType;
-	pDstProfile->CBMode = pSrcProfile->CBMode;
 	qdf_mem_copy(&pDstProfile->Keys, &pSrcProfile->Keys,
 		sizeof(pDstProfile->Keys));
 	if (pSrcProfile->MDID.mdiePresent) {
@@ -8643,12 +8629,6 @@
 		pConnectProfile->MFPCapable = pProfile->MFPCapable;
 #endif
 	}
-	if (pIes)
-		pConnectProfile->CBMode = csr_get_cb_mode_from_ies(pMac,
-				pSirBssDesc->channelId, pIes);
-	else
-		sme_err("IE unavailable to derive CB mode");
-
 	/* Save bssid */
 	pConnectProfile->operationChannel = pSirBssDesc->channelId;
 	pConnectProfile->beaconInterval = pSirBssDesc->beaconInterval;
@@ -9290,10 +9270,10 @@
 			if (pNeighborRoamInfo) {
 				qdf_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
 				csr_roam_call_callback(pMac,
-						       pSmeJoinRsp->sessionId,
-						       &roamInfo, roamId,
-						    eCSR_ROAM_FT_REASSOC_FAILED,
-						       eSIR_SME_SUCCESS);
+						pSmeJoinRsp->sessionId,
+						&roamInfo, roamId,
+						eCSR_ROAM_FT_REASSOC_FAILED,
+						eCSR_ROAM_RESULT_SUCCESS);
 				/*
 				 * Since the above callback sends a disconnect
 				 * to HDD, we should clean-up our state
@@ -9441,7 +9421,8 @@
 	/* Inform the upper layers that the reassoc failed */
 	qdf_mem_zero(roam_info, sizeof(tCsrRoamInfo));
 	csr_roam_call_callback(mac_ctx, session_id, roam_info, 0,
-			       eCSR_ROAM_FT_REASSOC_FAILED, eSIR_SME_SUCCESS);
+			       eCSR_ROAM_FT_REASSOC_FAILED,
+			       eCSR_ROAM_RESULT_SUCCESS);
 	/*
 	 * Issue a disassoc request so that PE/LIM uses this to clean-up the FT
 	 * session. Upon success, we would re-enter this routine after receiving
@@ -9871,6 +9852,17 @@
 		qdf_mem_copy(&pRoamInfo->chan_info,
 			     &pUpperLayerAssocCnf->chan_info,
 			     sizeof(tSirSmeChanInfo));
+		pRoamInfo->ampdu = pUpperLayerAssocCnf->ampdu;
+		pRoamInfo->sgi_enable = pUpperLayerAssocCnf->sgi_enable;
+		pRoamInfo->tx_stbc = pUpperLayerAssocCnf->tx_stbc;
+		pRoamInfo->tx_stbc = pUpperLayerAssocCnf->rx_stbc;
+		pRoamInfo->ch_width = pUpperLayerAssocCnf->ch_width;
+		pRoamInfo->mode = pUpperLayerAssocCnf->mode;
+		pRoamInfo->max_supp_idx = pUpperLayerAssocCnf->max_supp_idx;
+		pRoamInfo->max_ext_idx = pUpperLayerAssocCnf->max_ext_idx;
+		pRoamInfo->max_mcs_idx = pUpperLayerAssocCnf->max_mcs_idx;
+		pRoamInfo->rx_mcs_map = pUpperLayerAssocCnf->rx_mcs_map;
+		pRoamInfo->tx_mcs_map = pUpperLayerAssocCnf->tx_mcs_map;
 		if (CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile)) {
 			pMac->roam.roamSession[sessionId].connectState =
 				eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED;
@@ -14084,7 +14076,7 @@
 	uint8_t txBFCsnValue = 0;
 	tSirSmeJoinReq *csr_join_req;
 	tSirMacCapabilityInfo *pAP_capabilityInfo;
-	tAniBool fTmp;
+	bool fTmp;
 	int8_t pwrLimit = 0;
 	struct ps_global_info *ps_global_info = &pMac->sme.ps_global_info;
 	struct ps_params *ps_param = &ps_global_info->ps_params[sessionId];
@@ -14694,9 +14686,9 @@
 		 */
 		if (csr_is11h_supported(pMac) && pAP_capabilityInfo->spectrumMgt
 			&& eSIR_11A_NW_TYPE == pBssDescription->nwType) {
-			fTmp = (tAniBool) 1;
+			fTmp = true;
 		} else
-			fTmp = (tAniBool) 0;
+			fTmp = false;
 
 		csr_join_req->spectrumMgtIndicator = fTmp;
 		csr_join_req->powerCap.minTxPower = MIN_TX_PWR_CAP;
@@ -15190,54 +15182,90 @@
 		else
 			statusCode = eSIR_SME_ASSOC_REFUSED;
 		qdf_mem_copy(pBuf, &statusCode, sizeof(tSirResultCodes));
-		pBuf += sizeof(tSirResultCodes);
 		/* bssId */
-		qdf_mem_copy((tSirMacAddr *) pBuf, pAssocInd->bssId,
-			     sizeof(tSirMacAddr));
-		pBuf += sizeof(tSirMacAddr);
+		pBuf = (uint8_t *)&pMsg->bssId;
+		qdf_mem_copy((tSirMacAddr *)pBuf, pAssocInd->bssId,
+			sizeof(tSirMacAddr));
 		/* peerMacAddr */
-		qdf_mem_copy((tSirMacAddr *) pBuf, pAssocInd->peerMacAddr,
-			     sizeof(tSirMacAddr));
-		pBuf += sizeof(tSirMacAddr);
+		pBuf = (uint8_t *)&pMsg->peerMacAddr;
+		qdf_mem_copy((tSirMacAddr *)pBuf, pAssocInd->peerMacAddr,
+			sizeof(tSirMacAddr));
 		/* StaId */
+		pBuf = (uint8_t *)&pMsg->aid;
 		wTmp = pAssocInd->staId;
 		qdf_mem_copy(pBuf, &wTmp, sizeof(uint16_t));
-		pBuf += sizeof(uint16_t);
 		/* alternateBssId */
-		qdf_mem_copy((tSirMacAddr *) pBuf, pAssocInd->bssId,
-			     sizeof(tSirMacAddr));
-		pBuf += sizeof(tSirMacAddr);
+		pBuf = (uint8_t *)&pMsg->alternateBssId;
+		qdf_mem_copy((tSirMacAddr *)pBuf, pAssocInd->bssId,
+			sizeof(tSirMacAddr));
 		/* alternateChannelId */
+		pBuf = (uint8_t *)&pMsg->alternateChannelId;
 		*pBuf = 11;
-		pBuf += sizeof(uint8_t);
-		/* Instead of copying roam Info, we just copy only WmmEnabled,
-		 * RsnIE information
+		/*
+		 * Instead of copying roam Info,just copy WmmEnabled,
+		 * RsnIE information.
+		 * Wmm
 		 */
-		/* Wmm */
+		pBuf = (uint8_t *)&pMsg->wmmEnabledSta;
 		*pBuf = pAssocInd->wmmEnabledSta;
-		pBuf += sizeof(uint8_t);
 		/* RSN IE */
-		qdf_mem_copy((tSirRSNie *) pBuf, &pAssocInd->rsnIE,
-			     sizeof(tSirRSNie));
-		pBuf += sizeof(tSirRSNie);
+		pBuf = (uint8_t *)&pMsg->rsnIE;
+		qdf_mem_copy((tSirRSNie *)pBuf, &pAssocInd->rsnIE,
+			sizeof(tSirRSNie));
 #ifdef FEATURE_WLAN_WAPI
 		/* WAPI IE */
-		qdf_mem_copy((tSirWAPIie *) pBuf, &pAssocInd->wapiIE,
-			     sizeof(tSirWAPIie));
-		pBuf += sizeof(tSirWAPIie);
+		pBuf = (uint8_t *)&pMsg->wapiIE;
+		qdf_mem_copy((tSirWAPIie *)pBuf, &pAssocInd->wapiIE,
+			sizeof(tSirWAPIie));
 #endif
 		/* Additional IE */
-		qdf_mem_copy((void *)pBuf, &pAssocInd->addIE,
-			     sizeof(tSirAddie));
-		pBuf += sizeof(tSirAddie);
+		pBuf = (uint8_t *)&pMsg->addIE;
+		qdf_mem_copy((tSirAddie *)pBuf, &pAssocInd->addIE,
+			sizeof(tSirAddie));
 		/* reassocReq */
+		pBuf = (uint8_t *)&pMsg->reassocReq;
 		*pBuf = pAssocInd->reassocReq;
-		pBuf += sizeof(uint8_t);
 		/* timingMeasCap */
+		pBuf = (uint8_t *)&pMsg->timingMeasCap;
 		*pBuf = pAssocInd->timingMeasCap;
-		pBuf += sizeof(uint8_t);
+		/* chan_info */
+		pBuf = (uint8_t *)&pMsg->chan_info;
 		qdf_mem_copy((void *)pBuf, &pAssocInd->chan_info,
-			     sizeof(tSirSmeChanInfo));
+			sizeof(tSirSmeChanInfo));
+		/* ampdu */
+		pBuf = (uint8_t *)&pMsg->ampdu;
+		*((bool *)pBuf) = pAssocInd->ampdu;
+		/* sgi_enable */
+		pBuf = (uint8_t *)&pMsg->sgi_enable;
+		*((bool *)pBuf) = pAssocInd->sgi_enable;
+		/* tx stbc */
+		pBuf = (uint8_t *)&pMsg->tx_stbc;
+		*((bool *)pBuf) = pAssocInd->tx_stbc;
+		/* ch_width */
+		pBuf = (uint8_t *)&pMsg->ch_width;
+		*((tSirMacHTChannelWidth *)pBuf) = pAssocInd->ch_width;
+		/* mode */
+		pBuf = (uint8_t *)&pMsg->mode;
+		*((enum sir_sme_phy_mode *)pBuf) = pAssocInd->mode;
+		/* rx stbc */
+		pBuf = (uint8_t *)&pMsg->rx_stbc;
+		*((bool *)pBuf) = pAssocInd->rx_stbc;
+		/* max supported idx */
+		pBuf = (uint8_t *)&pMsg->max_supp_idx;
+		*pBuf = pAssocInd->max_supp_idx;
+		/* max extended idx */
+		pBuf = (uint8_t *)&pMsg->max_ext_idx;
+		*pBuf = pAssocInd->max_ext_idx;
+		/* max ht mcs idx */
+		pBuf = (uint8_t *)&pMsg->max_mcs_idx;
+		*pBuf = pAssocInd->max_mcs_idx;
+		/* vht rx mcs map */
+		pBuf = (uint8_t *)&pMsg->rx_mcs_map;
+		*pBuf = pAssocInd->rx_mcs_map;
+		/* vht tx mcs map */
+		pBuf = (uint8_t *)&pMsg->tx_mcs_map;
+		*pBuf = pAssocInd->tx_mcs_map;
+
 		msgQ.type = eWNI_SME_UPPER_LAYER_ASSOC_CNF;
 		msgQ.bodyptr = pMsg;
 		msgQ.bodyval = 0;
@@ -15886,7 +15914,7 @@
 {
 	struct del_sta_self_params *del_sta_self_req;
 	struct scheduler_msg msg = {0};
-	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	tSirRetStatus status;
 
 	del_sta_self_req = qdf_mem_malloc(sizeof(struct del_sta_self_params));
 	if (NULL == del_sta_self_req) {
@@ -15907,11 +15935,12 @@
 
 	sme_debug("sending WMA_DEL_STA_SELF_REQ");
 	status = wma_post_ctrl_msg(pMac, &msg);
-	if (status != QDF_STATUS_SUCCESS) {
+	if (status != eSIR_SUCCESS) {
 		sme_err("wma_post_ctrl_msg failed");
 		qdf_mem_free(del_sta_self_req);
+		return QDF_STATUS_E_FAILURE;
 	}
-	return status;
+	return QDF_STATUS_SUCCESS;
 }
 
 void csr_cleanup_session(tpAniSirGlobal pMac, uint32_t sessionId)
@@ -16144,109 +16173,6 @@
 
 }
 
-static void csr_roam_tl_stats_timer_handler(void *pv)
-{
-	tpAniSirGlobal pMac = PMAC_STRUCT(pv);
-	QDF_STATUS status;
-
-	pMac->roam.tlStatsReqInfo.timerRunning = false;
-
-	sme_debug("TL stat timer is no-op. It needs to support multiple stations");
-
-	if (!pMac->roam.tlStatsReqInfo.timerRunning) {
-		if (pMac->roam.tlStatsReqInfo.periodicity) {
-			/* start timer */
-			status =
-				qdf_mc_timer_start(&pMac->roam.tlStatsReqInfo.
-						   hTlStatsTimer,
-						   pMac->roam.tlStatsReqInfo.
-						   periodicity);
-			if (!QDF_IS_STATUS_SUCCESS(status)) {
-				sme_err("csr_roam_tl_stats_timer_handler:cannot start TlStatsTimer timer");
-				return;
-			}
-			pMac->roam.tlStatsReqInfo.timerRunning = true;
-		}
-	}
-}
-
-static void csr_roam_pe_stats_timer_handler(void *pv)
-{
-	tCsrPeStatsReqInfo *pPeStatsReqListEntry = (tCsrPeStatsReqInfo *) pv;
-	QDF_STATUS status;
-	tpAniSirGlobal pMac = pPeStatsReqListEntry->pMac;
-	QDF_STATUS qdf_status;
-
-	pPeStatsReqListEntry->timerRunning = false;
-	if (pPeStatsReqListEntry->timerStopFailed == true) {
-		/* If we entered here, meaning the timer could not be
-		 * successfully stopped in
-		 * csr_roam_remove_entry_from_pe_stats_req_list().
-		 * So do it here.
-		 * Destroy the timer
-		 */
-		qdf_status = qdf_mc_timer_destroy(&pPeStatsReqListEntry->
-						hPeStatsTimer);
-		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
-			sme_err("csr_roam_pe_stats_timer_handler:failed to destroy hPeStatsTimer timer");
-
-		/* Free the entry */
-		qdf_mem_free(pPeStatsReqListEntry);
-		pPeStatsReqListEntry = NULL;
-	} else {
-		if (!pPeStatsReqListEntry->rspPending) {
-			status = csr_send_mb_stats_req_msg(pMac,
-							  pPeStatsReqListEntry->
-							  statsMask & ~(1 <<
-							eCsrGlobalClassDStats),
-						pPeStatsReqListEntry->staId,
-							  pPeStatsReqListEntry->
-							  sessionId);
-			if (!QDF_IS_STATUS_SUCCESS(status))
-				sme_err("csr_roam_pe_stats_timer_handler:failed to send down stats req to PE");
-			else
-				pPeStatsReqListEntry->rspPending = true;
-		}
-		/* send down a req */
-		if (pPeStatsReqListEntry->periodicity &&
-		    (QDF_TIMER_STATE_STOPPED ==
-		     qdf_mc_timer_get_current_state(&pPeStatsReqListEntry->
-						    hPeStatsTimer))) {
-			if (pPeStatsReqListEntry->periodicity <
-					pMac->roam.configParam.
-					statsReqPeriodicityInPS) {
-				pPeStatsReqListEntry->periodicity =
-					pMac->roam.configParam.
-					statsReqPeriodicityInPS;
-			}
-			/* start timer */
-			qdf_status =
-				qdf_mc_timer_start(&pPeStatsReqListEntry->
-						   hPeStatsTimer,
-						   pPeStatsReqListEntry->
-						   periodicity);
-			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
-				sme_err("csr_roam_pe_stats_timer_handler:cannot start hPeStatsTimer timer");
-				return;
-			}
-			pPeStatsReqListEntry->timerRunning = true;
-
-		}
-
-	}
-}
-
-static void csr_roam_stats_client_timer_handler(void *pv)
-{
-	tCsrStatsClientReqInfo *pStaEntry = (tCsrStatsClientReqInfo *) pv;
-
-	if (QDF_TIMER_STATE_STOPPED ==
-	    qdf_mc_timer_get_current_state(&pStaEntry->timer)) {
-		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
-			 "roam stats client timer is stopped");
-	}
-}
-
 QDF_STATUS csr_send_mb_stats_req_msg(tpAniSirGlobal pMac, uint32_t statsMask,
 				     uint8_t staId, uint8_t sessionId)
 {
@@ -16456,8 +16382,6 @@
 		if ((pTempStaEntry->requesterId == pStaEntry->requesterId)
 		    && (pTempStaEntry->statsMask == pStaEntry->statsMask)) {
 			if (update) {
-				pTempStaEntry->periodicity =
-					pStaEntry->periodicity;
 				pTempStaEntry->callback = pStaEntry->callback;
 				pTempStaEntry->pContext = pStaEntry->pContext;
 			}
@@ -16503,8 +16427,9 @@
 							pStaEntry)
 {
 	tCsrStatsClientReqInfo *pNewStaEntry = NULL;
-	/* if same entity requested for same set of stats with different
-	 * periodicity & callback update it
+	/*
+	 * if same entity requested for same set of stats with different
+	 * callback update it
 	 */
 	if (NULL == csr_roam_checkn_update_client_req_list(pMac, pStaEntry,
 								true)) {
@@ -16517,7 +16442,6 @@
 
 		pNewStaEntry->callback = pStaEntry->callback;
 		pNewStaEntry->pContext = pStaEntry->pContext;
-		pNewStaEntry->periodicity = pStaEntry->periodicity;
 		pNewStaEntry->requesterId = pStaEntry->requesterId;
 		pNewStaEntry->statsMask = pStaEntry->statsMask;
 		pNewStaEntry->pPeStaEntry = pStaEntry->pPeStaEntry;
@@ -16531,34 +16455,6 @@
 	return pNewStaEntry;
 }
 
-static
-tCsrPeStatsReqInfo *csr_roam_insert_entry_into_pe_stats_req_list(
-							tpAniSirGlobal pMac,
-							tDblLinkList *pStaList,
-							tCsrPeStatsReqInfo *
-							pStaEntry)
-{
-	tCsrPeStatsReqInfo *pNewStaEntry = NULL;
-
-	pNewStaEntry = qdf_mem_malloc(sizeof(tCsrPeStatsReqInfo));
-	if (NULL == pNewStaEntry) {
-		sme_err("couldn't allocate memory for the entry");
-		return NULL;
-	}
-
-	pNewStaEntry->hPeStatsTimer = pStaEntry->hPeStatsTimer;
-	pNewStaEntry->numClient = pStaEntry->numClient;
-	pNewStaEntry->periodicity = pStaEntry->periodicity;
-	pNewStaEntry->statsMask = pStaEntry->statsMask;
-	pNewStaEntry->pMac = pStaEntry->pMac;
-	pNewStaEntry->staId = pStaEntry->staId;
-	pNewStaEntry->timerRunning = pStaEntry->timerRunning;
-	pNewStaEntry->rspPending = pStaEntry->rspPending;
-
-	csr_ll_insert_tail(pStaList, &pNewStaEntry->link, LL_ACCESS_LOCK);
-	return pNewStaEntry;
-}
-
 QDF_STATUS csr_get_rssi(tpAniSirGlobal pMac,
 			tCsrRssiCallback callback,
 			uint8_t staId,
@@ -16624,6 +16520,7 @@
 
 	status = csr_roam_get_session_id_from_bssid(pMac, &bssId, &sessionId);
 	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		qdf_mem_free(pMsg);
 		sme_err("Couldn't find session_id for given BSSID");
 		return status;
 	}
@@ -16680,19 +16577,6 @@
 	}
 	/* check if we need to stop the tl stats timer too */
 	mac_ctx->roam.tlStatsReqInfo.numClient--;
-	if (!mac_ctx->roam.tlStatsReqInfo.numClient) {
-		if (mac_ctx->roam.tlStatsReqInfo.timerRunning) {
-			status = qdf_mc_timer_stop(
-				&mac_ctx->roam.tlStatsReqInfo.hTlStatsTimer);
-			if (!QDF_IS_STATUS_SUCCESS(status)) {
-				sme_err(
-					"cannot stop TlStatsTimer timer");
-				return status;
-			}
-		}
-		mac_ctx->roam.tlStatsReqInfo.periodicity = 0;
-		mac_ctx->roam.tlStatsReqInfo.timerRunning = false;
-	}
 	qdf_mc_timer_stop(&ptr_sta_entry->timer);
 	/* Destroy the qdf timer... */
 	status = qdf_mc_timer_destroy(&ptr_sta_entry->timer);
@@ -16708,16 +16592,13 @@
  * csr_insert_stats_request_to_list() - inserts request to existing list
  * @mac_ctx:       mac global context
  * @sta_entry:     stats request entry
- * @periodicity:   periodicity of stats
  *
  * Return: status of operation
  */
 static QDF_STATUS
 csr_insert_stats_request_to_list(tpAniSirGlobal mac_ctx,
-				 tCsrStatsClientReqInfo *sta_entry,
-				 uint32_t periodicity)
+				 tCsrStatsClientReqInfo *sta_entry)
 {
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	tCsrStatsClientReqInfo *ptr_sta_entry = csr_roam_insert_entry_into_list(
 				mac_ctx, &mac_ctx->roam.statsClientReqList,
 				sta_entry);
@@ -16725,79 +16606,6 @@
 		sme_err("Failed to insert req in statsClientReqList");
 		return QDF_STATUS_E_FAILURE;
 	}
-	/* Init & start timer if needed */
-	ptr_sta_entry->periodicity = periodicity;
-	if (ptr_sta_entry->periodicity) {
-		status = qdf_mc_timer_init(&ptr_sta_entry->timer,
-					QDF_TIMER_TYPE_SW,
-					csr_roam_stats_client_timer_handler,
-					ptr_sta_entry);
-		if (!QDF_IS_STATUS_SUCCESS(status)) {
-			sme_err("cannot init StatsClient timer");
-			return QDF_STATUS_E_FAILURE;
-		}
-		status = qdf_mc_timer_start(&ptr_sta_entry->timer,
-					    ptr_sta_entry->periodicity);
-		if (!QDF_IS_STATUS_SUCCESS(status)) {
-			sme_err("cannot start StatsClient timer");
-			return QDF_STATUS_E_FAILURE;
-		}
-	}
-	return status;
-}
-
-/**
- * csr_get_statistics_from_tl() - fetch stats from tl layer
- * @mac_ctx:       mac global context
- * @cache:         indicate if cached stats are required
- * @staId:         station id
- * @periodicity:   periodicity of stats
- *
- * Return: status of operation
- */
-static QDF_STATUS
-csr_get_statistics_from_tl(tpAniSirGlobal mac_ctx,
-			   bool cache,
-			   uint8_t staId,
-			   uint32_t periodicity)
-{
-	QDF_STATUS status;
-
-	if (cache && mac_ctx->roam.tlStatsReqInfo.numClient) {
-		sme_err("Looking for cached stats from TL");
-		mac_ctx->roam.tlStatsReqInfo.numClient++;
-		return QDF_STATUS_SUCCESS;
-	}
-
-	/* update periodicity */
-	if (mac_ctx->roam.tlStatsReqInfo.periodicity)
-		mac_ctx->roam.tlStatsReqInfo.periodicity =
-		    QDF_MIN(periodicity,
-			    mac_ctx->roam.tlStatsReqInfo.periodicity);
-	else
-		mac_ctx->roam.tlStatsReqInfo.periodicity = periodicity;
-
-	if (mac_ctx->roam.tlStatsReqInfo.periodicity
-	    < CSR_MIN_TL_STAT_QUERY_PERIOD) {
-		mac_ctx->roam.tlStatsReqInfo.periodicity =
-		CSR_MIN_TL_STAT_QUERY_PERIOD;
-	}
-
-	if (!mac_ctx->roam.tlStatsReqInfo.timerRunning) {
-
-		if (mac_ctx->roam.tlStatsReqInfo.periodicity) {
-			/* start timer */
-			status = qdf_mc_timer_start(
-				&mac_ctx->roam.tlStatsReqInfo.hTlStatsTimer,
-				mac_ctx->roam.tlStatsReqInfo.periodicity);
-			if (!QDF_IS_STATUS_SUCCESS(status)) {
-				sme_err("cannot start TlStatsTimer timer");
-				return QDF_STATUS_E_FAILURE;
-			}
-			mac_ctx->roam.tlStatsReqInfo.timerRunning = true;
-		}
-	}
-	mac_ctx->roam.tlStatsReqInfo.numClient++;
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -16805,15 +16613,11 @@
 			      eCsrStatsRequesterType requesterId,
 			      uint32_t statsMask,
 			      tCsrStatsCallback callback,
-			      uint32_t periodicity,
-			      bool cache,
 			      uint8_t staId,
 			      void *pContext,
 			      uint8_t sessionId)
 {
 	tCsrStatsClientReqInfo staEntry;
-	tCsrPeStatsReqInfo *pPeStaEntry = NULL;
-	bool found = false;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	bool insertInClientList = false;
 	uint32_t temp_mask = 0;
@@ -16837,77 +16641,38 @@
 	if ((statsMask) && (!callback))
 		return csr_deregister_client_request(pMac, &staEntry);
 
-	if (cache && !periodicity) {
-		/* return the cached stats */
-		csr_roam_report_statistics(pMac, statsMask, callback, staId,
-					   pContext);
-		return QDF_STATUS_SUCCESS;
-	}
 	/* add the request in the client req list */
 	staEntry.callback = callback;
 	staEntry.pContext = pContext;
-	staEntry.periodicity = periodicity;
 	staEntry.pPeStaEntry = NULL;
 	staEntry.staId = staId;
 	staEntry.pMac = pMac;
 	staEntry.timerExpired = false;
 	staEntry.sessionId = sessionId;
 
-	/* if periodic report requested with non cached result from PE/TL */
-	if (periodicity) {
-		/* if looking for stats from PE */
-		temp_mask = statsMask & ~(1 << eCsrGlobalClassDStats);
-		if (temp_mask) {
-			/* check if same req made already & waiting for rsp */
-			pPeStaEntry = csr_roam_check_pe_stats_req_list(pMac,
-					temp_mask, periodicity, &found,
-					staId, sessionId);
-			if (!pPeStaEntry)
-				/* bail out, maxed out on num of req for PE */
-				return QDF_STATUS_E_FAILURE;
-			staEntry.pPeStaEntry = pPeStaEntry;
-		}
+	temp_mask = statsMask & ~(1 << eCsrGlobalClassDStats);
+	if (temp_mask) {
+		/* send down a req */
+		status = csr_send_mb_stats_req_msg(pMac,
+					temp_mask, staId, sessionId);
+		if (!QDF_IS_STATUS_SUCCESS(status))
+			sme_err("failed to send down stats req");
 		/*
-		 * request stats from TL rightaway if requested by client,
-		 * update tlStatsReqInfo if needed
+		 * so that when the stats rsp comes back from PE we
+		 * respond to upper layer right away
 		 */
-		temp_mask = statsMask & (1 << eCsrGlobalClassDStats);
-		if (temp_mask) {
-			status = csr_get_statistics_from_tl(pMac, cache, staId,
-							    periodicity);
-			if (!QDF_IS_STATUS_SUCCESS(status))
-				return status;
-		}
+		staEntry.timerExpired = true;
 		insertInClientList = true;
 	}
-	/* if one time report requested with non cached result from PE/TL */
-	else if (!cache && !periodicity) {
-		temp_mask = statsMask & ~(1 << eCsrGlobalClassDStats);
-		if (temp_mask) {
-			/* send down a req */
-			status = csr_send_mb_stats_req_msg(pMac,
-						temp_mask, staId, sessionId);
-			if (!QDF_IS_STATUS_SUCCESS(status))
-				sme_err(
-					"failed to send down stats req");
-			/*
-			 * so that when the stats rsp comes back from PE we
-			 * respond to upper layer right away
-			 */
-			staEntry.timerExpired = true;
-			insertInClientList = true;
-		}
-		/* if looking for stats from TL only */
-		if (!insertInClientList) {
-			/* return the stats */
-			csr_roam_report_statistics(pMac, statsMask, callback,
-						   staId, pContext);
-			return QDF_STATUS_SUCCESS;
-		}
+	/* if looking for stats from TL only */
+	if (!insertInClientList) {
+		/* return the stats */
+		csr_roam_report_statistics(pMac, statsMask, callback,
+					   staId, pContext);
+		return QDF_STATUS_SUCCESS;
 	}
 	if (insertInClientList)
-		return csr_insert_stats_request_to_list(pMac, &staEntry,
-							periodicity);
+		return csr_insert_stats_request_to_list(pMac, &staEntry);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -17505,15 +17270,26 @@
 		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;
@@ -17578,24 +17354,24 @@
 /*
  * Below Table describe whether RSO command can be send down to fimrware or not.
  * Host check it on the basis of previous RSO command sent down to firmware.
- *||==========================================================================||
- *|| New cmd        |            LAST SENT COMMAND --->                       ||
- *||====|=====================================================================||
- *||    V           | START | STOP | RESTART | UPDATE_CFG| ABORT_SCAN         ||
- *|| -------------------------------------------------------------------------||
- *|| RSO_START      | NO    | YES  |  NO     | NO        | NO                 ||
- *|| RSO_STOP       | YES   | YES  |  YES    | YES       | YES                ||
- *|| RSO_RESTART    | YES   | YES  |  NO     | YES       | YES                ||
- *|| RSO_UPDATE_CFG | YES   | NO   |  YES    | YES       | YES                ||
- *|| RSO_ABORT_SCAN | YES   | NO   |  YES    | YES       | YES                ||
- *||==========================================================================||
+ * ||=========================================================================||
+ * || New cmd        |            LAST SENT COMMAND --->                      ||
+ * ||====|====================================================================||
+ * ||    V           | START | STOP | RESTART | UPDATE_CFG| ABORT_SCAN        ||
+ * || ------------------------------------------------------------------------||
+ * || RSO_START      | NO    | YES  |  NO     | YES       | NO                ||
+ * || RSO_STOP       | YES   | YES  |  YES    | YES       | YES               ||
+ * || RSO_RESTART    | YES   | YES  |  NO     | YES       | YES               ||
+ * || RSO_UPDATE_CFG | YES   | NO   |  YES    | YES       | YES               ||
+ * || RSO_ABORT_SCAN | YES   | NO   |  YES    | YES       | YES               ||
+ * ||=========================================================================||
  **/
 #define RSO_START_BIT       (1<<ROAM_SCAN_OFFLOAD_START)
 #define RSO_STOP_BIT        (1<<ROAM_SCAN_OFFLOAD_STOP)
 #define RSO_RESTART_BIT     (1<<ROAM_SCAN_OFFLOAD_RESTART)
 #define RSO_UPDATE_CFG_BIT  (1<<ROAM_SCAN_OFFLOAD_UPDATE_CFG)
 #define RSO_ABORT_SCAN_BIT  (1<<ROAM_SCAN_OFFLOAD_ABORT_SCAN)
-#define RSO_START_ALLOW_MASK   (RSO_STOP_BIT)
+#define RSO_START_ALLOW_MASK   (RSO_STOP_BIT | RSO_UPDATE_CFG_BIT)
 #define RSO_STOP_ALLOW_MASK    (RSO_UPDATE_CFG_BIT | RSO_RESTART_BIT | \
 		RSO_STOP_BIT | RSO_START_BIT | RSO_ABORT_SCAN_BIT)
 #define RSO_RESTART_ALLOW_MASK (RSO_UPDATE_CFG_BIT | RSO_START_BIT | \
@@ -17988,7 +17764,7 @@
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	if ((true == b_roam_scan_offload_started)
+	if ((true == roam_info->b_roam_scan_offload_started)
 	    && (ROAM_SCAN_OFFLOAD_START == command)) {
 		sme_err("Roam Scan Offload is already started");
 		return QDF_STATUS_E_FAILURE;
@@ -18142,9 +17918,9 @@
 		return QDF_STATUS_E_FAILURE;
 	}
 	if (ROAM_SCAN_OFFLOAD_START == command)
-		b_roam_scan_offload_started = true;
+		roam_info->b_roam_scan_offload_started = true;
 	else if (ROAM_SCAN_OFFLOAD_STOP == command)
-		b_roam_scan_offload_started = false;
+		roam_info->b_roam_scan_offload_started = false;
 
 	/* update the last sent cmd */
 	roam_info->last_sent_cmd = command;
@@ -18177,102 +17953,6 @@
 }
 #endif
 
-tCsrPeStatsReqInfo *csr_roam_check_pe_stats_req_list(tpAniSirGlobal pMac,
-						     uint32_t statsMask,
-						     uint32_t periodicity,
-						     bool *pFound,
-						     uint8_t staId,
-							uint8_t sessionId)
-{
-	bool found = false;
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
-	tCsrPeStatsReqInfo staEntry;
-	tCsrPeStatsReqInfo *pTempStaEntry = NULL;
-	tListElem *pStaEntry = NULL;
-	QDF_STATUS qdf_status;
-	*pFound = false;
-
-	pStaEntry = csr_roam_find_in_pe_stats_req_list(pMac, statsMask);
-	if (pStaEntry) {
-		pTempStaEntry =
-			GET_BASE_ADDR(pStaEntry, tCsrPeStatsReqInfo, link);
-		if (pTempStaEntry->periodicity) {
-			pTempStaEntry->periodicity =
-				QDF_MIN(periodicity,
-					pTempStaEntry->periodicity);
-		} else {
-			pTempStaEntry->periodicity = periodicity;
-		}
-		pTempStaEntry->numClient++;
-		found = true;
-	} else {
-		qdf_mem_set(&staEntry, sizeof(tCsrPeStatsReqInfo), 0);
-		staEntry.numClient = 1;
-		staEntry.periodicity = periodicity;
-		staEntry.pMac = pMac;
-		staEntry.rspPending = false;
-		staEntry.staId = staId;
-		staEntry.statsMask = statsMask;
-		staEntry.timerRunning = false;
-		staEntry.sessionId = sessionId;
-		pTempStaEntry = csr_roam_insert_entry_into_pe_stats_req_list(
-								pMac,
-								&pMac->roam.
-								peStatsReqList,
-								&staEntry);
-		if (!pTempStaEntry) {
-			sme_err(
-				"Failed to insert req in peStatsReqList");
-			return NULL;
-		}
-	}
-	pTempStaEntry->periodicity =
-		pMac->roam.configParam.statsReqPeriodicityInPS;
-
-	if (!pTempStaEntry->timerRunning) {
-		/* send down a req in case of one time req, for periodic ones
-		 * wait for timer to expire
-		 */
-		if (!pTempStaEntry->rspPending && !pTempStaEntry->periodicity) {
-			status = csr_send_mb_stats_req_msg(pMac,
-							   statsMask & ~(1 <<
-							eCsrGlobalClassDStats),
-							   staId, sessionId);
-			if (!QDF_IS_STATUS_SUCCESS(status))
-				sme_err("csr_roam_check_pe_stats_req_list:failed to send down stats req to PE");
-			else
-				pTempStaEntry->rspPending = true;
-		}
-		if (pTempStaEntry->periodicity) {
-			if (!found) {
-
-				qdf_status = qdf_mc_timer_init(&pTempStaEntry->
-							  hPeStatsTimer,
-							  QDF_TIMER_TYPE_SW,
-						csr_roam_pe_stats_timer_handler,
-							  pTempStaEntry);
-				if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
-					sme_err("csr_roam_check_pe_stats_req_list:cannot init hPeStatsTimer timer");
-					return NULL;
-				}
-			}
-			/* start timer */
-			sme_debug("csr_roam_check_pe_stats_req_list:peStatsTimer period %d",
-				pTempStaEntry->periodicity);
-			qdf_status = qdf_mc_timer_start(&pTempStaEntry->
-							hPeStatsTimer,
-						   pTempStaEntry->periodicity);
-			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
-				sme_err("csr_roam_check_pe_stats_req_list:cannot start hPeStatsTimer timer");
-				return NULL;
-			}
-			pTempStaEntry->timerRunning = true;
-		}
-	}
-	*pFound = found;
-	return pTempStaEntry;
-}
-
 /* pStaEntry is no longer invalid upon the return of this function. */
 static void csr_roam_remove_stat_list_entry(tpAniSirGlobal pMac,
 						tListElem *pEntry)
@@ -18290,7 +17970,6 @@
 {
 	tListElem *pEntry;
 	tCsrPeStatsReqInfo *pTempStaEntry;
-	QDF_STATUS qdf_status;
 
 	pEntry = csr_ll_peek_head(&pMac->roam.peStatsReqList, LL_ACCESS_LOCK);
 	if (!pEntry) {
@@ -18307,42 +17986,10 @@
 			continue;
 		}
 		sme_debug("Match found");
-		if (pTempStaEntry->timerRunning) {
-			qdf_status = qdf_mc_timer_stop(
-					&pTempStaEntry->hPeStatsTimer);
-			/*
-			 * If we are not able to stop the timer here, just
-			 * remove the entry from the linked list. Destroy the
-			 * timer object and free the memory in the timer CB
-			 */
-			if (qdf_status == QDF_STATUS_SUCCESS) {
-				/* the timer is successfully stopped */
-				pTempStaEntry->timerRunning = false;
-				/* Destroy the timer */
-				qdf_status = qdf_mc_timer_destroy(
-						&pTempStaEntry->hPeStatsTimer);
-			} else {
-				/*
-				 * the timer could not be stopped. Hence destroy
-				 * and free the memory for the PE stat entry in
-				 * the timer CB.
-				 */
-				pTempStaEntry->timerStopFailed = true;
-			}
-			if (!QDF_IS_STATUS_SUCCESS(qdf_status))
-				sme_err("failed to stop/destroy timer");
-		}
-
 		if (csr_ll_remove_entry(&pMac->roam.peStatsReqList, pEntry,
 					LL_ACCESS_LOCK)) {
-			/*
-			 * Only free the memory if we could stop the timer
-			 * successfully
-			 */
-			if (!pTempStaEntry->timerStopFailed) {
-				qdf_mem_free(pTempStaEntry);
-				pTempStaEntry = NULL;
-			}
+			qdf_mem_free(pTempStaEntry);
+			pTempStaEntry = NULL;
 			break;
 		}
 		pEntry = csr_ll_next(&pMac->roam.peStatsReqList, pEntry,
@@ -18426,7 +18073,6 @@
 	tListElem *pPrevEntry = NULL;
 	tCsrStatsClientReqInfo *pTempStaEntry = NULL;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
-	QDF_STATUS qdf_status;
 
 	pEntry = csr_ll_peek_head(&pMac->roam.statsClientReqList,
 							LL_ACCESS_LOCK);
@@ -18465,38 +18111,9 @@
 		}
 		/* check if we need to stop the tl stats timer too */
 		pMac->roam.tlStatsReqInfo.numClient--;
-		if (!pMac->roam.tlStatsReqInfo.numClient) {
-			if (pMac->roam.tlStatsReqInfo.timerRunning) {
-				status =
-					qdf_mc_timer_stop(&pMac->roam.
-							  tlStatsReqInfo.
-							  hTlStatsTimer);
-				if (!QDF_IS_STATUS_SUCCESS(status))
-					sme_err("csr_roam_dereg_statistics_req:cannot stop TlStatsTimer timer");
-					/* we will continue */
-			}
-			pMac->roam.tlStatsReqInfo.periodicity = 0;
-			pMac->roam.tlStatsReqInfo.timerRunning = false;
-		}
-		if (pTempStaEntry->periodicity) {
-			/* While creating StaEntry in csr_get_statistics,
-			 * Initializing and starting timer only when periodicity
-			 * is set. So Stop and Destroy timer only when
-			 * periodicity is set.
-			 */
-
-			qdf_mc_timer_stop(&pTempStaEntry->timer);
-			/* Destroy the qdf timer... */
-			qdf_status =
-				qdf_mc_timer_destroy(&pTempStaEntry->timer);
-			if (!QDF_IS_STATUS_SUCCESS(qdf_status))
-				sme_err("csr_roam_dereg_statistics_req:failed to destroy Client req timer");
-		}
-
 		pPrevEntry = pEntry;
-		pEntry =
-			csr_ll_next(&pMac->roam.statsClientReqList, pEntry,
-				    LL_ACCESS_NOLOCK);
+		pEntry = csr_ll_next(&pMac->roam.statsClientReqList, pEntry,
+				     LL_ACCESS_NOLOCK);
 	}
 	/* the last one */
 	if (pPrevEntry) {
@@ -20201,24 +19818,24 @@
 			return QDF_STATUS_E_FAILURE;
 		}
 		csr_roam_call_callback(mac_ctx, session_id, NULL, 0,
-				eCSR_ROAM_FT_START, eSIR_SME_SUCCESS);
+				eCSR_ROAM_FT_START, eCSR_ROAM_RESULT_SUCCESS);
 		return status;
 	case SIR_ROAMING_START:
 		csr_roam_roaming_offload_timer_action(mac_ctx,
 				CSR_ROAMING_OFFLOAD_TIMEOUT_PERIOD, session_id,
 				ROAMING_OFFLOAD_TIMER_START);
 		csr_roam_call_callback(mac_ctx, session_id, NULL, 0,
-				eCSR_ROAM_START, eSIR_SME_SUCCESS);
+				eCSR_ROAM_START, eCSR_ROAM_RESULT_SUCCESS);
 		return status;
 	case SIR_ROAMING_ABORT:
 		csr_roam_roaming_offload_timer_action(mac_ctx,
 				0, session_id, ROAMING_OFFLOAD_TIMER_STOP);
 		csr_roam_call_callback(mac_ctx, session_id, NULL, 0,
-				eCSR_ROAM_ABORT, eSIR_SME_SUCCESS);
+				eCSR_ROAM_ABORT, eCSR_ROAM_RESULT_SUCCESS);
 		return status;
 	case SIR_ROAM_SYNCH_NAPI_OFF:
 		csr_roam_call_callback(mac_ctx, session_id, NULL, 0,
-				eCSR_ROAM_NAPI_OFF, eSIR_SME_SUCCESS);
+				eCSR_ROAM_NAPI_OFF, eCSR_ROAM_RESULT_SUCCESS);
 		return status;
 	case SIR_ROAMING_INVOKE_FAIL:
 		csr_roam_call_callback(mac_ctx, session_id, NULL, 0,
@@ -20440,7 +20057,6 @@
 		eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED;
 	sme_qos_csr_event_ind(mac_ctx, session_id,
 		SME_QOS_CSR_REASSOC_COMPLETE, &assoc_info);
-	sme_qos_remove_addts_delts_cmd(mac_ctx, session_id);
 	roam_info->pBssDesc = bss_desc;
 	conn_profile->acm_mask = sme_qos_get_acm_mask(mac_ctx,
 			bss_desc, NULL);
diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c
index ea915e9..0748943 100644
--- a/core/sme/src/csr/csr_api_scan.c
+++ b/core/sme/src/csr/csr_api_scan.c
@@ -3380,13 +3380,14 @@
 		}
 		if (CSR_ROAM_SESSION_MAX == i) {
 			uint32_t len = QDF_MAC_ADDR_SIZE;
+			tSirRetStatus sir_status;
 
-			status = wlan_cfg_get_str(pMac, WNI_CFG_STA_ID,
+			sir_status = wlan_cfg_get_str(pMac, WNI_CFG_STA_ID,
 						  selfmac.bytes, &len);
-			if (!QDF_IS_STATUS_SUCCESS(status)
+			if ((sir_status != eSIR_SUCCESS)
 			    || (len < QDF_MAC_ADDR_SIZE)) {
-				sme_err("Can't get self MAC address: %d",
-					status);
+				sme_err("Can't get self MAC: status:%d len:%d",
+					sir_status, len);
 				status = QDF_STATUS_E_FAILURE;
 				goto send_scan_req;
 			}
@@ -4603,18 +4604,20 @@
 QDF_STATUS csr_get_country_code(tpAniSirGlobal pMac, uint8_t *pBuf,
 				uint8_t *pbLen)
 {
-	QDF_STATUS status = QDF_STATUS_E_INVAL;
+	tSirRetStatus status;
 	uint32_t len;
 
 	if (pBuf && pbLen && (*pbLen >= WNI_CFG_COUNTRY_CODE_LEN)) {
 		len = *pbLen;
 		status = wlan_cfg_get_str(pMac, WNI_CFG_COUNTRY_CODE, pBuf,
 					&len);
-		if (QDF_IS_STATUS_SUCCESS(status))
+		if (status == eSIR_SUCCESS) {
 			*pbLen = (uint8_t) len;
+			return QDF_STATUS_SUCCESS;
+		}
 	}
 
-	return status;
+	return QDF_STATUS_E_INVAL;
 }
 
 void csr_set_cfg_scan_control_list(tpAniSirGlobal pMac, uint8_t *countryCode,
diff --git a/core/sme/src/csr/csr_host_scan_roam.c b/core/sme/src/csr/csr_host_scan_roam.c
index 1ac0d18..2f1c656 100644
--- a/core/sme/src/csr/csr_host_scan_roam.c
+++ b/core/sme/src/csr/csr_host_scan_roam.c
@@ -616,7 +616,7 @@
 
 	qdf_mem_zero(&roam_info, sizeof(tCsrRoamInfo));
 	csr_roam_call_callback(mac_ctx, session_id, &roam_info, roamid,
-			       eCSR_ROAM_FT_START, eSIR_SME_SUCCESS);
+			       eCSR_ROAM_FT_START, eCSR_ROAM_RESULT_SUCCESS);
 
 	qdf_mem_zero(&roam_info, sizeof(tCsrRoamInfo));
 	csr_neighbor_roam_state_transition(mac_ctx,
diff --git a/core/sme/src/csr/csr_neighbor_roam.c b/core/sme/src/csr/csr_neighbor_roam.c
index 61931cb..15b94e3 100644
--- a/core/sme/src/csr/csr_neighbor_roam.c
+++ b/core/sme/src/csr/csr_neighbor_roam.c
@@ -1420,6 +1420,7 @@
 						 &pNeighborRoamInfo->FTRoamInfo.
 						 preAuthDoneList);
 	csr_ll_close(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList);
+	pNeighborRoamInfo->b_roam_scan_offload_started = false;
 
 	csr_neighbor_roam_state_transition(pMac,
 		eCSR_NEIGHBOR_ROAM_STATE_CLOSED, sessionId);
diff --git a/core/sme/src/nan/nan_datapath_api.c b/core/sme/src/nan/nan_datapath_api.c
index f70d2bf..44b1e66 100644
--- a/core/sme/src/nan/nan_datapath_api.c
+++ b/core/sme/src/nan/nan_datapath_api.c
@@ -372,7 +372,6 @@
 		sizeof(connect_profile), 0);
 	connect_profile->AuthType = roam_profile->negotiatedAuthType;
 		connect_profile->AuthInfo = roam_profile->AuthType;
-	connect_profile->CBMode = roam_profile->CBMode;
 	connect_profile->EncryptionType =
 		roam_profile->negotiatedUCEncryptionType;
 		connect_profile->EncryptionInfo = roam_profile->EncryptionType;
diff --git a/core/sme/src/p2p/p2p_api.c b/core/sme/src/p2p/p2p_api.c
index 710ec5d..3b99871 100644
--- a/core/sme/src/p2p/p2p_api.c
+++ b/core/sme/src/p2p/p2p_api.c
@@ -117,9 +117,12 @@
 		return status;
 
 	callback = pCommand->u.remainChlCmd.callback;
-	if (callback)
+	if (callback && rsp) {
+		if (rsp->status != eSIR_SME_SUCCESS)
+			status = QDF_STATUS_E_FAILURE;
 		callback(pMac, pCommand->u.remainChlCmd.callbackCtx,
-			rsp->status, rsp->scan_id);
+				status, rsp->scan_id);
+	}
 
 	fFound = csr_scan_active_ll_remove_entry(pMac, pEntry,
 				     LL_ACCESS_LOCK);
diff --git a/core/sme/src/qos/sme_qos.c b/core/sme/src/qos/sme_qos.c
index 993eefb..b5bbe98 100644
--- a/core/sme/src/qos/sme_qos.c
+++ b/core/sme/src/qos/sme_qos.c
@@ -908,27 +908,6 @@
 	return status;
 }
 
-void sme_qos_remove_addts_delts_cmd(tpAniSirGlobal mac_ctx, uint8_t session_id)
-{
-	tListElem *entry;
-	tSmeCmd *command;
-
-	entry = csr_nonscan_active_ll_peek_head(mac_ctx, LL_ACCESS_LOCK);
-	if (NULL == entry)
-		return;
-	command = GET_BASE_ADDR(entry, tSmeCmd, Link);
-	if ((eSmeCommandAddTs   == command->command ||
-	    eSmeCommandDelTs == command->command) &&
-	    command->sessionId == session_id) {
-		if (csr_nonscan_active_ll_remove_entry(mac_ctx, entry,
-		    LL_ACCESS_LOCK)) {
-			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
-				  "%s: removed addts/delts command", __func__);
-			qos_release_command(mac_ctx, command);
-		}
-	}
-}
-
 /*--------------------------------------------------------------------------
    \brief sme_qos_csr_event_ind() - The QoS sub-module in SME expects notifications
    from CSR when certain events occur as mentioned in sme_qos_csr_event_indType.
@@ -2962,7 +2941,7 @@
 	pAddtsRsp->rc = eSIR_SUCCESS;
 	pAddtsRsp->sessionId = sessionId;
 	pAddtsRsp->rsp.dialogToken = 0;
-	pAddtsRsp->rsp.status = eSIR_SUCCESS;
+	pAddtsRsp->rsp.status = eSIR_MAC_SUCCESS_STATUS;
 	pAddtsRsp->rsp.wmeTspecPresent = pTspec->present;
 	QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
 		  "%s: Copy Tspec to local data structure ac=%d, tspecIdx=%d",
@@ -6771,7 +6750,7 @@
 	if (!QDF_IS_STATUS_SUCCESS(lock_status)) {
 		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
 			  "%s: %d: Unable to obtain lock", __func__, __LINE__);
-		return SME_QOS_STATUS_RELEASE_FAILURE_RSP;
+		return QDF_STATUS_E_FAILURE;
 	}
 	/* Call the internal function for QoS release, adding a layer of abstraction */
 	status =
@@ -7538,10 +7517,8 @@
 				sme_qos_add_ts_req(pMac, (uint8_t) pCommand->sessionId,
 						   &pCommand->u.qosCmd.tspecInfo,
 						   pCommand->u.qosCmd.ac);
-			if (QDF_IS_STATUS_SUCCESS(status)) {
+			if (QDF_IS_STATUS_SUCCESS(status))
 				fRemoveCmd = false;
-				status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP;
-			}
 			break;
 		case eSmeCommandDelTs:
 			status =
diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h
index 1ff0697..f0c79e7 100644
--- a/core/wma/inc/wma.h
+++ b/core/wma/inc/wma.h
@@ -40,6 +40,7 @@
 #include "cfg_api.h"
 #include "qdf_status.h"
 #include "cds_sched.h"
+#include "cds_config.h"
 #include "sir_mac_prot_def.h"
 #include "wma_types.h"
 #include <linux/workqueue.h>
@@ -520,18 +521,6 @@
 typedef void (*tp_wma_packetdump_cb)(qdf_nbuf_t netbuf,
 			uint8_t status, uint8_t vdev_id, uint8_t type);
 
-/**
- * enum t_wma_drv_type - wma driver type
- * @WMA_DRIVER_TYPE_PRODUCTION: production driver type
- * @WMA_DRIVER_TYPE_MFG: manufacture driver type
- * @WMA_DRIVER_TYPE_INVALID: invalid driver type
- */
-typedef enum {
-	WMA_DRIVER_TYPE_PRODUCTION = 0,
-	WMA_DRIVER_TYPE_MFG = 1,
-	WMA_DRIVER_TYPE_INVALID = 0x7FFFFFFF
-} t_wma_drv_type;
-
 #ifdef FEATURE_WLAN_TDLS
 /**
  * enum t_wma_tdls_mode - TDLS mode
@@ -1364,7 +1353,7 @@
 	qdf_event_t recovery_event;
 	uint16_t max_station;
 	uint16_t max_bssid;
-	t_wma_drv_type driver_type;
+	enum driver_type driver_type;
 	uint8_t myaddr[IEEE80211_ADDR_LEN];
 	uint8_t hwaddr[IEEE80211_ADDR_LEN];
 	wmi_abi_version target_abi_vers;
@@ -1571,7 +1560,7 @@
 typedef struct {
 	void *pConfigBuffer;
 	uint16_t usConfigBufferLen;
-	t_wma_drv_type driver_type;
+	enum driver_type driver_type;
 	void *pUserData;
 	void *pIndUserData;
 } t_wma_start_req;
diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h
index 35cd3b5..f31ff21 100644
--- a/core/wma/inc/wma_internal.h
+++ b/core/wma/inc/wma_internal.h
@@ -721,7 +721,14 @@
 
 int32_t wmi_unified_send_txbf(tp_wma_handle wma, tpAddStaParams params);
 
-void wma_update_txrx_chainmask(int num_rf_chains, int *cmd_value);
+/**
+ * wma_check_txrx_chainmask() - check txrx chainmask
+ * @num_rf_chains: number of rf chains
+ * @cmd_value: command value
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS wma_check_txrx_chainmask(int num_rf_chains, int cmd_value);
 
 int wma_peer_state_change_event_handler(void *handle,
 					       uint8_t *event_buff,
@@ -1254,4 +1261,17 @@
 int wma_rx_aggr_failure_event_handler(void *handle, u_int8_t *event_buf,
 							u_int32_t len);
 
+/**
+ * wma_wlan_bt_activity_evt_handler - event handler to handle bt activity
+ * @handle: the WMA handle
+ * @event: buffer with the event parameters
+ * @len: length of the buffer
+ *
+ * This function receives BT activity event from firmware and passes the event
+ * information to upper layers
+ *
+ * Return: 0 on success
+ */
+int wma_wlan_bt_activity_evt_handler(void *handle, uint8_t *event,
+				     uint32_t len);
 #endif
diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c
index 97eec99..d6bb573 100644
--- a/core/wma/src/wma_data.c
+++ b/core/wma/src/wma_data.c
@@ -913,27 +913,21 @@
 }
 
 /**
- * wma_update_txrx_chainmask() - update txrx chainmask
- * @num_rf_chains: number rf chains
+ * wma_check_txrx_chainmask() - check txrx chainmask
+ * @num_rf_chains: number of rf chains
  * @cmd_value: command value
  *
- * Return: none
+ * Return: QDF_STATUS_SUCCESS for success or error code
  */
-void wma_update_txrx_chainmask(int num_rf_chains, int *cmd_value)
+QDF_STATUS wma_check_txrx_chainmask(int num_rf_chains, int cmd_value)
 {
-	if (*cmd_value > WMA_MAX_RF_CHAINS(num_rf_chains)) {
-		WMA_LOGE("%s: Chainmask value exceeds the maximum supported range setting it to maximum value.",
-			__func__);
-		WMA_LOGE("%s: Requested value %d Updated value %d",
-			__func__, *cmd_value, WMA_MAX_RF_CHAINS(num_rf_chains));
-		*cmd_value = WMA_MAX_RF_CHAINS(num_rf_chains);
-	} else if (*cmd_value < WMA_MIN_RF_CHAINS) {
-		WMA_LOGE("%s: Chainmask value is less than the minimum supported range setting it to minimum value.",
-			__func__);
-		WMA_LOGE("%s: Requested value %d Updated value %d",
-			__func__, *cmd_value, WMA_MIN_RF_CHAINS);
-		*cmd_value = WMA_MIN_RF_CHAINS;
+	if ((cmd_value > WMA_MAX_RF_CHAINS(num_rf_chains)) ||
+	    (cmd_value < WMA_MIN_RF_CHAINS)) {
+		WMA_LOGE("%s: Requested value %d over the range",
+			__func__, cmd_value);
+		return QDF_STATUS_E_INVAL;
 	}
+	return QDF_STATUS_SUCCESS;
 }
 
 /**
@@ -968,7 +962,7 @@
 	event = param_buf->fixed_param;
 	vdev = wma_find_vdev_by_id(wma_handle, event->vdev_id);
 	if (NULL == vdev) {
-		WMA_LOGP("%s: Couldn't find vdev for vdev_id: %d",
+		WMA_LOGD("%s: Couldn't find vdev for vdev_id: %d",
 			 __func__, event->vdev_id);
 		return -EINVAL;
 	}
diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c
index c18df48..98b3a8b 100644
--- a/core/wma/src/wma_dev_if.c
+++ b/core/wma/src/wma_dev_if.c
@@ -650,8 +650,13 @@
 	if (!iface->handle) {
 		WMA_LOGE("handle of vdev_id %d is NULL vdev is already freed",
 			 vdev_id);
-		qdf_mem_free(pdel_sta_self_req_param);
-		pdel_sta_self_req_param = NULL;
+		pdel_sta_self_req_param->status = status;
+		if (generateRsp) {
+			wma_send_del_sta_self_resp(pdel_sta_self_req_param);
+		} else {
+			qdf_mem_free(pdel_sta_self_req_param);
+			pdel_sta_self_req_param = NULL;
+		}
 		return status;
 	}
 
@@ -2025,7 +2030,7 @@
 	    (self_sta_req->type == WMI_VDEV_TYPE_OCB) ||
 	    (self_sta_req->type == WMI_VDEV_TYPE_MONITOR) ||
 	    (self_sta_req->type == WMI_VDEV_TYPE_NDI)) {
-		WMA_LOGA("Creating self peer %pM, vdev_id %hu",
+		WMA_LOGD("Creating self peer %pM, vdev_id %hu",
 			 self_sta_req->self_mac_addr, self_sta_req->session_id);
 		status = wma_create_peer(wma_handle, txrx_pdev,
 					 txrx_vdev_handle,
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
index a499028..bebac44 100644
--- a/core/wma/src/wma_features.c
+++ b/core/wma/src/wma_features.c
@@ -1306,8 +1306,7 @@
 	 * basic sanity check: requested channel should not be 0
 	 * and equal to home channel
 	 */
-	if ((0 == csa_offload_event->channel) ||
-	    (cur_chan == csa_offload_event->channel)) {
+	if (0 == csa_offload_event->channel) {
 		WMA_LOGE("CSA Event with channel %d. Ignore !!",
 			 csa_offload_event->channel);
 		qdf_mem_free(csa_offload_event);
@@ -5406,3 +5405,38 @@
 
 	return 0;
 }
+
+int wma_wlan_bt_activity_evt_handler(void *handle, uint8_t *event, uint32_t len)
+{
+	wmi_coex_bt_activity_event_fixed_param *fixed_param;
+	WMI_WLAN_COEX_BT_ACTIVITY_EVENTID_param_tlvs *param_buf =
+		(WMI_WLAN_COEX_BT_ACTIVITY_EVENTID_param_tlvs *)event;
+	struct scheduler_msg sme_msg = {0};
+	QDF_STATUS qdf_status;
+
+	if (!param_buf) {
+		WMA_LOGE(FL("Invalid BT activity event buffer"));
+		return -EINVAL;
+	}
+
+	fixed_param = param_buf->fixed_param;
+	if (!fixed_param) {
+		WMA_LOGE(FL("Invalid BT activity event fixed param buffer"));
+		return -EINVAL;
+	}
+
+	WMA_LOGI(FL("Received BT activity event %u"),
+		    fixed_param->coex_profile_evt);
+
+	sme_msg.type = eWNI_SME_BT_ACTIVITY_INFO_IND;
+	sme_msg.bodyptr = NULL;
+	sme_msg.bodyval = fixed_param->coex_profile_evt;
+
+	qdf_status = scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		WMA_LOGE(FL("Failed to post msg to SME"));
+		return -EINVAL;
+	}
+
+	return 0;
+}
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index 9c7f205..6a8e431 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -947,8 +947,13 @@
 			 privcmd->param_value);
 		if ((privcmd->param_id == WMI_PDEV_PARAM_RX_CHAIN_MASK) ||
 		    (privcmd->param_id == WMI_PDEV_PARAM_TX_CHAIN_MASK)) {
-			wma_update_txrx_chainmask(wma->num_rf_chains,
-						  &privcmd->param_value);
+			if (QDF_STATUS_SUCCESS !=
+					wma_check_txrx_chainmask(
+					wma->num_rf_chains,
+					privcmd->param_value)) {
+				WMA_LOGD("Chainmask value is invalid");
+				return;
+			}
 		}
 		pdev_param.param_id = privcmd->param_id;
 		pdev_param.param_value = privcmd->param_value;
@@ -1732,7 +1737,7 @@
 		return;
 	}
 
-	while (qdf_list_peek_front(&wma->vdev_resp_queue, &node1) ==
+	while (qdf_list_remove_front(&wma->vdev_resp_queue, &node1) ==
 				   QDF_STATUS_SUCCESS) {
 		req_msg = qdf_container_of(node1, struct wma_target_req, node);
 		qdf_spin_unlock_bh(&wma->vdev_respq_lock);
@@ -1762,7 +1767,7 @@
 	}
 
 	while (QDF_STATUS_SUCCESS ==
-			qdf_list_peek_front(&wma->wma_hold_req_queue, &node1)) {
+		qdf_list_remove_front(&wma->wma_hold_req_queue, &node1)) {
 		req_msg = qdf_container_of(node1, struct wma_target_req, node);
 		qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
 		/* Cleanup timeout handler */
@@ -3343,6 +3348,16 @@
 	}
 #endif
 
+	status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
+			WMI_WLAN_COEX_BT_ACTIVITY_EVENTID,
+			wma_wlan_bt_activity_evt_handler,
+			WMA_RX_SERIALIZER_CTX);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		WMA_LOGE("Failed to register coex bt activity event handler");
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
 end:
 	WMA_LOGD("%s: Exit", __func__);
 	return qdf_status;
diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c
index bf34359..2418d03 100644
--- a/core/wma/src/wma_mgmt.c
+++ b/core/wma/src/wma_mgmt.c
@@ -1839,6 +1839,11 @@
 	     key_info->encType == eSIR_ED_WEP104)) {
 		wma_read_cfg_wepkey(wma_handle, key_info->key,
 				    &def_key_idx, &key_info->numKeys);
+	} else if ((key_info->encType == eSIR_ED_WEP40) ||
+		   (key_info->encType == eSIR_ED_WEP104)) {
+		struct wma_txrx_node *intf =
+			&wma_handle->interfaces[key_info->smesessionId];
+		key_params.def_key_idx = intf->wep_default_key_idx;
 	}
 
 	for (i = 0; i < key_info->numKeys; i++) {
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index 242f8a2..8f54da2 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -1577,11 +1577,12 @@
 {
 	int i;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
-	uint32_t len = 0, num_bssid_black_list = 0, num_ssid_white_list = 0,
+	uint32_t num_bssid_black_list = 0, num_ssid_white_list = 0,
 	   num_bssid_preferred_list = 0;
 	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,29 +1591,33 @@
 	}
 
 	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:
 			op_bitmap |= 0x1;
 			num_bssid_black_list =
 				roam_params->num_bssid_avoid_list;
-			len = num_bssid_black_list * sizeof(wmi_mac_addr);
-			len += WMI_TLV_HDR_SIZE;
 			break;
 		case REASON_ROAM_SET_SSID_ALLOWED:
 			op_bitmap |= 0x2;
 			num_ssid_white_list =
 				roam_params->num_ssid_allowed_list;
-			len = num_ssid_white_list * sizeof(wmi_ssid);
-			len += WMI_TLV_HDR_SIZE;
 			break;
 		case REASON_ROAM_SET_FAVORED_BSSID:
 			op_bitmap |= 0x4;
 			num_bssid_preferred_list =
 				roam_params->num_bssid_favored;
-			len = num_bssid_preferred_list * sizeof(wmi_mac_addr);
-			len += WMI_TLV_HDR_SIZE;
-			len += num_bssid_preferred_list * sizeof(A_UINT32);
+			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__);
@@ -1626,11 +1631,7 @@
 		 */
 		op_bitmap = 0x2 | 0x4;
 		num_ssid_white_list = roam_params->num_ssid_allowed_list;
-		len = num_ssid_white_list * sizeof(wmi_ssid);
 		num_bssid_preferred_list = roam_params->num_bssid_favored;
-		len += num_bssid_preferred_list * sizeof(wmi_mac_addr);
-		len += num_bssid_preferred_list * sizeof(A_UINT32);
-		len += (2 * WMI_TLV_HDR_SIZE);
 	}
 
 	/* fill in fixed values */
@@ -1639,7 +1640,6 @@
 	params->num_bssid_black_list = num_bssid_black_list;
 	params->num_ssid_white_list = num_ssid_white_list;
 	params->num_bssid_preferred_list = num_bssid_preferred_list;
-	params->len = len;
 	qdf_mem_copy(params->bssid_avoid_list, roam_params->bssid_avoid_list,
 			MAX_BSSID_AVOID_LIST * sizeof(struct qdf_mac_addr));
 
@@ -1660,6 +1660,14 @@
 	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);
 
@@ -1858,6 +1866,33 @@
 		break;
 
 	case ROAM_SCAN_OFFLOAD_STOP:
+		/*
+		 * If roam synch propagation is in progress and an user space
+		 * disconnect is requested, then there is no need to send the
+		 * RSO STOP to firmware, since the roaming is already complete.
+		 * If the RSO STOP is sent to firmware, then an HO_FAIL will be
+		 * generated and the expectation from firmware would be to
+		 * clean up the peer context on the host and not send down any
+		 * WMI PEER DELETE commands to firmware. But, if the user space
+		 * disconnect gets processed first, then there is a chance to
+		 * send down the PEER DELETE commands. Hence, if we do not
+		 * receive the HO_FAIL, and we complete the roam sync
+		 * propagation, then the host and firmware will be in sync with
+		 * respect to the peer and then the user space disconnect can
+		 * be handled gracefully in a normal way.
+		 *
+		 * Ensure to check the reason code since the RSO Stop might
+		 * come when roam sync failed as well and at that point it
+		 * should go through to the firmware and receive HO_FAIL
+		 * and clean up.
+		 */
+		if (wma_is_roam_synch_in_progress(wma_handle,
+				roam_req->sessionId) &&
+				roam_req->reason ==
+				REASON_ROAM_STOP_ALL) {
+				WMA_LOGD("Dont send RSO stop during roam sync");
+				break;
+		}
 		wma_handle->suitable_ap_hb_failure = false;
 		if (wma_handle->roam_offload_enabled) {
 			uint32_t mode;
@@ -2428,9 +2463,10 @@
 			wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
 				roam_synch_ind_ptr, NULL, SIR_ROAMING_ABORT);
 		roam_req = qdf_mem_malloc(sizeof(tSirRoamOffloadScanReq));
-		if (roam_req) {
+		if (roam_req && synch_event) {
 			roam_req->Command = ROAM_SCAN_OFFLOAD_STOP;
 			roam_req->reason = REASON_ROAM_SYNCH_FAILED;
+			roam_req->sessionId = synch_event->vdev_id;
 			wma_process_roaming_config(wma, roam_req);
 		}
 	}
@@ -2967,7 +3003,7 @@
 	if (!QDF_IS_STATUS_SUCCESS(status))
 		WMA_LOGE("policy_mgr_get_current_hw_mode failed");
 
-	if ((params->nss == 2) && !hw_mode.dbs_cap) {
+	if (params->nss == 2) {
 		req.preferred_rx_streams = 2;
 		req.preferred_tx_streams = 2;
 	} else {
diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c
index 1f7e307..7473d75 100644
--- a/core/wma/src/wma_utils.c
+++ b/core/wma/src/wma_utils.c
@@ -1064,9 +1064,26 @@
 		peer_stats[i].vdev_id = wmi_peer_signal->vdev_id;
 		peer_signal = &peer_stats[i].peer_signal_stats;
 
+		WMA_LOGD("%d antennas for peer %d",
+			 wmi_peer_signal->num_chains_valid,
+			 wmi_peer_signal->peer_id);
 		if (dst_len <= result_size) {
-			qdf_mem_copy(peer_signal,
-				     &wmi_peer_signal->vdev_id, dst_len);
+			peer_signal->vdev_id = wmi_peer_signal->vdev_id;
+			peer_signal->peer_id = wmi_peer_signal->peer_id;
+			peer_signal->num_chain =
+					wmi_peer_signal->num_chains_valid;
+			qdf_mem_copy(peer_signal->per_ant_snr,
+				     wmi_peer_signal->per_chain_snr,
+				     sizeof(peer_signal->per_ant_snr));
+			qdf_mem_copy(peer_signal->nf,
+				     wmi_peer_signal->per_chain_nf,
+				     sizeof(peer_signal->nf));
+			qdf_mem_copy(peer_signal->per_ant_rx_mpdus,
+				     wmi_peer_signal->per_antenna_rx_mpdus,
+				     sizeof(peer_signal->per_ant_rx_mpdus));
+			qdf_mem_copy(peer_signal->per_ant_tx_mpdus,
+				     wmi_peer_signal->per_antenna_tx_mpdus,
+				     sizeof(peer_signal->per_ant_tx_mpdus));
 			result_size -= dst_len;
 		} else {
 			WMA_LOGE(FL("Invalid length of PEER signal."));
@@ -3637,6 +3654,7 @@
 		node->stats_rsp->statsMask, get_stats_param->sessionId);
 
 	cmd.session_id = get_stats_param->sessionId;
+	cmd.stats_mask = get_stats_param->statsMask;
 	if (wmi_unified_get_stats_cmd(wma_handle->wmi_handle, &cmd,
 				 node->bssid)) {